json 2.7.5 → 2.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  /*