json 2.7.6 → 2.8.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,321 @@
1
1
  /* This file is automatically generated from parser.rl by using ragel */
2
2
  #line 1 "parser.rl"
3
+ #include "ruby.h"
3
4
  #include "../fbuffer/fbuffer.h"
4
- #include "parser.h"
5
+
6
+ static VALUE mJSON, mExt, cParser, eNestingError, Encoding_UTF_8;
7
+ static VALUE CNaN, CInfinity, CMinusInfinity;
8
+
9
+ static ID i_json_creatable_p, i_json_create, i_create_id,
10
+ i_chr, i_deep_const_get, i_match, i_aset, i_aref,
11
+ i_leftshift, i_new, i_try_convert, i_uminus, i_encode;
12
+
13
+ static VALUE sym_max_nesting, sym_allow_nan, sym_allow_trailing_comma, sym_symbolize_names, sym_freeze,
14
+ sym_create_additions, sym_create_id, sym_object_class, sym_array_class,
15
+ sym_decimal_class, sym_match_string;
16
+
17
+ static int binary_encindex;
18
+ static int utf8_encindex;
19
+
20
+ #ifdef HAVE_RB_CATEGORY_WARN
21
+ # define json_deprecated(message) rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, message)
22
+ #else
23
+ # define json_deprecated(message) rb_warn(message)
24
+ #endif
25
+
26
+ static const char deprecated_create_additions_warning[] =
27
+ "JSON.load implicit support for `create_additions: true` is deprecated "
28
+ "and will be removed in 3.0, use JSON.unsafe_load or explicitly "
29
+ "pass `create_additions: true`";
30
+
31
+ #ifndef HAVE_RB_GC_MARK_LOCATIONS
32
+ // For TruffleRuby
33
+ void rb_gc_mark_locations(const VALUE *start, const VALUE *end)
34
+ {
35
+ VALUE *value = start;
36
+
37
+ while (value < end) {
38
+ rb_gc_mark(*value);
39
+ value++;
40
+ }
41
+ }
42
+ #endif
43
+
44
+ #ifndef HAVE_RB_HASH_BULK_INSERT
45
+ // For TruffleRuby
46
+ void rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
47
+ {
48
+ long index = 0;
49
+ while (index < count) {
50
+ VALUE name = pairs[index++];
51
+ VALUE value = pairs[index++];
52
+ rb_hash_aset(hash, name, value);
53
+ }
54
+ RB_GC_GUARD(hash);
55
+ }
56
+ #endif
57
+
58
+ /* name cache */
59
+
60
+ #include <string.h>
61
+ #include <ctype.h>
62
+
63
+ // Object names are likely to be repeated, and are frozen.
64
+ // As such we can re-use them if we keep a cache of the ones we've seen so far,
65
+ // and save much more expensive lookups into the global fstring table.
66
+ // This cache implementation is deliberately simple, as we're optimizing for compactness,
67
+ // to be able to fit safely on the stack.
68
+ // As such, binary search into a sorted array gives a good tradeoff between compactness and
69
+ // performance.
70
+ #define JSON_RVALUE_CACHE_CAPA 63
71
+ typedef struct rvalue_cache_struct {
72
+ int length;
73
+ VALUE entries[JSON_RVALUE_CACHE_CAPA];
74
+ } rvalue_cache;
75
+
76
+ static rb_encoding *enc_utf8;
77
+
78
+ #define JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH 55
79
+
80
+ static inline VALUE build_interned_string(const char *str, const long length)
81
+ {
82
+ # ifdef HAVE_RB_ENC_INTERNED_STR
83
+ return rb_enc_interned_str(str, length, enc_utf8);
84
+ # else
85
+ VALUE rstring = rb_utf8_str_new(str, length);
86
+ return rb_funcall(rb_str_freeze(rstring), i_uminus, 0);
87
+ # endif
88
+ }
89
+
90
+ static inline VALUE build_symbol(const char *str, const long length)
91
+ {
92
+ return rb_str_intern(build_interned_string(str, length));
93
+ }
94
+
95
+ static void rvalue_cache_insert_at(rvalue_cache *cache, int index, VALUE rstring)
96
+ {
97
+ MEMMOVE(&cache->entries[index + 1], &cache->entries[index], VALUE, cache->length - index);
98
+ cache->length++;
99
+ cache->entries[index] = rstring;
100
+ }
101
+
102
+ static inline int rstring_cache_cmp(const char *str, const long length, VALUE rstring)
103
+ {
104
+ long rstring_length = RSTRING_LEN(rstring);
105
+ if (length == rstring_length) {
106
+ return memcmp(str, RSTRING_PTR(rstring), length);
107
+ } else {
108
+ return (int)(length - rstring_length);
109
+ }
110
+ }
111
+
112
+ static VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const long length)
113
+ {
114
+ if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
115
+ // Common names aren't likely to be very long. So we just don't
116
+ // cache names above an arbitrary threshold.
117
+ return Qfalse;
118
+ }
119
+
120
+ if (RB_UNLIKELY(!isalpha(str[0]))) {
121
+ // Simple heuristic, if the first character isn't a letter,
122
+ // we're much less likely to see this string again.
123
+ // We mostly want to cache strings that are likely to be repeated.
124
+ return Qfalse;
125
+ }
126
+
127
+ int low = 0;
128
+ int high = cache->length - 1;
129
+ int mid = 0;
130
+ int last_cmp = 0;
131
+
132
+ while (low <= high) {
133
+ mid = (high + low) >> 1;
134
+ VALUE entry = cache->entries[mid];
135
+ last_cmp = rstring_cache_cmp(str, length, entry);
136
+
137
+ if (last_cmp == 0) {
138
+ return entry;
139
+ } else if (last_cmp > 0) {
140
+ low = mid + 1;
141
+ } else {
142
+ high = mid - 1;
143
+ }
144
+ }
145
+
146
+ if (RB_UNLIKELY(memchr(str, '\\', length))) {
147
+ // We assume the overwhelming majority of names don't need to be escaped.
148
+ // But if they do, we have to fallback to the slow path.
149
+ return Qfalse;
150
+ }
151
+
152
+ VALUE rstring = build_interned_string(str, length);
153
+
154
+ if (cache->length < JSON_RVALUE_CACHE_CAPA) {
155
+ if (last_cmp > 0) {
156
+ mid += 1;
157
+ }
158
+
159
+ rvalue_cache_insert_at(cache, mid, rstring);
160
+ }
161
+ return rstring;
162
+ }
163
+
164
+ static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const long length)
165
+ {
166
+ if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
167
+ // Common names aren't likely to be very long. So we just don't
168
+ // cache names above an arbitrary threshold.
169
+ return Qfalse;
170
+ }
171
+
172
+ if (RB_UNLIKELY(!isalpha(str[0]))) {
173
+ // Simple heuristic, if the first character isn't a letter,
174
+ // we're much less likely to see this string again.
175
+ // We mostly want to cache strings that are likely to be repeated.
176
+ return Qfalse;
177
+ }
178
+
179
+ int low = 0;
180
+ int high = cache->length - 1;
181
+ int mid = 0;
182
+ int last_cmp = 0;
183
+
184
+ while (low <= high) {
185
+ mid = (high + low) >> 1;
186
+ VALUE entry = cache->entries[mid];
187
+ last_cmp = rstring_cache_cmp(str, length, rb_sym2str(entry));
188
+
189
+ if (last_cmp == 0) {
190
+ return entry;
191
+ } else if (last_cmp > 0) {
192
+ low = mid + 1;
193
+ } else {
194
+ high = mid - 1;
195
+ }
196
+ }
197
+
198
+ if (RB_UNLIKELY(memchr(str, '\\', length))) {
199
+ // We assume the overwhelming majority of names don't need to be escaped.
200
+ // But if they do, we have to fallback to the slow path.
201
+ return Qfalse;
202
+ }
203
+
204
+ VALUE rsymbol = build_symbol(str, length);
205
+
206
+ if (cache->length < JSON_RVALUE_CACHE_CAPA) {
207
+ if (last_cmp > 0) {
208
+ mid += 1;
209
+ }
210
+
211
+ rvalue_cache_insert_at(cache, mid, rsymbol);
212
+ }
213
+ return rsymbol;
214
+ }
215
+
216
+ /* rvalue stack */
217
+
218
+ #define RVALUE_STACK_INITIAL_CAPA 128
219
+
220
+ enum rvalue_stack_type {
221
+ RVALUE_STACK_HEAP_ALLOCATED = 0,
222
+ RVALUE_STACK_STACK_ALLOCATED = 1,
223
+ };
224
+
225
+ typedef struct rvalue_stack_struct {
226
+ enum rvalue_stack_type type;
227
+ long capa;
228
+ long head;
229
+ VALUE *ptr;
230
+ } rvalue_stack;
231
+
232
+ static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref);
233
+
234
+ static rvalue_stack *rvalue_stack_grow(rvalue_stack *stack, VALUE *handle, rvalue_stack **stack_ref)
235
+ {
236
+ long required = stack->capa * 2;
237
+
238
+ if (stack->type == RVALUE_STACK_STACK_ALLOCATED) {
239
+ stack = rvalue_stack_spill(stack, handle, stack_ref);
240
+ } else {
241
+ REALLOC_N(stack->ptr, VALUE, required);
242
+ stack->capa = required;
243
+ }
244
+ return stack;
245
+ }
246
+
247
+ static void rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref)
248
+ {
249
+ if (RB_UNLIKELY(stack->head >= stack->capa)) {
250
+ stack = rvalue_stack_grow(stack, handle, stack_ref);
251
+ }
252
+ stack->ptr[stack->head] = value;
253
+ stack->head++;
254
+ }
255
+
256
+ static inline VALUE *rvalue_stack_peek(rvalue_stack *stack, long count)
257
+ {
258
+ return stack->ptr + (stack->head - count);
259
+ }
260
+
261
+ static inline void rvalue_stack_pop(rvalue_stack *stack, long count)
262
+ {
263
+ stack->head -= count;
264
+ }
265
+
266
+ static void rvalue_stack_mark(void *ptr)
267
+ {
268
+ rvalue_stack *stack = (rvalue_stack *)ptr;
269
+ rb_gc_mark_locations(stack->ptr, stack->ptr + stack->head);
270
+ }
271
+
272
+ static void rvalue_stack_free(void *ptr)
273
+ {
274
+ rvalue_stack *stack = (rvalue_stack *)ptr;
275
+ if (stack) {
276
+ ruby_xfree(stack->ptr);
277
+ ruby_xfree(stack);
278
+ }
279
+ }
280
+
281
+ static size_t rvalue_stack_memsize(const void *ptr)
282
+ {
283
+ const rvalue_stack *stack = (const rvalue_stack *)ptr;
284
+ return sizeof(rvalue_stack) + sizeof(VALUE) * stack->capa;
285
+ }
286
+
287
+ static const rb_data_type_t JSON_Parser_rvalue_stack_type = {
288
+ "JSON::Ext::Parser/rvalue_stack",
289
+ {
290
+ .dmark = rvalue_stack_mark,
291
+ .dfree = rvalue_stack_free,
292
+ .dsize = rvalue_stack_memsize,
293
+ },
294
+ 0, 0,
295
+ RUBY_TYPED_FREE_IMMEDIATELY,
296
+ };
297
+
298
+ static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref)
299
+ {
300
+ rvalue_stack *stack;
301
+ *handle = TypedData_Make_Struct(0, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
302
+ *stack_ref = stack;
303
+ MEMCPY(stack, old_stack, rvalue_stack, 1);
304
+
305
+ stack->capa = old_stack->capa << 1;
306
+ stack->ptr = ALLOC_N(VALUE, stack->capa);
307
+ stack->type = RVALUE_STACK_HEAP_ALLOCATED;
308
+ MEMCPY(stack->ptr, old_stack->ptr, VALUE, old_stack->head);
309
+ return stack;
310
+ }
311
+
312
+ static void rvalue_stack_eagerly_release(VALUE handle)
313
+ {
314
+ rvalue_stack *stack;
315
+ TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
316
+ RTYPEDDATA_DATA(handle) = NULL;
317
+ rvalue_stack_free(stack);
318
+ }
5
319
 
6
320
  /* unicode */
7
321
 
@@ -69,6 +383,50 @@ static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
69
383
  return len;
70
384
  }
71
385
 
386
+ typedef struct JSON_ParserStruct {
387
+ VALUE Vsource;
388
+ char *source;
389
+ long len;
390
+ char *memo;
391
+ VALUE create_id;
392
+ VALUE object_class;
393
+ VALUE array_class;
394
+ VALUE decimal_class;
395
+ VALUE match_string;
396
+ FBuffer fbuffer;
397
+ int 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
  /*