json 2.7.5 → 2.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,321 @@
1
1
  /* This file is automatically generated from parser.rl by using ragel */
2
2
  #line 1 "parser.rl"
3
+ #include "ruby.h"
3
4
  #include "../fbuffer/fbuffer.h"
4
- #include "parser.h"
5
+
6
+ static VALUE mJSON, mExt, cParser, eNestingError, Encoding_UTF_8;
7
+ static VALUE CNaN, CInfinity, CMinusInfinity;
8
+
9
+ static ID i_json_creatable_p, i_json_create, i_create_id,
10
+ i_chr, i_deep_const_get, i_match, i_aset, i_aref,
11
+ i_leftshift, i_new, i_try_convert, i_uminus, i_encode;
12
+
13
+ static VALUE sym_max_nesting, sym_allow_nan, sym_allow_trailing_comma, sym_symbolize_names, sym_freeze,
14
+ sym_create_additions, sym_create_id, sym_object_class, sym_array_class,
15
+ sym_decimal_class, sym_match_string;
16
+
17
+ static int binary_encindex;
18
+ static int utf8_encindex;
19
+
20
+ #ifdef HAVE_RB_CATEGORY_WARN
21
+ # define json_deprecated(message) rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, message)
22
+ #else
23
+ # define json_deprecated(message) rb_warn(message)
24
+ #endif
25
+
26
+ static const char deprecated_create_additions_warning[] =
27
+ "JSON.load implicit support for `create_additions: true` is deprecated "
28
+ "and will be removed in 3.0, use JSON.unsafe_load or explicitly "
29
+ "pass `create_additions: true`";
30
+
31
+ #ifndef HAVE_RB_GC_MARK_LOCATIONS
32
+ // For TruffleRuby
33
+ void rb_gc_mark_locations(const VALUE *start, const VALUE *end)
34
+ {
35
+ VALUE *value = start;
36
+
37
+ while (value < end) {
38
+ rb_gc_mark(*value);
39
+ value++;
40
+ }
41
+ }
42
+ #endif
43
+
44
+ #ifndef HAVE_RB_HASH_BULK_INSERT
45
+ // For TruffleRuby
46
+ void rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
47
+ {
48
+ long index = 0;
49
+ while (index < count) {
50
+ VALUE name = pairs[index++];
51
+ VALUE value = pairs[index++];
52
+ rb_hash_aset(hash, name, value);
53
+ }
54
+ RB_GC_GUARD(hash);
55
+ }
56
+ #endif
57
+
58
+ /* name cache */
59
+
60
+ #include <string.h>
61
+ #include <ctype.h>
62
+
63
+ // Object names are likely to be repeated, and are frozen.
64
+ // As such we can re-use them if we keep a cache of the ones we've seen so far,
65
+ // and save much more expensive lookups into the global fstring table.
66
+ // This cache implementation is deliberately simple, as we're optimizing for compactness,
67
+ // to be able to fit safely on the stack.
68
+ // As such, binary search into a sorted array gives a good tradeoff between compactness and
69
+ // performance.
70
+ #define JSON_RVALUE_CACHE_CAPA 63
71
+ typedef struct rvalue_cache_struct {
72
+ int length;
73
+ VALUE entries[JSON_RVALUE_CACHE_CAPA];
74
+ } rvalue_cache;
75
+
76
+ static rb_encoding *enc_utf8;
77
+
78
+ #define JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH 55
79
+
80
+ static inline VALUE build_interned_string(const char *str, const long length)
81
+ {
82
+ # ifdef HAVE_RB_ENC_INTERNED_STR
83
+ return rb_enc_interned_str(str, length, enc_utf8);
84
+ # else
85
+ VALUE rstring = rb_utf8_str_new(str, length);
86
+ return rb_funcall(rb_str_freeze(rstring), i_uminus, 0);
87
+ # endif
88
+ }
89
+
90
+ static inline VALUE build_symbol(const char *str, const long length)
91
+ {
92
+ return rb_str_intern(build_interned_string(str, length));
93
+ }
94
+
95
+ static void rvalue_cache_insert_at(rvalue_cache *cache, int index, VALUE rstring)
96
+ {
97
+ MEMMOVE(&cache->entries[index + 1], &cache->entries[index], VALUE, cache->length - index);
98
+ cache->length++;
99
+ cache->entries[index] = rstring;
100
+ }
101
+
102
+ static inline int rstring_cache_cmp(const char *str, const long length, VALUE rstring)
103
+ {
104
+ long rstring_length = RSTRING_LEN(rstring);
105
+ if (length == rstring_length) {
106
+ return memcmp(str, RSTRING_PTR(rstring), length);
107
+ } else {
108
+ return (int)(length - rstring_length);
109
+ }
110
+ }
111
+
112
+ static VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const long length)
113
+ {
114
+ if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
115
+ // Common names aren't likely to be very long. So we just don't
116
+ // cache names above an arbitrary threshold.
117
+ return Qfalse;
118
+ }
119
+
120
+ if (RB_UNLIKELY(!isalpha(str[0]))) {
121
+ // Simple heuristic, if the first character isn't a letter,
122
+ // we're much less likely to see this string again.
123
+ // We mostly want to cache strings that are likely to be repeated.
124
+ return Qfalse;
125
+ }
126
+
127
+ int low = 0;
128
+ int high = cache->length - 1;
129
+ int mid = 0;
130
+ int last_cmp = 0;
131
+
132
+ while (low <= high) {
133
+ mid = (high + low) >> 1;
134
+ VALUE entry = cache->entries[mid];
135
+ last_cmp = rstring_cache_cmp(str, length, entry);
136
+
137
+ if (last_cmp == 0) {
138
+ return entry;
139
+ } else if (last_cmp > 0) {
140
+ low = mid + 1;
141
+ } else {
142
+ high = mid - 1;
143
+ }
144
+ }
145
+
146
+ if (RB_UNLIKELY(memchr(str, '\\', length))) {
147
+ // We assume the overwhelming majority of names don't need to be escaped.
148
+ // But if they do, we have to fallback to the slow path.
149
+ return Qfalse;
150
+ }
151
+
152
+ VALUE rstring = build_interned_string(str, length);
153
+
154
+ if (cache->length < JSON_RVALUE_CACHE_CAPA) {
155
+ if (last_cmp > 0) {
156
+ mid += 1;
157
+ }
158
+
159
+ rvalue_cache_insert_at(cache, mid, rstring);
160
+ }
161
+ return rstring;
162
+ }
163
+
164
+ static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const long length)
165
+ {
166
+ if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
167
+ // Common names aren't likely to be very long. So we just don't
168
+ // cache names above an arbitrary threshold.
169
+ return Qfalse;
170
+ }
171
+
172
+ if (RB_UNLIKELY(!isalpha(str[0]))) {
173
+ // Simple heuristic, if the first character isn't a letter,
174
+ // we're much less likely to see this string again.
175
+ // We mostly want to cache strings that are likely to be repeated.
176
+ return Qfalse;
177
+ }
178
+
179
+ int low = 0;
180
+ int high = cache->length - 1;
181
+ int mid = 0;
182
+ int last_cmp = 0;
183
+
184
+ while (low <= high) {
185
+ mid = (high + low) >> 1;
186
+ VALUE entry = cache->entries[mid];
187
+ last_cmp = rstring_cache_cmp(str, length, rb_sym2str(entry));
188
+
189
+ if (last_cmp == 0) {
190
+ return entry;
191
+ } else if (last_cmp > 0) {
192
+ low = mid + 1;
193
+ } else {
194
+ high = mid - 1;
195
+ }
196
+ }
197
+
198
+ if (RB_UNLIKELY(memchr(str, '\\', length))) {
199
+ // We assume the overwhelming majority of names don't need to be escaped.
200
+ // But if they do, we have to fallback to the slow path.
201
+ return Qfalse;
202
+ }
203
+
204
+ VALUE rsymbol = build_symbol(str, length);
205
+
206
+ if (cache->length < JSON_RVALUE_CACHE_CAPA) {
207
+ if (last_cmp > 0) {
208
+ mid += 1;
209
+ }
210
+
211
+ rvalue_cache_insert_at(cache, mid, rsymbol);
212
+ }
213
+ return rsymbol;
214
+ }
215
+
216
+ /* rvalue stack */
217
+
218
+ #define RVALUE_STACK_INITIAL_CAPA 128
219
+
220
+ enum rvalue_stack_type {
221
+ RVALUE_STACK_HEAP_ALLOCATED = 0,
222
+ RVALUE_STACK_STACK_ALLOCATED = 1,
223
+ };
224
+
225
+ typedef struct rvalue_stack_struct {
226
+ enum rvalue_stack_type type;
227
+ long capa;
228
+ long head;
229
+ VALUE *ptr;
230
+ } rvalue_stack;
231
+
232
+ static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref);
233
+
234
+ static rvalue_stack *rvalue_stack_grow(rvalue_stack *stack, VALUE *handle, rvalue_stack **stack_ref)
235
+ {
236
+ long required = stack->capa * 2;
237
+
238
+ if (stack->type == RVALUE_STACK_STACK_ALLOCATED) {
239
+ stack = rvalue_stack_spill(stack, handle, stack_ref);
240
+ } else {
241
+ REALLOC_N(stack->ptr, VALUE, required);
242
+ stack->capa = required;
243
+ }
244
+ return stack;
245
+ }
246
+
247
+ static void rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref)
248
+ {
249
+ if (RB_UNLIKELY(stack->head >= stack->capa)) {
250
+ stack = rvalue_stack_grow(stack, handle, stack_ref);
251
+ }
252
+ stack->ptr[stack->head] = value;
253
+ stack->head++;
254
+ }
255
+
256
+ static inline VALUE *rvalue_stack_peek(rvalue_stack *stack, long count)
257
+ {
258
+ return stack->ptr + (stack->head - count);
259
+ }
260
+
261
+ static inline void rvalue_stack_pop(rvalue_stack *stack, long count)
262
+ {
263
+ stack->head -= count;
264
+ }
265
+
266
+ static void rvalue_stack_mark(void *ptr)
267
+ {
268
+ rvalue_stack *stack = (rvalue_stack *)ptr;
269
+ rb_gc_mark_locations(stack->ptr, stack->ptr + stack->head);
270
+ }
271
+
272
+ static void rvalue_stack_free(void *ptr)
273
+ {
274
+ rvalue_stack *stack = (rvalue_stack *)ptr;
275
+ if (stack) {
276
+ ruby_xfree(stack->ptr);
277
+ ruby_xfree(stack);
278
+ }
279
+ }
280
+
281
+ static size_t rvalue_stack_memsize(const void *ptr)
282
+ {
283
+ const rvalue_stack *stack = (const rvalue_stack *)ptr;
284
+ return sizeof(rvalue_stack) + sizeof(VALUE) * stack->capa;
285
+ }
286
+
287
+ static const rb_data_type_t JSON_Parser_rvalue_stack_type = {
288
+ "JSON::Ext::Parser/rvalue_stack",
289
+ {
290
+ .dmark = rvalue_stack_mark,
291
+ .dfree = rvalue_stack_free,
292
+ .dsize = rvalue_stack_memsize,
293
+ },
294
+ 0, 0,
295
+ RUBY_TYPED_FREE_IMMEDIATELY,
296
+ };
297
+
298
+ static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref)
299
+ {
300
+ rvalue_stack *stack;
301
+ *handle = TypedData_Make_Struct(0, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
302
+ *stack_ref = stack;
303
+ MEMCPY(stack, old_stack, rvalue_stack, 1);
304
+
305
+ stack->capa = old_stack->capa << 1;
306
+ stack->ptr = ALLOC_N(VALUE, stack->capa);
307
+ stack->type = RVALUE_STACK_HEAP_ALLOCATED;
308
+ MEMCPY(stack->ptr, old_stack->ptr, VALUE, old_stack->head);
309
+ return stack;
310
+ }
311
+
312
+ static void rvalue_stack_eagerly_release(VALUE handle)
313
+ {
314
+ rvalue_stack *stack;
315
+ TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
316
+ RTYPEDDATA_DATA(handle) = NULL;
317
+ rvalue_stack_free(stack);
318
+ }
5
319
 
6
320
  /* unicode */
7
321
 
@@ -69,6 +383,50 @@ static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
69
383
  return len;
70
384
  }
71
385
 
386
+ typedef struct JSON_ParserStruct {
387
+ VALUE Vsource;
388
+ char *source;
389
+ long len;
390
+ char *memo;
391
+ VALUE create_id;
392
+ VALUE object_class;
393
+ VALUE array_class;
394
+ VALUE decimal_class;
395
+ VALUE match_string;
396
+ FBuffer fbuffer;
397
+ int in_array;
398
+ int max_nesting;
399
+ bool allow_nan;
400
+ bool allow_trailing_comma;
401
+ bool parsing_name;
402
+ bool symbolize_names;
403
+ bool freeze;
404
+ bool create_additions;
405
+ bool deprecated_create_additions;
406
+ rvalue_cache name_cache;
407
+ rvalue_stack *stack;
408
+ VALUE stack_handle;
409
+ } JSON_Parser;
410
+
411
+ #define GET_PARSER \
412
+ GET_PARSER_INIT; \
413
+ if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
414
+
415
+ #define GET_PARSER_INIT \
416
+ JSON_Parser *json; \
417
+ TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json)
418
+
419
+ #define MinusInfinity "-Infinity"
420
+ #define EVIL 0x666
421
+
422
+ static const rb_data_type_t JSON_Parser_type;
423
+ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
424
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
425
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
426
+ static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result);
427
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
428
+
429
+
72
430
  #define PARSE_ERROR_FRAGMENT_LEN 32
73
431
  #ifdef RBIMPL_ATTR_NORETURN
74
432
  RBIMPL_ATTR_NORETURN()
@@ -86,60 +444,49 @@ static void raise_parse_error(const char *format, const char *start)
86
444
  ptr = buffer;
87
445
  }
88
446
 
89
- rb_enc_raise(rb_utf8_encoding(), rb_path2class("JSON::ParserError"), format, ptr);
447
+ rb_enc_raise(enc_utf8, rb_path2class("JSON::ParserError"), format, ptr);
90
448
  }
91
449
 
92
- static VALUE mJSON, mExt, cParser, eNestingError;
93
- static VALUE CNaN, CInfinity, CMinusInfinity;
94
-
95
- static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
96
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
97
- i_object_class, i_array_class, i_decimal_class,
98
- i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
99
- i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
100
-
101
- static int binary_encindex;
102
- static int utf8_encindex;
103
-
104
450
 
105
451
 
106
- #line 129 "parser.rl"
452
+ #line 475 "parser.rl"
107
453
 
108
454
 
109
455
 
110
- #line 111 "parser.c"
456
+ #line 457 "parser.c"
111
457
  enum {JSON_object_start = 1};
112
- enum {JSON_object_first_final = 27};
458
+ enum {JSON_object_first_final = 32};
113
459
  enum {JSON_object_error = 0};
114
460
 
115
461
  enum {JSON_object_en_main = 1};
116
462
 
117
463
 
118
- #line 171 "parser.rl"
464
+ #line 515 "parser.rl"
119
465
 
120
466
 
467
+ #define PUSH(result) rvalue_stack_push(json->stack, result, &json->stack_handle, &json->stack)
468
+
121
469
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
122
470
  {
123
471
  int cs = EVIL;
124
- VALUE last_name = Qnil;
125
- VALUE object_class = json->object_class;
126
472
 
127
473
  if (json->max_nesting && current_nesting > json->max_nesting) {
128
474
  rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
129
475
  }
130
476
 
131
- *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
477
+ long stack_head = json->stack->head;
132
478
 
133
479
 
134
- #line 135 "parser.c"
480
+ #line 481 "parser.c"
135
481
  {
136
482
  cs = JSON_object_start;
137
483
  }
138
484
 
139
- #line 186 "parser.rl"
485
+ #line 530 "parser.rl"
140
486
 
141
- #line 142 "parser.c"
487
+ #line 488 "parser.c"
142
488
  {
489
+ short _widec;
143
490
  if ( p == pe )
144
491
  goto _test_eof;
145
492
  switch ( cs )
@@ -159,27 +506,30 @@ case 2:
159
506
  case 13: goto st2;
160
507
  case 32: goto st2;
161
508
  case 34: goto tr2;
162
- case 47: goto st23;
509
+ case 47: goto st28;
163
510
  case 125: goto tr4;
164
511
  }
165
512
  if ( 9 <= (*p) && (*p) <= 10 )
166
513
  goto st2;
167
514
  goto st0;
168
515
  tr2:
169
- #line 153 "parser.rl"
516
+ #line 494 "parser.rl"
170
517
  {
171
518
  char *np;
172
- json->parsing_name = 1;
173
- np = JSON_parse_string(json, p, pe, &last_name);
174
- json->parsing_name = 0;
175
- if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
519
+ json->parsing_name = true;
520
+ np = JSON_parse_string(json, p, pe, result);
521
+ json->parsing_name = false;
522
+ if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {
523
+ PUSH(*result);
524
+ {p = (( np))-1;}
525
+ }
176
526
  }
177
527
  goto st3;
178
528
  st3:
179
529
  if ( ++p == pe )
180
530
  goto _test_eof3;
181
531
  case 3:
182
- #line 183 "parser.c"
532
+ #line 533 "parser.c"
183
533
  switch( (*p) ) {
184
534
  case 13: goto st3;
185
535
  case 32: goto st3;
@@ -230,7 +580,7 @@ case 8:
230
580
  case 32: goto st8;
231
581
  case 34: goto tr11;
232
582
  case 45: goto tr11;
233
- case 47: goto st19;
583
+ case 47: goto st24;
234
584
  case 73: goto tr11;
235
585
  case 78: goto tr11;
236
586
  case 91: goto tr11;
@@ -246,19 +596,12 @@ case 8:
246
596
  goto st8;
247
597
  goto st0;
248
598
  tr11:
249
- #line 137 "parser.rl"
599
+ #line 483 "parser.rl"
250
600
  {
251
- VALUE v = Qnil;
252
- char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
601
+ char *np = JSON_parse_value(json, p, pe, result, current_nesting);
253
602
  if (np == NULL) {
254
603
  p--; {p++; cs = 9; goto _out;}
255
604
  } else {
256
- if (NIL_P(json->object_class)) {
257
- OBJ_FREEZE(last_name);
258
- rb_hash_aset(*result, last_name, v);
259
- } else {
260
- rb_funcall(*result, i_aset, 2, last_name, v);
261
- }
262
605
  {p = (( np))-1;}
263
606
  }
264
607
  }
@@ -267,16 +610,75 @@ st9:
267
610
  if ( ++p == pe )
268
611
  goto _test_eof9;
269
612
  case 9:
270
- #line 271 "parser.c"
271
- switch( (*p) ) {
272
- case 13: goto st9;
273
- case 32: goto st9;
274
- case 44: goto st10;
275
- case 47: goto st15;
613
+ #line 614 "parser.c"
614
+ _widec = (*p);
615
+ if ( (*p) < 13 ) {
616
+ if ( (*p) > 9 ) {
617
+ if ( 10 <= (*p) && (*p) <= 10 ) {
618
+ _widec = (short)(128 + ((*p) - -128));
619
+ if (
620
+ #line 492 "parser.rl"
621
+ json->allow_trailing_comma ) _widec += 256;
622
+ }
623
+ } else if ( (*p) >= 9 ) {
624
+ _widec = (short)(128 + ((*p) - -128));
625
+ if (
626
+ #line 492 "parser.rl"
627
+ json->allow_trailing_comma ) _widec += 256;
628
+ }
629
+ } else if ( (*p) > 13 ) {
630
+ if ( (*p) < 44 ) {
631
+ if ( 32 <= (*p) && (*p) <= 32 ) {
632
+ _widec = (short)(128 + ((*p) - -128));
633
+ if (
634
+ #line 492 "parser.rl"
635
+ json->allow_trailing_comma ) _widec += 256;
636
+ }
637
+ } else if ( (*p) > 44 ) {
638
+ if ( 47 <= (*p) && (*p) <= 47 ) {
639
+ _widec = (short)(128 + ((*p) - -128));
640
+ if (
641
+ #line 492 "parser.rl"
642
+ json->allow_trailing_comma ) _widec += 256;
643
+ }
644
+ } else {
645
+ _widec = (short)(128 + ((*p) - -128));
646
+ if (
647
+ #line 492 "parser.rl"
648
+ json->allow_trailing_comma ) _widec += 256;
649
+ }
650
+ } else {
651
+ _widec = (short)(128 + ((*p) - -128));
652
+ if (
653
+ #line 492 "parser.rl"
654
+ json->allow_trailing_comma ) _widec += 256;
655
+ }
656
+ switch( _widec ) {
276
657
  case 125: goto tr4;
277
- }
278
- if ( 9 <= (*p) && (*p) <= 10 )
279
- goto st9;
658
+ case 269: goto st10;
659
+ case 288: goto st10;
660
+ case 300: goto st11;
661
+ case 303: goto st16;
662
+ case 525: goto st9;
663
+ case 544: goto st9;
664
+ case 556: goto st2;
665
+ case 559: goto st20;
666
+ }
667
+ if ( _widec > 266 ) {
668
+ if ( 521 <= _widec && _widec <= 522 )
669
+ goto st9;
670
+ } else if ( _widec >= 265 )
671
+ goto st10;
672
+ goto st0;
673
+ tr4:
674
+ #line 505 "parser.rl"
675
+ { p--; {p++; cs = 32; goto _out;} }
676
+ goto st32;
677
+ st32:
678
+ if ( ++p == pe )
679
+ goto _test_eof32;
680
+ case 32:
681
+ #line 682 "parser.c"
280
682
  goto st0;
281
683
  st10:
282
684
  if ( ++p == pe )
@@ -285,8 +687,9 @@ case 10:
285
687
  switch( (*p) ) {
286
688
  case 13: goto st10;
287
689
  case 32: goto st10;
288
- case 34: goto tr2;
289
- case 47: goto st11;
690
+ case 44: goto st11;
691
+ case 47: goto st16;
692
+ case 125: goto tr4;
290
693
  }
291
694
  if ( 9 <= (*p) && (*p) <= 10 )
292
695
  goto st10;
@@ -296,139 +699,288 @@ st11:
296
699
  goto _test_eof11;
297
700
  case 11:
298
701
  switch( (*p) ) {
299
- case 42: goto st12;
300
- case 47: goto st14;
702
+ case 13: goto st11;
703
+ case 32: goto st11;
704
+ case 34: goto tr2;
705
+ case 47: goto st12;
301
706
  }
707
+ if ( 9 <= (*p) && (*p) <= 10 )
708
+ goto st11;
302
709
  goto st0;
303
710
  st12:
304
711
  if ( ++p == pe )
305
712
  goto _test_eof12;
306
713
  case 12:
307
- if ( (*p) == 42 )
308
- goto st13;
309
- goto st12;
714
+ switch( (*p) ) {
715
+ case 42: goto st13;
716
+ case 47: goto st15;
717
+ }
718
+ goto st0;
310
719
  st13:
311
720
  if ( ++p == pe )
312
721
  goto _test_eof13;
313
722
  case 13:
314
- switch( (*p) ) {
315
- case 42: goto st13;
316
- case 47: goto st10;
317
- }
318
- goto st12;
723
+ if ( (*p) == 42 )
724
+ goto st14;
725
+ goto st13;
319
726
  st14:
320
727
  if ( ++p == pe )
321
728
  goto _test_eof14;
322
729
  case 14:
323
- if ( (*p) == 10 )
324
- goto st10;
325
- goto st14;
730
+ switch( (*p) ) {
731
+ case 42: goto st14;
732
+ case 47: goto st11;
733
+ }
734
+ goto st13;
326
735
  st15:
327
736
  if ( ++p == pe )
328
737
  goto _test_eof15;
329
738
  case 15:
330
- switch( (*p) ) {
331
- case 42: goto st16;
332
- case 47: goto st18;
333
- }
334
- goto st0;
739
+ if ( (*p) == 10 )
740
+ goto st11;
741
+ goto st15;
335
742
  st16:
336
743
  if ( ++p == pe )
337
744
  goto _test_eof16;
338
745
  case 16:
339
- if ( (*p) == 42 )
340
- goto st17;
341
- goto st16;
746
+ switch( (*p) ) {
747
+ case 42: goto st17;
748
+ case 47: goto st19;
749
+ }
750
+ goto st0;
342
751
  st17:
343
752
  if ( ++p == pe )
344
753
  goto _test_eof17;
345
754
  case 17:
346
- switch( (*p) ) {
347
- case 42: goto st17;
348
- case 47: goto st9;
349
- }
350
- goto st16;
755
+ if ( (*p) == 42 )
756
+ goto st18;
757
+ goto st17;
351
758
  st18:
352
759
  if ( ++p == pe )
353
760
  goto _test_eof18;
354
761
  case 18:
355
- if ( (*p) == 10 )
356
- goto st9;
357
- goto st18;
358
- tr4:
359
- #line 161 "parser.rl"
360
- { p--; {p++; cs = 27; goto _out;} }
361
- goto st27;
362
- st27:
363
- if ( ++p == pe )
364
- goto _test_eof27;
365
- case 27:
366
- #line 367 "parser.c"
367
- goto st0;
762
+ switch( (*p) ) {
763
+ case 42: goto st18;
764
+ case 47: goto st10;
765
+ }
766
+ goto st17;
368
767
  st19:
369
768
  if ( ++p == pe )
370
769
  goto _test_eof19;
371
770
  case 19:
372
- switch( (*p) ) {
373
- case 42: goto st20;
374
- case 47: goto st22;
375
- }
376
- goto st0;
771
+ if ( (*p) == 10 )
772
+ goto st10;
773
+ goto st19;
377
774
  st20:
378
775
  if ( ++p == pe )
379
776
  goto _test_eof20;
380
777
  case 20:
381
- if ( (*p) == 42 )
382
- goto st21;
383
- goto st20;
778
+ _widec = (*p);
779
+ if ( (*p) > 42 ) {
780
+ if ( 47 <= (*p) && (*p) <= 47 ) {
781
+ _widec = (short)(128 + ((*p) - -128));
782
+ if (
783
+ #line 492 "parser.rl"
784
+ json->allow_trailing_comma ) _widec += 256;
785
+ }
786
+ } else if ( (*p) >= 42 ) {
787
+ _widec = (short)(128 + ((*p) - -128));
788
+ if (
789
+ #line 492 "parser.rl"
790
+ json->allow_trailing_comma ) _widec += 256;
791
+ }
792
+ switch( _widec ) {
793
+ case 298: goto st17;
794
+ case 303: goto st19;
795
+ case 554: goto st21;
796
+ case 559: goto st23;
797
+ }
798
+ goto st0;
384
799
  st21:
385
800
  if ( ++p == pe )
386
801
  goto _test_eof21;
387
802
  case 21:
388
- switch( (*p) ) {
389
- case 42: goto st21;
390
- case 47: goto st8;
391
- }
392
- goto st20;
803
+ _widec = (*p);
804
+ if ( (*p) < 42 ) {
805
+ if ( (*p) <= 41 ) {
806
+ _widec = (short)(128 + ((*p) - -128));
807
+ if (
808
+ #line 492 "parser.rl"
809
+ json->allow_trailing_comma ) _widec += 256;
810
+ }
811
+ } else if ( (*p) > 42 ) {
812
+ if ( 43 <= (*p) )
813
+ { _widec = (short)(128 + ((*p) - -128));
814
+ if (
815
+ #line 492 "parser.rl"
816
+ json->allow_trailing_comma ) _widec += 256;
817
+ }
818
+ } else {
819
+ _widec = (short)(128 + ((*p) - -128));
820
+ if (
821
+ #line 492 "parser.rl"
822
+ json->allow_trailing_comma ) _widec += 256;
823
+ }
824
+ switch( _widec ) {
825
+ case 298: goto st18;
826
+ case 554: goto st22;
827
+ }
828
+ if ( _widec > 383 ) {
829
+ if ( 384 <= _widec && _widec <= 639 )
830
+ goto st21;
831
+ } else if ( _widec >= 128 )
832
+ goto st17;
833
+ goto st0;
393
834
  st22:
394
835
  if ( ++p == pe )
395
836
  goto _test_eof22;
396
837
  case 22:
397
- if ( (*p) == 10 )
398
- goto st8;
399
- goto st22;
838
+ _widec = (*p);
839
+ if ( (*p) < 43 ) {
840
+ if ( (*p) > 41 ) {
841
+ if ( 42 <= (*p) && (*p) <= 42 ) {
842
+ _widec = (short)(128 + ((*p) - -128));
843
+ if (
844
+ #line 492 "parser.rl"
845
+ json->allow_trailing_comma ) _widec += 256;
846
+ }
847
+ } else {
848
+ _widec = (short)(128 + ((*p) - -128));
849
+ if (
850
+ #line 492 "parser.rl"
851
+ json->allow_trailing_comma ) _widec += 256;
852
+ }
853
+ } else if ( (*p) > 46 ) {
854
+ if ( (*p) > 47 ) {
855
+ if ( 48 <= (*p) )
856
+ { _widec = (short)(128 + ((*p) - -128));
857
+ if (
858
+ #line 492 "parser.rl"
859
+ json->allow_trailing_comma ) _widec += 256;
860
+ }
861
+ } else if ( (*p) >= 47 ) {
862
+ _widec = (short)(128 + ((*p) - -128));
863
+ if (
864
+ #line 492 "parser.rl"
865
+ json->allow_trailing_comma ) _widec += 256;
866
+ }
867
+ } else {
868
+ _widec = (short)(128 + ((*p) - -128));
869
+ if (
870
+ #line 492 "parser.rl"
871
+ json->allow_trailing_comma ) _widec += 256;
872
+ }
873
+ switch( _widec ) {
874
+ case 298: goto st18;
875
+ case 303: goto st10;
876
+ case 554: goto st22;
877
+ case 559: goto st9;
878
+ }
879
+ if ( _widec > 383 ) {
880
+ if ( 384 <= _widec && _widec <= 639 )
881
+ goto st21;
882
+ } else if ( _widec >= 128 )
883
+ goto st17;
884
+ goto st0;
400
885
  st23:
401
886
  if ( ++p == pe )
402
887
  goto _test_eof23;
403
888
  case 23:
404
- switch( (*p) ) {
405
- case 42: goto st24;
406
- case 47: goto st26;
407
- }
889
+ _widec = (*p);
890
+ if ( (*p) < 10 ) {
891
+ if ( (*p) <= 9 ) {
892
+ _widec = (short)(128 + ((*p) - -128));
893
+ if (
894
+ #line 492 "parser.rl"
895
+ json->allow_trailing_comma ) _widec += 256;
896
+ }
897
+ } else if ( (*p) > 10 ) {
898
+ if ( 11 <= (*p) )
899
+ { _widec = (short)(128 + ((*p) - -128));
900
+ if (
901
+ #line 492 "parser.rl"
902
+ json->allow_trailing_comma ) _widec += 256;
903
+ }
904
+ } else {
905
+ _widec = (short)(128 + ((*p) - -128));
906
+ if (
907
+ #line 492 "parser.rl"
908
+ json->allow_trailing_comma ) _widec += 256;
909
+ }
910
+ switch( _widec ) {
911
+ case 266: goto st10;
912
+ case 522: goto st9;
913
+ }
914
+ if ( _widec > 383 ) {
915
+ if ( 384 <= _widec && _widec <= 639 )
916
+ goto st23;
917
+ } else if ( _widec >= 128 )
918
+ goto st19;
408
919
  goto st0;
409
920
  st24:
410
921
  if ( ++p == pe )
411
922
  goto _test_eof24;
412
923
  case 24:
413
- if ( (*p) == 42 )
414
- goto st25;
415
- goto st24;
924
+ switch( (*p) ) {
925
+ case 42: goto st25;
926
+ case 47: goto st27;
927
+ }
928
+ goto st0;
416
929
  st25:
417
930
  if ( ++p == pe )
418
931
  goto _test_eof25;
419
932
  case 25:
420
- switch( (*p) ) {
421
- case 42: goto st25;
422
- case 47: goto st2;
423
- }
424
- goto st24;
933
+ if ( (*p) == 42 )
934
+ goto st26;
935
+ goto st25;
425
936
  st26:
426
937
  if ( ++p == pe )
427
938
  goto _test_eof26;
428
939
  case 26:
940
+ switch( (*p) ) {
941
+ case 42: goto st26;
942
+ case 47: goto st8;
943
+ }
944
+ goto st25;
945
+ st27:
946
+ if ( ++p == pe )
947
+ goto _test_eof27;
948
+ case 27:
949
+ if ( (*p) == 10 )
950
+ goto st8;
951
+ goto st27;
952
+ st28:
953
+ if ( ++p == pe )
954
+ goto _test_eof28;
955
+ case 28:
956
+ switch( (*p) ) {
957
+ case 42: goto st29;
958
+ case 47: goto st31;
959
+ }
960
+ goto st0;
961
+ st29:
962
+ if ( ++p == pe )
963
+ goto _test_eof29;
964
+ case 29:
965
+ if ( (*p) == 42 )
966
+ goto st30;
967
+ goto st29;
968
+ st30:
969
+ if ( ++p == pe )
970
+ goto _test_eof30;
971
+ case 30:
972
+ switch( (*p) ) {
973
+ case 42: goto st30;
974
+ case 47: goto st2;
975
+ }
976
+ goto st29;
977
+ st31:
978
+ if ( ++p == pe )
979
+ goto _test_eof31;
980
+ case 31:
429
981
  if ( (*p) == 10 )
430
982
  goto st2;
431
- goto st26;
983
+ goto st31;
432
984
  }
433
985
  _test_eof2: cs = 2; goto _test_eof;
434
986
  _test_eof3: cs = 3; goto _test_eof;
@@ -438,6 +990,7 @@ case 26:
438
990
  _test_eof7: cs = 7; goto _test_eof;
439
991
  _test_eof8: cs = 8; goto _test_eof;
440
992
  _test_eof9: cs = 9; goto _test_eof;
993
+ _test_eof32: cs = 32; goto _test_eof;
441
994
  _test_eof10: cs = 10; goto _test_eof;
442
995
  _test_eof11: cs = 11; goto _test_eof;
443
996
  _test_eof12: cs = 12; goto _test_eof;
@@ -447,7 +1000,6 @@ case 26:
447
1000
  _test_eof16: cs = 16; goto _test_eof;
448
1001
  _test_eof17: cs = 17; goto _test_eof;
449
1002
  _test_eof18: cs = 18; goto _test_eof;
450
- _test_eof27: cs = 27; goto _test_eof;
451
1003
  _test_eof19: cs = 19; goto _test_eof;
452
1004
  _test_eof20: cs = 20; goto _test_eof;
453
1005
  _test_eof21: cs = 21; goto _test_eof;
@@ -456,24 +1008,56 @@ case 26:
456
1008
  _test_eof24: cs = 24; goto _test_eof;
457
1009
  _test_eof25: cs = 25; goto _test_eof;
458
1010
  _test_eof26: cs = 26; goto _test_eof;
1011
+ _test_eof27: cs = 27; goto _test_eof;
1012
+ _test_eof28: cs = 28; goto _test_eof;
1013
+ _test_eof29: cs = 29; goto _test_eof;
1014
+ _test_eof30: cs = 30; goto _test_eof;
1015
+ _test_eof31: cs = 31; goto _test_eof;
459
1016
 
460
1017
  _test_eof: {}
461
1018
  _out: {}
462
1019
  }
463
1020
 
464
- #line 187 "parser.rl"
1021
+ #line 531 "parser.rl"
465
1022
 
466
1023
  if (cs >= JSON_object_first_final) {
467
- if (json->create_additions) {
1024
+ long count = json->stack->head - stack_head;
1025
+
1026
+ if (RB_UNLIKELY(json->object_class)) {
1027
+ VALUE object = rb_class_new_instance(0, 0, json->object_class);
1028
+ long index = 0;
1029
+ VALUE *items = rvalue_stack_peek(json->stack, count);
1030
+ while (index < count) {
1031
+ VALUE name = items[index++];
1032
+ VALUE value = items[index++];
1033
+ rb_funcall(object, i_aset, 2, name, value);
1034
+ }
1035
+ *result = object;
1036
+ } else {
1037
+ VALUE hash;
1038
+ #ifdef HAVE_RB_HASH_NEW_CAPA
1039
+ hash = rb_hash_new_capa(count >> 1);
1040
+ #else
1041
+ hash = rb_hash_new();
1042
+ #endif
1043
+ rb_hash_bulk_insert(count, rvalue_stack_peek(json->stack, count), hash);
1044
+ *result = hash;
1045
+ }
1046
+ rvalue_stack_pop(json->stack, count);
1047
+
1048
+ if (RB_UNLIKELY(json->create_additions)) {
468
1049
  VALUE klassname;
469
- if (NIL_P(json->object_class)) {
470
- klassname = rb_hash_aref(*result, json->create_id);
1050
+ if (json->object_class) {
1051
+ klassname = rb_funcall(*result, i_aref, 1, json->create_id);
471
1052
  } else {
472
- klassname = rb_funcall(*result, i_aref, 1, json->create_id);
1053
+ klassname = rb_hash_aref(*result, json->create_id);
473
1054
  }
474
1055
  if (!NIL_P(klassname)) {
475
1056
  VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
476
1057
  if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
1058
+ if (json->deprecated_create_additions) {
1059
+ json_deprecated(deprecated_create_additions_warning);
1060
+ }
477
1061
  *result = rb_funcall(klass, i_json_create, 1, *result);
478
1062
  }
479
1063
  }
@@ -485,8 +1069,7 @@ case 26:
485
1069
  }
486
1070
 
487
1071
 
488
-
489
- #line 490 "parser.c"
1072
+ #line 1073 "parser.c"
490
1073
  enum {JSON_value_start = 1};
491
1074
  enum {JSON_value_first_final = 29};
492
1075
  enum {JSON_value_error = 0};
@@ -494,7 +1077,7 @@ enum {JSON_value_error = 0};
494
1077
  enum {JSON_value_en_main = 1};
495
1078
 
496
1079
 
497
- #line 287 "parser.rl"
1080
+ #line 664 "parser.rl"
498
1081
 
499
1082
 
500
1083
  static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -502,14 +1085,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
502
1085
  int cs = EVIL;
503
1086
 
504
1087
 
505
- #line 506 "parser.c"
1088
+ #line 1089 "parser.c"
506
1089
  {
507
1090
  cs = JSON_value_start;
508
1091
  }
509
1092
 
510
- #line 294 "parser.rl"
1093
+ #line 671 "parser.rl"
511
1094
 
512
- #line 513 "parser.c"
1095
+ #line 1096 "parser.c"
513
1096
  {
514
1097
  if ( p == pe )
515
1098
  goto _test_eof;
@@ -543,14 +1126,19 @@ st0:
543
1126
  cs = 0;
544
1127
  goto _out;
545
1128
  tr2:
546
- #line 239 "parser.rl"
1129
+ #line 609 "parser.rl"
547
1130
  {
548
1131
  char *np = JSON_parse_string(json, p, pe, result);
549
- if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
1132
+ if (np == NULL) {
1133
+ p--;
1134
+ {p++; cs = 29; goto _out;}
1135
+ } else {
1136
+ {p = (( np))-1;}
1137
+ }
550
1138
  }
551
1139
  goto st29;
552
1140
  tr3:
553
- #line 244 "parser.rl"
1141
+ #line 619 "parser.rl"
554
1142
  {
555
1143
  char *np;
556
1144
  if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
@@ -562,23 +1150,25 @@ tr3:
562
1150
  raise_parse_error("unexpected token at '%s'", p);
563
1151
  }
564
1152
  }
565
- np = JSON_parse_float(json, p, pe, result);
566
- if (np != NULL) {p = (( np))-1;}
567
- np = JSON_parse_integer(json, p, pe, result);
568
- if (np != NULL) {p = (( np))-1;}
1153
+ np = JSON_parse_number(json, p, pe, result);
1154
+ if (np != NULL) {
1155
+ {p = (( np))-1;}
1156
+ }
569
1157
  p--; {p++; cs = 29; goto _out;}
570
1158
  }
571
1159
  goto st29;
572
1160
  tr7:
573
- #line 262 "parser.rl"
1161
+ #line 637 "parser.rl"
574
1162
  {
575
1163
  char *np;
1164
+ json->in_array++;
576
1165
  np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
1166
+ json->in_array--;
577
1167
  if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
578
1168
  }
579
1169
  goto st29;
580
1170
  tr11:
581
- #line 268 "parser.rl"
1171
+ #line 645 "parser.rl"
582
1172
  {
583
1173
  char *np;
584
1174
  np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
@@ -586,7 +1176,7 @@ tr11:
586
1176
  }
587
1177
  goto st29;
588
1178
  tr25:
589
- #line 232 "parser.rl"
1179
+ #line 602 "parser.rl"
590
1180
  {
591
1181
  if (json->allow_nan) {
592
1182
  *result = CInfinity;
@@ -596,7 +1186,7 @@ tr25:
596
1186
  }
597
1187
  goto st29;
598
1188
  tr27:
599
- #line 225 "parser.rl"
1189
+ #line 595 "parser.rl"
600
1190
  {
601
1191
  if (json->allow_nan) {
602
1192
  *result = CNaN;
@@ -606,19 +1196,19 @@ tr27:
606
1196
  }
607
1197
  goto st29;
608
1198
  tr31:
609
- #line 219 "parser.rl"
1199
+ #line 589 "parser.rl"
610
1200
  {
611
1201
  *result = Qfalse;
612
1202
  }
613
1203
  goto st29;
614
1204
  tr34:
615
- #line 216 "parser.rl"
1205
+ #line 586 "parser.rl"
616
1206
  {
617
1207
  *result = Qnil;
618
1208
  }
619
1209
  goto st29;
620
1210
  tr37:
621
- #line 222 "parser.rl"
1211
+ #line 592 "parser.rl"
622
1212
  {
623
1213
  *result = Qtrue;
624
1214
  }
@@ -627,9 +1217,9 @@ st29:
627
1217
  if ( ++p == pe )
628
1218
  goto _test_eof29;
629
1219
  case 29:
630
- #line 274 "parser.rl"
1220
+ #line 651 "parser.rl"
631
1221
  { p--; {p++; cs = 29; goto _out;} }
632
- #line 633 "parser.c"
1222
+ #line 1223 "parser.c"
633
1223
  switch( (*p) ) {
634
1224
  case 13: goto st29;
635
1225
  case 32: goto st29;
@@ -870,13 +1460,14 @@ case 28:
870
1460
  _out: {}
871
1461
  }
872
1462
 
873
- #line 295 "parser.rl"
1463
+ #line 672 "parser.rl"
874
1464
 
875
1465
  if (json->freeze) {
876
1466
  OBJ_FREEZE(*result);
877
1467
  }
878
1468
 
879
1469
  if (cs >= JSON_value_first_final) {
1470
+ PUSH(*result);
880
1471
  return p;
881
1472
  } else {
882
1473
  return NULL;
@@ -884,7 +1475,7 @@ case 28:
884
1475
  }
885
1476
 
886
1477
 
887
- #line 888 "parser.c"
1478
+ #line 1479 "parser.c"
888
1479
  enum {JSON_integer_start = 1};
889
1480
  enum {JSON_integer_first_final = 3};
890
1481
  enum {JSON_integer_error = 0};
@@ -892,122 +1483,72 @@ enum {JSON_integer_error = 0};
892
1483
  enum {JSON_integer_en_main = 1};
893
1484
 
894
1485
 
895
- #line 315 "parser.rl"
1486
+ #line 693 "parser.rl"
896
1487
 
897
1488
 
898
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
1489
+ #define MAX_FAST_INTEGER_SIZE 18
1490
+ static inline VALUE fast_parse_integer(char *p, char *pe)
899
1491
  {
900
- int cs = EVIL;
901
-
902
-
903
- #line 904 "parser.c"
904
- {
905
- cs = JSON_integer_start;
906
- }
907
-
908
- #line 322 "parser.rl"
909
- json->memo = p;
910
-
911
- #line 912 "parser.c"
912
- {
913
- if ( p == pe )
914
- goto _test_eof;
915
- switch ( cs )
916
- {
917
- case 1:
918
- switch( (*p) ) {
919
- case 45: goto st2;
920
- case 48: goto st3;
921
- }
922
- if ( 49 <= (*p) && (*p) <= 57 )
923
- goto st5;
924
- goto st0;
925
- st0:
926
- cs = 0;
927
- goto _out;
928
- st2:
929
- if ( ++p == pe )
930
- goto _test_eof2;
931
- case 2:
932
- if ( (*p) == 48 )
933
- goto st3;
934
- if ( 49 <= (*p) && (*p) <= 57 )
935
- goto st5;
936
- goto st0;
937
- st3:
938
- if ( ++p == pe )
939
- goto _test_eof3;
940
- case 3:
941
- if ( 48 <= (*p) && (*p) <= 57 )
942
- goto st0;
943
- goto tr4;
944
- tr4:
945
- #line 312 "parser.rl"
946
- { p--; {p++; cs = 4; goto _out;} }
947
- goto st4;
948
- st4:
949
- if ( ++p == pe )
950
- goto _test_eof4;
951
- case 4:
952
- #line 953 "parser.c"
953
- goto st0;
954
- st5:
955
- if ( ++p == pe )
956
- goto _test_eof5;
957
- case 5:
958
- if ( 48 <= (*p) && (*p) <= 57 )
959
- goto st5;
960
- goto tr4;
961
- }
962
- _test_eof2: cs = 2; goto _test_eof;
963
- _test_eof3: cs = 3; goto _test_eof;
964
- _test_eof4: cs = 4; goto _test_eof;
965
- _test_eof5: cs = 5; goto _test_eof;
1492
+ bool negative = false;
1493
+ if (*p == '-') {
1494
+ negative = true;
1495
+ p++;
1496
+ }
966
1497
 
967
- _test_eof: {}
968
- _out: {}
969
- }
1498
+ long long memo = 0;
1499
+ while (p < pe) {
1500
+ memo *= 10;
1501
+ memo += *p - '0';
1502
+ p++;
1503
+ }
970
1504
 
971
- #line 324 "parser.rl"
1505
+ if (negative) {
1506
+ memo = -memo;
1507
+ }
1508
+ return LL2NUM(memo);
1509
+ }
972
1510
 
973
- if (cs >= JSON_integer_first_final) {
1511
+ static char *JSON_decode_integer(JSON_Parser *json, char *p, VALUE *result)
1512
+ {
974
1513
  long len = p - json->memo;
975
- fbuffer_clear(json->fbuffer);
976
- fbuffer_append(json->fbuffer, json->memo, len);
977
- fbuffer_append_char(json->fbuffer, '\0');
978
- *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
1514
+ if (RB_LIKELY(len < MAX_FAST_INTEGER_SIZE)) {
1515
+ *result = fast_parse_integer(json->memo, p);
1516
+ } else {
1517
+ fbuffer_clear(&json->fbuffer);
1518
+ fbuffer_append(&json->fbuffer, json->memo, len);
1519
+ fbuffer_append_char(&json->fbuffer, '\0');
1520
+ *result = rb_cstr2inum(FBUFFER_PTR(&json->fbuffer), 10);
1521
+ }
979
1522
  return p + 1;
980
- } else {
981
- return NULL;
982
- }
983
1523
  }
984
1524
 
985
1525
 
986
- #line 987 "parser.c"
1526
+ #line 1527 "parser.c"
987
1527
  enum {JSON_float_start = 1};
988
- enum {JSON_float_first_final = 8};
1528
+ enum {JSON_float_first_final = 6};
989
1529
  enum {JSON_float_error = 0};
990
1530
 
991
1531
  enum {JSON_float_en_main = 1};
992
1532
 
993
1533
 
994
- #line 349 "parser.rl"
1534
+ #line 745 "parser.rl"
995
1535
 
996
1536
 
997
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
1537
+ static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result)
998
1538
  {
999
1539
  int cs = EVIL;
1540
+ bool is_float = false;
1000
1541
 
1001
1542
 
1002
- #line 1003 "parser.c"
1543
+ #line 1544 "parser.c"
1003
1544
  {
1004
1545
  cs = JSON_float_start;
1005
1546
  }
1006
1547
 
1007
- #line 356 "parser.rl"
1548
+ #line 753 "parser.rl"
1008
1549
  json->memo = p;
1009
1550
 
1010
- #line 1011 "parser.c"
1551
+ #line 1552 "parser.c"
1011
1552
  {
1012
1553
  if ( p == pe )
1013
1554
  goto _test_eof;
@@ -1016,10 +1557,10 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
1016
1557
  case 1:
1017
1558
  switch( (*p) ) {
1018
1559
  case 45: goto st2;
1019
- case 48: goto st3;
1560
+ case 48: goto st6;
1020
1561
  }
1021
1562
  if ( 49 <= (*p) && (*p) <= 57 )
1022
- goto st7;
1563
+ goto st10;
1023
1564
  goto st0;
1024
1565
  st0:
1025
1566
  cs = 0;
@@ -1029,24 +1570,42 @@ st2:
1029
1570
  goto _test_eof2;
1030
1571
  case 2:
1031
1572
  if ( (*p) == 48 )
1032
- goto st3;
1573
+ goto st6;
1033
1574
  if ( 49 <= (*p) && (*p) <= 57 )
1034
- goto st7;
1575
+ goto st10;
1035
1576
  goto st0;
1036
- st3:
1577
+ st6:
1037
1578
  if ( ++p == pe )
1038
- goto _test_eof3;
1039
- case 3:
1579
+ goto _test_eof6;
1580
+ case 6:
1040
1581
  switch( (*p) ) {
1041
- case 46: goto st4;
1042
- case 69: goto st5;
1043
- case 101: goto st5;
1582
+ case 45: goto st0;
1583
+ case 46: goto tr8;
1584
+ case 69: goto tr9;
1585
+ case 101: goto tr9;
1044
1586
  }
1587
+ if ( 48 <= (*p) && (*p) <= 57 )
1588
+ goto st0;
1589
+ goto tr7;
1590
+ tr7:
1591
+ #line 737 "parser.rl"
1592
+ { p--; {p++; cs = 7; goto _out;} }
1593
+ goto st7;
1594
+ st7:
1595
+ if ( ++p == pe )
1596
+ goto _test_eof7;
1597
+ case 7:
1598
+ #line 1599 "parser.c"
1045
1599
  goto st0;
1046
- st4:
1600
+ tr8:
1601
+ #line 738 "parser.rl"
1602
+ { is_float = true; }
1603
+ goto st3;
1604
+ st3:
1047
1605
  if ( ++p == pe )
1048
- goto _test_eof4;
1049
- case 4:
1606
+ goto _test_eof3;
1607
+ case 3:
1608
+ #line 1609 "parser.c"
1050
1609
  if ( 48 <= (*p) && (*p) <= 57 )
1051
1610
  goto st8;
1052
1611
  goto st0;
@@ -1055,90 +1614,89 @@ st8:
1055
1614
  goto _test_eof8;
1056
1615
  case 8:
1057
1616
  switch( (*p) ) {
1058
- case 69: goto st5;
1059
- case 101: goto st5;
1617
+ case 69: goto st4;
1618
+ case 101: goto st4;
1060
1619
  }
1061
1620
  if ( (*p) > 46 ) {
1062
1621
  if ( 48 <= (*p) && (*p) <= 57 )
1063
1622
  goto st8;
1064
1623
  } else if ( (*p) >= 45 )
1065
1624
  goto st0;
1066
- goto tr9;
1625
+ goto tr7;
1067
1626
  tr9:
1068
- #line 343 "parser.rl"
1069
- { p--; {p++; cs = 9; goto _out;} }
1070
- goto st9;
1071
- st9:
1072
- if ( ++p == pe )
1073
- goto _test_eof9;
1074
- case 9:
1075
- #line 1076 "parser.c"
1076
- goto st0;
1077
- st5:
1627
+ #line 738 "parser.rl"
1628
+ { is_float = true; }
1629
+ goto st4;
1630
+ st4:
1078
1631
  if ( ++p == pe )
1079
- goto _test_eof5;
1080
- case 5:
1632
+ goto _test_eof4;
1633
+ case 4:
1634
+ #line 1635 "parser.c"
1081
1635
  switch( (*p) ) {
1082
- case 43: goto st6;
1083
- case 45: goto st6;
1636
+ case 43: goto st5;
1637
+ case 45: goto st5;
1084
1638
  }
1085
1639
  if ( 48 <= (*p) && (*p) <= 57 )
1086
- goto st10;
1640
+ goto st9;
1087
1641
  goto st0;
1088
- st6:
1642
+ st5:
1089
1643
  if ( ++p == pe )
1090
- goto _test_eof6;
1091
- case 6:
1644
+ goto _test_eof5;
1645
+ case 5:
1092
1646
  if ( 48 <= (*p) && (*p) <= 57 )
1093
- goto st10;
1647
+ goto st9;
1094
1648
  goto st0;
1095
- st10:
1649
+ st9:
1096
1650
  if ( ++p == pe )
1097
- goto _test_eof10;
1098
- case 10:
1651
+ goto _test_eof9;
1652
+ case 9:
1099
1653
  switch( (*p) ) {
1100
1654
  case 69: goto st0;
1101
1655
  case 101: goto st0;
1102
1656
  }
1103
1657
  if ( (*p) > 46 ) {
1104
1658
  if ( 48 <= (*p) && (*p) <= 57 )
1105
- goto st10;
1659
+ goto st9;
1106
1660
  } else if ( (*p) >= 45 )
1107
1661
  goto st0;
1108
- goto tr9;
1109
- st7:
1662
+ goto tr7;
1663
+ st10:
1110
1664
  if ( ++p == pe )
1111
- goto _test_eof7;
1112
- case 7:
1665
+ goto _test_eof10;
1666
+ case 10:
1113
1667
  switch( (*p) ) {
1114
- case 46: goto st4;
1115
- case 69: goto st5;
1116
- case 101: goto st5;
1668
+ case 45: goto st0;
1669
+ case 46: goto tr8;
1670
+ case 69: goto tr9;
1671
+ case 101: goto tr9;
1117
1672
  }
1118
1673
  if ( 48 <= (*p) && (*p) <= 57 )
1119
- goto st7;
1120
- goto st0;
1674
+ goto st10;
1675
+ goto tr7;
1121
1676
  }
1122
1677
  _test_eof2: cs = 2; goto _test_eof;
1678
+ _test_eof6: cs = 6; goto _test_eof;
1679
+ _test_eof7: cs = 7; goto _test_eof;
1123
1680
  _test_eof3: cs = 3; goto _test_eof;
1124
- _test_eof4: cs = 4; goto _test_eof;
1125
1681
  _test_eof8: cs = 8; goto _test_eof;
1126
- _test_eof9: cs = 9; goto _test_eof;
1682
+ _test_eof4: cs = 4; goto _test_eof;
1127
1683
  _test_eof5: cs = 5; goto _test_eof;
1128
- _test_eof6: cs = 6; goto _test_eof;
1684
+ _test_eof9: cs = 9; goto _test_eof;
1129
1685
  _test_eof10: cs = 10; goto _test_eof;
1130
- _test_eof7: cs = 7; goto _test_eof;
1131
1686
 
1132
1687
  _test_eof: {}
1133
1688
  _out: {}
1134
1689
  }
1135
1690
 
1136
- #line 358 "parser.rl"
1691
+ #line 755 "parser.rl"
1137
1692
 
1138
1693
  if (cs >= JSON_float_first_final) {
1694
+ if (!is_float) {
1695
+ return JSON_decode_integer(json, p, result);
1696
+ }
1139
1697
  VALUE mod = Qnil;
1140
1698
  ID method_id = 0;
1141
- if (!NIL_P(json->decimal_class)) {
1699
+ if (json->decimal_class) {
1142
1700
  if (rb_respond_to(json->decimal_class, i_try_convert)) {
1143
1701
  mod = json->decimal_class;
1144
1702
  method_id = i_try_convert;
@@ -1167,15 +1725,15 @@ case 7:
1167
1725
  }
1168
1726
 
1169
1727
  long len = p - json->memo;
1170
- fbuffer_clear(json->fbuffer);
1171
- fbuffer_append(json->fbuffer, json->memo, len);
1172
- fbuffer_append_char(json->fbuffer, '\0');
1728
+ fbuffer_clear(&json->fbuffer);
1729
+ fbuffer_append(&json->fbuffer, json->memo, len);
1730
+ fbuffer_append_char(&json->fbuffer, '\0');
1173
1731
 
1174
1732
  if (method_id) {
1175
- VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1733
+ VALUE text = rb_str_new2(FBUFFER_PTR(&json->fbuffer));
1176
1734
  *result = rb_funcallv(mod, method_id, 1, &text);
1177
1735
  } else {
1178
- *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1736
+ *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(&json->fbuffer), 1));
1179
1737
  }
1180
1738
 
1181
1739
  return p + 1;
@@ -1186,37 +1744,37 @@ case 7:
1186
1744
 
1187
1745
 
1188
1746
 
1189
- #line 1190 "parser.c"
1747
+ #line 1748 "parser.c"
1190
1748
  enum {JSON_array_start = 1};
1191
- enum {JSON_array_first_final = 17};
1749
+ enum {JSON_array_first_final = 22};
1192
1750
  enum {JSON_array_error = 0};
1193
1751
 
1194
1752
  enum {JSON_array_en_main = 1};
1195
1753
 
1196
1754
 
1197
- #line 438 "parser.rl"
1755
+ #line 835 "parser.rl"
1198
1756
 
1199
1757
 
1200
1758
  static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
1201
1759
  {
1202
1760
  int cs = EVIL;
1203
- VALUE array_class = json->array_class;
1204
1761
 
1205
1762
  if (json->max_nesting && current_nesting > json->max_nesting) {
1206
1763
  rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
1207
1764
  }
1208
- *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1765
+ long stack_head = json->stack->head;
1209
1766
 
1210
1767
 
1211
- #line 1212 "parser.c"
1768
+ #line 1769 "parser.c"
1212
1769
  {
1213
1770
  cs = JSON_array_start;
1214
1771
  }
1215
1772
 
1216
- #line 451 "parser.rl"
1773
+ #line 847 "parser.rl"
1217
1774
 
1218
- #line 1219 "parser.c"
1775
+ #line 1776 "parser.c"
1219
1776
  {
1777
+ short _widec;
1220
1778
  if ( p == pe )
1221
1779
  goto _test_eof;
1222
1780
  switch ( cs )
@@ -1237,7 +1795,7 @@ case 2:
1237
1795
  case 32: goto st2;
1238
1796
  case 34: goto tr2;
1239
1797
  case 45: goto tr2;
1240
- case 47: goto st13;
1798
+ case 47: goto st18;
1241
1799
  case 73: goto tr2;
1242
1800
  case 78: goto tr2;
1243
1801
  case 91: goto tr2;
@@ -1254,18 +1812,13 @@ case 2:
1254
1812
  goto st2;
1255
1813
  goto st0;
1256
1814
  tr2:
1257
- #line 415 "parser.rl"
1815
+ #line 815 "parser.rl"
1258
1816
  {
1259
1817
  VALUE v = Qnil;
1260
1818
  char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
1261
1819
  if (np == NULL) {
1262
1820
  p--; {p++; cs = 3; goto _out;}
1263
1821
  } else {
1264
- if (NIL_P(json->array_class)) {
1265
- rb_ary_push(*result, v);
1266
- } else {
1267
- rb_funcall(*result, i_leftshift, 1, v);
1268
- }
1269
1822
  {p = (( np))-1;}
1270
1823
  }
1271
1824
  }
@@ -1274,15 +1827,23 @@ st3:
1274
1827
  if ( ++p == pe )
1275
1828
  goto _test_eof3;
1276
1829
  case 3:
1277
- #line 1278 "parser.c"
1278
- switch( (*p) ) {
1830
+ #line 1831 "parser.c"
1831
+ _widec = (*p);
1832
+ if ( 44 <= (*p) && (*p) <= 44 ) {
1833
+ _widec = (short)(128 + ((*p) - -128));
1834
+ if (
1835
+ #line 825 "parser.rl"
1836
+ json->allow_trailing_comma ) _widec += 256;
1837
+ }
1838
+ switch( _widec ) {
1279
1839
  case 13: goto st3;
1280
1840
  case 32: goto st3;
1281
- case 44: goto st4;
1282
- case 47: goto st9;
1841
+ case 47: goto st4;
1283
1842
  case 93: goto tr4;
1843
+ case 300: goto st8;
1844
+ case 556: goto st13;
1284
1845
  }
1285
- if ( 9 <= (*p) && (*p) <= 10 )
1846
+ if ( 9 <= _widec && _widec <= 10 )
1286
1847
  goto st3;
1287
1848
  goto st0;
1288
1849
  st4:
@@ -1290,57 +1851,67 @@ st4:
1290
1851
  goto _test_eof4;
1291
1852
  case 4:
1292
1853
  switch( (*p) ) {
1293
- case 13: goto st4;
1294
- case 32: goto st4;
1295
- case 34: goto tr2;
1296
- case 45: goto tr2;
1297
- case 47: goto st5;
1298
- case 73: goto tr2;
1299
- case 78: goto tr2;
1300
- case 91: goto tr2;
1301
- case 102: goto tr2;
1302
- case 110: goto tr2;
1303
- case 116: goto tr2;
1304
- case 123: goto tr2;
1854
+ case 42: goto st5;
1855
+ case 47: goto st7;
1305
1856
  }
1306
- if ( (*p) > 10 ) {
1307
- if ( 48 <= (*p) && (*p) <= 57 )
1308
- goto tr2;
1309
- } else if ( (*p) >= 9 )
1310
- goto st4;
1311
1857
  goto st0;
1312
1858
  st5:
1313
1859
  if ( ++p == pe )
1314
1860
  goto _test_eof5;
1315
1861
  case 5:
1316
- switch( (*p) ) {
1317
- case 42: goto st6;
1318
- case 47: goto st8;
1319
- }
1320
- goto st0;
1862
+ if ( (*p) == 42 )
1863
+ goto st6;
1864
+ goto st5;
1321
1865
  st6:
1322
1866
  if ( ++p == pe )
1323
1867
  goto _test_eof6;
1324
1868
  case 6:
1325
- if ( (*p) == 42 )
1326
- goto st7;
1327
- goto st6;
1869
+ switch( (*p) ) {
1870
+ case 42: goto st6;
1871
+ case 47: goto st3;
1872
+ }
1873
+ goto st5;
1328
1874
  st7:
1329
1875
  if ( ++p == pe )
1330
1876
  goto _test_eof7;
1331
1877
  case 7:
1332
- switch( (*p) ) {
1333
- case 42: goto st7;
1334
- case 47: goto st4;
1335
- }
1336
- goto st6;
1878
+ if ( (*p) == 10 )
1879
+ goto st3;
1880
+ goto st7;
1881
+ tr4:
1882
+ #line 827 "parser.rl"
1883
+ { p--; {p++; cs = 22; goto _out;} }
1884
+ goto st22;
1885
+ st22:
1886
+ if ( ++p == pe )
1887
+ goto _test_eof22;
1888
+ case 22:
1889
+ #line 1890 "parser.c"
1890
+ goto st0;
1337
1891
  st8:
1338
1892
  if ( ++p == pe )
1339
1893
  goto _test_eof8;
1340
1894
  case 8:
1341
- if ( (*p) == 10 )
1342
- goto st4;
1343
- goto st8;
1895
+ switch( (*p) ) {
1896
+ case 13: goto st8;
1897
+ case 32: goto st8;
1898
+ case 34: goto tr2;
1899
+ case 45: goto tr2;
1900
+ case 47: goto st9;
1901
+ case 73: goto tr2;
1902
+ case 78: goto tr2;
1903
+ case 91: goto tr2;
1904
+ case 102: goto tr2;
1905
+ case 110: goto tr2;
1906
+ case 116: goto tr2;
1907
+ case 123: goto tr2;
1908
+ }
1909
+ if ( (*p) > 10 ) {
1910
+ if ( 48 <= (*p) && (*p) <= 57 )
1911
+ goto tr2;
1912
+ } else if ( (*p) >= 9 )
1913
+ goto st8;
1914
+ goto st0;
1344
1915
  st9:
1345
1916
  if ( ++p == pe )
1346
1917
  goto _test_eof9;
@@ -1363,7 +1934,7 @@ st11:
1363
1934
  case 11:
1364
1935
  switch( (*p) ) {
1365
1936
  case 42: goto st11;
1366
- case 47: goto st3;
1937
+ case 47: goto st8;
1367
1938
  }
1368
1939
  goto st10;
1369
1940
  st12:
@@ -1371,50 +1942,252 @@ st12:
1371
1942
  goto _test_eof12;
1372
1943
  case 12:
1373
1944
  if ( (*p) == 10 )
1374
- goto st3;
1945
+ goto st8;
1375
1946
  goto st12;
1376
- tr4:
1377
- #line 430 "parser.rl"
1378
- { p--; {p++; cs = 17; goto _out;} }
1379
- goto st17;
1380
- st17:
1381
- if ( ++p == pe )
1382
- goto _test_eof17;
1383
- case 17:
1384
- #line 1385 "parser.c"
1385
- goto st0;
1386
1947
  st13:
1387
1948
  if ( ++p == pe )
1388
1949
  goto _test_eof13;
1389
1950
  case 13:
1390
- switch( (*p) ) {
1391
- case 42: goto st14;
1392
- case 47: goto st16;
1393
- }
1951
+ _widec = (*p);
1952
+ if ( (*p) < 13 ) {
1953
+ if ( (*p) > 9 ) {
1954
+ if ( 10 <= (*p) && (*p) <= 10 ) {
1955
+ _widec = (short)(128 + ((*p) - -128));
1956
+ if (
1957
+ #line 825 "parser.rl"
1958
+ json->allow_trailing_comma ) _widec += 256;
1959
+ }
1960
+ } else if ( (*p) >= 9 ) {
1961
+ _widec = (short)(128 + ((*p) - -128));
1962
+ if (
1963
+ #line 825 "parser.rl"
1964
+ json->allow_trailing_comma ) _widec += 256;
1965
+ }
1966
+ } else if ( (*p) > 13 ) {
1967
+ if ( (*p) > 32 ) {
1968
+ if ( 47 <= (*p) && (*p) <= 47 ) {
1969
+ _widec = (short)(128 + ((*p) - -128));
1970
+ if (
1971
+ #line 825 "parser.rl"
1972
+ json->allow_trailing_comma ) _widec += 256;
1973
+ }
1974
+ } else if ( (*p) >= 32 ) {
1975
+ _widec = (short)(128 + ((*p) - -128));
1976
+ if (
1977
+ #line 825 "parser.rl"
1978
+ json->allow_trailing_comma ) _widec += 256;
1979
+ }
1980
+ } else {
1981
+ _widec = (short)(128 + ((*p) - -128));
1982
+ if (
1983
+ #line 825 "parser.rl"
1984
+ json->allow_trailing_comma ) _widec += 256;
1985
+ }
1986
+ switch( _widec ) {
1987
+ case 34: goto tr2;
1988
+ case 45: goto tr2;
1989
+ case 73: goto tr2;
1990
+ case 78: goto tr2;
1991
+ case 91: goto tr2;
1992
+ case 93: goto tr4;
1993
+ case 102: goto tr2;
1994
+ case 110: goto tr2;
1995
+ case 116: goto tr2;
1996
+ case 123: goto tr2;
1997
+ case 269: goto st8;
1998
+ case 288: goto st8;
1999
+ case 303: goto st9;
2000
+ case 525: goto st13;
2001
+ case 544: goto st13;
2002
+ case 559: goto st14;
2003
+ }
2004
+ if ( _widec < 265 ) {
2005
+ if ( 48 <= _widec && _widec <= 57 )
2006
+ goto tr2;
2007
+ } else if ( _widec > 266 ) {
2008
+ if ( 521 <= _widec && _widec <= 522 )
2009
+ goto st13;
2010
+ } else
2011
+ goto st8;
1394
2012
  goto st0;
1395
2013
  st14:
1396
2014
  if ( ++p == pe )
1397
2015
  goto _test_eof14;
1398
2016
  case 14:
1399
- if ( (*p) == 42 )
1400
- goto st15;
1401
- goto st14;
2017
+ _widec = (*p);
2018
+ if ( (*p) > 42 ) {
2019
+ if ( 47 <= (*p) && (*p) <= 47 ) {
2020
+ _widec = (short)(128 + ((*p) - -128));
2021
+ if (
2022
+ #line 825 "parser.rl"
2023
+ json->allow_trailing_comma ) _widec += 256;
2024
+ }
2025
+ } else if ( (*p) >= 42 ) {
2026
+ _widec = (short)(128 + ((*p) - -128));
2027
+ if (
2028
+ #line 825 "parser.rl"
2029
+ json->allow_trailing_comma ) _widec += 256;
2030
+ }
2031
+ switch( _widec ) {
2032
+ case 298: goto st10;
2033
+ case 303: goto st12;
2034
+ case 554: goto st15;
2035
+ case 559: goto st17;
2036
+ }
2037
+ goto st0;
1402
2038
  st15:
1403
2039
  if ( ++p == pe )
1404
2040
  goto _test_eof15;
1405
2041
  case 15:
1406
- switch( (*p) ) {
1407
- case 42: goto st15;
1408
- case 47: goto st2;
1409
- }
1410
- goto st14;
2042
+ _widec = (*p);
2043
+ if ( (*p) < 42 ) {
2044
+ if ( (*p) <= 41 ) {
2045
+ _widec = (short)(128 + ((*p) - -128));
2046
+ if (
2047
+ #line 825 "parser.rl"
2048
+ json->allow_trailing_comma ) _widec += 256;
2049
+ }
2050
+ } else if ( (*p) > 42 ) {
2051
+ if ( 43 <= (*p) )
2052
+ { _widec = (short)(128 + ((*p) - -128));
2053
+ if (
2054
+ #line 825 "parser.rl"
2055
+ json->allow_trailing_comma ) _widec += 256;
2056
+ }
2057
+ } else {
2058
+ _widec = (short)(128 + ((*p) - -128));
2059
+ if (
2060
+ #line 825 "parser.rl"
2061
+ json->allow_trailing_comma ) _widec += 256;
2062
+ }
2063
+ switch( _widec ) {
2064
+ case 298: goto st11;
2065
+ case 554: goto st16;
2066
+ }
2067
+ if ( _widec > 383 ) {
2068
+ if ( 384 <= _widec && _widec <= 639 )
2069
+ goto st15;
2070
+ } else if ( _widec >= 128 )
2071
+ goto st10;
2072
+ goto st0;
1411
2073
  st16:
1412
2074
  if ( ++p == pe )
1413
2075
  goto _test_eof16;
1414
2076
  case 16:
2077
+ _widec = (*p);
2078
+ if ( (*p) < 43 ) {
2079
+ if ( (*p) > 41 ) {
2080
+ if ( 42 <= (*p) && (*p) <= 42 ) {
2081
+ _widec = (short)(128 + ((*p) - -128));
2082
+ if (
2083
+ #line 825 "parser.rl"
2084
+ json->allow_trailing_comma ) _widec += 256;
2085
+ }
2086
+ } else {
2087
+ _widec = (short)(128 + ((*p) - -128));
2088
+ if (
2089
+ #line 825 "parser.rl"
2090
+ json->allow_trailing_comma ) _widec += 256;
2091
+ }
2092
+ } else if ( (*p) > 46 ) {
2093
+ if ( (*p) > 47 ) {
2094
+ if ( 48 <= (*p) )
2095
+ { _widec = (short)(128 + ((*p) - -128));
2096
+ if (
2097
+ #line 825 "parser.rl"
2098
+ json->allow_trailing_comma ) _widec += 256;
2099
+ }
2100
+ } else if ( (*p) >= 47 ) {
2101
+ _widec = (short)(128 + ((*p) - -128));
2102
+ if (
2103
+ #line 825 "parser.rl"
2104
+ json->allow_trailing_comma ) _widec += 256;
2105
+ }
2106
+ } else {
2107
+ _widec = (short)(128 + ((*p) - -128));
2108
+ if (
2109
+ #line 825 "parser.rl"
2110
+ json->allow_trailing_comma ) _widec += 256;
2111
+ }
2112
+ switch( _widec ) {
2113
+ case 298: goto st11;
2114
+ case 303: goto st8;
2115
+ case 554: goto st16;
2116
+ case 559: goto st13;
2117
+ }
2118
+ if ( _widec > 383 ) {
2119
+ if ( 384 <= _widec && _widec <= 639 )
2120
+ goto st15;
2121
+ } else if ( _widec >= 128 )
2122
+ goto st10;
2123
+ goto st0;
2124
+ st17:
2125
+ if ( ++p == pe )
2126
+ goto _test_eof17;
2127
+ case 17:
2128
+ _widec = (*p);
2129
+ if ( (*p) < 10 ) {
2130
+ if ( (*p) <= 9 ) {
2131
+ _widec = (short)(128 + ((*p) - -128));
2132
+ if (
2133
+ #line 825 "parser.rl"
2134
+ json->allow_trailing_comma ) _widec += 256;
2135
+ }
2136
+ } else if ( (*p) > 10 ) {
2137
+ if ( 11 <= (*p) )
2138
+ { _widec = (short)(128 + ((*p) - -128));
2139
+ if (
2140
+ #line 825 "parser.rl"
2141
+ json->allow_trailing_comma ) _widec += 256;
2142
+ }
2143
+ } else {
2144
+ _widec = (short)(128 + ((*p) - -128));
2145
+ if (
2146
+ #line 825 "parser.rl"
2147
+ json->allow_trailing_comma ) _widec += 256;
2148
+ }
2149
+ switch( _widec ) {
2150
+ case 266: goto st8;
2151
+ case 522: goto st13;
2152
+ }
2153
+ if ( _widec > 383 ) {
2154
+ if ( 384 <= _widec && _widec <= 639 )
2155
+ goto st17;
2156
+ } else if ( _widec >= 128 )
2157
+ goto st12;
2158
+ goto st0;
2159
+ st18:
2160
+ if ( ++p == pe )
2161
+ goto _test_eof18;
2162
+ case 18:
2163
+ switch( (*p) ) {
2164
+ case 42: goto st19;
2165
+ case 47: goto st21;
2166
+ }
2167
+ goto st0;
2168
+ st19:
2169
+ if ( ++p == pe )
2170
+ goto _test_eof19;
2171
+ case 19:
2172
+ if ( (*p) == 42 )
2173
+ goto st20;
2174
+ goto st19;
2175
+ st20:
2176
+ if ( ++p == pe )
2177
+ goto _test_eof20;
2178
+ case 20:
2179
+ switch( (*p) ) {
2180
+ case 42: goto st20;
2181
+ case 47: goto st2;
2182
+ }
2183
+ goto st19;
2184
+ st21:
2185
+ if ( ++p == pe )
2186
+ goto _test_eof21;
2187
+ case 21:
1415
2188
  if ( (*p) == 10 )
1416
2189
  goto st2;
1417
- goto st16;
2190
+ goto st21;
1418
2191
  }
1419
2192
  _test_eof2: cs = 2; goto _test_eof;
1420
2193
  _test_eof3: cs = 3; goto _test_eof;
@@ -1422,24 +2195,45 @@ case 16:
1422
2195
  _test_eof5: cs = 5; goto _test_eof;
1423
2196
  _test_eof6: cs = 6; goto _test_eof;
1424
2197
  _test_eof7: cs = 7; goto _test_eof;
2198
+ _test_eof22: cs = 22; goto _test_eof;
1425
2199
  _test_eof8: cs = 8; goto _test_eof;
1426
2200
  _test_eof9: cs = 9; goto _test_eof;
1427
2201
  _test_eof10: cs = 10; goto _test_eof;
1428
2202
  _test_eof11: cs = 11; goto _test_eof;
1429
2203
  _test_eof12: cs = 12; goto _test_eof;
1430
- _test_eof17: cs = 17; goto _test_eof;
1431
2204
  _test_eof13: cs = 13; goto _test_eof;
1432
2205
  _test_eof14: cs = 14; goto _test_eof;
1433
2206
  _test_eof15: cs = 15; goto _test_eof;
1434
2207
  _test_eof16: cs = 16; goto _test_eof;
2208
+ _test_eof17: cs = 17; goto _test_eof;
2209
+ _test_eof18: cs = 18; goto _test_eof;
2210
+ _test_eof19: cs = 19; goto _test_eof;
2211
+ _test_eof20: cs = 20; goto _test_eof;
2212
+ _test_eof21: cs = 21; goto _test_eof;
1435
2213
 
1436
2214
  _test_eof: {}
1437
2215
  _out: {}
1438
2216
  }
1439
2217
 
1440
- #line 452 "parser.rl"
2218
+ #line 848 "parser.rl"
1441
2219
 
1442
2220
  if(cs >= JSON_array_first_final) {
2221
+ long count = json->stack->head - stack_head;
2222
+
2223
+ if (RB_UNLIKELY(json->array_class)) {
2224
+ VALUE array = rb_class_new_instance(0, 0, json->array_class);
2225
+ VALUE *items = rvalue_stack_peek(json->stack, count);
2226
+ long index;
2227
+ for (index = 0; index < count; index++) {
2228
+ rb_funcall(array, i_leftshift, 1, items[index]);
2229
+ }
2230
+ *result = array;
2231
+ } else {
2232
+ VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(json->stack, count));
2233
+ *result = array;
2234
+ }
2235
+ rvalue_stack_pop(json->stack, count);
2236
+
1443
2237
  return p + 1;
1444
2238
  } else {
1445
2239
  raise_parse_error("unexpected token at '%s'", p);
@@ -1447,29 +2241,81 @@ case 16:
1447
2241
  }
1448
2242
  }
1449
2243
 
1450
- static const size_t MAX_STACK_BUFFER_SIZE = 128;
1451
- static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
2244
+ static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
2245
+ {
2246
+ if (symbolize) {
2247
+ intern = true;
2248
+ }
2249
+ VALUE result;
2250
+ # ifdef HAVE_RB_ENC_INTERNED_STR
2251
+ if (intern) {
2252
+ result = rb_enc_interned_str(start, (long)(end - start), enc_utf8);
2253
+ } else {
2254
+ result = rb_utf8_str_new(start, (long)(end - start));
2255
+ }
2256
+ # else
2257
+ result = rb_utf8_str_new(start, (long)(end - start));
2258
+ if (intern) {
2259
+ result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
2260
+ }
2261
+ # endif
2262
+
2263
+ if (symbolize) {
2264
+ result = rb_str_intern(result);
2265
+ }
2266
+
2267
+ return result;
2268
+ }
2269
+
2270
+ static VALUE json_string_fastpath(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
2271
+ {
2272
+ size_t bufferSize = stringEnd - string;
2273
+
2274
+ if (is_name && json->in_array) {
2275
+ VALUE cached_key;
2276
+ if (RB_UNLIKELY(symbolize)) {
2277
+ cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
2278
+ } else {
2279
+ cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
2280
+ }
2281
+
2282
+ if (RB_LIKELY(cached_key)) {
2283
+ return cached_key;
2284
+ }
2285
+ }
2286
+
2287
+ return build_string(string, stringEnd, intern, symbolize);
2288
+ }
2289
+
2290
+ static VALUE json_string_unescape(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
1452
2291
  {
1453
- VALUE result = Qnil;
1454
2292
  size_t bufferSize = stringEnd - string;
1455
2293
  char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
1456
2294
  int unescape_len;
1457
2295
  char buf[4];
1458
2296
 
1459
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1460
- # ifdef HAVE_RB_ENC_INTERNED_STR
1461
- bufferStart = buffer = ALLOC_N(char, bufferSize ? bufferSize : 1);
1462
- # else
1463
- bufferStart = buffer = ALLOC_N(char, bufferSize);
1464
- # endif
1465
- } else {
1466
- # ifdef HAVE_RB_ENC_INTERNED_STR
1467
- bufferStart = buffer = ALLOCA_N(char, bufferSize ? bufferSize : 1);
1468
- # else
1469
- bufferStart = buffer = ALLOCA_N(char, bufferSize);
1470
- # endif
2297
+ if (is_name && json->in_array) {
2298
+ VALUE cached_key;
2299
+ if (RB_UNLIKELY(symbolize)) {
2300
+ cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
2301
+ } else {
2302
+ cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
2303
+ }
2304
+
2305
+ if (RB_LIKELY(cached_key)) {
2306
+ return cached_key;
2307
+ }
2308
+ }
2309
+
2310
+ pe = memchr(p, '\\', bufferSize);
2311
+ if (RB_UNLIKELY(pe == NULL)) {
2312
+ return build_string(string, stringEnd, intern, symbolize);
1471
2313
  }
1472
2314
 
2315
+ VALUE result = rb_str_buf_new(bufferSize);
2316
+ rb_enc_associate_index(result, utf8_encindex);
2317
+ buffer = bufferStart = RSTRING_PTR(result);
2318
+
1473
2319
  while (pe < stringEnd) {
1474
2320
  if (*pe == '\\') {
1475
2321
  unescape = (char *) "?";
@@ -1502,9 +2348,6 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
1502
2348
  break;
1503
2349
  case 'u':
1504
2350
  if (pe > stringEnd - 4) {
1505
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1506
- ruby_xfree(bufferStart);
1507
- }
1508
2351
  raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
1509
2352
  } else {
1510
2353
  uint32_t ch = unescape_unicode((unsigned char *) ++pe);
@@ -1522,9 +2365,6 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
1522
2365
  if ((ch & 0xFC00) == 0xD800) {
1523
2366
  pe++;
1524
2367
  if (pe > stringEnd - 6) {
1525
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1526
- ruby_xfree(bufferStart);
1527
- }
1528
2368
  raise_parse_error("incomplete surrogate pair at '%s'", p);
1529
2369
  }
1530
2370
  if (pe[0] == '\\' && pe[1] == 'u') {
@@ -1557,56 +2397,27 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
1557
2397
  MEMCPY(buffer, p, char, pe - p);
1558
2398
  buffer += pe - p;
1559
2399
  }
1560
-
1561
- # ifdef HAVE_RB_ENC_INTERNED_STR
1562
- if (intern) {
1563
- result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
1564
- } else {
1565
- result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1566
- }
1567
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1568
- ruby_xfree(bufferStart);
1569
- }
1570
- # else
1571
- result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1572
-
1573
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1574
- ruby_xfree(bufferStart);
1575
- }
1576
-
1577
- if (intern) {
1578
- # if STR_UMINUS_DEDUPE_FROZEN
1579
- // Starting from MRI 2.8 it is preferable to freeze the string
1580
- // before deduplication so that it can be interned directly
1581
- // otherwise it would be duplicated first which is wasteful.
1582
- result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
1583
- # elif STR_UMINUS_DEDUPE
1584
- // MRI 2.5 and older do not deduplicate strings that are already
1585
- // frozen.
1586
- result = rb_funcall(result, i_uminus, 0);
1587
- # else
1588
- result = rb_str_freeze(result);
1589
- # endif
1590
- }
1591
- # endif
2400
+ rb_str_set_len(result, buffer - bufferStart);
1592
2401
 
1593
2402
  if (symbolize) {
1594
- result = rb_str_intern(result);
2403
+ result = rb_str_intern(result);
2404
+ } else if (intern) {
2405
+ result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
1595
2406
  }
1596
2407
 
1597
2408
  return result;
1598
2409
  }
1599
2410
 
1600
2411
 
1601
- #line 1602 "parser.c"
2412
+ #line 2413 "parser.c"
1602
2413
  enum {JSON_string_start = 1};
1603
- enum {JSON_string_first_final = 8};
2414
+ enum {JSON_string_first_final = 9};
1604
2415
  enum {JSON_string_error = 0};
1605
2416
 
1606
2417
  enum {JSON_string_en_main = 1};
1607
2418
 
1608
2419
 
1609
- #line 630 "parser.rl"
2420
+ #line 1071 "parser.rl"
1610
2421
 
1611
2422
 
1612
2423
  static int
@@ -1627,15 +2438,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
1627
2438
  VALUE match_string;
1628
2439
 
1629
2440
 
1630
- #line 1631 "parser.c"
2441
+ #line 2442 "parser.c"
1631
2442
  {
1632
2443
  cs = JSON_string_start;
1633
2444
  }
1634
2445
 
1635
- #line 650 "parser.rl"
2446
+ #line 1091 "parser.rl"
1636
2447
  json->memo = p;
1637
2448
 
1638
- #line 1639 "parser.c"
2449
+ #line 2450 "parser.c"
1639
2450
  {
1640
2451
  if ( p == pe )
1641
2452
  goto _test_eof;
@@ -1660,47 +2471,56 @@ case 2:
1660
2471
  goto st0;
1661
2472
  goto st2;
1662
2473
  tr2:
1663
- #line 617 "parser.rl"
2474
+ #line 1053 "parser.rl"
1664
2475
  {
1665
- *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
1666
- if (NIL_P(*result)) {
1667
- p--;
1668
- {p++; cs = 8; goto _out;}
1669
- } else {
1670
- {p = (( p + 1))-1;}
1671
- }
2476
+ *result = json_string_fastpath(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
2477
+ {p = (( p + 1))-1;}
2478
+ p--;
2479
+ {p++; cs = 9; goto _out;}
1672
2480
  }
1673
- #line 627 "parser.rl"
1674
- { p--; {p++; cs = 8; goto _out;} }
1675
- goto st8;
1676
- st8:
2481
+ #line 1046 "parser.rl"
2482
+ {
2483
+ *result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
2484
+ {p = (( p + 1))-1;}
2485
+ p--;
2486
+ {p++; cs = 9; goto _out;}
2487
+ }
2488
+ goto st9;
2489
+ tr6:
2490
+ #line 1046 "parser.rl"
2491
+ {
2492
+ *result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
2493
+ {p = (( p + 1))-1;}
2494
+ p--;
2495
+ {p++; cs = 9; goto _out;}
2496
+ }
2497
+ goto st9;
2498
+ st9:
1677
2499
  if ( ++p == pe )
1678
- goto _test_eof8;
1679
- case 8:
1680
- #line 1681 "parser.c"
2500
+ goto _test_eof9;
2501
+ case 9:
2502
+ #line 2503 "parser.c"
1681
2503
  goto st0;
1682
2504
  st3:
1683
2505
  if ( ++p == pe )
1684
2506
  goto _test_eof3;
1685
2507
  case 3:
1686
2508
  if ( (*p) == 117 )
1687
- goto st4;
2509
+ goto st5;
1688
2510
  if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
1689
2511
  goto st0;
1690
- goto st2;
2512
+ goto st4;
1691
2513
  st4:
1692
- if ( ++p == pe )
1693
- goto _test_eof4;
1694
- case 4:
1695
- if ( (*p) < 65 ) {
1696
- if ( 48 <= (*p) && (*p) <= 57 )
1697
- goto st5;
1698
- } else if ( (*p) > 70 ) {
1699
- if ( 97 <= (*p) && (*p) <= 102 )
1700
- goto st5;
1701
- } else
1702
- goto st5;
1703
- goto st0;
2514
+ if ( ++p == pe )
2515
+ goto _test_eof4;
2516
+ case 4:
2517
+ switch( (*p) ) {
2518
+ case 34: goto tr6;
2519
+ case 92: goto st3;
2520
+ }
2521
+ if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
2522
+ goto st0;
2523
+ goto st4;
1704
2524
  st5:
1705
2525
  if ( ++p == pe )
1706
2526
  goto _test_eof5;
@@ -1733,27 +2553,41 @@ st7:
1733
2553
  case 7:
1734
2554
  if ( (*p) < 65 ) {
1735
2555
  if ( 48 <= (*p) && (*p) <= 57 )
1736
- goto st2;
2556
+ goto st8;
1737
2557
  } else if ( (*p) > 70 ) {
1738
2558
  if ( 97 <= (*p) && (*p) <= 102 )
1739
- goto st2;
2559
+ goto st8;
1740
2560
  } else
1741
- goto st2;
2561
+ goto st8;
2562
+ goto st0;
2563
+ st8:
2564
+ if ( ++p == pe )
2565
+ goto _test_eof8;
2566
+ case 8:
2567
+ if ( (*p) < 65 ) {
2568
+ if ( 48 <= (*p) && (*p) <= 57 )
2569
+ goto st4;
2570
+ } else if ( (*p) > 70 ) {
2571
+ if ( 97 <= (*p) && (*p) <= 102 )
2572
+ goto st4;
2573
+ } else
2574
+ goto st4;
1742
2575
  goto st0;
1743
2576
  }
1744
2577
  _test_eof2: cs = 2; goto _test_eof;
1745
- _test_eof8: cs = 8; goto _test_eof;
2578
+ _test_eof9: cs = 9; goto _test_eof;
1746
2579
  _test_eof3: cs = 3; goto _test_eof;
1747
2580
  _test_eof4: cs = 4; goto _test_eof;
1748
2581
  _test_eof5: cs = 5; goto _test_eof;
1749
2582
  _test_eof6: cs = 6; goto _test_eof;
1750
2583
  _test_eof7: cs = 7; goto _test_eof;
2584
+ _test_eof8: cs = 8; goto _test_eof;
1751
2585
 
1752
2586
  _test_eof: {}
1753
2587
  _out: {}
1754
2588
  }
1755
2589
 
1756
- #line 652 "parser.rl"
2590
+ #line 1093 "parser.rl"
1757
2591
 
1758
2592
  if (json->create_additions && RTEST(match_string = json->match_string)) {
1759
2593
  VALUE klass;
@@ -1789,18 +2623,78 @@ static VALUE convert_encoding(VALUE source)
1789
2623
  {
1790
2624
  int encindex = RB_ENCODING_GET(source);
1791
2625
 
1792
- if (encindex == utf8_encindex) {
2626
+ if (RB_LIKELY(encindex == utf8_encindex)) {
1793
2627
  return source;
1794
2628
  }
1795
2629
 
1796
2630
  if (encindex == binary_encindex) {
1797
- // For historical reason, we silently reinterpret binary strings as UTF-8 if it would work.
1798
- // TODO: Deprecate in 2.8.0
1799
- // TODO: Remove in 3.0.0
2631
+ // For historical reason, we silently reinterpret binary strings as UTF-8
1800
2632
  return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
1801
2633
  }
1802
2634
 
1803
- return rb_str_conv_enc(source, rb_enc_from_index(encindex), rb_utf8_encoding());
2635
+ return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
2636
+ }
2637
+
2638
+ static int configure_parser_i(VALUE key, VALUE val, VALUE data)
2639
+ {
2640
+ JSON_Parser *json = (JSON_Parser *)data;
2641
+
2642
+ if (key == sym_max_nesting) { json->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
2643
+ else if (key == sym_allow_nan) { json->allow_nan = RTEST(val); }
2644
+ else if (key == sym_allow_trailing_comma) { json->allow_trailing_comma = RTEST(val); }
2645
+ else if (key == sym_symbolize_names) { json->symbolize_names = RTEST(val); }
2646
+ else if (key == sym_freeze) { json->freeze = RTEST(val); }
2647
+ else if (key == sym_create_id) { json->create_id = RTEST(val) ? val : Qfalse; }
2648
+ else if (key == sym_object_class) { json->object_class = RTEST(val) ? val : Qfalse; }
2649
+ else if (key == sym_array_class) { json->array_class = RTEST(val) ? val : Qfalse; }
2650
+ else if (key == sym_decimal_class) { json->decimal_class = RTEST(val) ? val : Qfalse; }
2651
+ else if (key == sym_match_string) { json->match_string = RTEST(val) ? val : Qfalse; }
2652
+ else if (key == sym_create_additions) {
2653
+ if (NIL_P(val)) {
2654
+ json->create_additions = true;
2655
+ json->deprecated_create_additions = true;
2656
+ } else {
2657
+ json->create_additions = RTEST(val);
2658
+ json->deprecated_create_additions = false;
2659
+ }
2660
+ }
2661
+
2662
+ return ST_CONTINUE;
2663
+ }
2664
+
2665
+ static void parser_init(JSON_Parser *json, VALUE source, VALUE opts)
2666
+ {
2667
+ if (json->Vsource) {
2668
+ rb_raise(rb_eTypeError, "already initialized instance");
2669
+ }
2670
+
2671
+ json->fbuffer.initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
2672
+ json->max_nesting = 100;
2673
+
2674
+ if (!NIL_P(opts)) {
2675
+ Check_Type(opts, T_HASH);
2676
+ if (RHASH_SIZE(opts) > 0) {
2677
+ // We assume in most cases few keys are set so it's faster to go over
2678
+ // the provided keys than to check all possible keys.
2679
+ rb_hash_foreach(opts, configure_parser_i, (VALUE)json);
2680
+
2681
+ if (json->symbolize_names && json->create_additions) {
2682
+ rb_raise(rb_eArgError,
2683
+ "options :symbolize_names and :create_additions cannot be "
2684
+ " used in conjunction");
2685
+ }
2686
+
2687
+ if (json->create_additions && !json->create_id) {
2688
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
2689
+ }
2690
+ }
2691
+
2692
+ }
2693
+ source = convert_encoding(StringValue(source));
2694
+ StringValue(source);
2695
+ json->len = RSTRING_LEN(source);
2696
+ json->source = RSTRING_PTR(source);
2697
+ json->Vsource = source;
1804
2698
  }
1805
2699
 
1806
2700
  /*
@@ -1837,116 +2731,16 @@ static VALUE convert_encoding(VALUE source)
1837
2731
  */
1838
2732
  static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1839
2733
  {
1840
- VALUE source, opts;
1841
2734
  GET_PARSER_INIT;
1842
2735
 
1843
- if (json->Vsource) {
1844
- rb_raise(rb_eTypeError, "already initialized instance");
1845
- }
1846
-
1847
2736
  rb_check_arity(argc, 1, 2);
1848
- source = argv[0];
1849
- opts = Qnil;
1850
- if (argc == 2) {
1851
- opts = argv[1];
1852
- Check_Type(argv[1], T_HASH);
1853
- if (RHASH_SIZE(argv[1]) > 0) {
1854
- opts = argv[1];
1855
- }
1856
- }
1857
2737
 
1858
- if (!NIL_P(opts)) {
1859
- VALUE tmp = ID2SYM(i_max_nesting);
1860
- if (option_given_p(opts, tmp)) {
1861
- VALUE max_nesting = rb_hash_aref(opts, tmp);
1862
- if (RTEST(max_nesting)) {
1863
- Check_Type(max_nesting, T_FIXNUM);
1864
- json->max_nesting = FIX2INT(max_nesting);
1865
- } else {
1866
- json->max_nesting = 0;
1867
- }
1868
- } else {
1869
- json->max_nesting = 100;
1870
- }
1871
- tmp = ID2SYM(i_allow_nan);
1872
- if (option_given_p(opts, tmp)) {
1873
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1874
- } else {
1875
- json->allow_nan = 0;
1876
- }
1877
- tmp = ID2SYM(i_symbolize_names);
1878
- if (option_given_p(opts, tmp)) {
1879
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1880
- } else {
1881
- json->symbolize_names = 0;
1882
- }
1883
- tmp = ID2SYM(i_freeze);
1884
- if (option_given_p(opts, tmp)) {
1885
- json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1886
- } else {
1887
- json->freeze = 0;
1888
- }
1889
- tmp = ID2SYM(i_create_additions);
1890
- if (option_given_p(opts, tmp)) {
1891
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1892
- } else {
1893
- json->create_additions = 0;
1894
- }
1895
- if (json->symbolize_names && json->create_additions) {
1896
- rb_raise(rb_eArgError,
1897
- "options :symbolize_names and :create_additions cannot be "
1898
- " used in conjunction");
1899
- }
1900
- tmp = ID2SYM(i_create_id);
1901
- if (option_given_p(opts, tmp)) {
1902
- json->create_id = rb_hash_aref(opts, tmp);
1903
- } else {
1904
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
1905
- }
1906
- tmp = ID2SYM(i_object_class);
1907
- if (option_given_p(opts, tmp)) {
1908
- json->object_class = rb_hash_aref(opts, tmp);
1909
- } else {
1910
- json->object_class = Qnil;
1911
- }
1912
- tmp = ID2SYM(i_array_class);
1913
- if (option_given_p(opts, tmp)) {
1914
- json->array_class = rb_hash_aref(opts, tmp);
1915
- } else {
1916
- json->array_class = Qnil;
1917
- }
1918
- tmp = ID2SYM(i_decimal_class);
1919
- if (option_given_p(opts, tmp)) {
1920
- json->decimal_class = rb_hash_aref(opts, tmp);
1921
- } else {
1922
- json->decimal_class = Qnil;
1923
- }
1924
- tmp = ID2SYM(i_match_string);
1925
- if (option_given_p(opts, tmp)) {
1926
- VALUE match_string = rb_hash_aref(opts, tmp);
1927
- json->match_string = RTEST(match_string) ? match_string : Qnil;
1928
- } else {
1929
- json->match_string = Qnil;
1930
- }
1931
- } else {
1932
- json->max_nesting = 100;
1933
- json->allow_nan = 0;
1934
- json->create_additions = 0;
1935
- json->create_id = Qnil;
1936
- json->object_class = Qnil;
1937
- json->array_class = Qnil;
1938
- json->decimal_class = Qnil;
1939
- }
1940
- source = convert_encoding(StringValue(source));
1941
- StringValue(source);
1942
- json->len = RSTRING_LEN(source);
1943
- json->source = RSTRING_PTR(source);;
1944
- json->Vsource = source;
2738
+ parser_init(json, argv[0], argc == 2 ? argv[1] : Qnil);
1945
2739
  return self;
1946
2740
  }
1947
2741
 
1948
2742
 
1949
- #line 1950 "parser.c"
2743
+ #line 2744 "parser.c"
1950
2744
  enum {JSON_start = 1};
1951
2745
  enum {JSON_first_final = 10};
1952
2746
  enum {JSON_error = 0};
@@ -1954,7 +2748,7 @@ enum {JSON_error = 0};
1954
2748
  enum {JSON_en_main = 1};
1955
2749
 
1956
2750
 
1957
- #line 858 "parser.rl"
2751
+ #line 1259 "parser.rl"
1958
2752
 
1959
2753
 
1960
2754
  /*
@@ -1971,17 +2765,206 @@ static VALUE cParser_parse(VALUE self)
1971
2765
  VALUE result = Qnil;
1972
2766
  GET_PARSER;
1973
2767
 
2768
+ char stack_buffer[FBUFFER_STACK_SIZE];
2769
+ fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
2770
+
2771
+ VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
2772
+ rvalue_stack stack = {
2773
+ .type = RVALUE_STACK_STACK_ALLOCATED,
2774
+ .ptr = rvalue_stack_buffer,
2775
+ .capa = RVALUE_STACK_INITIAL_CAPA,
2776
+ };
2777
+ json->stack = &stack;
2778
+
2779
+
2780
+ #line 2781 "parser.c"
2781
+ {
2782
+ cs = JSON_start;
2783
+ }
2784
+
2785
+ #line 1287 "parser.rl"
2786
+ p = json->source;
2787
+ pe = p + json->len;
2788
+
2789
+ #line 2790 "parser.c"
2790
+ {
2791
+ if ( p == pe )
2792
+ goto _test_eof;
2793
+ switch ( cs )
2794
+ {
2795
+ st1:
2796
+ if ( ++p == pe )
2797
+ goto _test_eof1;
2798
+ case 1:
2799
+ switch( (*p) ) {
2800
+ case 13: goto st1;
2801
+ case 32: goto st1;
2802
+ case 34: goto tr2;
2803
+ case 45: goto tr2;
2804
+ case 47: goto st6;
2805
+ case 73: goto tr2;
2806
+ case 78: goto tr2;
2807
+ case 91: goto tr2;
2808
+ case 102: goto tr2;
2809
+ case 110: goto tr2;
2810
+ case 116: goto tr2;
2811
+ case 123: goto tr2;
2812
+ }
2813
+ if ( (*p) > 10 ) {
2814
+ if ( 48 <= (*p) && (*p) <= 57 )
2815
+ goto tr2;
2816
+ } else if ( (*p) >= 9 )
2817
+ goto st1;
2818
+ goto st0;
2819
+ st0:
2820
+ cs = 0;
2821
+ goto _out;
2822
+ tr2:
2823
+ #line 1251 "parser.rl"
2824
+ {
2825
+ char *np = JSON_parse_value(json, p, pe, &result, 0);
2826
+ if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
2827
+ }
2828
+ goto st10;
2829
+ st10:
2830
+ if ( ++p == pe )
2831
+ goto _test_eof10;
2832
+ case 10:
2833
+ #line 2834 "parser.c"
2834
+ switch( (*p) ) {
2835
+ case 13: goto st10;
2836
+ case 32: goto st10;
2837
+ case 47: goto st2;
2838
+ }
2839
+ if ( 9 <= (*p) && (*p) <= 10 )
2840
+ goto st10;
2841
+ goto st0;
2842
+ st2:
2843
+ if ( ++p == pe )
2844
+ goto _test_eof2;
2845
+ case 2:
2846
+ switch( (*p) ) {
2847
+ case 42: goto st3;
2848
+ case 47: goto st5;
2849
+ }
2850
+ goto st0;
2851
+ st3:
2852
+ if ( ++p == pe )
2853
+ goto _test_eof3;
2854
+ case 3:
2855
+ if ( (*p) == 42 )
2856
+ goto st4;
2857
+ goto st3;
2858
+ st4:
2859
+ if ( ++p == pe )
2860
+ goto _test_eof4;
2861
+ case 4:
2862
+ switch( (*p) ) {
2863
+ case 42: goto st4;
2864
+ case 47: goto st10;
2865
+ }
2866
+ goto st3;
2867
+ st5:
2868
+ if ( ++p == pe )
2869
+ goto _test_eof5;
2870
+ case 5:
2871
+ if ( (*p) == 10 )
2872
+ goto st10;
2873
+ goto st5;
2874
+ st6:
2875
+ if ( ++p == pe )
2876
+ goto _test_eof6;
2877
+ case 6:
2878
+ switch( (*p) ) {
2879
+ case 42: goto st7;
2880
+ case 47: goto st9;
2881
+ }
2882
+ goto st0;
2883
+ st7:
2884
+ if ( ++p == pe )
2885
+ goto _test_eof7;
2886
+ case 7:
2887
+ if ( (*p) == 42 )
2888
+ goto st8;
2889
+ goto st7;
2890
+ st8:
2891
+ if ( ++p == pe )
2892
+ goto _test_eof8;
2893
+ case 8:
2894
+ switch( (*p) ) {
2895
+ case 42: goto st8;
2896
+ case 47: goto st1;
2897
+ }
2898
+ goto st7;
2899
+ st9:
2900
+ if ( ++p == pe )
2901
+ goto _test_eof9;
2902
+ case 9:
2903
+ if ( (*p) == 10 )
2904
+ goto st1;
2905
+ goto st9;
2906
+ }
2907
+ _test_eof1: cs = 1; goto _test_eof;
2908
+ _test_eof10: cs = 10; goto _test_eof;
2909
+ _test_eof2: cs = 2; goto _test_eof;
2910
+ _test_eof3: cs = 3; goto _test_eof;
2911
+ _test_eof4: cs = 4; goto _test_eof;
2912
+ _test_eof5: cs = 5; goto _test_eof;
2913
+ _test_eof6: cs = 6; goto _test_eof;
2914
+ _test_eof7: cs = 7; goto _test_eof;
2915
+ _test_eof8: cs = 8; goto _test_eof;
2916
+ _test_eof9: cs = 9; goto _test_eof;
2917
+
2918
+ _test_eof: {}
2919
+ _out: {}
2920
+ }
2921
+
2922
+ #line 1290 "parser.rl"
2923
+
2924
+ if (json->stack_handle) {
2925
+ rvalue_stack_eagerly_release(json->stack_handle);
2926
+ }
2927
+
2928
+ if (cs >= JSON_first_final && p == pe) {
2929
+ return result;
2930
+ } else {
2931
+ raise_parse_error("unexpected token at '%s'", p);
2932
+ return Qnil;
2933
+ }
2934
+ }
2935
+
2936
+ static VALUE cParser_m_parse(VALUE klass, VALUE source, VALUE opts)
2937
+ {
2938
+ char *p, *pe;
2939
+ int cs = EVIL;
2940
+ VALUE result = Qnil;
2941
+
2942
+ JSON_Parser _parser = {0};
2943
+ JSON_Parser *json = &_parser;
2944
+ parser_init(json, source, opts);
2945
+
2946
+ char stack_buffer[FBUFFER_STACK_SIZE];
2947
+ fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
2948
+
2949
+ VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
2950
+ rvalue_stack stack = {
2951
+ .type = RVALUE_STACK_STACK_ALLOCATED,
2952
+ .ptr = rvalue_stack_buffer,
2953
+ .capa = RVALUE_STACK_INITIAL_CAPA,
2954
+ };
2955
+ json->stack = &stack;
1974
2956
 
1975
- #line 1976 "parser.c"
2957
+
2958
+ #line 2959 "parser.c"
1976
2959
  {
1977
2960
  cs = JSON_start;
1978
2961
  }
1979
2962
 
1980
- #line 875 "parser.rl"
2963
+ #line 1325 "parser.rl"
1981
2964
  p = json->source;
1982
2965
  pe = p + json->len;
1983
2966
 
1984
- #line 1985 "parser.c"
2967
+ #line 2968 "parser.c"
1985
2968
  {
1986
2969
  if ( p == pe )
1987
2970
  goto _test_eof;
@@ -2015,7 +2998,7 @@ st0:
2015
2998
  cs = 0;
2016
2999
  goto _out;
2017
3000
  tr2:
2018
- #line 850 "parser.rl"
3001
+ #line 1251 "parser.rl"
2019
3002
  {
2020
3003
  char *np = JSON_parse_value(json, p, pe, &result, 0);
2021
3004
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
@@ -2025,7 +3008,7 @@ st10:
2025
3008
  if ( ++p == pe )
2026
3009
  goto _test_eof10;
2027
3010
  case 10:
2028
- #line 2029 "parser.c"
3011
+ #line 3012 "parser.c"
2029
3012
  switch( (*p) ) {
2030
3013
  case 13: goto st10;
2031
3014
  case 32: goto st10;
@@ -2114,7 +3097,11 @@ case 9:
2114
3097
  _out: {}
2115
3098
  }
2116
3099
 
2117
- #line 878 "parser.rl"
3100
+ #line 1328 "parser.rl"
3101
+
3102
+ if (json->stack_handle) {
3103
+ rvalue_stack_eagerly_release(json->stack_handle);
3104
+ }
2118
3105
 
2119
3106
  if (cs >= JSON_first_final && p == pe) {
2120
3107
  return result;
@@ -2133,19 +3120,23 @@ static void JSON_mark(void *ptr)
2133
3120
  rb_gc_mark(json->array_class);
2134
3121
  rb_gc_mark(json->decimal_class);
2135
3122
  rb_gc_mark(json->match_string);
3123
+ rb_gc_mark(json->stack_handle);
3124
+
3125
+ const VALUE *name_cache_entries = &json->name_cache.entries[0];
3126
+ rb_gc_mark_locations(name_cache_entries, name_cache_entries + json->name_cache.length);
2136
3127
  }
2137
3128
 
2138
3129
  static void JSON_free(void *ptr)
2139
3130
  {
2140
3131
  JSON_Parser *json = ptr;
2141
- fbuffer_free(json->fbuffer);
3132
+ fbuffer_free(&json->fbuffer);
2142
3133
  ruby_xfree(json);
2143
3134
  }
2144
3135
 
2145
3136
  static size_t JSON_memsize(const void *ptr)
2146
3137
  {
2147
3138
  const JSON_Parser *json = ptr;
2148
- return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
3139
+ return sizeof(*json) + FBUFFER_CAPA(&json->fbuffer);
2149
3140
  }
2150
3141
 
2151
3142
  static const rb_data_type_t JSON_Parser_type = {
@@ -2159,7 +3150,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
2159
3150
  {
2160
3151
  JSON_Parser *json;
2161
3152
  VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
2162
- json->fbuffer = fbuffer_alloc(0);
3153
+ fbuffer_stack_init(&json->fbuffer, 0, NULL, 0);
2163
3154
  return obj;
2164
3155
  }
2165
3156
 
@@ -2193,6 +3184,8 @@ void Init_parser(void)
2193
3184
  rb_define_method(cParser, "parse", cParser_parse, 0);
2194
3185
  rb_define_method(cParser, "source", cParser_source, 0);
2195
3186
 
3187
+ rb_define_singleton_method(cParser, "parse", cParser_m_parse, 2);
3188
+
2196
3189
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2197
3190
  rb_gc_register_mark_object(CNaN);
2198
3191
 
@@ -2202,30 +3195,38 @@ void Init_parser(void)
2202
3195
  CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
2203
3196
  rb_gc_register_mark_object(CMinusInfinity);
2204
3197
 
3198
+ rb_global_variable(&Encoding_UTF_8);
3199
+ Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8"));
3200
+
3201
+ sym_max_nesting = ID2SYM(rb_intern("max_nesting"));
3202
+ sym_allow_nan = ID2SYM(rb_intern("allow_nan"));
3203
+ sym_allow_trailing_comma = ID2SYM(rb_intern("allow_trailing_comma"));
3204
+ sym_symbolize_names = ID2SYM(rb_intern("symbolize_names"));
3205
+ sym_freeze = ID2SYM(rb_intern("freeze"));
3206
+ sym_create_additions = ID2SYM(rb_intern("create_additions"));
3207
+ sym_create_id = ID2SYM(rb_intern("create_id"));
3208
+ sym_object_class = ID2SYM(rb_intern("object_class"));
3209
+ sym_array_class = ID2SYM(rb_intern("array_class"));
3210
+ sym_decimal_class = ID2SYM(rb_intern("decimal_class"));
3211
+ sym_match_string = ID2SYM(rb_intern("match_string"));
3212
+
3213
+ i_create_id = rb_intern("create_id");
2205
3214
  i_json_creatable_p = rb_intern("json_creatable?");
2206
3215
  i_json_create = rb_intern("json_create");
2207
- i_create_id = rb_intern("create_id");
2208
- i_create_additions = rb_intern("create_additions");
2209
3216
  i_chr = rb_intern("chr");
2210
- i_max_nesting = rb_intern("max_nesting");
2211
- i_allow_nan = rb_intern("allow_nan");
2212
- i_symbolize_names = rb_intern("symbolize_names");
2213
- i_object_class = rb_intern("object_class");
2214
- i_array_class = rb_intern("array_class");
2215
- i_decimal_class = rb_intern("decimal_class");
2216
3217
  i_match = rb_intern("match");
2217
- i_match_string = rb_intern("match_string");
2218
3218
  i_deep_const_get = rb_intern("deep_const_get");
2219
3219
  i_aset = rb_intern("[]=");
2220
3220
  i_aref = rb_intern("[]");
2221
3221
  i_leftshift = rb_intern("<<");
2222
3222
  i_new = rb_intern("new");
2223
3223
  i_try_convert = rb_intern("try_convert");
2224
- i_freeze = rb_intern("freeze");
2225
3224
  i_uminus = rb_intern("-@");
3225
+ i_encode = rb_intern("encode");
2226
3226
 
2227
3227
  binary_encindex = rb_ascii8bit_encindex();
2228
3228
  utf8_encindex = rb_utf8_encindex();
3229
+ enc_utf8 = rb_utf8_encoding();
2229
3230
  }
2230
3231
 
2231
3232
  /*