json 2.7.2 → 2.9.0

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