@@ -21,6 +21,16 @@ typedef unsigned char _Bool;
2121#endif
2222#endif
2323
24+ #if SIZEOF_UINT64_T == SIZEOF_LONG_LONG
25+ # define INT64T2NUM (x ) LL2NUM(x)
26+ # define UINT64T2NUM (x ) ULL2NUM(x)
27+ #elif SIZEOF_UINT64_T == SIZEOF_LONG
28+ # define INT64T2NUM (x ) LONG2NUM(x)
29+ # define UINT64T2NUM (x ) ULONG2NUM(x)
30+ #else
31+ # error No uint64_t conversion
32+ #endif
33+
2434#include "../simd/simd.h"
2535
2636#ifndef RB_UNLIKELY
@@ -756,26 +766,6 @@ static VALUE json_string_unescape(JSON_ParserState *state, const char *string, c
756766}
757767
758768#define MAX_FAST_INTEGER_SIZE 18
759- static inline VALUE fast_decode_integer (const char * p , const char * pe )
760- {
761- bool negative = false;
762- if (* p == '-' ) {
763- negative = true;
764- p ++ ;
765- }
766-
767- long long memo = 0 ;
768- while (p < pe ) {
769- memo *= 10 ;
770- memo += * p - '0' ;
771- p ++ ;
772- }
773-
774- if (negative ) {
775- memo = - memo ;
776- }
777- return LL2NUM (memo );
778- }
779769
780770static VALUE json_decode_large_integer (const char * start , long len )
781771{
@@ -789,13 +779,16 @@ static VALUE json_decode_large_integer(const char *start, long len)
789779}
790780
791781static inline VALUE
792- json_decode_integer (const char * start , const char * end )
782+ json_decode_integer (uint64_t mantissa , int mantissa_digits , bool negative , const char * start , const char * end )
793783{
794- long len = end - start ;
795- if (RB_LIKELY (len < MAX_FAST_INTEGER_SIZE )) {
796- return fast_decode_integer (start , end );
784+ if (RB_LIKELY (mantissa_digits < MAX_FAST_INTEGER_SIZE )) {
785+ if (negative ) {
786+ return INT64T2NUM (- ((int64_t )mantissa ));
787+ }
788+ return UINT64T2NUM (mantissa );
797789 }
798- return json_decode_large_integer (start , len );
790+
791+ return json_decode_large_integer (start , end - start );
799792}
800793
801794static VALUE json_decode_large_float (const char * start , long len )
@@ -1119,12 +1112,9 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
11191112 state -> cursor ++ ;
11201113 }
11211114
1122- long integer_length = state -> cursor - start ;
1123- if (negative ) integer_length -- ; // Don't count the sign
1124-
1125- if (RB_UNLIKELY (start [0 ] == '0' && integer_length > 1 )) {
1115+ if (RB_UNLIKELY (start [0 ] == '0' && mantissa_digits > 1 )) {
11261116 raise_parse_error_at ("invalid number: %s" , state , start );
1127- } else if (RB_UNLIKELY (integer_length > 1 && negative && start [1 ] == '0' )) {
1117+ } else if (RB_UNLIKELY (mantissa_digits > 1 && negative && start [1 ] == '0' )) {
11281118 raise_parse_error_at ("invalid number: %s" , state , start );
11291119 }
11301120
@@ -1171,7 +1161,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
11711161 }
11721162
11731163 if (integer ) {
1174- return json_push_value (state , config , json_decode_integer (start , state -> cursor ));
1164+ return json_push_value (state , config , json_decode_integer (mantissa , mantissa_digits , negative , start , state -> cursor ));
11751165 }
11761166
11771167 // Adjust exponent based on decimal point position
0 commit comments