json 2.7.5 → 2.9.1

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