json 2.7.2 → 2.8.2

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,30 +1,322 @@
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
5
 
6
- #if defined HAVE_RUBY_ENCODING_H
7
- # define EXC_ENCODING rb_utf8_encoding(),
8
- # ifndef HAVE_RB_ENC_RAISE
9
- static void
10
- enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
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)
11
34
  {
12
- va_list args;
13
- VALUE mesg;
35
+ VALUE *value = start;
14
36
 
15
- va_start(args, fmt);
16
- mesg = rb_enc_vsprintf(enc, fmt, args);
17
- va_end(args);
37
+ while (value < end) {
38
+ rb_gc_mark(*value);
39
+ value++;
40
+ }
41
+ }
42
+ #endif
18
43
 
19
- rb_exc_raise(rb_exc_new3(exc, mesg));
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);
20
55
  }
21
- # define rb_enc_raise enc_raise
22
- # endif
23
- #else
24
- # define EXC_ENCODING /* nothing */
25
- # define rb_enc_raise rb_raise
26
56
  #endif
27
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
+ }
319
+
28
320
  /* unicode */
29
321
 
30
322
  static const signed char digit_values[256] = {
@@ -44,26 +336,28 @@ static const signed char digit_values[256] = {
44
336
  -1, -1, -1, -1, -1, -1, -1
45
337
  };
46
338
 
47
- static UTF32 unescape_unicode(const unsigned char *p)
339
+ static uint32_t unescape_unicode(const unsigned char *p)
48
340
  {
341
+ const uint32_t replacement_char = 0xFFFD;
342
+
49
343
  signed char b;
50
- UTF32 result = 0;
344
+ uint32_t result = 0;
51
345
  b = digit_values[p[0]];
52
- if (b < 0) return UNI_REPLACEMENT_CHAR;
346
+ if (b < 0) return replacement_char;
53
347
  result = (result << 4) | (unsigned char)b;
54
348
  b = digit_values[p[1]];
55
- if (b < 0) return UNI_REPLACEMENT_CHAR;
349
+ if (b < 0) return replacement_char;
56
350
  result = (result << 4) | (unsigned char)b;
57
351
  b = digit_values[p[2]];
58
- if (b < 0) return UNI_REPLACEMENT_CHAR;
352
+ if (b < 0) return replacement_char;
59
353
  result = (result << 4) | (unsigned char)b;
60
354
  b = digit_values[p[3]];
61
- if (b < 0) return UNI_REPLACEMENT_CHAR;
355
+ if (b < 0) return replacement_char;
62
356
  result = (result << 4) | (unsigned char)b;
63
357
  return result;
64
358
  }
65
359
 
66
- static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
360
+ static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
67
361
  {
68
362
  int len = 1;
69
363
  if (ch <= 0x7F) {
@@ -89,53 +383,110 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
89
383
  return len;
90
384
  }
91
385
 
92
- static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
93
- static VALUE CNaN, CInfinity, CMinusInfinity;
386
+ typedef struct JSON_ParserStruct {
387
+ VALUE Vsource;
388
+ char *source;
389
+ long len;
390
+ char *memo;
391
+ VALUE create_id;
392
+ VALUE object_class;
393
+ VALUE array_class;
394
+ VALUE decimal_class;
395
+ VALUE match_string;
396
+ FBuffer fbuffer;
397
+ int in_array;
398
+ int max_nesting;
399
+ bool allow_nan;
400
+ bool allow_trailing_comma;
401
+ bool parsing_name;
402
+ bool symbolize_names;
403
+ bool freeze;
404
+ bool create_additions;
405
+ bool deprecated_create_additions;
406
+ rvalue_cache name_cache;
407
+ rvalue_stack *stack;
408
+ VALUE stack_handle;
409
+ } JSON_Parser;
410
+
411
+ #define GET_PARSER \
412
+ GET_PARSER_INIT; \
413
+ if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
414
+
415
+ #define GET_PARSER_INIT \
416
+ JSON_Parser *json; \
417
+ TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json)
418
+
419
+ #define MinusInfinity "-Infinity"
420
+ #define EVIL 0x666
421
+
422
+ static const rb_data_type_t JSON_Parser_type;
423
+ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
424
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
425
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
426
+ static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result);
427
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
428
+
429
+
430
+ #define PARSE_ERROR_FRAGMENT_LEN 32
431
+ #ifdef RBIMPL_ATTR_NORETURN
432
+ RBIMPL_ATTR_NORETURN()
433
+ #endif
434
+ static void raise_parse_error(const char *format, const char *start)
435
+ {
436
+ char buffer[PARSE_ERROR_FRAGMENT_LEN + 1];
437
+
438
+ size_t len = strnlen(start, PARSE_ERROR_FRAGMENT_LEN);
439
+ const char *ptr = start;
94
440
 
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, i_key_p,
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;
441
+ if (len == PARSE_ERROR_FRAGMENT_LEN) {
442
+ MEMCPY(buffer, start, char, PARSE_ERROR_FRAGMENT_LEN);
443
+ buffer[PARSE_ERROR_FRAGMENT_LEN] = '\0';
444
+ ptr = buffer;
445
+ }
446
+
447
+ rb_enc_raise(enc_utf8, rb_path2class("JSON::ParserError"), format, ptr);
448
+ }
100
449
 
101
450
 
102
- #line 125 "parser.rl"
103
451
 
452
+ #line 475 "parser.rl"
104
453
 
105
454
 
106
- #line 107 "parser.c"
455
+
456
+ #line 457 "parser.c"
107
457
  enum {JSON_object_start = 1};
108
- enum {JSON_object_first_final = 27};
458
+ enum {JSON_object_first_final = 32};
109
459
  enum {JSON_object_error = 0};
110
460
 
111
461
  enum {JSON_object_en_main = 1};
112
462
 
113
463
 
114
- #line 167 "parser.rl"
464
+ #line 515 "parser.rl"
465
+
115
466
 
467
+ #define PUSH(result) rvalue_stack_push(json->stack, result, &json->stack_handle, &json->stack)
116
468
 
117
469
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
118
470
  {
119
471
  int cs = EVIL;
120
- VALUE last_name = Qnil;
121
- VALUE object_class = json->object_class;
122
472
 
123
473
  if (json->max_nesting && current_nesting > json->max_nesting) {
124
474
  rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
125
475
  }
126
476
 
127
- *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
477
+ long stack_head = json->stack->head;
128
478
 
129
479
 
130
- #line 131 "parser.c"
480
+ #line 481 "parser.c"
131
481
  {
132
482
  cs = JSON_object_start;
133
483
  }
134
484
 
135
- #line 182 "parser.rl"
485
+ #line 530 "parser.rl"
136
486
 
137
- #line 138 "parser.c"
487
+ #line 488 "parser.c"
138
488
  {
489
+ short _widec;
139
490
  if ( p == pe )
140
491
  goto _test_eof;
141
492
  switch ( cs )
@@ -155,27 +506,30 @@ case 2:
155
506
  case 13: goto st2;
156
507
  case 32: goto st2;
157
508
  case 34: goto tr2;
158
- case 47: goto st23;
509
+ case 47: goto st28;
159
510
  case 125: goto tr4;
160
511
  }
161
512
  if ( 9 <= (*p) && (*p) <= 10 )
162
513
  goto st2;
163
514
  goto st0;
164
515
  tr2:
165
- #line 149 "parser.rl"
516
+ #line 494 "parser.rl"
166
517
  {
167
518
  char *np;
168
- json->parsing_name = 1;
169
- np = JSON_parse_string(json, p, pe, &last_name);
170
- json->parsing_name = 0;
171
- 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
+ }
172
526
  }
173
527
  goto st3;
174
528
  st3:
175
529
  if ( ++p == pe )
176
530
  goto _test_eof3;
177
531
  case 3:
178
- #line 179 "parser.c"
532
+ #line 533 "parser.c"
179
533
  switch( (*p) ) {
180
534
  case 13: goto st3;
181
535
  case 32: goto st3;
@@ -226,7 +580,7 @@ case 8:
226
580
  case 32: goto st8;
227
581
  case 34: goto tr11;
228
582
  case 45: goto tr11;
229
- case 47: goto st19;
583
+ case 47: goto st24;
230
584
  case 73: goto tr11;
231
585
  case 78: goto tr11;
232
586
  case 91: goto tr11;
@@ -242,19 +596,12 @@ case 8:
242
596
  goto st8;
243
597
  goto st0;
244
598
  tr11:
245
- #line 133 "parser.rl"
599
+ #line 483 "parser.rl"
246
600
  {
247
- VALUE v = Qnil;
248
- char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
601
+ char *np = JSON_parse_value(json, p, pe, result, current_nesting);
249
602
  if (np == NULL) {
250
603
  p--; {p++; cs = 9; goto _out;}
251
604
  } else {
252
- if (NIL_P(json->object_class)) {
253
- OBJ_FREEZE(last_name);
254
- rb_hash_aset(*result, last_name, v);
255
- } else {
256
- rb_funcall(*result, i_aset, 2, last_name, v);
257
- }
258
605
  {p = (( np))-1;}
259
606
  }
260
607
  }
@@ -263,16 +610,75 @@ st9:
263
610
  if ( ++p == pe )
264
611
  goto _test_eof9;
265
612
  case 9:
266
- #line 267 "parser.c"
267
- switch( (*p) ) {
268
- case 13: goto st9;
269
- case 32: goto st9;
270
- case 44: goto st10;
271
- case 47: goto st15;
272
- case 125: goto tr4;
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;
273
655
  }
274
- if ( 9 <= (*p) && (*p) <= 10 )
275
- goto st9;
656
+ switch( _widec ) {
657
+ case 125: goto tr4;
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"
276
682
  goto st0;
277
683
  st10:
278
684
  if ( ++p == pe )
@@ -281,8 +687,9 @@ case 10:
281
687
  switch( (*p) ) {
282
688
  case 13: goto st10;
283
689
  case 32: goto st10;
284
- case 34: goto tr2;
285
- case 47: goto st11;
690
+ case 44: goto st11;
691
+ case 47: goto st16;
692
+ case 125: goto tr4;
286
693
  }
287
694
  if ( 9 <= (*p) && (*p) <= 10 )
288
695
  goto st10;
@@ -292,139 +699,288 @@ st11:
292
699
  goto _test_eof11;
293
700
  case 11:
294
701
  switch( (*p) ) {
295
- case 42: goto st12;
296
- case 47: goto st14;
702
+ case 13: goto st11;
703
+ case 32: goto st11;
704
+ case 34: goto tr2;
705
+ case 47: goto st12;
297
706
  }
707
+ if ( 9 <= (*p) && (*p) <= 10 )
708
+ goto st11;
298
709
  goto st0;
299
710
  st12:
300
711
  if ( ++p == pe )
301
712
  goto _test_eof12;
302
713
  case 12:
303
- if ( (*p) == 42 )
304
- goto st13;
305
- goto st12;
714
+ switch( (*p) ) {
715
+ case 42: goto st13;
716
+ case 47: goto st15;
717
+ }
718
+ goto st0;
306
719
  st13:
307
720
  if ( ++p == pe )
308
721
  goto _test_eof13;
309
722
  case 13:
310
- switch( (*p) ) {
311
- case 42: goto st13;
312
- case 47: goto st10;
313
- }
314
- goto st12;
723
+ if ( (*p) == 42 )
724
+ goto st14;
725
+ goto st13;
315
726
  st14:
316
727
  if ( ++p == pe )
317
728
  goto _test_eof14;
318
729
  case 14:
319
- if ( (*p) == 10 )
320
- goto st10;
321
- goto st14;
730
+ switch( (*p) ) {
731
+ case 42: goto st14;
732
+ case 47: goto st11;
733
+ }
734
+ goto st13;
322
735
  st15:
323
736
  if ( ++p == pe )
324
737
  goto _test_eof15;
325
738
  case 15:
326
- switch( (*p) ) {
327
- case 42: goto st16;
328
- case 47: goto st18;
329
- }
330
- goto st0;
739
+ if ( (*p) == 10 )
740
+ goto st11;
741
+ goto st15;
331
742
  st16:
332
743
  if ( ++p == pe )
333
744
  goto _test_eof16;
334
745
  case 16:
335
- if ( (*p) == 42 )
336
- goto st17;
337
- goto st16;
746
+ switch( (*p) ) {
747
+ case 42: goto st17;
748
+ case 47: goto st19;
749
+ }
750
+ goto st0;
338
751
  st17:
339
752
  if ( ++p == pe )
340
753
  goto _test_eof17;
341
754
  case 17:
342
- switch( (*p) ) {
343
- case 42: goto st17;
344
- case 47: goto st9;
345
- }
346
- goto st16;
755
+ if ( (*p) == 42 )
756
+ goto st18;
757
+ goto st17;
347
758
  st18:
348
759
  if ( ++p == pe )
349
760
  goto _test_eof18;
350
761
  case 18:
351
- if ( (*p) == 10 )
352
- goto st9;
353
- goto st18;
354
- tr4:
355
- #line 157 "parser.rl"
356
- { p--; {p++; cs = 27; goto _out;} }
357
- goto st27;
358
- st27:
359
- if ( ++p == pe )
360
- goto _test_eof27;
361
- case 27:
362
- #line 363 "parser.c"
363
- goto st0;
762
+ switch( (*p) ) {
763
+ case 42: goto st18;
764
+ case 47: goto st10;
765
+ }
766
+ goto st17;
364
767
  st19:
365
768
  if ( ++p == pe )
366
769
  goto _test_eof19;
367
770
  case 19:
368
- switch( (*p) ) {
369
- case 42: goto st20;
370
- case 47: goto st22;
371
- }
372
- goto st0;
771
+ if ( (*p) == 10 )
772
+ goto st10;
773
+ goto st19;
373
774
  st20:
374
775
  if ( ++p == pe )
375
776
  goto _test_eof20;
376
777
  case 20:
377
- if ( (*p) == 42 )
378
- goto st21;
379
- 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;
380
799
  st21:
381
800
  if ( ++p == pe )
382
801
  goto _test_eof21;
383
802
  case 21:
384
- switch( (*p) ) {
385
- case 42: goto st21;
386
- case 47: goto st8;
387
- }
388
- 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;
389
834
  st22:
390
835
  if ( ++p == pe )
391
836
  goto _test_eof22;
392
837
  case 22:
393
- if ( (*p) == 10 )
394
- goto st8;
395
- 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;
396
885
  st23:
397
886
  if ( ++p == pe )
398
887
  goto _test_eof23;
399
888
  case 23:
400
- switch( (*p) ) {
401
- case 42: goto st24;
402
- case 47: goto st26;
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;
403
913
  }
914
+ if ( _widec > 383 ) {
915
+ if ( 384 <= _widec && _widec <= 639 )
916
+ goto st23;
917
+ } else if ( _widec >= 128 )
918
+ goto st19;
404
919
  goto st0;
405
920
  st24:
406
921
  if ( ++p == pe )
407
922
  goto _test_eof24;
408
923
  case 24:
409
- if ( (*p) == 42 )
410
- goto st25;
411
- goto st24;
924
+ switch( (*p) ) {
925
+ case 42: goto st25;
926
+ case 47: goto st27;
927
+ }
928
+ goto st0;
412
929
  st25:
413
930
  if ( ++p == pe )
414
931
  goto _test_eof25;
415
932
  case 25:
416
- switch( (*p) ) {
417
- case 42: goto st25;
418
- case 47: goto st2;
419
- }
420
- goto st24;
933
+ if ( (*p) == 42 )
934
+ goto st26;
935
+ goto st25;
421
936
  st26:
422
937
  if ( ++p == pe )
423
938
  goto _test_eof26;
424
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:
425
981
  if ( (*p) == 10 )
426
982
  goto st2;
427
- goto st26;
983
+ goto st31;
428
984
  }
429
985
  _test_eof2: cs = 2; goto _test_eof;
430
986
  _test_eof3: cs = 3; goto _test_eof;
@@ -434,6 +990,7 @@ case 26:
434
990
  _test_eof7: cs = 7; goto _test_eof;
435
991
  _test_eof8: cs = 8; goto _test_eof;
436
992
  _test_eof9: cs = 9; goto _test_eof;
993
+ _test_eof32: cs = 32; goto _test_eof;
437
994
  _test_eof10: cs = 10; goto _test_eof;
438
995
  _test_eof11: cs = 11; goto _test_eof;
439
996
  _test_eof12: cs = 12; goto _test_eof;
@@ -443,7 +1000,6 @@ case 26:
443
1000
  _test_eof16: cs = 16; goto _test_eof;
444
1001
  _test_eof17: cs = 17; goto _test_eof;
445
1002
  _test_eof18: cs = 18; goto _test_eof;
446
- _test_eof27: cs = 27; goto _test_eof;
447
1003
  _test_eof19: cs = 19; goto _test_eof;
448
1004
  _test_eof20: cs = 20; goto _test_eof;
449
1005
  _test_eof21: cs = 21; goto _test_eof;
@@ -452,24 +1008,56 @@ case 26:
452
1008
  _test_eof24: cs = 24; goto _test_eof;
453
1009
  _test_eof25: cs = 25; goto _test_eof;
454
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;
455
1016
 
456
1017
  _test_eof: {}
457
1018
  _out: {}
458
1019
  }
459
1020
 
460
- #line 183 "parser.rl"
1021
+ #line 531 "parser.rl"
461
1022
 
462
1023
  if (cs >= JSON_object_first_final) {
463
- 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)) {
464
1049
  VALUE klassname;
465
- if (NIL_P(json->object_class)) {
466
- klassname = rb_hash_aref(*result, json->create_id);
1050
+ if (json->object_class) {
1051
+ klassname = rb_funcall(*result, i_aref, 1, json->create_id);
467
1052
  } else {
468
- klassname = rb_funcall(*result, i_aref, 1, json->create_id);
1053
+ klassname = rb_hash_aref(*result, json->create_id);
469
1054
  }
470
1055
  if (!NIL_P(klassname)) {
471
1056
  VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
472
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
+ }
473
1061
  *result = rb_funcall(klass, i_json_create, 1, *result);
474
1062
  }
475
1063
  }
@@ -481,8 +1069,7 @@ case 26:
481
1069
  }
482
1070
 
483
1071
 
484
-
485
- #line 486 "parser.c"
1072
+ #line 1073 "parser.c"
486
1073
  enum {JSON_value_start = 1};
487
1074
  enum {JSON_value_first_final = 29};
488
1075
  enum {JSON_value_error = 0};
@@ -490,7 +1077,7 @@ enum {JSON_value_error = 0};
490
1077
  enum {JSON_value_en_main = 1};
491
1078
 
492
1079
 
493
- #line 283 "parser.rl"
1080
+ #line 664 "parser.rl"
494
1081
 
495
1082
 
496
1083
  static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -498,14 +1085,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
498
1085
  int cs = EVIL;
499
1086
 
500
1087
 
501
- #line 502 "parser.c"
1088
+ #line 1089 "parser.c"
502
1089
  {
503
1090
  cs = JSON_value_start;
504
1091
  }
505
1092
 
506
- #line 290 "parser.rl"
1093
+ #line 671 "parser.rl"
507
1094
 
508
- #line 509 "parser.c"
1095
+ #line 1096 "parser.c"
509
1096
  {
510
1097
  if ( p == pe )
511
1098
  goto _test_eof;
@@ -539,14 +1126,19 @@ st0:
539
1126
  cs = 0;
540
1127
  goto _out;
541
1128
  tr2:
542
- #line 235 "parser.rl"
1129
+ #line 609 "parser.rl"
543
1130
  {
544
1131
  char *np = JSON_parse_string(json, p, pe, result);
545
- 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
+ }
546
1138
  }
547
1139
  goto st29;
548
1140
  tr3:
549
- #line 240 "parser.rl"
1141
+ #line 619 "parser.rl"
550
1142
  {
551
1143
  char *np;
552
1144
  if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
@@ -555,26 +1147,28 @@ tr3:
555
1147
  {p = (( p + 10))-1;}
556
1148
  p--; {p++; cs = 29; goto _out;}
557
1149
  } else {
558
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
1150
+ raise_parse_error("unexpected token at '%s'", p);
559
1151
  }
560
1152
  }
561
- np = JSON_parse_float(json, p, pe, result);
562
- if (np != NULL) {p = (( np))-1;}
563
- np = JSON_parse_integer(json, p, pe, result);
564
- if (np != NULL) {p = (( np))-1;}
1153
+ np = JSON_parse_number(json, p, pe, result);
1154
+ if (np != NULL) {
1155
+ {p = (( np))-1;}
1156
+ }
565
1157
  p--; {p++; cs = 29; goto _out;}
566
1158
  }
567
1159
  goto st29;
568
1160
  tr7:
569
- #line 258 "parser.rl"
1161
+ #line 637 "parser.rl"
570
1162
  {
571
1163
  char *np;
1164
+ json->in_array++;
572
1165
  np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
1166
+ json->in_array--;
573
1167
  if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
574
1168
  }
575
1169
  goto st29;
576
1170
  tr11:
577
- #line 264 "parser.rl"
1171
+ #line 645 "parser.rl"
578
1172
  {
579
1173
  char *np;
580
1174
  np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
@@ -582,39 +1176,39 @@ tr11:
582
1176
  }
583
1177
  goto st29;
584
1178
  tr25:
585
- #line 228 "parser.rl"
1179
+ #line 602 "parser.rl"
586
1180
  {
587
1181
  if (json->allow_nan) {
588
1182
  *result = CInfinity;
589
1183
  } else {
590
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 7);
1184
+ raise_parse_error("unexpected token at '%s'", p - 7);
591
1185
  }
592
1186
  }
593
1187
  goto st29;
594
1188
  tr27:
595
- #line 221 "parser.rl"
1189
+ #line 595 "parser.rl"
596
1190
  {
597
1191
  if (json->allow_nan) {
598
1192
  *result = CNaN;
599
1193
  } else {
600
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 2);
1194
+ raise_parse_error("unexpected token at '%s'", p - 2);
601
1195
  }
602
1196
  }
603
1197
  goto st29;
604
1198
  tr31:
605
- #line 215 "parser.rl"
1199
+ #line 589 "parser.rl"
606
1200
  {
607
1201
  *result = Qfalse;
608
1202
  }
609
1203
  goto st29;
610
1204
  tr34:
611
- #line 212 "parser.rl"
1205
+ #line 586 "parser.rl"
612
1206
  {
613
1207
  *result = Qnil;
614
1208
  }
615
1209
  goto st29;
616
1210
  tr37:
617
- #line 218 "parser.rl"
1211
+ #line 592 "parser.rl"
618
1212
  {
619
1213
  *result = Qtrue;
620
1214
  }
@@ -623,9 +1217,9 @@ st29:
623
1217
  if ( ++p == pe )
624
1218
  goto _test_eof29;
625
1219
  case 29:
626
- #line 270 "parser.rl"
1220
+ #line 651 "parser.rl"
627
1221
  { p--; {p++; cs = 29; goto _out;} }
628
- #line 629 "parser.c"
1222
+ #line 1223 "parser.c"
629
1223
  switch( (*p) ) {
630
1224
  case 13: goto st29;
631
1225
  case 32: goto st29;
@@ -866,13 +1460,14 @@ case 28:
866
1460
  _out: {}
867
1461
  }
868
1462
 
869
- #line 291 "parser.rl"
1463
+ #line 672 "parser.rl"
870
1464
 
871
1465
  if (json->freeze) {
872
1466
  OBJ_FREEZE(*result);
873
1467
  }
874
1468
 
875
1469
  if (cs >= JSON_value_first_final) {
1470
+ PUSH(*result);
876
1471
  return p;
877
1472
  } else {
878
1473
  return NULL;
@@ -880,7 +1475,7 @@ case 28:
880
1475
  }
881
1476
 
882
1477
 
883
- #line 884 "parser.c"
1478
+ #line 1479 "parser.c"
884
1479
  enum {JSON_integer_start = 1};
885
1480
  enum {JSON_integer_first_final = 3};
886
1481
  enum {JSON_integer_error = 0};
@@ -888,122 +1483,72 @@ enum {JSON_integer_error = 0};
888
1483
  enum {JSON_integer_en_main = 1};
889
1484
 
890
1485
 
891
- #line 311 "parser.rl"
1486
+ #line 693 "parser.rl"
892
1487
 
893
1488
 
894
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
1489
+ #define MAX_FAST_INTEGER_SIZE 18
1490
+ static inline VALUE fast_parse_integer(char *p, char *pe)
895
1491
  {
896
- int cs = EVIL;
897
-
898
-
899
- #line 900 "parser.c"
900
- {
901
- cs = JSON_integer_start;
902
- }
903
-
904
- #line 318 "parser.rl"
905
- json->memo = p;
906
-
907
- #line 908 "parser.c"
908
- {
909
- if ( p == pe )
910
- goto _test_eof;
911
- switch ( cs )
912
- {
913
- case 1:
914
- switch( (*p) ) {
915
- case 45: goto st2;
916
- case 48: goto st3;
917
- }
918
- if ( 49 <= (*p) && (*p) <= 57 )
919
- goto st5;
920
- goto st0;
921
- st0:
922
- cs = 0;
923
- goto _out;
924
- st2:
925
- if ( ++p == pe )
926
- goto _test_eof2;
927
- case 2:
928
- if ( (*p) == 48 )
929
- goto st3;
930
- if ( 49 <= (*p) && (*p) <= 57 )
931
- goto st5;
932
- goto st0;
933
- st3:
934
- if ( ++p == pe )
935
- goto _test_eof3;
936
- case 3:
937
- if ( 48 <= (*p) && (*p) <= 57 )
938
- goto st0;
939
- goto tr4;
940
- tr4:
941
- #line 308 "parser.rl"
942
- { p--; {p++; cs = 4; goto _out;} }
943
- goto st4;
944
- st4:
945
- if ( ++p == pe )
946
- goto _test_eof4;
947
- case 4:
948
- #line 949 "parser.c"
949
- goto st0;
950
- st5:
951
- if ( ++p == pe )
952
- goto _test_eof5;
953
- case 5:
954
- if ( 48 <= (*p) && (*p) <= 57 )
955
- goto st5;
956
- goto tr4;
957
- }
958
- _test_eof2: cs = 2; goto _test_eof;
959
- _test_eof3: cs = 3; goto _test_eof;
960
- _test_eof4: cs = 4; goto _test_eof;
961
- _test_eof5: cs = 5; goto _test_eof;
1492
+ bool negative = false;
1493
+ if (*p == '-') {
1494
+ negative = true;
1495
+ p++;
1496
+ }
962
1497
 
963
- _test_eof: {}
964
- _out: {}
965
- }
1498
+ long long memo = 0;
1499
+ while (p < pe) {
1500
+ memo *= 10;
1501
+ memo += *p - '0';
1502
+ p++;
1503
+ }
966
1504
 
967
- #line 320 "parser.rl"
1505
+ if (negative) {
1506
+ memo = -memo;
1507
+ }
1508
+ return LL2NUM(memo);
1509
+ }
968
1510
 
969
- if (cs >= JSON_integer_first_final) {
1511
+ static char *JSON_decode_integer(JSON_Parser *json, char *p, VALUE *result)
1512
+ {
970
1513
  long len = p - json->memo;
971
- fbuffer_clear(json->fbuffer);
972
- fbuffer_append(json->fbuffer, json->memo, len);
973
- fbuffer_append_char(json->fbuffer, '\0');
974
- *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
1514
+ if (RB_LIKELY(len < MAX_FAST_INTEGER_SIZE)) {
1515
+ *result = fast_parse_integer(json->memo, p);
1516
+ } else {
1517
+ fbuffer_clear(&json->fbuffer);
1518
+ fbuffer_append(&json->fbuffer, json->memo, len);
1519
+ fbuffer_append_char(&json->fbuffer, '\0');
1520
+ *result = rb_cstr2inum(FBUFFER_PTR(&json->fbuffer), 10);
1521
+ }
975
1522
  return p + 1;
976
- } else {
977
- return NULL;
978
- }
979
1523
  }
980
1524
 
981
1525
 
982
- #line 983 "parser.c"
1526
+ #line 1527 "parser.c"
983
1527
  enum {JSON_float_start = 1};
984
- enum {JSON_float_first_final = 8};
1528
+ enum {JSON_float_first_final = 6};
985
1529
  enum {JSON_float_error = 0};
986
1530
 
987
1531
  enum {JSON_float_en_main = 1};
988
1532
 
989
1533
 
990
- #line 345 "parser.rl"
1534
+ #line 745 "parser.rl"
991
1535
 
992
1536
 
993
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
1537
+ static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result)
994
1538
  {
995
1539
  int cs = EVIL;
1540
+ bool is_float = false;
996
1541
 
997
1542
 
998
- #line 999 "parser.c"
1543
+ #line 1544 "parser.c"
999
1544
  {
1000
1545
  cs = JSON_float_start;
1001
1546
  }
1002
1547
 
1003
- #line 352 "parser.rl"
1548
+ #line 753 "parser.rl"
1004
1549
  json->memo = p;
1005
1550
 
1006
- #line 1007 "parser.c"
1551
+ #line 1552 "parser.c"
1007
1552
  {
1008
1553
  if ( p == pe )
1009
1554
  goto _test_eof;
@@ -1012,10 +1557,10 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
1012
1557
  case 1:
1013
1558
  switch( (*p) ) {
1014
1559
  case 45: goto st2;
1015
- case 48: goto st3;
1560
+ case 48: goto st6;
1016
1561
  }
1017
1562
  if ( 49 <= (*p) && (*p) <= 57 )
1018
- goto st7;
1563
+ goto st10;
1019
1564
  goto st0;
1020
1565
  st0:
1021
1566
  cs = 0;
@@ -1025,24 +1570,42 @@ st2:
1025
1570
  goto _test_eof2;
1026
1571
  case 2:
1027
1572
  if ( (*p) == 48 )
1028
- goto st3;
1573
+ goto st6;
1029
1574
  if ( 49 <= (*p) && (*p) <= 57 )
1030
- goto st7;
1575
+ goto st10;
1031
1576
  goto st0;
1032
- st3:
1577
+ st6:
1033
1578
  if ( ++p == pe )
1034
- goto _test_eof3;
1035
- case 3:
1579
+ goto _test_eof6;
1580
+ case 6:
1036
1581
  switch( (*p) ) {
1037
- case 46: goto st4;
1038
- case 69: goto st5;
1039
- case 101: goto st5;
1582
+ case 45: goto st0;
1583
+ case 46: goto tr8;
1584
+ case 69: goto tr9;
1585
+ case 101: goto tr9;
1040
1586
  }
1587
+ if ( 48 <= (*p) && (*p) <= 57 )
1588
+ goto st0;
1589
+ goto tr7;
1590
+ tr7:
1591
+ #line 737 "parser.rl"
1592
+ { p--; {p++; cs = 7; goto _out;} }
1593
+ goto st7;
1594
+ st7:
1595
+ if ( ++p == pe )
1596
+ goto _test_eof7;
1597
+ case 7:
1598
+ #line 1599 "parser.c"
1041
1599
  goto st0;
1042
- st4:
1600
+ tr8:
1601
+ #line 738 "parser.rl"
1602
+ { is_float = true; }
1603
+ goto st3;
1604
+ st3:
1043
1605
  if ( ++p == pe )
1044
- goto _test_eof4;
1045
- case 4:
1606
+ goto _test_eof3;
1607
+ case 3:
1608
+ #line 1609 "parser.c"
1046
1609
  if ( 48 <= (*p) && (*p) <= 57 )
1047
1610
  goto st8;
1048
1611
  goto st0;
@@ -1051,125 +1614,126 @@ st8:
1051
1614
  goto _test_eof8;
1052
1615
  case 8:
1053
1616
  switch( (*p) ) {
1054
- case 69: goto st5;
1055
- case 101: goto st5;
1617
+ case 69: goto st4;
1618
+ case 101: goto st4;
1056
1619
  }
1057
1620
  if ( (*p) > 46 ) {
1058
1621
  if ( 48 <= (*p) && (*p) <= 57 )
1059
1622
  goto st8;
1060
1623
  } else if ( (*p) >= 45 )
1061
1624
  goto st0;
1062
- goto tr9;
1625
+ goto tr7;
1063
1626
  tr9:
1064
- #line 339 "parser.rl"
1065
- { p--; {p++; cs = 9; goto _out;} }
1066
- goto st9;
1067
- st9:
1068
- if ( ++p == pe )
1069
- goto _test_eof9;
1070
- case 9:
1071
- #line 1072 "parser.c"
1072
- goto st0;
1073
- st5:
1627
+ #line 738 "parser.rl"
1628
+ { is_float = true; }
1629
+ goto st4;
1630
+ st4:
1074
1631
  if ( ++p == pe )
1075
- goto _test_eof5;
1076
- case 5:
1632
+ goto _test_eof4;
1633
+ case 4:
1634
+ #line 1635 "parser.c"
1077
1635
  switch( (*p) ) {
1078
- case 43: goto st6;
1079
- case 45: goto st6;
1636
+ case 43: goto st5;
1637
+ case 45: goto st5;
1080
1638
  }
1081
1639
  if ( 48 <= (*p) && (*p) <= 57 )
1082
- goto st10;
1640
+ goto st9;
1083
1641
  goto st0;
1084
- st6:
1642
+ st5:
1085
1643
  if ( ++p == pe )
1086
- goto _test_eof6;
1087
- case 6:
1644
+ goto _test_eof5;
1645
+ case 5:
1088
1646
  if ( 48 <= (*p) && (*p) <= 57 )
1089
- goto st10;
1647
+ goto st9;
1090
1648
  goto st0;
1091
- st10:
1649
+ st9:
1092
1650
  if ( ++p == pe )
1093
- goto _test_eof10;
1094
- case 10:
1651
+ goto _test_eof9;
1652
+ case 9:
1095
1653
  switch( (*p) ) {
1096
1654
  case 69: goto st0;
1097
1655
  case 101: goto st0;
1098
1656
  }
1099
1657
  if ( (*p) > 46 ) {
1100
1658
  if ( 48 <= (*p) && (*p) <= 57 )
1101
- goto st10;
1659
+ goto st9;
1102
1660
  } else if ( (*p) >= 45 )
1103
1661
  goto st0;
1104
- goto tr9;
1105
- st7:
1662
+ goto tr7;
1663
+ st10:
1106
1664
  if ( ++p == pe )
1107
- goto _test_eof7;
1108
- case 7:
1665
+ goto _test_eof10;
1666
+ case 10:
1109
1667
  switch( (*p) ) {
1110
- case 46: goto st4;
1111
- case 69: goto st5;
1112
- case 101: goto st5;
1668
+ case 45: goto st0;
1669
+ case 46: goto tr8;
1670
+ case 69: goto tr9;
1671
+ case 101: goto tr9;
1113
1672
  }
1114
1673
  if ( 48 <= (*p) && (*p) <= 57 )
1115
- goto st7;
1116
- goto st0;
1674
+ goto st10;
1675
+ goto tr7;
1117
1676
  }
1118
1677
  _test_eof2: cs = 2; goto _test_eof;
1678
+ _test_eof6: cs = 6; goto _test_eof;
1679
+ _test_eof7: cs = 7; goto _test_eof;
1119
1680
  _test_eof3: cs = 3; goto _test_eof;
1120
- _test_eof4: cs = 4; goto _test_eof;
1121
1681
  _test_eof8: cs = 8; goto _test_eof;
1122
- _test_eof9: cs = 9; goto _test_eof;
1682
+ _test_eof4: cs = 4; goto _test_eof;
1123
1683
  _test_eof5: cs = 5; goto _test_eof;
1124
- _test_eof6: cs = 6; goto _test_eof;
1684
+ _test_eof9: cs = 9; goto _test_eof;
1125
1685
  _test_eof10: cs = 10; goto _test_eof;
1126
- _test_eof7: cs = 7; goto _test_eof;
1127
1686
 
1128
1687
  _test_eof: {}
1129
1688
  _out: {}
1130
1689
  }
1131
1690
 
1132
- #line 354 "parser.rl"
1691
+ #line 755 "parser.rl"
1133
1692
 
1134
1693
  if (cs >= JSON_float_first_final) {
1694
+ if (!is_float) {
1695
+ return JSON_decode_integer(json, p, result);
1696
+ }
1135
1697
  VALUE mod = Qnil;
1136
1698
  ID method_id = 0;
1137
- if (rb_respond_to(json->decimal_class, i_try_convert)) {
1138
- mod = json->decimal_class;
1139
- method_id = i_try_convert;
1140
- } else if (rb_respond_to(json->decimal_class, i_new)) {
1141
- mod = json->decimal_class;
1142
- method_id = i_new;
1143
- } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
1144
- VALUE name = rb_class_name(json->decimal_class);
1145
- const char *name_cstr = RSTRING_PTR(name);
1146
- const char *last_colon = strrchr(name_cstr, ':');
1147
- if (last_colon) {
1148
- const char *mod_path_end = last_colon - 1;
1149
- VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
1150
- mod = rb_path_to_class(mod_path);
1151
-
1152
- const char *method_name_beg = last_colon + 1;
1153
- long before_len = method_name_beg - name_cstr;
1154
- long len = RSTRING_LEN(name) - before_len;
1155
- VALUE method_name = rb_str_substr(name, before_len, len);
1156
- method_id = SYM2ID(rb_str_intern(method_name));
1157
- } else {
1158
- mod = rb_mKernel;
1159
- method_id = SYM2ID(rb_str_intern(name));
1699
+ if (json->decimal_class) {
1700
+ if (rb_respond_to(json->decimal_class, i_try_convert)) {
1701
+ mod = json->decimal_class;
1702
+ method_id = i_try_convert;
1703
+ } else if (rb_respond_to(json->decimal_class, i_new)) {
1704
+ mod = json->decimal_class;
1705
+ method_id = i_new;
1706
+ } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
1707
+ VALUE name = rb_class_name(json->decimal_class);
1708
+ const char *name_cstr = RSTRING_PTR(name);
1709
+ const char *last_colon = strrchr(name_cstr, ':');
1710
+ if (last_colon) {
1711
+ const char *mod_path_end = last_colon - 1;
1712
+ VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
1713
+ mod = rb_path_to_class(mod_path);
1714
+
1715
+ const char *method_name_beg = last_colon + 1;
1716
+ long before_len = method_name_beg - name_cstr;
1717
+ long len = RSTRING_LEN(name) - before_len;
1718
+ VALUE method_name = rb_str_substr(name, before_len, len);
1719
+ method_id = SYM2ID(rb_str_intern(method_name));
1720
+ } else {
1721
+ mod = rb_mKernel;
1722
+ method_id = SYM2ID(rb_str_intern(name));
1723
+ }
1160
1724
  }
1161
1725
  }
1162
1726
 
1163
1727
  long len = p - json->memo;
1164
- fbuffer_clear(json->fbuffer);
1165
- fbuffer_append(json->fbuffer, json->memo, len);
1166
- fbuffer_append_char(json->fbuffer, '\0');
1728
+ fbuffer_clear(&json->fbuffer);
1729
+ fbuffer_append(&json->fbuffer, json->memo, len);
1730
+ fbuffer_append_char(&json->fbuffer, '\0');
1167
1731
 
1168
1732
  if (method_id) {
1169
- VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1733
+ VALUE text = rb_str_new2(FBUFFER_PTR(&json->fbuffer));
1170
1734
  *result = rb_funcallv(mod, method_id, 1, &text);
1171
1735
  } else {
1172
- *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1736
+ *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(&json->fbuffer), 1));
1173
1737
  }
1174
1738
 
1175
1739
  return p + 1;
@@ -1180,37 +1744,37 @@ case 7:
1180
1744
 
1181
1745
 
1182
1746
 
1183
- #line 1184 "parser.c"
1747
+ #line 1748 "parser.c"
1184
1748
  enum {JSON_array_start = 1};
1185
- enum {JSON_array_first_final = 17};
1749
+ enum {JSON_array_first_final = 22};
1186
1750
  enum {JSON_array_error = 0};
1187
1751
 
1188
1752
  enum {JSON_array_en_main = 1};
1189
1753
 
1190
1754
 
1191
- #line 432 "parser.rl"
1755
+ #line 835 "parser.rl"
1192
1756
 
1193
1757
 
1194
1758
  static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
1195
1759
  {
1196
1760
  int cs = EVIL;
1197
- VALUE array_class = json->array_class;
1198
1761
 
1199
1762
  if (json->max_nesting && current_nesting > json->max_nesting) {
1200
1763
  rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
1201
1764
  }
1202
- *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1765
+ long stack_head = json->stack->head;
1203
1766
 
1204
1767
 
1205
- #line 1206 "parser.c"
1768
+ #line 1769 "parser.c"
1206
1769
  {
1207
1770
  cs = JSON_array_start;
1208
1771
  }
1209
1772
 
1210
- #line 445 "parser.rl"
1773
+ #line 847 "parser.rl"
1211
1774
 
1212
- #line 1213 "parser.c"
1775
+ #line 1776 "parser.c"
1213
1776
  {
1777
+ short _widec;
1214
1778
  if ( p == pe )
1215
1779
  goto _test_eof;
1216
1780
  switch ( cs )
@@ -1231,7 +1795,7 @@ case 2:
1231
1795
  case 32: goto st2;
1232
1796
  case 34: goto tr2;
1233
1797
  case 45: goto tr2;
1234
- case 47: goto st13;
1798
+ case 47: goto st18;
1235
1799
  case 73: goto tr2;
1236
1800
  case 78: goto tr2;
1237
1801
  case 91: goto tr2;
@@ -1248,18 +1812,13 @@ case 2:
1248
1812
  goto st2;
1249
1813
  goto st0;
1250
1814
  tr2:
1251
- #line 409 "parser.rl"
1815
+ #line 815 "parser.rl"
1252
1816
  {
1253
1817
  VALUE v = Qnil;
1254
1818
  char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
1255
1819
  if (np == NULL) {
1256
1820
  p--; {p++; cs = 3; goto _out;}
1257
1821
  } else {
1258
- if (NIL_P(json->array_class)) {
1259
- rb_ary_push(*result, v);
1260
- } else {
1261
- rb_funcall(*result, i_leftshift, 1, v);
1262
- }
1263
1822
  {p = (( np))-1;}
1264
1823
  }
1265
1824
  }
@@ -1268,15 +1827,23 @@ st3:
1268
1827
  if ( ++p == pe )
1269
1828
  goto _test_eof3;
1270
1829
  case 3:
1271
- #line 1272 "parser.c"
1272
- switch( (*p) ) {
1830
+ #line 1831 "parser.c"
1831
+ _widec = (*p);
1832
+ if ( 44 <= (*p) && (*p) <= 44 ) {
1833
+ _widec = (short)(128 + ((*p) - -128));
1834
+ if (
1835
+ #line 825 "parser.rl"
1836
+ json->allow_trailing_comma ) _widec += 256;
1837
+ }
1838
+ switch( _widec ) {
1273
1839
  case 13: goto st3;
1274
1840
  case 32: goto st3;
1275
- case 44: goto st4;
1276
- case 47: goto st9;
1841
+ case 47: goto st4;
1277
1842
  case 93: goto tr4;
1843
+ case 300: goto st8;
1844
+ case 556: goto st13;
1278
1845
  }
1279
- if ( 9 <= (*p) && (*p) <= 10 )
1846
+ if ( 9 <= _widec && _widec <= 10 )
1280
1847
  goto st3;
1281
1848
  goto st0;
1282
1849
  st4:
@@ -1284,57 +1851,67 @@ st4:
1284
1851
  goto _test_eof4;
1285
1852
  case 4:
1286
1853
  switch( (*p) ) {
1287
- case 13: goto st4;
1288
- case 32: goto st4;
1289
- case 34: goto tr2;
1290
- case 45: goto tr2;
1291
- case 47: goto st5;
1292
- case 73: goto tr2;
1293
- case 78: goto tr2;
1294
- case 91: goto tr2;
1295
- case 102: goto tr2;
1296
- case 110: goto tr2;
1297
- case 116: goto tr2;
1298
- case 123: goto tr2;
1854
+ case 42: goto st5;
1855
+ case 47: goto st7;
1299
1856
  }
1300
- if ( (*p) > 10 ) {
1301
- if ( 48 <= (*p) && (*p) <= 57 )
1302
- goto tr2;
1303
- } else if ( (*p) >= 9 )
1304
- goto st4;
1305
1857
  goto st0;
1306
1858
  st5:
1307
1859
  if ( ++p == pe )
1308
1860
  goto _test_eof5;
1309
1861
  case 5:
1310
- switch( (*p) ) {
1311
- case 42: goto st6;
1312
- case 47: goto st8;
1313
- }
1314
- goto st0;
1862
+ if ( (*p) == 42 )
1863
+ goto st6;
1864
+ goto st5;
1315
1865
  st6:
1316
1866
  if ( ++p == pe )
1317
1867
  goto _test_eof6;
1318
1868
  case 6:
1319
- if ( (*p) == 42 )
1320
- goto st7;
1321
- goto st6;
1869
+ switch( (*p) ) {
1870
+ case 42: goto st6;
1871
+ case 47: goto st3;
1872
+ }
1873
+ goto st5;
1322
1874
  st7:
1323
1875
  if ( ++p == pe )
1324
1876
  goto _test_eof7;
1325
1877
  case 7:
1326
- switch( (*p) ) {
1327
- case 42: goto st7;
1328
- case 47: goto st4;
1329
- }
1330
- goto st6;
1878
+ if ( (*p) == 10 )
1879
+ goto st3;
1880
+ goto st7;
1881
+ tr4:
1882
+ #line 827 "parser.rl"
1883
+ { p--; {p++; cs = 22; goto _out;} }
1884
+ goto st22;
1885
+ st22:
1886
+ if ( ++p == pe )
1887
+ goto _test_eof22;
1888
+ case 22:
1889
+ #line 1890 "parser.c"
1890
+ goto st0;
1331
1891
  st8:
1332
1892
  if ( ++p == pe )
1333
1893
  goto _test_eof8;
1334
1894
  case 8:
1335
- if ( (*p) == 10 )
1336
- goto st4;
1337
- goto st8;
1895
+ switch( (*p) ) {
1896
+ case 13: goto st8;
1897
+ case 32: goto st8;
1898
+ case 34: goto tr2;
1899
+ case 45: goto tr2;
1900
+ case 47: goto st9;
1901
+ case 73: goto tr2;
1902
+ case 78: goto tr2;
1903
+ case 91: goto tr2;
1904
+ case 102: goto tr2;
1905
+ case 110: goto tr2;
1906
+ case 116: goto tr2;
1907
+ case 123: goto tr2;
1908
+ }
1909
+ if ( (*p) > 10 ) {
1910
+ if ( 48 <= (*p) && (*p) <= 57 )
1911
+ goto tr2;
1912
+ } else if ( (*p) >= 9 )
1913
+ goto st8;
1914
+ goto st0;
1338
1915
  st9:
1339
1916
  if ( ++p == pe )
1340
1917
  goto _test_eof9;
@@ -1357,7 +1934,7 @@ st11:
1357
1934
  case 11:
1358
1935
  switch( (*p) ) {
1359
1936
  case 42: goto st11;
1360
- case 47: goto st3;
1937
+ case 47: goto st8;
1361
1938
  }
1362
1939
  goto st10;
1363
1940
  st12:
@@ -1365,50 +1942,252 @@ st12:
1365
1942
  goto _test_eof12;
1366
1943
  case 12:
1367
1944
  if ( (*p) == 10 )
1368
- goto st3;
1945
+ goto st8;
1369
1946
  goto st12;
1370
- tr4:
1371
- #line 424 "parser.rl"
1372
- { p--; {p++; cs = 17; goto _out;} }
1373
- goto st17;
1374
- st17:
1375
- if ( ++p == pe )
1376
- goto _test_eof17;
1377
- case 17:
1378
- #line 1379 "parser.c"
1379
- goto st0;
1380
1947
  st13:
1381
1948
  if ( ++p == pe )
1382
1949
  goto _test_eof13;
1383
1950
  case 13:
1384
- switch( (*p) ) {
1385
- case 42: goto st14;
1386
- case 47: goto st16;
1951
+ _widec = (*p);
1952
+ if ( (*p) < 13 ) {
1953
+ if ( (*p) > 9 ) {
1954
+ if ( 10 <= (*p) && (*p) <= 10 ) {
1955
+ _widec = (short)(128 + ((*p) - -128));
1956
+ if (
1957
+ #line 825 "parser.rl"
1958
+ json->allow_trailing_comma ) _widec += 256;
1959
+ }
1960
+ } else if ( (*p) >= 9 ) {
1961
+ _widec = (short)(128 + ((*p) - -128));
1962
+ if (
1963
+ #line 825 "parser.rl"
1964
+ json->allow_trailing_comma ) _widec += 256;
1965
+ }
1966
+ } else if ( (*p) > 13 ) {
1967
+ if ( (*p) > 32 ) {
1968
+ if ( 47 <= (*p) && (*p) <= 47 ) {
1969
+ _widec = (short)(128 + ((*p) - -128));
1970
+ if (
1971
+ #line 825 "parser.rl"
1972
+ json->allow_trailing_comma ) _widec += 256;
1973
+ }
1974
+ } else if ( (*p) >= 32 ) {
1975
+ _widec = (short)(128 + ((*p) - -128));
1976
+ if (
1977
+ #line 825 "parser.rl"
1978
+ json->allow_trailing_comma ) _widec += 256;
1979
+ }
1980
+ } else {
1981
+ _widec = (short)(128 + ((*p) - -128));
1982
+ if (
1983
+ #line 825 "parser.rl"
1984
+ json->allow_trailing_comma ) _widec += 256;
1387
1985
  }
1986
+ switch( _widec ) {
1987
+ case 34: goto tr2;
1988
+ case 45: goto tr2;
1989
+ case 73: goto tr2;
1990
+ case 78: goto tr2;
1991
+ case 91: goto tr2;
1992
+ case 93: goto tr4;
1993
+ case 102: goto tr2;
1994
+ case 110: goto tr2;
1995
+ case 116: goto tr2;
1996
+ case 123: goto tr2;
1997
+ case 269: goto st8;
1998
+ case 288: goto st8;
1999
+ case 303: goto st9;
2000
+ case 525: goto st13;
2001
+ case 544: goto st13;
2002
+ case 559: goto st14;
2003
+ }
2004
+ if ( _widec < 265 ) {
2005
+ if ( 48 <= _widec && _widec <= 57 )
2006
+ goto tr2;
2007
+ } else if ( _widec > 266 ) {
2008
+ if ( 521 <= _widec && _widec <= 522 )
2009
+ goto st13;
2010
+ } else
2011
+ goto st8;
1388
2012
  goto st0;
1389
2013
  st14:
1390
2014
  if ( ++p == pe )
1391
2015
  goto _test_eof14;
1392
2016
  case 14:
1393
- if ( (*p) == 42 )
1394
- goto st15;
1395
- goto st14;
2017
+ _widec = (*p);
2018
+ if ( (*p) > 42 ) {
2019
+ if ( 47 <= (*p) && (*p) <= 47 ) {
2020
+ _widec = (short)(128 + ((*p) - -128));
2021
+ if (
2022
+ #line 825 "parser.rl"
2023
+ json->allow_trailing_comma ) _widec += 256;
2024
+ }
2025
+ } else if ( (*p) >= 42 ) {
2026
+ _widec = (short)(128 + ((*p) - -128));
2027
+ if (
2028
+ #line 825 "parser.rl"
2029
+ json->allow_trailing_comma ) _widec += 256;
2030
+ }
2031
+ switch( _widec ) {
2032
+ case 298: goto st10;
2033
+ case 303: goto st12;
2034
+ case 554: goto st15;
2035
+ case 559: goto st17;
2036
+ }
2037
+ goto st0;
1396
2038
  st15:
1397
2039
  if ( ++p == pe )
1398
2040
  goto _test_eof15;
1399
2041
  case 15:
1400
- switch( (*p) ) {
1401
- case 42: goto st15;
1402
- case 47: goto st2;
1403
- }
1404
- goto st14;
2042
+ _widec = (*p);
2043
+ if ( (*p) < 42 ) {
2044
+ if ( (*p) <= 41 ) {
2045
+ _widec = (short)(128 + ((*p) - -128));
2046
+ if (
2047
+ #line 825 "parser.rl"
2048
+ json->allow_trailing_comma ) _widec += 256;
2049
+ }
2050
+ } else if ( (*p) > 42 ) {
2051
+ if ( 43 <= (*p) )
2052
+ { _widec = (short)(128 + ((*p) - -128));
2053
+ if (
2054
+ #line 825 "parser.rl"
2055
+ json->allow_trailing_comma ) _widec += 256;
2056
+ }
2057
+ } else {
2058
+ _widec = (short)(128 + ((*p) - -128));
2059
+ if (
2060
+ #line 825 "parser.rl"
2061
+ json->allow_trailing_comma ) _widec += 256;
2062
+ }
2063
+ switch( _widec ) {
2064
+ case 298: goto st11;
2065
+ case 554: goto st16;
2066
+ }
2067
+ if ( _widec > 383 ) {
2068
+ if ( 384 <= _widec && _widec <= 639 )
2069
+ goto st15;
2070
+ } else if ( _widec >= 128 )
2071
+ goto st10;
2072
+ goto st0;
1405
2073
  st16:
1406
2074
  if ( ++p == pe )
1407
2075
  goto _test_eof16;
1408
2076
  case 16:
2077
+ _widec = (*p);
2078
+ if ( (*p) < 43 ) {
2079
+ if ( (*p) > 41 ) {
2080
+ if ( 42 <= (*p) && (*p) <= 42 ) {
2081
+ _widec = (short)(128 + ((*p) - -128));
2082
+ if (
2083
+ #line 825 "parser.rl"
2084
+ json->allow_trailing_comma ) _widec += 256;
2085
+ }
2086
+ } else {
2087
+ _widec = (short)(128 + ((*p) - -128));
2088
+ if (
2089
+ #line 825 "parser.rl"
2090
+ json->allow_trailing_comma ) _widec += 256;
2091
+ }
2092
+ } else if ( (*p) > 46 ) {
2093
+ if ( (*p) > 47 ) {
2094
+ if ( 48 <= (*p) )
2095
+ { _widec = (short)(128 + ((*p) - -128));
2096
+ if (
2097
+ #line 825 "parser.rl"
2098
+ json->allow_trailing_comma ) _widec += 256;
2099
+ }
2100
+ } else if ( (*p) >= 47 ) {
2101
+ _widec = (short)(128 + ((*p) - -128));
2102
+ if (
2103
+ #line 825 "parser.rl"
2104
+ json->allow_trailing_comma ) _widec += 256;
2105
+ }
2106
+ } else {
2107
+ _widec = (short)(128 + ((*p) - -128));
2108
+ if (
2109
+ #line 825 "parser.rl"
2110
+ json->allow_trailing_comma ) _widec += 256;
2111
+ }
2112
+ switch( _widec ) {
2113
+ case 298: goto st11;
2114
+ case 303: goto st8;
2115
+ case 554: goto st16;
2116
+ case 559: goto st13;
2117
+ }
2118
+ if ( _widec > 383 ) {
2119
+ if ( 384 <= _widec && _widec <= 639 )
2120
+ goto st15;
2121
+ } else if ( _widec >= 128 )
2122
+ goto st10;
2123
+ goto st0;
2124
+ st17:
2125
+ if ( ++p == pe )
2126
+ goto _test_eof17;
2127
+ case 17:
2128
+ _widec = (*p);
2129
+ if ( (*p) < 10 ) {
2130
+ if ( (*p) <= 9 ) {
2131
+ _widec = (short)(128 + ((*p) - -128));
2132
+ if (
2133
+ #line 825 "parser.rl"
2134
+ json->allow_trailing_comma ) _widec += 256;
2135
+ }
2136
+ } else if ( (*p) > 10 ) {
2137
+ if ( 11 <= (*p) )
2138
+ { _widec = (short)(128 + ((*p) - -128));
2139
+ if (
2140
+ #line 825 "parser.rl"
2141
+ json->allow_trailing_comma ) _widec += 256;
2142
+ }
2143
+ } else {
2144
+ _widec = (short)(128 + ((*p) - -128));
2145
+ if (
2146
+ #line 825 "parser.rl"
2147
+ json->allow_trailing_comma ) _widec += 256;
2148
+ }
2149
+ switch( _widec ) {
2150
+ case 266: goto st8;
2151
+ case 522: goto st13;
2152
+ }
2153
+ if ( _widec > 383 ) {
2154
+ if ( 384 <= _widec && _widec <= 639 )
2155
+ goto st17;
2156
+ } else if ( _widec >= 128 )
2157
+ goto st12;
2158
+ goto st0;
2159
+ st18:
2160
+ if ( ++p == pe )
2161
+ goto _test_eof18;
2162
+ case 18:
2163
+ switch( (*p) ) {
2164
+ case 42: goto st19;
2165
+ case 47: goto st21;
2166
+ }
2167
+ goto st0;
2168
+ st19:
2169
+ if ( ++p == pe )
2170
+ goto _test_eof19;
2171
+ case 19:
2172
+ if ( (*p) == 42 )
2173
+ goto st20;
2174
+ goto st19;
2175
+ st20:
2176
+ if ( ++p == pe )
2177
+ goto _test_eof20;
2178
+ case 20:
2179
+ switch( (*p) ) {
2180
+ case 42: goto st20;
2181
+ case 47: goto st2;
2182
+ }
2183
+ goto st19;
2184
+ st21:
2185
+ if ( ++p == pe )
2186
+ goto _test_eof21;
2187
+ case 21:
1409
2188
  if ( (*p) == 10 )
1410
2189
  goto st2;
1411
- goto st16;
2190
+ goto st21;
1412
2191
  }
1413
2192
  _test_eof2: cs = 2; goto _test_eof;
1414
2193
  _test_eof3: cs = 3; goto _test_eof;
@@ -1416,54 +2195,127 @@ case 16:
1416
2195
  _test_eof5: cs = 5; goto _test_eof;
1417
2196
  _test_eof6: cs = 6; goto _test_eof;
1418
2197
  _test_eof7: cs = 7; goto _test_eof;
2198
+ _test_eof22: cs = 22; goto _test_eof;
1419
2199
  _test_eof8: cs = 8; goto _test_eof;
1420
2200
  _test_eof9: cs = 9; goto _test_eof;
1421
2201
  _test_eof10: cs = 10; goto _test_eof;
1422
2202
  _test_eof11: cs = 11; goto _test_eof;
1423
2203
  _test_eof12: cs = 12; goto _test_eof;
1424
- _test_eof17: cs = 17; goto _test_eof;
1425
2204
  _test_eof13: cs = 13; goto _test_eof;
1426
2205
  _test_eof14: cs = 14; goto _test_eof;
1427
2206
  _test_eof15: cs = 15; goto _test_eof;
1428
2207
  _test_eof16: cs = 16; goto _test_eof;
2208
+ _test_eof17: cs = 17; goto _test_eof;
2209
+ _test_eof18: cs = 18; goto _test_eof;
2210
+ _test_eof19: cs = 19; goto _test_eof;
2211
+ _test_eof20: cs = 20; goto _test_eof;
2212
+ _test_eof21: cs = 21; goto _test_eof;
1429
2213
 
1430
2214
  _test_eof: {}
1431
2215
  _out: {}
1432
2216
  }
1433
2217
 
1434
- #line 446 "parser.rl"
2218
+ #line 848 "parser.rl"
1435
2219
 
1436
2220
  if(cs >= JSON_array_first_final) {
2221
+ long count = json->stack->head - stack_head;
2222
+
2223
+ if (RB_UNLIKELY(json->array_class)) {
2224
+ VALUE array = rb_class_new_instance(0, 0, json->array_class);
2225
+ VALUE *items = rvalue_stack_peek(json->stack, count);
2226
+ long index;
2227
+ for (index = 0; index < count; index++) {
2228
+ rb_funcall(array, i_leftshift, 1, items[index]);
2229
+ }
2230
+ *result = array;
2231
+ } else {
2232
+ VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(json->stack, count));
2233
+ *result = array;
2234
+ }
2235
+ rvalue_stack_pop(json->stack, count);
2236
+
1437
2237
  return p + 1;
1438
2238
  } else {
1439
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
2239
+ raise_parse_error("unexpected token at '%s'", p);
1440
2240
  return NULL;
1441
2241
  }
1442
2242
  }
1443
2243
 
1444
- static const size_t MAX_STACK_BUFFER_SIZE = 128;
1445
- static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
2244
+ static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
2245
+ {
2246
+ if (symbolize) {
2247
+ intern = true;
2248
+ }
2249
+ VALUE result;
2250
+ # ifdef HAVE_RB_ENC_INTERNED_STR
2251
+ if (intern) {
2252
+ result = rb_enc_interned_str(start, (long)(end - start), enc_utf8);
2253
+ } else {
2254
+ result = rb_utf8_str_new(start, (long)(end - start));
2255
+ }
2256
+ # else
2257
+ result = rb_utf8_str_new(start, (long)(end - start));
2258
+ if (intern) {
2259
+ result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
2260
+ }
2261
+ # endif
2262
+
2263
+ if (symbolize) {
2264
+ result = rb_str_intern(result);
2265
+ }
2266
+
2267
+ return result;
2268
+ }
2269
+
2270
+ static VALUE json_string_fastpath(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
2271
+ {
2272
+ size_t bufferSize = stringEnd - string;
2273
+
2274
+ if (is_name && json->in_array) {
2275
+ VALUE cached_key;
2276
+ if (RB_UNLIKELY(symbolize)) {
2277
+ cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
2278
+ } else {
2279
+ cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
2280
+ }
2281
+
2282
+ if (RB_LIKELY(cached_key)) {
2283
+ return cached_key;
2284
+ }
2285
+ }
2286
+
2287
+ return build_string(string, stringEnd, intern, symbolize);
2288
+ }
2289
+
2290
+ static VALUE json_string_unescape(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
1446
2291
  {
1447
- VALUE result = Qnil;
1448
2292
  size_t bufferSize = stringEnd - string;
1449
2293
  char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
1450
2294
  int unescape_len;
1451
2295
  char buf[4];
1452
2296
 
1453
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1454
- # ifdef HAVE_RB_ENC_INTERNED_STR
1455
- bufferStart = buffer = ALLOC_N(char, bufferSize ? bufferSize : 1);
1456
- # else
1457
- bufferStart = buffer = ALLOC_N(char, bufferSize);
1458
- # endif
1459
- } else {
1460
- # ifdef HAVE_RB_ENC_INTERNED_STR
1461
- bufferStart = buffer = ALLOCA_N(char, bufferSize ? bufferSize : 1);
1462
- # else
1463
- bufferStart = buffer = ALLOCA_N(char, bufferSize);
1464
- # endif
2297
+ if (is_name && json->in_array) {
2298
+ VALUE cached_key;
2299
+ if (RB_UNLIKELY(symbolize)) {
2300
+ cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
2301
+ } else {
2302
+ cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
2303
+ }
2304
+
2305
+ if (RB_LIKELY(cached_key)) {
2306
+ return cached_key;
2307
+ }
2308
+ }
2309
+
2310
+ pe = memchr(p, '\\', bufferSize);
2311
+ if (RB_UNLIKELY(pe == NULL)) {
2312
+ return build_string(string, stringEnd, intern, symbolize);
1465
2313
  }
1466
2314
 
2315
+ VALUE result = rb_str_buf_new(bufferSize);
2316
+ rb_enc_associate_index(result, utf8_encindex);
2317
+ buffer = bufferStart = RSTRING_PTR(result);
2318
+
1467
2319
  while (pe < stringEnd) {
1468
2320
  if (*pe == '\\') {
1469
2321
  unescape = (char *) "?";
@@ -1496,29 +2348,27 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
1496
2348
  break;
1497
2349
  case 'u':
1498
2350
  if (pe > stringEnd - 4) {
1499
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1500
- ruby_xfree(bufferStart);
1501
- }
1502
- rb_enc_raise(
1503
- EXC_ENCODING eParserError,
1504
- "incomplete unicode character escape sequence at '%s'", p
1505
- );
2351
+ raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
1506
2352
  } else {
1507
- UTF32 ch = unescape_unicode((unsigned char *) ++pe);
2353
+ uint32_t ch = unescape_unicode((unsigned char *) ++pe);
1508
2354
  pe += 3;
1509
- if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
2355
+ /* To handle values above U+FFFF, we take a sequence of
2356
+ * \uXXXX escapes in the U+D800..U+DBFF then
2357
+ * U+DC00..U+DFFF ranges, take the low 10 bits from each
2358
+ * to make a 20-bit number, then add 0x10000 to get the
2359
+ * final codepoint.
2360
+ *
2361
+ * See Unicode 15: 3.8 "Surrogates", 5.3 "Handling
2362
+ * Surrogate Pairs in UTF-16", and 23.6 "Surrogates
2363
+ * Area".
2364
+ */
2365
+ if ((ch & 0xFC00) == 0xD800) {
1510
2366
  pe++;
1511
2367
  if (pe > stringEnd - 6) {
1512
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1513
- ruby_xfree(bufferStart);
1514
- }
1515
- rb_enc_raise(
1516
- EXC_ENCODING eParserError,
1517
- "incomplete surrogate pair at '%s'", p
1518
- );
2368
+ raise_parse_error("incomplete surrogate pair at '%s'", p);
1519
2369
  }
1520
2370
  if (pe[0] == '\\' && pe[1] == 'u') {
1521
- UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
2371
+ uint32_t sur = unescape_unicode((unsigned char *) pe + 2);
1522
2372
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
1523
2373
  | (sur & 0x3FF));
1524
2374
  pe += 5;
@@ -1547,56 +2397,27 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
1547
2397
  MEMCPY(buffer, p, char, pe - p);
1548
2398
  buffer += pe - p;
1549
2399
  }
1550
-
1551
- # ifdef HAVE_RB_ENC_INTERNED_STR
1552
- if (intern) {
1553
- result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
1554
- } else {
1555
- result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1556
- }
1557
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1558
- ruby_xfree(bufferStart);
1559
- }
1560
- # else
1561
- result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1562
-
1563
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1564
- ruby_xfree(bufferStart);
1565
- }
1566
-
1567
- if (intern) {
1568
- # if STR_UMINUS_DEDUPE_FROZEN
1569
- // Starting from MRI 2.8 it is preferable to freeze the string
1570
- // before deduplication so that it can be interned directly
1571
- // otherwise it would be duplicated first which is wasteful.
1572
- result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
1573
- # elif STR_UMINUS_DEDUPE
1574
- // MRI 2.5 and older do not deduplicate strings that are already
1575
- // frozen.
1576
- result = rb_funcall(result, i_uminus, 0);
1577
- # else
1578
- result = rb_str_freeze(result);
1579
- # endif
1580
- }
1581
- # endif
2400
+ rb_str_set_len(result, buffer - bufferStart);
1582
2401
 
1583
2402
  if (symbolize) {
1584
- result = rb_str_intern(result);
2403
+ result = rb_str_intern(result);
2404
+ } else if (intern) {
2405
+ result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
1585
2406
  }
1586
2407
 
1587
2408
  return result;
1588
2409
  }
1589
2410
 
1590
2411
 
1591
- #line 1592 "parser.c"
2412
+ #line 2413 "parser.c"
1592
2413
  enum {JSON_string_start = 1};
1593
- enum {JSON_string_first_final = 8};
2414
+ enum {JSON_string_first_final = 9};
1594
2415
  enum {JSON_string_error = 0};
1595
2416
 
1596
2417
  enum {JSON_string_en_main = 1};
1597
2418
 
1598
2419
 
1599
- #line 620 "parser.rl"
2420
+ #line 1071 "parser.rl"
1600
2421
 
1601
2422
 
1602
2423
  static int
@@ -1617,15 +2438,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
1617
2438
  VALUE match_string;
1618
2439
 
1619
2440
 
1620
- #line 1621 "parser.c"
2441
+ #line 2442 "parser.c"
1621
2442
  {
1622
2443
  cs = JSON_string_start;
1623
2444
  }
1624
2445
 
1625
- #line 640 "parser.rl"
2446
+ #line 1091 "parser.rl"
1626
2447
  json->memo = p;
1627
2448
 
1628
- #line 1629 "parser.c"
2449
+ #line 2450 "parser.c"
1629
2450
  {
1630
2451
  if ( p == pe )
1631
2452
  goto _test_eof;
@@ -1650,47 +2471,56 @@ case 2:
1650
2471
  goto st0;
1651
2472
  goto st2;
1652
2473
  tr2:
1653
- #line 607 "parser.rl"
2474
+ #line 1053 "parser.rl"
1654
2475
  {
1655
- *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
1656
- if (NIL_P(*result)) {
1657
- p--;
1658
- {p++; cs = 8; goto _out;}
1659
- } else {
1660
- {p = (( p + 1))-1;}
1661
- }
2476
+ *result = json_string_fastpath(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
2477
+ {p = (( p + 1))-1;}
2478
+ p--;
2479
+ {p++; cs = 9; goto _out;}
1662
2480
  }
1663
- #line 617 "parser.rl"
1664
- { p--; {p++; cs = 8; goto _out;} }
1665
- goto st8;
1666
- st8:
2481
+ #line 1046 "parser.rl"
2482
+ {
2483
+ *result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
2484
+ {p = (( p + 1))-1;}
2485
+ p--;
2486
+ {p++; cs = 9; goto _out;}
2487
+ }
2488
+ goto st9;
2489
+ tr6:
2490
+ #line 1046 "parser.rl"
2491
+ {
2492
+ *result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
2493
+ {p = (( p + 1))-1;}
2494
+ p--;
2495
+ {p++; cs = 9; goto _out;}
2496
+ }
2497
+ goto st9;
2498
+ st9:
1667
2499
  if ( ++p == pe )
1668
- goto _test_eof8;
1669
- case 8:
1670
- #line 1671 "parser.c"
2500
+ goto _test_eof9;
2501
+ case 9:
2502
+ #line 2503 "parser.c"
1671
2503
  goto st0;
1672
2504
  st3:
1673
2505
  if ( ++p == pe )
1674
2506
  goto _test_eof3;
1675
2507
  case 3:
1676
2508
  if ( (*p) == 117 )
1677
- goto st4;
2509
+ goto st5;
1678
2510
  if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
1679
2511
  goto st0;
1680
- goto st2;
2512
+ goto st4;
1681
2513
  st4:
1682
2514
  if ( ++p == pe )
1683
2515
  goto _test_eof4;
1684
2516
  case 4:
1685
- if ( (*p) < 65 ) {
1686
- if ( 48 <= (*p) && (*p) <= 57 )
1687
- goto st5;
1688
- } else if ( (*p) > 70 ) {
1689
- if ( 97 <= (*p) && (*p) <= 102 )
1690
- goto st5;
1691
- } else
1692
- goto st5;
1693
- goto st0;
2517
+ switch( (*p) ) {
2518
+ case 34: goto tr6;
2519
+ case 92: goto st3;
2520
+ }
2521
+ if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
2522
+ goto st0;
2523
+ goto st4;
1694
2524
  st5:
1695
2525
  if ( ++p == pe )
1696
2526
  goto _test_eof5;
@@ -1723,27 +2553,41 @@ st7:
1723
2553
  case 7:
1724
2554
  if ( (*p) < 65 ) {
1725
2555
  if ( 48 <= (*p) && (*p) <= 57 )
1726
- goto st2;
2556
+ goto st8;
1727
2557
  } else if ( (*p) > 70 ) {
1728
2558
  if ( 97 <= (*p) && (*p) <= 102 )
1729
- goto st2;
2559
+ goto st8;
1730
2560
  } else
1731
- goto st2;
2561
+ goto st8;
2562
+ goto st0;
2563
+ st8:
2564
+ if ( ++p == pe )
2565
+ goto _test_eof8;
2566
+ case 8:
2567
+ if ( (*p) < 65 ) {
2568
+ if ( 48 <= (*p) && (*p) <= 57 )
2569
+ goto st4;
2570
+ } else if ( (*p) > 70 ) {
2571
+ if ( 97 <= (*p) && (*p) <= 102 )
2572
+ goto st4;
2573
+ } else
2574
+ goto st4;
1732
2575
  goto st0;
1733
2576
  }
1734
2577
  _test_eof2: cs = 2; goto _test_eof;
1735
- _test_eof8: cs = 8; goto _test_eof;
2578
+ _test_eof9: cs = 9; goto _test_eof;
1736
2579
  _test_eof3: cs = 3; goto _test_eof;
1737
2580
  _test_eof4: cs = 4; goto _test_eof;
1738
2581
  _test_eof5: cs = 5; goto _test_eof;
1739
2582
  _test_eof6: cs = 6; goto _test_eof;
1740
2583
  _test_eof7: cs = 7; goto _test_eof;
2584
+ _test_eof8: cs = 8; goto _test_eof;
1741
2585
 
1742
2586
  _test_eof: {}
1743
2587
  _out: {}
1744
2588
  }
1745
2589
 
1746
- #line 642 "parser.rl"
2590
+ #line 1093 "parser.rl"
1747
2591
 
1748
2592
  if (json->create_additions && RTEST(match_string = json->match_string)) {
1749
2593
  VALUE klass;
@@ -1777,18 +2621,80 @@ case 7:
1777
2621
 
1778
2622
  static VALUE convert_encoding(VALUE source)
1779
2623
  {
1780
- #ifdef HAVE_RUBY_ENCODING_H
1781
- rb_encoding *enc = rb_enc_get(source);
1782
- if (enc == rb_ascii8bit_encoding()) {
1783
- if (OBJ_FROZEN(source)) {
1784
- source = rb_str_dup(source);
1785
- }
1786
- FORCE_UTF8(source);
1787
- } else {
1788
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1789
- }
1790
- #endif
2624
+ int encindex = RB_ENCODING_GET(source);
2625
+
2626
+ if (RB_LIKELY(encindex == utf8_encindex)) {
1791
2627
  return source;
2628
+ }
2629
+
2630
+ if (encindex == binary_encindex) {
2631
+ // For historical reason, we silently reinterpret binary strings as UTF-8
2632
+ return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
2633
+ }
2634
+
2635
+ return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
2636
+ }
2637
+
2638
+ static int configure_parser_i(VALUE key, VALUE val, VALUE data)
2639
+ {
2640
+ JSON_Parser *json = (JSON_Parser *)data;
2641
+
2642
+ if (key == sym_max_nesting) { json->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
2643
+ else if (key == sym_allow_nan) { json->allow_nan = RTEST(val); }
2644
+ else if (key == sym_allow_trailing_comma) { json->allow_trailing_comma = RTEST(val); }
2645
+ else if (key == sym_symbolize_names) { json->symbolize_names = RTEST(val); }
2646
+ else if (key == sym_freeze) { json->freeze = RTEST(val); }
2647
+ else if (key == sym_create_id) { json->create_id = RTEST(val) ? val : Qfalse; }
2648
+ else if (key == sym_object_class) { json->object_class = RTEST(val) ? val : Qfalse; }
2649
+ else if (key == sym_array_class) { json->array_class = RTEST(val) ? val : Qfalse; }
2650
+ else if (key == sym_decimal_class) { json->decimal_class = RTEST(val) ? val : Qfalse; }
2651
+ else if (key == sym_match_string) { json->match_string = RTEST(val) ? val : Qfalse; }
2652
+ else if (key == sym_create_additions) {
2653
+ if (NIL_P(val)) {
2654
+ json->create_additions = true;
2655
+ json->deprecated_create_additions = true;
2656
+ } else {
2657
+ json->create_additions = RTEST(val);
2658
+ json->deprecated_create_additions = false;
2659
+ }
2660
+ }
2661
+
2662
+ return ST_CONTINUE;
2663
+ }
2664
+
2665
+ static void parser_init(JSON_Parser *json, VALUE source, VALUE opts)
2666
+ {
2667
+ if (json->Vsource) {
2668
+ rb_raise(rb_eTypeError, "already initialized instance");
2669
+ }
2670
+
2671
+ json->fbuffer.initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
2672
+ json->max_nesting = 100;
2673
+
2674
+ if (!NIL_P(opts)) {
2675
+ Check_Type(opts, T_HASH);
2676
+ if (RHASH_SIZE(opts) > 0) {
2677
+ // We assume in most cases few keys are set so it's faster to go over
2678
+ // the provided keys than to check all possible keys.
2679
+ rb_hash_foreach(opts, configure_parser_i, (VALUE)json);
2680
+
2681
+ if (json->symbolize_names && json->create_additions) {
2682
+ rb_raise(rb_eArgError,
2683
+ "options :symbolize_names and :create_additions cannot be "
2684
+ " used in conjunction");
2685
+ }
2686
+
2687
+ if (json->create_additions && !json->create_id) {
2688
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
2689
+ }
2690
+ }
2691
+
2692
+ }
2693
+ source = convert_encoding(StringValue(source));
2694
+ StringValue(source);
2695
+ json->len = RSTRING_LEN(source);
2696
+ json->source = RSTRING_PTR(source);
2697
+ json->Vsource = source;
1792
2698
  }
1793
2699
 
1794
2700
  /*
@@ -1813,110 +2719,28 @@ static VALUE convert_encoding(VALUE source)
1813
2719
  * * *create_additions*: If set to false, the Parser doesn't create
1814
2720
  * additions even if a matching class and create_id was found. This option
1815
2721
  * defaults to false.
1816
- * * *object_class*: Defaults to Hash
1817
- * * *array_class*: Defaults to Array
2722
+ * * *object_class*: Defaults to Hash. If another type is provided, it will be used
2723
+ * instead of Hash to represent JSON objects. The type must respond to
2724
+ * +new+ without arguments, and return an object that respond to +[]=+.
2725
+ * * *array_class*: Defaults to Array If another type is provided, it will be used
2726
+ * instead of Hash to represent JSON arrays. The type must respond to
2727
+ * +new+ without arguments, and return an object that respond to +<<+.
2728
+ * * *decimal_class*: Specifies which class to use instead of the default
2729
+ * (Float) when parsing decimal numbers. This class must accept a single
2730
+ * string argument in its constructor.
1818
2731
  */
1819
2732
  static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1820
2733
  {
1821
- VALUE source, opts;
1822
2734
  GET_PARSER_INIT;
1823
2735
 
1824
- if (json->Vsource) {
1825
- rb_raise(rb_eTypeError, "already initialized instance");
1826
- }
1827
- rb_scan_args(argc, argv, "1:", &source, &opts);
1828
- if (!NIL_P(opts)) {
1829
- VALUE tmp = ID2SYM(i_max_nesting);
1830
- if (option_given_p(opts, tmp)) {
1831
- VALUE max_nesting = rb_hash_aref(opts, tmp);
1832
- if (RTEST(max_nesting)) {
1833
- Check_Type(max_nesting, T_FIXNUM);
1834
- json->max_nesting = FIX2INT(max_nesting);
1835
- } else {
1836
- json->max_nesting = 0;
1837
- }
1838
- } else {
1839
- json->max_nesting = 100;
1840
- }
1841
- tmp = ID2SYM(i_allow_nan);
1842
- if (option_given_p(opts, tmp)) {
1843
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1844
- } else {
1845
- json->allow_nan = 0;
1846
- }
1847
- tmp = ID2SYM(i_symbolize_names);
1848
- if (option_given_p(opts, tmp)) {
1849
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1850
- } else {
1851
- json->symbolize_names = 0;
1852
- }
1853
- tmp = ID2SYM(i_freeze);
1854
- if (option_given_p(opts, tmp)) {
1855
- json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1856
- } else {
1857
- json->freeze = 0;
1858
- }
1859
- tmp = ID2SYM(i_create_additions);
1860
- if (option_given_p(opts, tmp)) {
1861
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1862
- } else {
1863
- json->create_additions = 0;
1864
- }
1865
- if (json->symbolize_names && json->create_additions) {
1866
- rb_raise(rb_eArgError,
1867
- "options :symbolize_names and :create_additions cannot be "
1868
- " used in conjunction");
1869
- }
1870
- tmp = ID2SYM(i_create_id);
1871
- if (option_given_p(opts, tmp)) {
1872
- json->create_id = rb_hash_aref(opts, tmp);
1873
- } else {
1874
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
1875
- }
1876
- tmp = ID2SYM(i_object_class);
1877
- if (option_given_p(opts, tmp)) {
1878
- json->object_class = rb_hash_aref(opts, tmp);
1879
- } else {
1880
- json->object_class = Qnil;
1881
- }
1882
- tmp = ID2SYM(i_array_class);
1883
- if (option_given_p(opts, tmp)) {
1884
- json->array_class = rb_hash_aref(opts, tmp);
1885
- } else {
1886
- json->array_class = Qnil;
1887
- }
1888
- tmp = ID2SYM(i_decimal_class);
1889
- if (option_given_p(opts, tmp)) {
1890
- json->decimal_class = rb_hash_aref(opts, tmp);
1891
- } else {
1892
- json->decimal_class = Qnil;
1893
- }
1894
- tmp = ID2SYM(i_match_string);
1895
- if (option_given_p(opts, tmp)) {
1896
- VALUE match_string = rb_hash_aref(opts, tmp);
1897
- json->match_string = RTEST(match_string) ? match_string : Qnil;
1898
- } else {
1899
- json->match_string = Qnil;
1900
- }
1901
- } else {
1902
- json->max_nesting = 100;
1903
- json->allow_nan = 0;
1904
- json->create_additions = 0;
1905
- json->create_id = Qnil;
1906
- json->object_class = Qnil;
1907
- json->array_class = Qnil;
1908
- json->decimal_class = Qnil;
1909
- }
1910
- source = convert_encoding(StringValue(source));
1911
- StringValue(source);
1912
- json->len = RSTRING_LEN(source);
1913
- json->source = RSTRING_PTR(source);;
1914
- json->Vsource = source;
2736
+ rb_check_arity(argc, 1, 2);
2737
+
2738
+ parser_init(json, argv[0], argc == 2 ? argv[1] : Qnil);
1915
2739
  return self;
1916
2740
  }
1917
2741
 
1918
2742
 
1919
- #line 1920 "parser.c"
2743
+ #line 2744 "parser.c"
1920
2744
  enum {JSON_start = 1};
1921
2745
  enum {JSON_first_final = 10};
1922
2746
  enum {JSON_error = 0};
@@ -1924,7 +2748,7 @@ enum {JSON_error = 0};
1924
2748
  enum {JSON_en_main = 1};
1925
2749
 
1926
2750
 
1927
- #line 828 "parser.rl"
2751
+ #line 1259 "parser.rl"
1928
2752
 
1929
2753
 
1930
2754
  /*
@@ -1936,22 +2760,33 @@ enum {JSON_en_main = 1};
1936
2760
  */
1937
2761
  static VALUE cParser_parse(VALUE self)
1938
2762
  {
1939
- char *p, *pe;
1940
- int cs = EVIL;
1941
- VALUE result = Qnil;
1942
- GET_PARSER;
2763
+ char *p, *pe;
2764
+ int cs = EVIL;
2765
+ VALUE result = Qnil;
2766
+ GET_PARSER;
2767
+
2768
+ char stack_buffer[FBUFFER_STACK_SIZE];
2769
+ fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
2770
+
2771
+ VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
2772
+ rvalue_stack stack = {
2773
+ .type = RVALUE_STACK_STACK_ALLOCATED,
2774
+ .ptr = rvalue_stack_buffer,
2775
+ .capa = RVALUE_STACK_INITIAL_CAPA,
2776
+ };
2777
+ json->stack = &stack;
1943
2778
 
1944
2779
 
1945
- #line 1946 "parser.c"
2780
+ #line 2781 "parser.c"
1946
2781
  {
1947
2782
  cs = JSON_start;
1948
2783
  }
1949
2784
 
1950
- #line 845 "parser.rl"
1951
- p = json->source;
1952
- pe = p + json->len;
2785
+ #line 1287 "parser.rl"
2786
+ p = json->source;
2787
+ pe = p + json->len;
1953
2788
 
1954
- #line 1955 "parser.c"
2789
+ #line 2790 "parser.c"
1955
2790
  {
1956
2791
  if ( p == pe )
1957
2792
  goto _test_eof;
@@ -1985,7 +2820,7 @@ st0:
1985
2820
  cs = 0;
1986
2821
  goto _out;
1987
2822
  tr2:
1988
- #line 820 "parser.rl"
2823
+ #line 1251 "parser.rl"
1989
2824
  {
1990
2825
  char *np = JSON_parse_value(json, p, pe, &result, 0);
1991
2826
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
@@ -1995,7 +2830,7 @@ st10:
1995
2830
  if ( ++p == pe )
1996
2831
  goto _test_eof10;
1997
2832
  case 10:
1998
- #line 1999 "parser.c"
2833
+ #line 2834 "parser.c"
1999
2834
  switch( (*p) ) {
2000
2835
  case 13: goto st10;
2001
2836
  case 32: goto st10;
@@ -2084,56 +2919,238 @@ case 9:
2084
2919
  _out: {}
2085
2920
  }
2086
2921
 
2087
- #line 848 "parser.rl"
2922
+ #line 1290 "parser.rl"
2088
2923
 
2089
- if (cs >= JSON_first_final && p == pe) {
2090
- return result;
2091
- } else {
2092
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
2093
- return Qnil;
2094
- }
2924
+ if (json->stack_handle) {
2925
+ rvalue_stack_eagerly_release(json->stack_handle);
2926
+ }
2927
+
2928
+ if (cs >= JSON_first_final && p == pe) {
2929
+ return result;
2930
+ } else {
2931
+ raise_parse_error("unexpected token at '%s'", p);
2932
+ return Qnil;
2933
+ }
2934
+ }
2935
+
2936
+ static VALUE cParser_m_parse(VALUE klass, VALUE source, VALUE opts)
2937
+ {
2938
+ char *p, *pe;
2939
+ int cs = EVIL;
2940
+ VALUE result = Qnil;
2941
+
2942
+ JSON_Parser _parser = {0};
2943
+ JSON_Parser *json = &_parser;
2944
+ parser_init(json, source, opts);
2945
+
2946
+ char stack_buffer[FBUFFER_STACK_SIZE];
2947
+ fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
2948
+
2949
+ VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
2950
+ rvalue_stack stack = {
2951
+ .type = RVALUE_STACK_STACK_ALLOCATED,
2952
+ .ptr = rvalue_stack_buffer,
2953
+ .capa = RVALUE_STACK_INITIAL_CAPA,
2954
+ };
2955
+ json->stack = &stack;
2956
+
2957
+
2958
+ #line 2959 "parser.c"
2959
+ {
2960
+ cs = JSON_start;
2961
+ }
2962
+
2963
+ #line 1325 "parser.rl"
2964
+ p = json->source;
2965
+ pe = p + json->len;
2966
+
2967
+ #line 2968 "parser.c"
2968
+ {
2969
+ if ( p == pe )
2970
+ goto _test_eof;
2971
+ switch ( cs )
2972
+ {
2973
+ st1:
2974
+ if ( ++p == pe )
2975
+ goto _test_eof1;
2976
+ case 1:
2977
+ switch( (*p) ) {
2978
+ case 13: goto st1;
2979
+ case 32: goto st1;
2980
+ case 34: goto tr2;
2981
+ case 45: goto tr2;
2982
+ case 47: goto st6;
2983
+ case 73: goto tr2;
2984
+ case 78: goto tr2;
2985
+ case 91: goto tr2;
2986
+ case 102: goto tr2;
2987
+ case 110: goto tr2;
2988
+ case 116: goto tr2;
2989
+ case 123: goto tr2;
2990
+ }
2991
+ if ( (*p) > 10 ) {
2992
+ if ( 48 <= (*p) && (*p) <= 57 )
2993
+ goto tr2;
2994
+ } else if ( (*p) >= 9 )
2995
+ goto st1;
2996
+ goto st0;
2997
+ st0:
2998
+ cs = 0;
2999
+ goto _out;
3000
+ tr2:
3001
+ #line 1251 "parser.rl"
3002
+ {
3003
+ char *np = JSON_parse_value(json, p, pe, &result, 0);
3004
+ if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
3005
+ }
3006
+ goto st10;
3007
+ st10:
3008
+ if ( ++p == pe )
3009
+ goto _test_eof10;
3010
+ case 10:
3011
+ #line 3012 "parser.c"
3012
+ switch( (*p) ) {
3013
+ case 13: goto st10;
3014
+ case 32: goto st10;
3015
+ case 47: goto st2;
3016
+ }
3017
+ if ( 9 <= (*p) && (*p) <= 10 )
3018
+ goto st10;
3019
+ goto st0;
3020
+ st2:
3021
+ if ( ++p == pe )
3022
+ goto _test_eof2;
3023
+ case 2:
3024
+ switch( (*p) ) {
3025
+ case 42: goto st3;
3026
+ case 47: goto st5;
3027
+ }
3028
+ goto st0;
3029
+ st3:
3030
+ if ( ++p == pe )
3031
+ goto _test_eof3;
3032
+ case 3:
3033
+ if ( (*p) == 42 )
3034
+ goto st4;
3035
+ goto st3;
3036
+ st4:
3037
+ if ( ++p == pe )
3038
+ goto _test_eof4;
3039
+ case 4:
3040
+ switch( (*p) ) {
3041
+ case 42: goto st4;
3042
+ case 47: goto st10;
3043
+ }
3044
+ goto st3;
3045
+ st5:
3046
+ if ( ++p == pe )
3047
+ goto _test_eof5;
3048
+ case 5:
3049
+ if ( (*p) == 10 )
3050
+ goto st10;
3051
+ goto st5;
3052
+ st6:
3053
+ if ( ++p == pe )
3054
+ goto _test_eof6;
3055
+ case 6:
3056
+ switch( (*p) ) {
3057
+ case 42: goto st7;
3058
+ case 47: goto st9;
3059
+ }
3060
+ goto st0;
3061
+ st7:
3062
+ if ( ++p == pe )
3063
+ goto _test_eof7;
3064
+ case 7:
3065
+ if ( (*p) == 42 )
3066
+ goto st8;
3067
+ goto st7;
3068
+ st8:
3069
+ if ( ++p == pe )
3070
+ goto _test_eof8;
3071
+ case 8:
3072
+ switch( (*p) ) {
3073
+ case 42: goto st8;
3074
+ case 47: goto st1;
3075
+ }
3076
+ goto st7;
3077
+ st9:
3078
+ if ( ++p == pe )
3079
+ goto _test_eof9;
3080
+ case 9:
3081
+ if ( (*p) == 10 )
3082
+ goto st1;
3083
+ goto st9;
3084
+ }
3085
+ _test_eof1: cs = 1; goto _test_eof;
3086
+ _test_eof10: cs = 10; goto _test_eof;
3087
+ _test_eof2: cs = 2; goto _test_eof;
3088
+ _test_eof3: cs = 3; goto _test_eof;
3089
+ _test_eof4: cs = 4; goto _test_eof;
3090
+ _test_eof5: cs = 5; goto _test_eof;
3091
+ _test_eof6: cs = 6; goto _test_eof;
3092
+ _test_eof7: cs = 7; goto _test_eof;
3093
+ _test_eof8: cs = 8; goto _test_eof;
3094
+ _test_eof9: cs = 9; goto _test_eof;
3095
+
3096
+ _test_eof: {}
3097
+ _out: {}
3098
+ }
3099
+
3100
+ #line 1328 "parser.rl"
3101
+
3102
+ if (json->stack_handle) {
3103
+ rvalue_stack_eagerly_release(json->stack_handle);
3104
+ }
3105
+
3106
+ if (cs >= JSON_first_final && p == pe) {
3107
+ return result;
3108
+ } else {
3109
+ raise_parse_error("unexpected token at '%s'", p);
3110
+ return Qnil;
3111
+ }
2095
3112
  }
2096
3113
 
2097
3114
  static void JSON_mark(void *ptr)
2098
3115
  {
2099
3116
  JSON_Parser *json = ptr;
2100
- rb_gc_mark_maybe(json->Vsource);
2101
- rb_gc_mark_maybe(json->create_id);
2102
- rb_gc_mark_maybe(json->object_class);
2103
- rb_gc_mark_maybe(json->array_class);
2104
- rb_gc_mark_maybe(json->decimal_class);
2105
- rb_gc_mark_maybe(json->match_string);
3117
+ rb_gc_mark(json->Vsource);
3118
+ rb_gc_mark(json->create_id);
3119
+ rb_gc_mark(json->object_class);
3120
+ rb_gc_mark(json->array_class);
3121
+ rb_gc_mark(json->decimal_class);
3122
+ rb_gc_mark(json->match_string);
3123
+ rb_gc_mark(json->stack_handle);
3124
+
3125
+ const VALUE *name_cache_entries = &json->name_cache.entries[0];
3126
+ rb_gc_mark_locations(name_cache_entries, name_cache_entries + json->name_cache.length);
2106
3127
  }
2107
3128
 
2108
3129
  static void JSON_free(void *ptr)
2109
3130
  {
2110
3131
  JSON_Parser *json = ptr;
2111
- fbuffer_free(json->fbuffer);
3132
+ fbuffer_free(&json->fbuffer);
2112
3133
  ruby_xfree(json);
2113
3134
  }
2114
3135
 
2115
3136
  static size_t JSON_memsize(const void *ptr)
2116
3137
  {
2117
3138
  const JSON_Parser *json = ptr;
2118
- return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
3139
+ return sizeof(*json) + FBUFFER_CAPA(&json->fbuffer);
2119
3140
  }
2120
3141
 
2121
- #ifdef NEW_TYPEDDATA_WRAPPER
2122
3142
  static const rb_data_type_t JSON_Parser_type = {
2123
3143
  "JSON/Parser",
2124
3144
  {JSON_mark, JSON_free, JSON_memsize,},
2125
- #ifdef RUBY_TYPED_FREE_IMMEDIATELY
2126
3145
  0, 0,
2127
3146
  RUBY_TYPED_FREE_IMMEDIATELY,
2128
- #endif
2129
3147
  };
2130
- #endif
2131
3148
 
2132
3149
  static VALUE cJSON_parser_s_allocate(VALUE klass)
2133
3150
  {
2134
3151
  JSON_Parser *json;
2135
3152
  VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
2136
- json->fbuffer = fbuffer_alloc(0);
3153
+ fbuffer_stack_init(&json->fbuffer, 0, NULL, 0);
2137
3154
  return obj;
2138
3155
  }
2139
3156
 
@@ -2160,15 +3177,15 @@ void Init_parser(void)
2160
3177
  mJSON = rb_define_module("JSON");
2161
3178
  mExt = rb_define_module_under(mJSON, "Ext");
2162
3179
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
2163
- eParserError = rb_path2class("JSON::ParserError");
2164
3180
  eNestingError = rb_path2class("JSON::NestingError");
2165
- rb_gc_register_mark_object(eParserError);
2166
3181
  rb_gc_register_mark_object(eNestingError);
2167
3182
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
2168
3183
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
2169
3184
  rb_define_method(cParser, "parse", cParser_parse, 0);
2170
3185
  rb_define_method(cParser, "source", cParser_source, 0);
2171
3186
 
3187
+ rb_define_singleton_method(cParser, "parse", cParser_m_parse, 2);
3188
+
2172
3189
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2173
3190
  rb_gc_register_mark_object(CNaN);
2174
3191
 
@@ -2178,28 +3195,38 @@ void Init_parser(void)
2178
3195
  CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
2179
3196
  rb_gc_register_mark_object(CMinusInfinity);
2180
3197
 
3198
+ rb_global_variable(&Encoding_UTF_8);
3199
+ Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8"));
3200
+
3201
+ sym_max_nesting = ID2SYM(rb_intern("max_nesting"));
3202
+ sym_allow_nan = ID2SYM(rb_intern("allow_nan"));
3203
+ sym_allow_trailing_comma = ID2SYM(rb_intern("allow_trailing_comma"));
3204
+ sym_symbolize_names = ID2SYM(rb_intern("symbolize_names"));
3205
+ sym_freeze = ID2SYM(rb_intern("freeze"));
3206
+ sym_create_additions = ID2SYM(rb_intern("create_additions"));
3207
+ sym_create_id = ID2SYM(rb_intern("create_id"));
3208
+ sym_object_class = ID2SYM(rb_intern("object_class"));
3209
+ sym_array_class = ID2SYM(rb_intern("array_class"));
3210
+ sym_decimal_class = ID2SYM(rb_intern("decimal_class"));
3211
+ sym_match_string = ID2SYM(rb_intern("match_string"));
3212
+
3213
+ i_create_id = rb_intern("create_id");
2181
3214
  i_json_creatable_p = rb_intern("json_creatable?");
2182
3215
  i_json_create = rb_intern("json_create");
2183
- i_create_id = rb_intern("create_id");
2184
- i_create_additions = rb_intern("create_additions");
2185
3216
  i_chr = rb_intern("chr");
2186
- i_max_nesting = rb_intern("max_nesting");
2187
- i_allow_nan = rb_intern("allow_nan");
2188
- i_symbolize_names = rb_intern("symbolize_names");
2189
- i_object_class = rb_intern("object_class");
2190
- i_array_class = rb_intern("array_class");
2191
- i_decimal_class = rb_intern("decimal_class");
2192
3217
  i_match = rb_intern("match");
2193
- i_match_string = rb_intern("match_string");
2194
- i_key_p = rb_intern("key?");
2195
3218
  i_deep_const_get = rb_intern("deep_const_get");
2196
3219
  i_aset = rb_intern("[]=");
2197
3220
  i_aref = rb_intern("[]");
2198
3221
  i_leftshift = rb_intern("<<");
2199
3222
  i_new = rb_intern("new");
2200
3223
  i_try_convert = rb_intern("try_convert");
2201
- i_freeze = rb_intern("freeze");
2202
3224
  i_uminus = rb_intern("-@");
3225
+ i_encode = rb_intern("encode");
3226
+
3227
+ binary_encindex = rb_ascii8bit_encindex();
3228
+ utf8_encindex = rb_utf8_encindex();
3229
+ enc_utf8 = rb_utf8_encoding();
2203
3230
  }
2204
3231
 
2205
3232
  /*