json 2.7.2 → 2.9.1

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