@@ -424,7 +424,6 @@ typedef struct JSON_ParserStruct {
424
424
} JSON_ParserConfig ;
425
425
426
426
typedef struct JSON_ParserStateStruct {
427
- JSON_ParserConfig * config ;
428
427
VALUE stack_handle ;
429
428
const char * cursor ;
430
429
const char * end ;
@@ -728,7 +727,7 @@ static VALUE json_decode_large_integer(const char *start, long len)
728
727
}
729
728
730
729
static inline VALUE
731
- json_decode_integer (JSON_ParserState * state , const char * start , const char * end )
730
+ json_decode_integer (const char * start , const char * end )
732
731
{
733
732
long len = end - start ;
734
733
if (RB_LIKELY (len < MAX_FAST_INTEGER_SIZE )) {
@@ -748,11 +747,10 @@ static VALUE json_decode_large_float(const char *start, long len)
748
747
return number ;
749
748
}
750
749
751
- static VALUE json_decode_float (JSON_ParserState * state , const char * start , const char * end )
750
+ static VALUE json_decode_float (JSON_ParserConfig * config , const char * start , const char * end )
752
751
{
753
752
VALUE mod = Qnil ;
754
753
ID method_id = 0 ;
755
- JSON_ParserConfig * config = state -> config ;
756
754
if (RB_UNLIKELY (config -> decimal_class )) {
757
755
// TODO: we should move this to the constructor
758
756
if (rb_respond_to (config -> decimal_class , i_try_convert )) {
@@ -797,11 +795,11 @@ static VALUE json_decode_float(JSON_ParserState *state, const char *start, const
797
795
}
798
796
}
799
797
800
- static inline VALUE json_decode_array (JSON_ParserState * state , long count )
798
+ static inline VALUE json_decode_array (JSON_ParserState * state , JSON_ParserConfig * config , long count )
801
799
{
802
800
VALUE array ;
803
- if (RB_UNLIKELY (state -> config -> array_class )) {
804
- array = rb_class_new_instance (0 , 0 , state -> config -> array_class );
801
+ if (RB_UNLIKELY (config -> array_class )) {
802
+ array = rb_class_new_instance (0 , 0 , config -> array_class );
805
803
VALUE * items = rvalue_stack_peek (state -> stack , count );
806
804
long index ;
807
805
for (index = 0 ; index < count ; index ++ ) {
@@ -813,18 +811,18 @@ static inline VALUE json_decode_array(JSON_ParserState *state, long count)
813
811
814
812
rvalue_stack_pop (state -> stack , count );
815
813
816
- if (state -> config -> freeze ) {
814
+ if (config -> freeze ) {
817
815
RB_OBJ_FREEZE (array );
818
816
}
819
817
820
818
return array ;
821
819
}
822
820
823
- static inline VALUE json_decode_object (JSON_ParserState * state , long count )
821
+ static inline VALUE json_decode_object (JSON_ParserState * state , JSON_ParserConfig * config , long count )
824
822
{
825
823
VALUE object ;
826
- if (RB_UNLIKELY (state -> config -> object_class )) {
827
- object = rb_class_new_instance (0 , 0 , state -> config -> object_class );
824
+ if (RB_UNLIKELY (config -> object_class )) {
825
+ object = rb_class_new_instance (0 , 0 , config -> object_class );
828
826
long index = 0 ;
829
827
VALUE * items = rvalue_stack_peek (state -> stack , count );
830
828
while (index < count ) {
@@ -839,25 +837,25 @@ static inline VALUE json_decode_object(JSON_ParserState *state, long count)
839
837
840
838
rvalue_stack_pop (state -> stack , count );
841
839
842
- if (RB_UNLIKELY (state -> config -> create_additions )) {
840
+ if (RB_UNLIKELY (config -> create_additions )) {
843
841
VALUE klassname ;
844
- if (state -> config -> object_class ) {
845
- klassname = rb_funcall (object , i_aref , 1 , state -> config -> create_id );
842
+ if (config -> object_class ) {
843
+ klassname = rb_funcall (object , i_aref , 1 , config -> create_id );
846
844
} else {
847
- klassname = rb_hash_aref (object , state -> config -> create_id );
845
+ klassname = rb_hash_aref (object , config -> create_id );
848
846
}
849
847
if (!NIL_P (klassname )) {
850
848
VALUE klass = rb_funcall (mJSON , i_deep_const_get , 1 , klassname );
851
849
if (RTEST (rb_funcall (klass , i_json_creatable_p , 0 ))) {
852
- if (state -> config -> deprecated_create_additions ) {
850
+ if (config -> deprecated_create_additions ) {
853
851
json_deprecated (deprecated_create_additions_warning );
854
852
}
855
853
object = rb_funcall (klass , i_json_create , 1 , object );
856
854
}
857
855
}
858
856
}
859
857
860
- if (state -> config -> freeze ) {
858
+ if (config -> freeze ) {
861
859
RB_OBJ_FREEZE (object );
862
860
}
863
861
@@ -875,22 +873,22 @@ static int match_i(VALUE regexp, VALUE klass, VALUE memo)
875
873
return ST_CONTINUE ;
876
874
}
877
875
878
- static inline VALUE json_decode_string (JSON_ParserState * state , const char * start , const char * end , bool escaped , bool is_name )
876
+ static inline VALUE json_decode_string (JSON_ParserState * state , JSON_ParserConfig * config , const char * start , const char * end , bool escaped , bool is_name )
879
877
{
880
878
VALUE string ;
881
- bool intern = is_name || state -> config -> freeze ;
882
- bool symbolize = is_name && state -> config -> symbolize_names ;
879
+ bool intern = is_name || config -> freeze ;
880
+ bool symbolize = is_name && config -> symbolize_names ;
883
881
if (escaped ) {
884
882
string = json_string_unescape (state , start , end , is_name , intern , symbolize );
885
883
} else {
886
884
string = json_string_fastpath (state , start , end , is_name , intern , symbolize );
887
885
}
888
886
889
- if (RB_UNLIKELY (state -> config -> create_additions && RTEST (state -> config -> match_string ))) {
887
+ if (RB_UNLIKELY (config -> create_additions && RTEST (config -> match_string ))) {
890
888
VALUE klass ;
891
889
VALUE memo = rb_ary_new2 (2 );
892
890
rb_ary_push (memo , string );
893
- rb_hash_foreach (state -> config -> match_string , match_i , memo );
891
+ rb_hash_foreach (config -> match_string , match_i , memo );
894
892
klass = rb_ary_entry (memo , 1 );
895
893
if (RTEST (klass )) {
896
894
string = rb_funcall (klass , i_json_create , 1 , string );
@@ -915,7 +913,7 @@ static const bool string_scan[256] = {
915
913
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
916
914
};
917
915
918
- static inline VALUE json_parse_string (JSON_ParserState * state , bool is_name )
916
+ static inline VALUE json_parse_string (JSON_ParserState * state , JSON_ParserConfig * config , bool is_name )
919
917
{
920
918
state -> cursor ++ ;
921
919
const char * start = state -> cursor ;
@@ -925,7 +923,7 @@ static inline VALUE json_parse_string(JSON_ParserState *state, bool is_name)
925
923
if (RB_UNLIKELY (string_scan [(unsigned char )* state -> cursor ])) {
926
924
switch (* state -> cursor ) {
927
925
case '"' : {
928
- VALUE string = json_decode_string (state , start , state -> cursor , escaped , is_name );
926
+ VALUE string = json_decode_string (state , config , start , state -> cursor , escaped , is_name );
929
927
state -> cursor ++ ;
930
928
return PUSH (string );
931
929
}
@@ -950,7 +948,7 @@ static inline VALUE json_parse_string(JSON_ParserState *state, bool is_name)
950
948
return Qfalse ;
951
949
}
952
950
953
- static VALUE json_parse_any (JSON_ParserState * state )
951
+ static VALUE json_parse_any (JSON_ParserState * state , JSON_ParserConfig * config )
954
952
{
955
953
json_eat_whitespace (state );
956
954
if (state -> cursor >= state -> end ) {
@@ -985,15 +983,15 @@ static VALUE json_parse_any(JSON_ParserState *state)
985
983
break ;
986
984
case 'N' :
987
985
// Note: memcmp with a small power of two compile to an integer comparison
988
- if (state -> config -> allow_nan && (state -> end - state -> cursor >= 3 ) && (memcmp (state -> cursor + 1 , "aN" , 2 ) == 0 )) {
986
+ if (config -> allow_nan && (state -> end - state -> cursor >= 3 ) && (memcmp (state -> cursor + 1 , "aN" , 2 ) == 0 )) {
989
987
state -> cursor += 3 ;
990
988
return PUSH (CNaN );
991
989
}
992
990
993
991
raise_parse_error ("unexpected token at '%s'" , state -> cursor );
994
992
break ;
995
993
case 'I' :
996
- if (state -> config -> allow_nan && (state -> end - state -> cursor >= 8 ) && (memcmp (state -> cursor , "Infinity" , 8 ) == 0 )) {
994
+ if (config -> allow_nan && (state -> end - state -> cursor >= 8 ) && (memcmp (state -> cursor , "Infinity" , 8 ) == 0 )) {
997
995
state -> cursor += 8 ;
998
996
return PUSH (CInfinity );
999
997
}
@@ -1003,7 +1001,7 @@ static VALUE json_parse_any(JSON_ParserState *state)
1003
1001
case '-' :
1004
1002
// Note: memcmp with a small power of two compile to an integer comparison
1005
1003
if ((state -> end - state -> cursor >= 9 ) && (memcmp (state -> cursor + 1 , "Infinity" , 8 ) == 0 )) {
1006
- if (state -> config -> allow_nan ) {
1004
+ if (config -> allow_nan ) {
1007
1005
state -> cursor += 9 ;
1008
1006
return PUSH (CMinusInfinity );
1009
1007
} else {
@@ -1060,13 +1058,13 @@ static VALUE json_parse_any(JSON_ParserState *state)
1060
1058
}
1061
1059
1062
1060
if (integer ) {
1063
- return PUSH (json_decode_integer (state , start , state -> cursor ));
1061
+ return PUSH (json_decode_integer (start , state -> cursor ));
1064
1062
}
1065
- return PUSH (json_decode_float (state , start , state -> cursor ));
1063
+ return PUSH (json_decode_float (config , start , state -> cursor ));
1066
1064
}
1067
1065
case '"' : {
1068
1066
// %r{\A"[^"\\\t\n\x00]*(?:\\[bfnrtu\\/"][^"\\]*)*"}
1069
- return json_parse_string (state , false);
1067
+ return json_parse_string (state , config , false);
1070
1068
break ;
1071
1069
}
1072
1070
case '[' : {
@@ -1076,14 +1074,14 @@ static VALUE json_parse_any(JSON_ParserState *state)
1076
1074
1077
1075
if ((state -> cursor < state -> end ) && (* state -> cursor == ']' )) {
1078
1076
state -> cursor ++ ;
1079
- return PUSH (json_decode_array (state , 0 ));
1077
+ return PUSH (json_decode_array (state , config , 0 ));
1080
1078
} else {
1081
1079
state -> current_nesting ++ ;
1082
- if (RB_UNLIKELY (state -> config -> max_nesting && (state -> config -> max_nesting < state -> current_nesting ))) {
1080
+ if (RB_UNLIKELY (config -> max_nesting && (config -> max_nesting < state -> current_nesting ))) {
1083
1081
rb_raise (eNestingError , "nesting of %d is too deep" , state -> current_nesting );
1084
1082
}
1085
1083
state -> in_array ++ ;
1086
- json_parse_any (state );
1084
+ json_parse_any (state , config );
1087
1085
}
1088
1086
1089
1087
while (true) {
@@ -1095,18 +1093,18 @@ static VALUE json_parse_any(JSON_ParserState *state)
1095
1093
long count = state -> stack -> head - stack_head ;
1096
1094
state -> current_nesting -- ;
1097
1095
state -> in_array -- ;
1098
- return PUSH (json_decode_array (state , count ));
1096
+ return PUSH (json_decode_array (state , config , count ));
1099
1097
}
1100
1098
1101
1099
if (* state -> cursor == ',' ) {
1102
1100
state -> cursor ++ ;
1103
- if (state -> config -> allow_trailing_comma ) {
1101
+ if (config -> allow_trailing_comma ) {
1104
1102
json_eat_whitespace (state );
1105
1103
if ((state -> cursor < state -> end ) && (* state -> cursor == ']' )) {
1106
1104
continue ;
1107
1105
}
1108
1106
}
1109
- json_parse_any (state );
1107
+ json_parse_any (state , config );
1110
1108
continue ;
1111
1109
}
1112
1110
}
@@ -1122,25 +1120,25 @@ static VALUE json_parse_any(JSON_ParserState *state)
1122
1120
1123
1121
if ((state -> cursor < state -> end ) && (* state -> cursor == '}' )) {
1124
1122
state -> cursor ++ ;
1125
- return PUSH (json_decode_object (state , 0 ));
1123
+ return PUSH (json_decode_object (state , config , 0 ));
1126
1124
} else {
1127
1125
state -> current_nesting ++ ;
1128
- if (RB_UNLIKELY (state -> config -> max_nesting && (state -> config -> max_nesting < state -> current_nesting ))) {
1126
+ if (RB_UNLIKELY (config -> max_nesting && (config -> max_nesting < state -> current_nesting ))) {
1129
1127
rb_raise (eNestingError , "nesting of %d is too deep" , state -> current_nesting );
1130
1128
}
1131
1129
1132
1130
if (* state -> cursor != '"' ) {
1133
1131
raise_parse_error ("expected object key, got '%s" , state -> cursor );
1134
1132
}
1135
- json_parse_string (state , true);
1133
+ json_parse_string (state , config , true);
1136
1134
1137
1135
json_eat_whitespace (state );
1138
1136
if ((state -> cursor >= state -> end ) || (* state -> cursor != ':' )) {
1139
1137
raise_parse_error ("expected ':' after object key" , state -> cursor );
1140
1138
}
1141
1139
state -> cursor ++ ;
1142
1140
1143
- json_parse_any (state );
1141
+ json_parse_any (state , config );
1144
1142
}
1145
1143
1146
1144
while (true) {
@@ -1151,14 +1149,14 @@ static VALUE json_parse_any(JSON_ParserState *state)
1151
1149
state -> cursor ++ ;
1152
1150
state -> current_nesting -- ;
1153
1151
long count = state -> stack -> head - stack_head ;
1154
- return PUSH (json_decode_object (state , count ));
1152
+ return PUSH (json_decode_object (state , config , count ));
1155
1153
}
1156
1154
1157
1155
if (* state -> cursor == ',' ) {
1158
1156
state -> cursor ++ ;
1159
1157
json_eat_whitespace (state );
1160
1158
1161
- if (state -> config -> allow_trailing_comma ) {
1159
+ if (config -> allow_trailing_comma ) {
1162
1160
if ((state -> cursor < state -> end ) && (* state -> cursor == '}' )) {
1163
1161
continue ;
1164
1162
}
@@ -1167,15 +1165,15 @@ static VALUE json_parse_any(JSON_ParserState *state)
1167
1165
if (* state -> cursor != '"' ) {
1168
1166
raise_parse_error ("expected object key, got: '%s'" , state -> cursor );
1169
1167
}
1170
- json_parse_string (state , true);
1168
+ json_parse_string (state , config , true);
1171
1169
1172
1170
json_eat_whitespace (state );
1173
1171
if ((state -> cursor >= state -> end ) || (* state -> cursor != ':' )) {
1174
1172
raise_parse_error ("expected ':' after object key, got: '%s" , state -> cursor );
1175
1173
}
1176
1174
state -> cursor ++ ;
1177
1175
1178
- json_parse_any (state );
1176
+ json_parse_any (state , config );
1179
1177
1180
1178
continue ;
1181
1179
}
@@ -1342,14 +1340,13 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
1342
1340
};
1343
1341
1344
1342
JSON_ParserState _state = {
1345
- .config = config ,
1346
1343
.cursor = RSTRING_PTR (Vsource ),
1347
1344
.end = RSTRING_END (Vsource ),
1348
1345
.stack = & stack ,
1349
1346
};
1350
1347
JSON_ParserState * state = & _state ;
1351
1348
1352
- VALUE result = json_parse_any (state );
1349
+ VALUE result = json_parse_any (state , config );
1353
1350
1354
1351
// This may be skipped in case of exception, but
1355
1352
// it won't cause a leak.
0 commit comments