json 2.7.5 → 2.9.1

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