@@ -770,16 +770,36 @@ NOINLINE(static) VALUE json_string_unescape(JSON_ParserState *state, JSON_Parser
770770}
771771
772772#define MAX_FAST_INTEGER_SIZE 18
773+ #define MAX_NUMBER_STACK_BUFFER 128
774+
775+ typedef VALUE (* json_number_decode_func_t )(const char * ptr );
776+
777+ static inline VALUE json_decode_large_number (const char * start , long len , json_number_decode_func_t func )
778+ {
779+ if (RB_LIKELY (len < MAX_NUMBER_STACK_BUFFER )) {
780+ char buffer [MAX_NUMBER_STACK_BUFFER ];
781+ MEMCPY (buffer , start , char , len );
782+ buffer [len ] = '\0' ;
783+ return func (buffer );
784+ } else {
785+ VALUE buffer_v = rb_str_tmp_new (len );
786+ char * buffer = RSTRING_PTR (buffer_v );
787+ MEMCPY (buffer , start , char , len );
788+ buffer [len ] = '\0' ;
789+ VALUE number = func (buffer );
790+ RB_GC_GUARD (buffer_v );
791+ return number ;
792+ }
793+ }
794+
795+ static VALUE json_decode_inum (const char * buffer )
796+ {
797+ return rb_cstr2inum (buffer , 10 );
798+ }
773799
774800NOINLINE (static ) VALUE json_decode_large_integer (const char * start , long len )
775801{
776- VALUE buffer_v ;
777- char * buffer = RB_ALLOCV_N (char , buffer_v , len + 1 );
778- MEMCPY (buffer , start , char , len );
779- buffer [len ] = '\0' ;
780- VALUE number = rb_cstr2inum (buffer , 10 );
781- RB_ALLOCV_END (buffer_v );
782- return number ;
802+ return json_decode_large_number (start , len , json_decode_inum );
783803}
784804
785805static inline VALUE json_decode_integer (uint64_t mantissa , int mantissa_digits , bool negative , const char * start , const char * end )
@@ -794,22 +814,14 @@ static inline VALUE json_decode_integer(uint64_t mantissa, int mantissa_digits,
794814 return json_decode_large_integer (start , end - start );
795815}
796816
797- NOINLINE ( static ) VALUE json_decode_large_float (const char * start , long len )
817+ static VALUE json_decode_dnum (const char * buffer )
798818{
799- if (RB_LIKELY (len < 64 )) {
800- char buffer [64 ];
801- MEMCPY (buffer , start , char , len );
802- buffer [len ] = '\0' ;
803- return DBL2NUM (rb_cstr_to_dbl (buffer , 1 ));
804- }
819+ return DBL2NUM (rb_cstr_to_dbl (buffer , 1 ));
820+ }
805821
806- VALUE buffer_v ;
807- char * buffer = RB_ALLOCV_N (char , buffer_v , len + 1 );
808- MEMCPY (buffer , start , char , len );
809- buffer [len ] = '\0' ;
810- VALUE number = DBL2NUM (rb_cstr_to_dbl (buffer , 1 ));
811- RB_ALLOCV_END (buffer_v );
812- return number ;
822+ NOINLINE (static ) VALUE json_decode_large_float (const char * start , long len )
823+ {
824+ return json_decode_large_number (start , len , json_decode_dnum );
813825}
814826
815827/* Ruby JSON optimized float decoder using vendored Ryu algorithm
0 commit comments