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