json 2.7.2 → 2.9.1

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