json 2.7.2 → 2.9.0

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