json 1.6.3 → 1.6.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of json might be problematic. Click here for more details.

@@ -79,7 +79,7 @@ static VALUE CNaN, CInfinity, CMinusInfinity;
79
79
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
80
80
  i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
81
81
  i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
82
- i_match_string, i_aset, i_leftshift;
82
+ i_match_string, i_aset, i_aref, i_leftshift;
83
83
 
84
84
  %%{
85
85
  machine JSON_common;
@@ -167,7 +167,12 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
167
167
 
168
168
  if (cs >= JSON_object_first_final) {
169
169
  if (json->create_additions) {
170
- VALUE klassname = rb_hash_aref(*result, json->create_id);
170
+ VALUE klassname;
171
+ if (NIL_P(json->object_class)) {
172
+ klassname = rb_hash_aref(*result, json->create_id);
173
+ } else {
174
+ klassname = rb_funcall(*result, i_aref, 1, json->create_id);
175
+ }
171
176
  if (!NIL_P(klassname)) {
172
177
  VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
173
178
  if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
@@ -896,6 +901,7 @@ void Init_parser()
896
901
  i_key_p = rb_intern("key?");
897
902
  i_deep_const_get = rb_intern("deep_const_get");
898
903
  i_aset = rb_intern("[]=");
904
+ i_aref = rb_intern("[]");
899
905
  i_leftshift = rb_intern("<<");
900
906
  #ifdef HAVE_RUBY_ENCODING_H
901
907
  CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
@@ -102,13 +102,7 @@ final class OptionsReader {
102
102
  IRubyObject value = get(key);
103
103
 
104
104
  if (value == null || value.isNil()) return defaultValue;
105
-
106
- if (value instanceof RubyClass &&
107
- ((RubyClass)value).getAllocator() == defaultValue.getAllocator()) {
108
- return (RubyClass)value;
109
- }
110
- throw runtime.newTypeError(key + " option must be a subclass of "
111
- + defaultValue);
105
+ return (RubyClass)value;
112
106
  }
113
107
 
114
108
  public RubyHash getHash(String key) {
@@ -28,6 +28,8 @@ import org.jruby.runtime.ThreadContext;
28
28
  import org.jruby.runtime.Visibility;
29
29
  import org.jruby.runtime.builtin.IRubyObject;
30
30
  import org.jruby.util.ByteList;
31
+ import org.jruby.util.ConvertBytes;
32
+ import static org.jruby.util.ConvertDouble.DoubleConverter;
31
33
 
32
34
  /**
33
35
  * The <code>JSON::Ext::Parser</code> class.
@@ -58,7 +60,7 @@ public class Parser extends RubyObject {
58
60
 
59
61
  private static final int DEFAULT_MAX_NESTING = 19;
60
62
 
61
- private static final String JSON_MINUS_INFINITY = "-Infinity";
63
+ private static final ByteList JSON_MINUS_INFINITY = new ByteList(ByteList.plain("-Infinity"));
62
64
  // constant names in the JSON module containing those values
63
65
  private static final String CONST_NAN = "NaN";
64
66
  private static final String CONST_INFINITY = "Infinity";
@@ -82,13 +84,13 @@ public class Parser extends RubyObject {
82
84
  * The result of the successful parsing. Should never be
83
85
  * <code>null</code>.
84
86
  */
85
- final IRubyObject result;
87
+ IRubyObject result;
86
88
  /**
87
89
  * The point where the parser returned.
88
90
  */
89
- final int p;
91
+ int p;
90
92
 
91
- ParserResult(IRubyObject result, int p) {
93
+ void update(IRubyObject result, int p) {
92
94
  this.result = result;
93
95
  this.p = p;
94
96
  }
@@ -303,9 +305,11 @@ public class Parser extends RubyObject {
303
305
  private final Parser parser;
304
306
  private final ThreadContext context;
305
307
  private final ByteList byteList;
308
+ private final ByteList view;
306
309
  private final byte[] data;
307
310
  private final StringDecoder decoder;
308
311
  private int currentNesting = 0;
312
+ private final DoubleConverter dc;
309
313
 
310
314
  // initialization value for all state variables.
311
315
  // no idea about the origins of this value, ask Flori ;)
@@ -316,7 +320,9 @@ public class Parser extends RubyObject {
316
320
  this.context = context;
317
321
  this.byteList = parser.checkAndGetSource().getByteList();
318
322
  this.data = byteList.unsafeBytes();
323
+ this.view = new ByteList(data, false);
319
324
  this.decoder = new StringDecoder(context);
325
+ this.dc = new DoubleConverter();
320
326
  }
321
327
 
322
328
  private RaiseException unexpectedToken(int absStart, int absEnd) {
@@ -331,11 +337,11 @@ public class Parser extends RubyObject {
331
337
  }
332
338
 
333
339
 
334
- // line 357 "Parser.rl"
340
+ // line 363 "Parser.rl"
335
341
 
336
342
 
337
343
 
338
- // line 339 "Parser.java"
344
+ // line 345 "Parser.java"
339
345
  private static byte[] init__JSON_value_actions_0()
340
346
  {
341
347
  return new byte [] {
@@ -449,22 +455,22 @@ static final int JSON_value_error = 0;
449
455
  static final int JSON_value_en_main = 1;
450
456
 
451
457
 
452
- // line 463 "Parser.rl"
458
+ // line 469 "Parser.rl"
453
459
 
454
460
 
455
- ParserResult parseValue(int p, int pe) {
461
+ void parseValue(ParserResult res, int p, int pe) {
456
462
  int cs = EVIL;
457
463
  IRubyObject result = null;
458
464
 
459
465
 
460
- // line 461 "Parser.java"
466
+ // line 467 "Parser.java"
461
467
  {
462
468
  cs = JSON_value_start;
463
469
  }
464
470
 
465
- // line 470 "Parser.rl"
471
+ // line 476 "Parser.rl"
466
472
 
467
- // line 468 "Parser.java"
473
+ // line 474 "Parser.java"
468
474
  {
469
475
  int _klen;
470
476
  int _trans = 0;
@@ -490,13 +496,13 @@ case 1:
490
496
  while ( _nacts-- > 0 ) {
491
497
  switch ( _JSON_value_actions[_acts++] ) {
492
498
  case 9:
493
- // line 448 "Parser.rl"
499
+ // line 454 "Parser.rl"
494
500
  {
495
501
  p--;
496
502
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
497
503
  }
498
504
  break;
499
- // line 500 "Parser.java"
505
+ // line 506 "Parser.java"
500
506
  }
501
507
  }
502
508
 
@@ -559,25 +565,25 @@ case 1:
559
565
  switch ( _JSON_value_actions[_acts++] )
560
566
  {
561
567
  case 0:
562
- // line 365 "Parser.rl"
568
+ // line 371 "Parser.rl"
563
569
  {
564
570
  result = getRuntime().getNil();
565
571
  }
566
572
  break;
567
573
  case 1:
568
- // line 368 "Parser.rl"
574
+ // line 374 "Parser.rl"
569
575
  {
570
576
  result = getRuntime().getFalse();
571
577
  }
572
578
  break;
573
579
  case 2:
574
- // line 371 "Parser.rl"
580
+ // line 377 "Parser.rl"
575
581
  {
576
582
  result = getRuntime().getTrue();
577
583
  }
578
584
  break;
579
585
  case 3:
580
- // line 374 "Parser.rl"
586
+ // line 380 "Parser.rl"
581
587
  {
582
588
  if (parser.allowNaN) {
583
589
  result = getConstant(CONST_NAN);
@@ -587,7 +593,7 @@ case 1:
587
593
  }
588
594
  break;
589
595
  case 4:
590
- // line 381 "Parser.rl"
596
+ // line 387 "Parser.rl"
591
597
  {
592
598
  if (parser.allowNaN) {
593
599
  result = getConstant(CONST_INFINITY);
@@ -597,10 +603,10 @@ case 1:
597
603
  }
598
604
  break;
599
605
  case 5:
600
- // line 388 "Parser.rl"
606
+ // line 394 "Parser.rl"
601
607
  {
602
608
  if (pe > p + 9 - (parser.quirksMode ? 1 : 0) &&
603
- absSubSequence(p, p + 9).toString().equals(JSON_MINUS_INFINITY)) {
609
+ absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) {
604
610
 
605
611
  if (parser.allowNaN) {
606
612
  result = getConstant(CONST_MINUS_INFINITY);
@@ -611,13 +617,13 @@ case 1:
611
617
  throw unexpectedToken(p, pe);
612
618
  }
613
619
  }
614
- ParserResult res = parseFloat(p, pe);
615
- if (res != null) {
620
+ parseFloat(res, p, pe);
621
+ if (res.result != null) {
616
622
  result = res.result;
617
623
  {p = (( res.p))-1;}
618
624
  }
619
- res = parseInteger(p, pe);
620
- if (res != null) {
625
+ parseInteger(res, p, pe);
626
+ if (res.result != null) {
621
627
  result = res.result;
622
628
  {p = (( res.p))-1;}
623
629
  }
@@ -626,10 +632,10 @@ case 1:
626
632
  }
627
633
  break;
628
634
  case 6:
629
- // line 414 "Parser.rl"
635
+ // line 420 "Parser.rl"
630
636
  {
631
- ParserResult res = parseString(p, pe);
632
- if (res == null) {
637
+ parseString(res, p, pe);
638
+ if (res.result == null) {
633
639
  p--;
634
640
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
635
641
  } else {
@@ -639,12 +645,12 @@ case 1:
639
645
  }
640
646
  break;
641
647
  case 7:
642
- // line 424 "Parser.rl"
648
+ // line 430 "Parser.rl"
643
649
  {
644
650
  currentNesting++;
645
- ParserResult res = parseArray(p, pe);
651
+ parseArray(res, p, pe);
646
652
  currentNesting--;
647
- if (res == null) {
653
+ if (res.result == null) {
648
654
  p--;
649
655
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
650
656
  } else {
@@ -654,12 +660,12 @@ case 1:
654
660
  }
655
661
  break;
656
662
  case 8:
657
- // line 436 "Parser.rl"
663
+ // line 442 "Parser.rl"
658
664
  {
659
665
  currentNesting++;
660
- ParserResult res = parseObject(p, pe);
666
+ parseObject(res, p, pe);
661
667
  currentNesting--;
662
- if (res == null) {
668
+ if (res.result == null) {
663
669
  p--;
664
670
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
665
671
  } else {
@@ -668,7 +674,7 @@ case 1:
668
674
  }
669
675
  }
670
676
  break;
671
- // line 672 "Parser.java"
677
+ // line 678 "Parser.java"
672
678
  }
673
679
  }
674
680
  }
@@ -688,17 +694,17 @@ case 5:
688
694
  break; }
689
695
  }
690
696
 
691
- // line 471 "Parser.rl"
697
+ // line 477 "Parser.rl"
692
698
 
693
699
  if (cs >= JSON_value_first_final && result != null) {
694
- return new ParserResult(result, p);
700
+ res.update(result, p);
695
701
  } else {
696
- return null;
702
+ res.update(null, p);
697
703
  }
698
704
  }
699
705
 
700
706
 
701
- // line 702 "Parser.java"
707
+ // line 708 "Parser.java"
702
708
  private static byte[] init__JSON_integer_actions_0()
703
709
  {
704
710
  return new byte [] {
@@ -797,22 +803,33 @@ static final int JSON_integer_error = 0;
797
803
  static final int JSON_integer_en_main = 1;
798
804
 
799
805
 
800
- // line 490 "Parser.rl"
806
+ // line 496 "Parser.rl"
801
807
 
802
808
 
803
- ParserResult parseInteger(int p, int pe) {
809
+ void parseInteger(ParserResult res, int p, int pe) {
810
+ int new_p = parseIntegerInternal(p, pe);
811
+ if (new_p == -1) {
812
+ res.update(null, p);
813
+ return;
814
+ }
815
+ RubyInteger number = createInteger(p, new_p);
816
+ res.update(number, new_p + 1);
817
+ return;
818
+ }
819
+
820
+ int parseIntegerInternal(int p, int pe) {
804
821
  int cs = EVIL;
805
822
 
806
823
 
807
- // line 808 "Parser.java"
824
+ // line 825 "Parser.java"
808
825
  {
809
826
  cs = JSON_integer_start;
810
827
  }
811
828
 
812
- // line 496 "Parser.rl"
829
+ // line 513 "Parser.rl"
813
830
  int memo = p;
814
831
 
815
- // line 816 "Parser.java"
832
+ // line 833 "Parser.java"
816
833
  {
817
834
  int _klen;
818
835
  int _trans = 0;
@@ -893,13 +910,13 @@ case 1:
893
910
  switch ( _JSON_integer_actions[_acts++] )
894
911
  {
895
912
  case 0:
896
- // line 484 "Parser.rl"
913
+ // line 490 "Parser.rl"
897
914
  {
898
915
  p--;
899
916
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
900
917
  }
901
918
  break;
902
- // line 903 "Parser.java"
919
+ // line 920 "Parser.java"
903
920
  }
904
921
  }
905
922
  }
@@ -919,22 +936,29 @@ case 5:
919
936
  break; }
920
937
  }
921
938
 
922
- // line 498 "Parser.rl"
939
+ // line 515 "Parser.rl"
923
940
 
924
941
  if (cs < JSON_integer_first_final) {
925
- return null;
942
+ return -1;
926
943
  }
927
944
 
928
- ByteList num = absSubSequence(memo, p);
929
- // note: this is actually a shared string, but since it is temporary and
930
- // read-only, it doesn't really matter
931
- RubyString expr = RubyString.newStringLight(getRuntime(), num);
932
- RubyInteger number = RubyNumeric.str2inum(getRuntime(), expr, 10, true);
933
- return new ParserResult(number, p + 1);
945
+ return p;
946
+ }
947
+
948
+ RubyInteger createInteger(int p, int new_p) {
949
+ Ruby runtime = getRuntime();
950
+ ByteList num = absSubSequence(p, new_p);
951
+ return bytesToInum(runtime, num);
952
+ }
953
+
954
+ RubyInteger bytesToInum(Ruby runtime, ByteList num) {
955
+ return runtime.is1_9() ?
956
+ ConvertBytes.byteListToInum19(runtime, num, 10, true) :
957
+ ConvertBytes.byteListToInum(runtime, num, 10, true);
934
958
  }
935
959
 
936
960
 
937
- // line 938 "Parser.java"
961
+ // line 962 "Parser.java"
938
962
  private static byte[] init__JSON_float_actions_0()
939
963
  {
940
964
  return new byte [] {
@@ -1036,22 +1060,33 @@ static final int JSON_float_error = 0;
1036
1060
  static final int JSON_float_en_main = 1;
1037
1061
 
1038
1062
 
1039
- // line 526 "Parser.rl"
1063
+ // line 550 "Parser.rl"
1040
1064
 
1041
1065
 
1042
- ParserResult parseFloat(int p, int pe) {
1066
+ void parseFloat(ParserResult res, int p, int pe) {
1067
+ int new_p = parseFloatInternal(p, pe);
1068
+ if (new_p == -1) {
1069
+ res.update(null, p);
1070
+ return;
1071
+ }
1072
+ RubyFloat number = createFloat(p, new_p);
1073
+ res.update(number, new_p + 1);
1074
+ return;
1075
+ }
1076
+
1077
+ int parseFloatInternal(int p, int pe) {
1043
1078
  int cs = EVIL;
1044
1079
 
1045
1080
 
1046
- // line 1047 "Parser.java"
1081
+ // line 1082 "Parser.java"
1047
1082
  {
1048
1083
  cs = JSON_float_start;
1049
1084
  }
1050
1085
 
1051
- // line 532 "Parser.rl"
1086
+ // line 567 "Parser.rl"
1052
1087
  int memo = p;
1053
1088
 
1054
- // line 1055 "Parser.java"
1089
+ // line 1090 "Parser.java"
1055
1090
  {
1056
1091
  int _klen;
1057
1092
  int _trans = 0;
@@ -1132,13 +1167,13 @@ case 1:
1132
1167
  switch ( _JSON_float_actions[_acts++] )
1133
1168
  {
1134
1169
  case 0:
1135
- // line 517 "Parser.rl"
1170
+ // line 541 "Parser.rl"
1136
1171
  {
1137
1172
  p--;
1138
1173
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1139
1174
  }
1140
1175
  break;
1141
- // line 1142 "Parser.java"
1176
+ // line 1177 "Parser.java"
1142
1177
  }
1143
1178
  }
1144
1179
  }
@@ -1158,22 +1193,23 @@ case 5:
1158
1193
  break; }
1159
1194
  }
1160
1195
 
1161
- // line 534 "Parser.rl"
1196
+ // line 569 "Parser.rl"
1162
1197
 
1163
1198
  if (cs < JSON_float_first_final) {
1164
- return null;
1199
+ return -1;
1165
1200
  }
1166
-
1167
- ByteList num = absSubSequence(memo, p);
1168
- // note: this is actually a shared string, but since it is temporary and
1169
- // read-only, it doesn't really matter
1170
- RubyString expr = RubyString.newStringLight(getRuntime(), num);
1171
- RubyFloat number = RubyNumeric.str2fnum(getRuntime(), expr, true);
1172
- return new ParserResult(number, p + 1);
1201
+
1202
+ return p;
1203
+ }
1204
+
1205
+ RubyFloat createFloat(int p, int new_p) {
1206
+ Ruby runtime = getRuntime();
1207
+ ByteList num = absSubSequence(p, new_p);
1208
+ return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9()));
1173
1209
  }
1174
1210
 
1175
1211
 
1176
- // line 1177 "Parser.java"
1212
+ // line 1213 "Parser.java"
1177
1213
  private static byte[] init__JSON_string_actions_0()
1178
1214
  {
1179
1215
  return new byte [] {
@@ -1275,23 +1311,23 @@ static final int JSON_string_error = 0;
1275
1311
  static final int JSON_string_en_main = 1;
1276
1312
 
1277
1313
 
1278
- // line 578 "Parser.rl"
1314
+ // line 614 "Parser.rl"
1279
1315
 
1280
1316
 
1281
- ParserResult parseString(int p, int pe) {
1317
+ void parseString(ParserResult res, int p, int pe) {
1282
1318
  int cs = EVIL;
1283
1319
  IRubyObject result = null;
1284
1320
 
1285
1321
 
1286
- // line 1287 "Parser.java"
1322
+ // line 1323 "Parser.java"
1287
1323
  {
1288
1324
  cs = JSON_string_start;
1289
1325
  }
1290
1326
 
1291
- // line 585 "Parser.rl"
1327
+ // line 621 "Parser.rl"
1292
1328
  int memo = p;
1293
1329
 
1294
- // line 1295 "Parser.java"
1330
+ // line 1331 "Parser.java"
1295
1331
  {
1296
1332
  int _klen;
1297
1333
  int _trans = 0;
@@ -1372,7 +1408,7 @@ case 1:
1372
1408
  switch ( _JSON_string_actions[_acts++] )
1373
1409
  {
1374
1410
  case 0:
1375
- // line 553 "Parser.rl"
1411
+ // line 589 "Parser.rl"
1376
1412
  {
1377
1413
  int offset = byteList.begin();
1378
1414
  ByteList decoded = decoder.decode(byteList, memo + 1 - offset,
@@ -1387,13 +1423,13 @@ case 1:
1387
1423
  }
1388
1424
  break;
1389
1425
  case 1:
1390
- // line 566 "Parser.rl"
1426
+ // line 602 "Parser.rl"
1391
1427
  {
1392
1428
  p--;
1393
1429
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1394
1430
  }
1395
1431
  break;
1396
- // line 1397 "Parser.java"
1432
+ // line 1433 "Parser.java"
1397
1433
  }
1398
1434
  }
1399
1435
  }
@@ -1413,7 +1449,7 @@ case 5:
1413
1449
  break; }
1414
1450
  }
1415
1451
 
1416
- // line 587 "Parser.rl"
1452
+ // line 623 "Parser.rl"
1417
1453
 
1418
1454
  if (parser.createAdditions) {
1419
1455
  RubyHash match_string = parser.match_string;
@@ -1441,14 +1477,14 @@ case 5:
1441
1477
  }
1442
1478
 
1443
1479
  if (cs >= JSON_string_first_final && result != null) {
1444
- return new ParserResult(result, p + 1);
1480
+ res.update(result, p + 1);
1445
1481
  } else {
1446
- return null;
1482
+ res.update(null, p + 1);
1447
1483
  }
1448
1484
  }
1449
1485
 
1450
1486
 
1451
- // line 1452 "Parser.java"
1487
+ // line 1488 "Parser.java"
1452
1488
  private static byte[] init__JSON_array_actions_0()
1453
1489
  {
1454
1490
  return new byte [] {
@@ -1561,10 +1597,10 @@ static final int JSON_array_error = 0;
1561
1597
  static final int JSON_array_en_main = 1;
1562
1598
 
1563
1599
 
1564
- // line 657 "Parser.rl"
1600
+ // line 693 "Parser.rl"
1565
1601
 
1566
1602
 
1567
- ParserResult parseArray(int p, int pe) {
1603
+ void parseArray(ParserResult res, int p, int pe) {
1568
1604
  int cs = EVIL;
1569
1605
 
1570
1606
  if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) {
@@ -1572,21 +1608,23 @@ static final int JSON_array_en_main = 1;
1572
1608
  "nesting of " + currentNesting + " is too deep");
1573
1609
  }
1574
1610
 
1575
- // this is guaranteed to be a RubyArray due to the earlier
1576
- // allocator test at OptionsReader#getClass
1577
- RubyArray result =
1578
- (RubyArray)parser.arrayClass.newInstance(context,
1579
- IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
1611
+ IRubyObject result;
1612
+ if (parser.arrayClass == getRuntime().getArray()) {
1613
+ result = RubyArray.newArray(getRuntime());
1614
+ } else {
1615
+ result = parser.arrayClass.newInstance(context,
1616
+ IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
1617
+ }
1580
1618
 
1581
1619
 
1582
- // line 1583 "Parser.java"
1620
+ // line 1623 "Parser.java"
1583
1621
  {
1584
1622
  cs = JSON_array_start;
1585
1623
  }
1586
1624
 
1587
- // line 674 "Parser.rl"
1625
+ // line 714 "Parser.rl"
1588
1626
 
1589
- // line 1590 "Parser.java"
1627
+ // line 1630 "Parser.java"
1590
1628
  {
1591
1629
  int _klen;
1592
1630
  int _trans = 0;
@@ -1667,30 +1705,30 @@ case 1:
1667
1705
  switch ( _JSON_array_actions[_acts++] )
1668
1706
  {
1669
1707
  case 0:
1670
- // line 626 "Parser.rl"
1708
+ // line 662 "Parser.rl"
1671
1709
  {
1672
- ParserResult res = parseValue(p, pe);
1673
- if (res == null) {
1710
+ parseValue(res, p, pe);
1711
+ if (res.result == null) {
1674
1712
  p--;
1675
1713
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1676
1714
  } else {
1677
- if (!parser.arrayClass.getName().equals("Array")) {
1678
- result.callMethod(context, "<<", res.result);
1715
+ if (parser.arrayClass == getRuntime().getArray()) {
1716
+ ((RubyArray)result).append(res.result);
1679
1717
  } else {
1680
- result.append(res.result);
1718
+ result.callMethod(context, "<<", res.result);
1681
1719
  }
1682
1720
  {p = (( res.p))-1;}
1683
1721
  }
1684
1722
  }
1685
1723
  break;
1686
1724
  case 1:
1687
- // line 641 "Parser.rl"
1725
+ // line 677 "Parser.rl"
1688
1726
  {
1689
1727
  p--;
1690
1728
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1691
1729
  }
1692
1730
  break;
1693
- // line 1694 "Parser.java"
1731
+ // line 1734 "Parser.java"
1694
1732
  }
1695
1733
  }
1696
1734
  }
@@ -1710,17 +1748,17 @@ case 5:
1710
1748
  break; }
1711
1749
  }
1712
1750
 
1713
- // line 675 "Parser.rl"
1751
+ // line 715 "Parser.rl"
1714
1752
 
1715
1753
  if (cs >= JSON_array_first_final) {
1716
- return new ParserResult(result, p + 1);
1754
+ res.update(result, p + 1);
1717
1755
  } else {
1718
1756
  throw unexpectedToken(p, pe);
1719
1757
  }
1720
1758
  }
1721
1759
 
1722
1760
 
1723
- // line 1724 "Parser.java"
1761
+ // line 1764 "Parser.java"
1724
1762
  private static byte[] init__JSON_object_actions_0()
1725
1763
  {
1726
1764
  return new byte [] {
@@ -1843,12 +1881,13 @@ static final int JSON_object_error = 0;
1843
1881
  static final int JSON_object_en_main = 1;
1844
1882
 
1845
1883
 
1846
- // line 734 "Parser.rl"
1884
+ // line 774 "Parser.rl"
1847
1885
 
1848
1886
 
1849
- ParserResult parseObject(int p, int pe) {
1887
+ void parseObject(ParserResult res, int p, int pe) {
1850
1888
  int cs = EVIL;
1851
1889
  IRubyObject lastName = null;
1890
+ boolean objectDefault = true;
1852
1891
 
1853
1892
  if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) {
1854
1893
  throw newException(Utils.M_NESTING_ERROR,
@@ -1857,19 +1896,24 @@ static final int JSON_object_en_main = 1;
1857
1896
 
1858
1897
  // this is guaranteed to be a RubyHash due to the earlier
1859
1898
  // allocator test at OptionsReader#getClass
1860
- RubyHash result =
1861
- (RubyHash)parser.objectClass.newInstance(context,
1862
- IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
1899
+ IRubyObject result;
1900
+ if (parser.objectClass == getRuntime().getHash()) {
1901
+ result = RubyHash.newHash(getRuntime());
1902
+ } else {
1903
+ objectDefault = false;
1904
+ result = parser.objectClass.newInstance(context,
1905
+ IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
1906
+ }
1863
1907
 
1864
1908
 
1865
- // line 1866 "Parser.java"
1909
+ // line 1912 "Parser.java"
1866
1910
  {
1867
1911
  cs = JSON_object_start;
1868
1912
  }
1869
1913
 
1870
- // line 752 "Parser.rl"
1914
+ // line 798 "Parser.rl"
1871
1915
 
1872
- // line 1873 "Parser.java"
1916
+ // line 1919 "Parser.java"
1873
1917
  {
1874
1918
  int _klen;
1875
1919
  int _trans = 0;
@@ -1950,27 +1994,27 @@ case 1:
1950
1994
  switch ( _JSON_object_actions[_acts++] )
1951
1995
  {
1952
1996
  case 0:
1953
- // line 689 "Parser.rl"
1997
+ // line 729 "Parser.rl"
1954
1998
  {
1955
- ParserResult res = parseValue(p, pe);
1956
- if (res == null) {
1999
+ parseValue(res, p, pe);
2000
+ if (res.result == null) {
1957
2001
  p--;
1958
2002
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1959
2003
  } else {
1960
- if (!parser.objectClass.getName().equals("Hash")) {
1961
- result.callMethod(context, "[]=", new IRubyObject[] { lastName, res.result });
2004
+ if (parser.objectClass == getRuntime().getHash()) {
2005
+ ((RubyHash)result).op_aset(context, lastName, res.result);
1962
2006
  } else {
1963
- result.op_aset(context, lastName, res.result);
2007
+ result.callMethod(context, "[]=", new IRubyObject[] { lastName, res.result });
1964
2008
  }
1965
2009
  {p = (( res.p))-1;}
1966
2010
  }
1967
2011
  }
1968
2012
  break;
1969
2013
  case 1:
1970
- // line 704 "Parser.rl"
2014
+ // line 744 "Parser.rl"
1971
2015
  {
1972
- ParserResult res = parseString(p, pe);
1973
- if (res == null) {
2016
+ parseString(res, p, pe);
2017
+ if (res.result == null) {
1974
2018
  p--;
1975
2019
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1976
2020
  } else {
@@ -1987,13 +2031,13 @@ case 1:
1987
2031
  }
1988
2032
  break;
1989
2033
  case 2:
1990
- // line 722 "Parser.rl"
2034
+ // line 762 "Parser.rl"
1991
2035
  {
1992
2036
  p--;
1993
2037
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1994
2038
  }
1995
2039
  break;
1996
- // line 1997 "Parser.java"
2040
+ // line 2043 "Parser.java"
1997
2041
  }
1998
2042
  }
1999
2043
  }
@@ -2013,17 +2057,24 @@ case 5:
2013
2057
  break; }
2014
2058
  }
2015
2059
 
2016
- // line 753 "Parser.rl"
2060
+ // line 799 "Parser.rl"
2017
2061
 
2018
2062
  if (cs < JSON_object_first_final) {
2019
- return null;
2063
+ res.update(null, p + 1);
2064
+ return;
2020
2065
  }
2021
2066
 
2022
2067
  IRubyObject returnedResult = result;
2023
2068
 
2024
2069
  // attempt to de-serialize object
2025
2070
  if (parser.createAdditions) {
2026
- IRubyObject vKlassName = result.op_aref(context, parser.createId);
2071
+ IRubyObject vKlassName;
2072
+ if (objectDefault) {
2073
+ vKlassName = ((RubyHash)result).op_aref(context, parser.createId);
2074
+ } else {
2075
+ vKlassName = result.callMethod(context, "[]", parser.createId);
2076
+ }
2077
+
2027
2078
  if (!vKlassName.isNil()) {
2028
2079
  // might throw ArgumentError, we let it propagate
2029
2080
  IRubyObject klass = parser.info.jsonModule.get().
@@ -2035,11 +2086,11 @@ case 5:
2035
2086
  }
2036
2087
  }
2037
2088
  }
2038
- return new ParserResult(returnedResult, p + 1);
2089
+ res.update(returnedResult, p + 1);
2039
2090
  }
2040
2091
 
2041
2092
 
2042
- // line 2043 "Parser.java"
2093
+ // line 2096 "Parser.java"
2043
2094
  private static byte[] init__JSON_actions_0()
2044
2095
  {
2045
2096
  return new byte [] {
@@ -2143,25 +2194,26 @@ static final int JSON_error = 0;
2143
2194
  static final int JSON_en_main = 1;
2144
2195
 
2145
2196
 
2146
- // line 811 "Parser.rl"
2197
+ // line 864 "Parser.rl"
2147
2198
 
2148
2199
 
2149
2200
  public IRubyObject parseStrict() {
2150
2201
  int cs = EVIL;
2151
2202
  int p, pe;
2152
2203
  IRubyObject result = null;
2204
+ ParserResult res = new ParserResult();
2153
2205
 
2154
2206
 
2155
- // line 2156 "Parser.java"
2207
+ // line 2210 "Parser.java"
2156
2208
  {
2157
2209
  cs = JSON_start;
2158
2210
  }
2159
2211
 
2160
- // line 819 "Parser.rl"
2212
+ // line 873 "Parser.rl"
2161
2213
  p = byteList.begin();
2162
2214
  pe = p + byteList.length();
2163
2215
 
2164
- // line 2165 "Parser.java"
2216
+ // line 2219 "Parser.java"
2165
2217
  {
2166
2218
  int _klen;
2167
2219
  int _trans = 0;
@@ -2242,11 +2294,11 @@ case 1:
2242
2294
  switch ( _JSON_actions[_acts++] )
2243
2295
  {
2244
2296
  case 0:
2245
- // line 783 "Parser.rl"
2297
+ // line 836 "Parser.rl"
2246
2298
  {
2247
2299
  currentNesting = 1;
2248
- ParserResult res = parseObject(p, pe);
2249
- if (res == null) {
2300
+ parseObject(res, p, pe);
2301
+ if (res.result == null) {
2250
2302
  p--;
2251
2303
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
2252
2304
  } else {
@@ -2256,11 +2308,11 @@ case 1:
2256
2308
  }
2257
2309
  break;
2258
2310
  case 1:
2259
- // line 795 "Parser.rl"
2311
+ // line 848 "Parser.rl"
2260
2312
  {
2261
2313
  currentNesting = 1;
2262
- ParserResult res = parseArray(p, pe);
2263
- if (res == null) {
2314
+ parseArray(res, p, pe);
2315
+ if (res.result == null) {
2264
2316
  p--;
2265
2317
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
2266
2318
  } else {
@@ -2269,7 +2321,7 @@ case 1:
2269
2321
  }
2270
2322
  }
2271
2323
  break;
2272
- // line 2273 "Parser.java"
2324
+ // line 2327 "Parser.java"
2273
2325
  }
2274
2326
  }
2275
2327
  }
@@ -2289,7 +2341,7 @@ case 5:
2289
2341
  break; }
2290
2342
  }
2291
2343
 
2292
- // line 822 "Parser.rl"
2344
+ // line 876 "Parser.rl"
2293
2345
 
2294
2346
  if (cs >= JSON_first_final && p == pe) {
2295
2347
  return result;
@@ -2299,7 +2351,7 @@ case 5:
2299
2351
  }
2300
2352
 
2301
2353
 
2302
- // line 2303 "Parser.java"
2354
+ // line 2357 "Parser.java"
2303
2355
  private static byte[] init__JSON_quirks_mode_actions_0()
2304
2356
  {
2305
2357
  return new byte [] {
@@ -2402,25 +2454,26 @@ static final int JSON_quirks_mode_error = 0;
2402
2454
  static final int JSON_quirks_mode_en_main = 1;
2403
2455
 
2404
2456
 
2405
- // line 850 "Parser.rl"
2457
+ // line 904 "Parser.rl"
2406
2458
 
2407
2459
 
2408
2460
  public IRubyObject parseQuirksMode() {
2409
2461
  int cs = EVIL;
2410
2462
  int p, pe;
2411
2463
  IRubyObject result = null;
2464
+ ParserResult res = new ParserResult();
2412
2465
 
2413
2466
 
2414
- // line 2415 "Parser.java"
2467
+ // line 2470 "Parser.java"
2415
2468
  {
2416
2469
  cs = JSON_quirks_mode_start;
2417
2470
  }
2418
2471
 
2419
- // line 858 "Parser.rl"
2472
+ // line 913 "Parser.rl"
2420
2473
  p = byteList.begin();
2421
2474
  pe = p + byteList.length();
2422
2475
 
2423
- // line 2424 "Parser.java"
2476
+ // line 2479 "Parser.java"
2424
2477
  {
2425
2478
  int _klen;
2426
2479
  int _trans = 0;
@@ -2501,10 +2554,10 @@ case 1:
2501
2554
  switch ( _JSON_quirks_mode_actions[_acts++] )
2502
2555
  {
2503
2556
  case 0:
2504
- // line 836 "Parser.rl"
2557
+ // line 890 "Parser.rl"
2505
2558
  {
2506
- ParserResult res = parseValue(p, pe);
2507
- if (res == null) {
2559
+ parseValue(res, p, pe);
2560
+ if (res.result == null) {
2508
2561
  p--;
2509
2562
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
2510
2563
  } else {
@@ -2513,7 +2566,7 @@ case 1:
2513
2566
  }
2514
2567
  }
2515
2568
  break;
2516
- // line 2517 "Parser.java"
2569
+ // line 2572 "Parser.java"
2517
2570
  }
2518
2571
  }
2519
2572
  }
@@ -2533,7 +2586,7 @@ case 5:
2533
2586
  break; }
2534
2587
  }
2535
2588
 
2536
- // line 861 "Parser.rl"
2589
+ // line 916 "Parser.rl"
2537
2590
 
2538
2591
  if (cs >= JSON_quirks_mode_first_final && p == pe) {
2539
2592
  return result;
@@ -2552,16 +2605,14 @@ case 5:
2552
2605
  }
2553
2606
 
2554
2607
  /**
2555
- * Returns a subsequence of the source ByteList, based on source
2556
- * array byte offsets (i.e., the ByteList's own begin offset is not
2557
- * automatically added).
2608
+ * Updates the "view" bytelist with the new offsets and returns it.
2558
2609
  * @param start
2559
2610
  * @param end
2560
2611
  */
2561
2612
  private ByteList absSubSequence(int absStart, int absEnd) {
2562
- int offset = byteList.begin();
2563
- return (ByteList)byteList.subSequence(absStart - offset,
2564
- absEnd - offset);
2613
+ view.setBegin(absStart);
2614
+ view.setRealSize(absEnd - absStart);
2615
+ return view;
2565
2616
  }
2566
2617
 
2567
2618
  /**