oj 3.13.17 → 3.13.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/ext/oj/custom.c +7 -7
- data/ext/oj/dump.c +2 -2
- data/ext/oj/dump_compat.c +5 -5
- data/ext/oj/dump_object.c +3 -3
- data/ext/oj/dump_strict.c +5 -5
- data/ext/oj/extconf.rb +1 -1
- data/ext/oj/oj.c +1 -0
- data/ext/oj/parse.c +57 -66
- data/ext/oj/parse.h +2 -0
- data/ext/oj/rails.c +5 -5
- data/ext/oj/saj2.c +3 -3
- data/ext/oj/wab.c +2 -2
- data/lib/oj/version.rb +1 -1
- data/test/helper.rb +8 -2
- data/test/json_gem/json_parser_test.rb +2 -0
- data/test/json_gem/test_helper.rb +7 -3
- data/test/test_custom.rb +12 -0
- data/test/test_file.rb +7 -2
- data/test/test_gc.rb +13 -0
- data/test/test_integer_range.rb +6 -0
- data/test/test_object.rb +39 -1
- data/test/test_parser_saj.rb +11 -0
- data/test/test_scp.rb +4 -4
- data/test/test_strict.rb +2 -0
- data/test/test_wab.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 958a558e09c25d5de9548af67dff6586686def4a9073b3cee6ba8403930eda48
|
4
|
+
data.tar.gz: 2f928e9e849ca695d03ad9a396ec7f2df3508b99d10baa11a8cb538a7b3a0e52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 758bb300ed853d161750d100a8fbdd755e37ae8e15ae94f1e7a4cbd613c787002758d4fc5834fd47a7ef8fb78446208f896afee31c0bc023bcdeb381aba1f98c
|
7
|
+
data.tar.gz: 54127873544ca146a61d7ca4012ff9d2eb4b83bdcbb3f06eea092d4e4ad517c453196a59edc2743b42736ab276e0eb96889045e0d3f2200dcbaf4a2b79353db3
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 3.13.20 - 2022-08-07
|
4
|
+
|
5
|
+
- SSE4 made optional with a `--with-sse42` flag to the compile.
|
6
|
+
|
7
|
+
## 3.13.19 - 2022-07-29
|
8
|
+
|
9
|
+
- TruffleRuby issues resolved.
|
10
|
+
|
11
|
+
## 3.13.18 - 2022-07-25
|
12
|
+
|
13
|
+
- Fixed SSE detection at run time.
|
14
|
+
|
3
15
|
## 3.13.17 - 2022-07-15
|
4
16
|
|
5
17
|
- Fixed Oj::Parser to detect unterminated arrays and objects.
|
data/ext/oj/custom.c
CHANGED
@@ -484,7 +484,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
484
484
|
const char * s;
|
485
485
|
int len;
|
486
486
|
|
487
|
-
if (Yes == out->opts->trace) {
|
487
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
488
488
|
oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
489
489
|
}
|
490
490
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
@@ -492,7 +492,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
492
492
|
} else {
|
493
493
|
rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
|
494
494
|
}
|
495
|
-
if (Yes == out->opts->trace) {
|
495
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
496
496
|
oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
497
497
|
}
|
498
498
|
s = RSTRING_PTR(rs);
|
@@ -504,7 +504,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
504
504
|
} else if (Yes == out->opts->as_json && rb_respond_to(obj, oj_as_json_id)) {
|
505
505
|
volatile VALUE aj;
|
506
506
|
|
507
|
-
if (Yes == out->opts->trace) {
|
507
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
508
508
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
509
509
|
}
|
510
510
|
// Some classes elect to not take an options argument so check the arity
|
@@ -514,7 +514,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
514
514
|
} else {
|
515
515
|
aj = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
516
516
|
}
|
517
|
-
if (Yes == out->opts->trace) {
|
517
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
518
518
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
519
519
|
}
|
520
520
|
// Catch the obvious brain damaged recursive dumping.
|
@@ -885,7 +885,7 @@ static DumpFunc custom_funcs[] = {
|
|
885
885
|
void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
886
886
|
int type = rb_type(obj);
|
887
887
|
|
888
|
-
if (Yes == out->opts->trace) {
|
888
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
889
889
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
890
890
|
}
|
891
891
|
if (MAX_DEPTH < depth) {
|
@@ -896,14 +896,14 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
896
896
|
|
897
897
|
if (NULL != f) {
|
898
898
|
f(obj, depth, out, true);
|
899
|
-
if (Yes == out->opts->trace) {
|
899
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
900
900
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
901
901
|
}
|
902
902
|
return;
|
903
903
|
}
|
904
904
|
}
|
905
905
|
oj_dump_nil(Qnil, depth, out, false);
|
906
|
-
if (Yes == out->opts->trace) {
|
906
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
907
907
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
908
908
|
}
|
909
909
|
}
|
data/ext/oj/dump.c
CHANGED
@@ -736,11 +736,11 @@ void oj_dump_raw_json(VALUE obj, int depth, Out out) {
|
|
736
736
|
} else {
|
737
737
|
volatile VALUE jv;
|
738
738
|
|
739
|
-
if (Yes == out->opts->trace) {
|
739
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
740
740
|
oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
741
741
|
}
|
742
742
|
jv = rb_funcall(obj, oj_raw_json_id, 2, RB_INT2NUM(depth), RB_INT2NUM(out->indent));
|
743
|
-
if (Yes == out->opts->trace) {
|
743
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
744
744
|
oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
745
745
|
}
|
746
746
|
oj_dump_raw(RSTRING_PTR(jv), (size_t)RSTRING_LEN(jv), out);
|
data/ext/oj/dump_compat.c
CHANGED
@@ -109,7 +109,7 @@ dump_to_json(VALUE obj, Out out) {
|
|
109
109
|
const char *s;
|
110
110
|
int len;
|
111
111
|
|
112
|
-
if (Yes == out->opts->trace) {
|
112
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
113
113
|
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyIn);
|
114
114
|
}
|
115
115
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
@@ -117,7 +117,7 @@ dump_to_json(VALUE obj, Out out) {
|
|
117
117
|
} else {
|
118
118
|
rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
|
119
119
|
}
|
120
|
-
if (Yes == out->opts->trace) {
|
120
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
121
121
|
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyOut);
|
122
122
|
}
|
123
123
|
|
@@ -893,7 +893,7 @@ void
|
|
893
893
|
oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
|
894
894
|
int type = rb_type(obj);
|
895
895
|
|
896
|
-
if (Yes == out->opts->trace) {
|
896
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
897
897
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
898
898
|
}
|
899
899
|
if (out->opts->dump_opts.max_depth <= depth) {
|
@@ -918,14 +918,14 @@ oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
918
918
|
|
919
919
|
if (NULL != f) {
|
920
920
|
f(obj, depth, out, as_ok);
|
921
|
-
if (Yes == out->opts->trace) {
|
921
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
922
922
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
923
923
|
}
|
924
924
|
return;
|
925
925
|
}
|
926
926
|
}
|
927
927
|
oj_dump_nil(Qnil, depth, out, false);
|
928
|
-
if (Yes == out->opts->trace) {
|
928
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
929
929
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
930
930
|
}
|
931
931
|
}
|
data/ext/oj/dump_object.c
CHANGED
@@ -682,7 +682,7 @@ static DumpFunc obj_funcs[] = {
|
|
682
682
|
void oj_dump_obj_val(VALUE obj, int depth, Out out) {
|
683
683
|
int type = rb_type(obj);
|
684
684
|
|
685
|
-
if (Yes == out->opts->trace) {
|
685
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
686
686
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
687
687
|
}
|
688
688
|
if (MAX_DEPTH < depth) {
|
@@ -693,14 +693,14 @@ void oj_dump_obj_val(VALUE obj, int depth, Out out) {
|
|
693
693
|
|
694
694
|
if (NULL != f) {
|
695
695
|
f(obj, depth, out, false);
|
696
|
-
if (Yes == out->opts->trace) {
|
696
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
697
697
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
698
698
|
}
|
699
699
|
return;
|
700
700
|
}
|
701
701
|
}
|
702
702
|
oj_dump_nil(Qnil, depth, out, false);
|
703
|
-
if (Yes == out->opts->trace) {
|
703
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
704
704
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
705
705
|
}
|
706
706
|
}
|
data/ext/oj/dump_strict.c
CHANGED
@@ -338,7 +338,7 @@ static DumpFunc strict_funcs[] = {
|
|
338
338
|
void oj_dump_strict_val(VALUE obj, int depth, Out out) {
|
339
339
|
int type = rb_type(obj);
|
340
340
|
|
341
|
-
if (Yes == out->opts->trace) {
|
341
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
342
342
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
343
343
|
}
|
344
344
|
if (MAX_DEPTH < depth) {
|
@@ -349,7 +349,7 @@ void oj_dump_strict_val(VALUE obj, int depth, Out out) {
|
|
349
349
|
|
350
350
|
if (NULL != f) {
|
351
351
|
f(obj, depth, out, false);
|
352
|
-
if (Yes == out->opts->trace) {
|
352
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
353
353
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
354
354
|
}
|
355
355
|
return;
|
@@ -386,7 +386,7 @@ static DumpFunc null_funcs[] = {
|
|
386
386
|
void oj_dump_null_val(VALUE obj, int depth, Out out) {
|
387
387
|
int type = rb_type(obj);
|
388
388
|
|
389
|
-
if (Yes == out->opts->trace) {
|
389
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
390
390
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
391
391
|
}
|
392
392
|
if (MAX_DEPTH < depth) {
|
@@ -397,14 +397,14 @@ void oj_dump_null_val(VALUE obj, int depth, Out out) {
|
|
397
397
|
|
398
398
|
if (NULL != f) {
|
399
399
|
f(obj, depth, out, false);
|
400
|
-
if (Yes == out->opts->trace) {
|
400
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
401
401
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
402
402
|
}
|
403
403
|
return;
|
404
404
|
}
|
405
405
|
}
|
406
406
|
oj_dump_nil(Qnil, depth, out, false);
|
407
|
-
if (Yes == out->opts->trace) {
|
407
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
408
408
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
409
409
|
}
|
410
410
|
}
|
data/ext/oj/extconf.rb
CHANGED
@@ -34,7 +34,7 @@ have_func('rb_hash_bulk_insert', 'ruby.h') unless '2' == version[0] && '6' == ve
|
|
34
34
|
|
35
35
|
dflags['OJ_DEBUG'] = true unless ENV['OJ_DEBUG'].nil?
|
36
36
|
|
37
|
-
if
|
37
|
+
if with_config('--with-sse42')
|
38
38
|
$CPPFLAGS += ' -msse4.2'
|
39
39
|
dflags['OJ_USE_SSE4_2'] = 1
|
40
40
|
end
|
data/ext/oj/oj.c
CHANGED
data/ext/oj/parse.c
CHANGED
@@ -192,9 +192,7 @@ static inline const char *scan_string_noSIMD(const char *str, const char *end) {
|
|
192
192
|
return str;
|
193
193
|
}
|
194
194
|
|
195
|
-
#
|
196
|
-
#include <nmmintrin.h>
|
197
|
-
|
195
|
+
#ifdef OJ_USE_SSE4_2
|
198
196
|
static inline const char *scan_string_SIMD(const char *str, const char *end) {
|
199
197
|
static const char chars[16] = "\x00\\\"";
|
200
198
|
const __m128i terminate = _mm_loadu_si128((const __m128i *)&chars[0]);
|
@@ -213,6 +211,14 @@ static inline const char *scan_string_SIMD(const char *str, const char *end) {
|
|
213
211
|
}
|
214
212
|
#endif
|
215
213
|
|
214
|
+
static const char *(*scan_func) (const char *str, const char *end) = scan_string_noSIMD;
|
215
|
+
|
216
|
+
void oj_scanner_init(void) {
|
217
|
+
#ifdef OJ_USE_SSE4_2
|
218
|
+
scan_func = scan_string_SIMD;
|
219
|
+
#endif
|
220
|
+
}
|
221
|
+
|
216
222
|
// entered at /
|
217
223
|
static void read_escaped_str(ParseInfo pi, const char *start) {
|
218
224
|
struct _buf buf;
|
@@ -225,11 +231,7 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
225
231
|
buf_append_string(&buf, start, cnt);
|
226
232
|
|
227
233
|
for (s = pi->cur; '"' != *s;) {
|
228
|
-
|
229
|
-
const char *scanned = scan_string_SIMD(s, pi->end);
|
230
|
-
#else
|
231
|
-
const char *scanned = scan_string_noSIMD(s, pi->end);
|
232
|
-
#endif
|
234
|
+
const char *scanned = scan_func(s, pi->end);
|
233
235
|
if (scanned >= pi->end) {
|
234
236
|
oj_set_error_at(pi,
|
235
237
|
oj_parse_error_class,
|
@@ -369,11 +371,7 @@ static void read_str(ParseInfo pi) {
|
|
369
371
|
const char *str = pi->cur;
|
370
372
|
Val parent = stack_peek(&pi->stack);
|
371
373
|
|
372
|
-
|
373
|
-
pi->cur = scan_string_SIMD(pi->cur, pi->end);
|
374
|
-
#else
|
375
|
-
pi->cur = scan_string_noSIMD(pi->cur, pi->end);
|
376
|
-
#endif
|
374
|
+
pi->cur = scan_func(pi->cur, pi->end);
|
377
375
|
if (RB_UNLIKELY(pi->end <= pi->cur)) {
|
378
376
|
oj_set_error_at(pi,
|
379
377
|
oj_parse_error_class,
|
@@ -503,33 +501,31 @@ static void read_num(ParseInfo pi) {
|
|
503
501
|
int dec_cnt = 0;
|
504
502
|
bool zero1 = false;
|
505
503
|
|
504
|
+
// Skip leading zeros.
|
505
|
+
for (; '0' == *pi->cur; pi->cur++) {
|
506
|
+
zero1 = true;
|
507
|
+
}
|
508
|
+
|
506
509
|
for (; '0' <= *pi->cur && *pi->cur <= '9'; pi->cur++) {
|
507
|
-
|
508
|
-
zero1 = true;
|
509
|
-
}
|
510
|
-
if (0 < ni.i) {
|
511
|
-
dec_cnt++;
|
512
|
-
}
|
513
|
-
if (!ni.big) {
|
514
|
-
int d = (*pi->cur - '0');
|
510
|
+
int d = (*pi->cur - '0');
|
515
511
|
|
516
|
-
|
517
|
-
|
518
|
-
oj_set_error_at(pi,
|
519
|
-
oj_parse_error_class,
|
520
|
-
__FILE__,
|
521
|
-
__LINE__,
|
522
|
-
"not a number");
|
523
|
-
return;
|
524
|
-
}
|
525
|
-
zero1 = false;
|
526
|
-
}
|
527
|
-
ni.i = ni.i * 10 + d;
|
528
|
-
if (INT64_MAX <= ni.i || DEC_MAX < dec_cnt) {
|
529
|
-
ni.big = 1;
|
530
|
-
}
|
512
|
+
if (RB_LIKELY(0 != ni.i)) {
|
513
|
+
dec_cnt++;
|
531
514
|
}
|
515
|
+
ni.i = ni.i * 10 + d;
|
516
|
+
}
|
517
|
+
if (RB_UNLIKELY(0 != ni.i && zero1 && CompatMode == pi->options.mode)) {
|
518
|
+
oj_set_error_at(pi,
|
519
|
+
oj_parse_error_class,
|
520
|
+
__FILE__,
|
521
|
+
__LINE__,
|
522
|
+
"not a number");
|
523
|
+
return;
|
524
|
+
}
|
525
|
+
if (INT64_MAX <= ni.i || DEC_MAX < dec_cnt) {
|
526
|
+
ni.big = true;
|
532
527
|
}
|
528
|
+
|
533
529
|
if ('.' == *pi->cur) {
|
534
530
|
pi->cur++;
|
535
531
|
// A trailing . is not a valid decimal but if encountered allow it
|
@@ -549,25 +545,20 @@ static void read_num(ParseInfo pi) {
|
|
549
545
|
for (; '0' <= *pi->cur && *pi->cur <= '9'; pi->cur++) {
|
550
546
|
int d = (*pi->cur - '0');
|
551
547
|
|
552
|
-
if (0
|
548
|
+
if (RB_LIKELY(0 != ni.num || 0 != ni.i)) {
|
553
549
|
dec_cnt++;
|
554
550
|
}
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
|
564
|
-
if (!ni.no_big) {
|
565
|
-
ni.big = true;
|
566
|
-
}
|
567
|
-
}
|
568
|
-
}
|
551
|
+
ni.num = ni.num * 10 + d;
|
552
|
+
ni.div *= 10;
|
553
|
+
ni.di++;
|
554
|
+
}
|
555
|
+
}
|
556
|
+
if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
|
557
|
+
if (!ni.no_big) {
|
558
|
+
ni.big = true;
|
569
559
|
}
|
570
560
|
}
|
561
|
+
|
571
562
|
if ('e' == *pi->cur || 'E' == *pi->cur) {
|
572
563
|
int eneg = 0;
|
573
564
|
|
@@ -640,7 +631,7 @@ static void read_num(ParseInfo pi) {
|
|
640
631
|
}
|
641
632
|
|
642
633
|
static void array_start(ParseInfo pi) {
|
643
|
-
|
634
|
+
VALUE v = pi->start_array(pi);
|
644
635
|
|
645
636
|
stack_push(&pi->stack, v, NEXT_ARRAY_NEW);
|
646
637
|
}
|
@@ -664,13 +655,13 @@ static void array_end(ParseInfo pi) {
|
|
664
655
|
}
|
665
656
|
|
666
657
|
static void hash_start(ParseInfo pi) {
|
667
|
-
|
658
|
+
VALUE v = pi->start_hash(pi);
|
668
659
|
|
669
660
|
stack_push(&pi->stack, v, NEXT_HASH_NEW);
|
670
661
|
}
|
671
662
|
|
672
663
|
static void hash_end(ParseInfo pi) {
|
673
|
-
|
664
|
+
Val hash = stack_peek(&pi->stack);
|
674
665
|
|
675
666
|
// leave hash on stack until just before
|
676
667
|
if (0 == hash) {
|
@@ -857,7 +848,7 @@ static long double exp_plus[] = {
|
|
857
848
|
|
858
849
|
VALUE
|
859
850
|
oj_num_as_value(NumInfo ni) {
|
860
|
-
|
851
|
+
VALUE rnum = Qnil;
|
861
852
|
|
862
853
|
if (ni->infinity) {
|
863
854
|
if (ni->neg) {
|
@@ -892,7 +883,7 @@ oj_num_as_value(NumInfo ni) {
|
|
892
883
|
}
|
893
884
|
} else { // decimal
|
894
885
|
if (ni->big) {
|
895
|
-
|
886
|
+
VALUE bd = rb_str_new(ni->str, ni->len);
|
896
887
|
|
897
888
|
rnum = rb_rescue2(parse_big_decimal, bd, rescue_big_decimal, bd, rb_eException, 0);
|
898
889
|
if (ni->no_big) {
|
@@ -920,7 +911,7 @@ oj_num_as_value(NumInfo ni) {
|
|
920
911
|
}
|
921
912
|
rnum = rb_float_new((double)ld);
|
922
913
|
} else if (RubyDec == ni->bigdec_load) {
|
923
|
-
|
914
|
+
VALUE sv = rb_str_new(ni->str, ni->len);
|
924
915
|
|
925
916
|
rnum = rb_funcall(sv, rb_intern("to_f"), 0);
|
926
917
|
} else {
|
@@ -1015,7 +1006,7 @@ static VALUE protect_parse(VALUE pip) {
|
|
1015
1006
|
|
1016
1007
|
extern int oj_utf8_index;
|
1017
1008
|
|
1018
|
-
static void oj_pi_set_input_str(ParseInfo pi,
|
1009
|
+
static void oj_pi_set_input_str(ParseInfo pi, VALUE *inputp) {
|
1019
1010
|
int idx = RB_ENCODING_GET(*inputp);
|
1020
1011
|
|
1021
1012
|
if (oj_utf8_encoding_index != idx) {
|
@@ -1028,12 +1019,12 @@ static void oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) {
|
|
1028
1019
|
|
1029
1020
|
VALUE
|
1030
1021
|
oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yieldOk) {
|
1031
|
-
char *
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
int
|
1036
|
-
int
|
1022
|
+
char * buf = 0;
|
1023
|
+
VALUE input;
|
1024
|
+
VALUE wrapped_stack;
|
1025
|
+
VALUE result = Qnil;
|
1026
|
+
int line = 0;
|
1027
|
+
int free_json = 0;
|
1037
1028
|
|
1038
1029
|
if (argc < 1) {
|
1039
1030
|
rb_raise(rb_eArgError, "Wrong number of arguments to parse.");
|
@@ -1069,8 +1060,8 @@ oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yie
|
|
1069
1060
|
rb_raise(rb_eTypeError, "Nil is not a valid JSON source.");
|
1070
1061
|
}
|
1071
1062
|
} else {
|
1072
|
-
VALUE
|
1073
|
-
|
1063
|
+
VALUE clas = rb_obj_class(input);
|
1064
|
+
VALUE s;
|
1074
1065
|
|
1075
1066
|
if (oj_stringio_class == clas) {
|
1076
1067
|
s = rb_funcall2(input, oj_string_id, 0, 0);
|
data/ext/oj/parse.h
CHANGED
data/ext/oj/rails.c
CHANGED
@@ -517,7 +517,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
|
517
517
|
static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
518
518
|
volatile VALUE ja;
|
519
519
|
|
520
|
-
if (Yes == out->opts->trace) {
|
520
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
521
521
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
522
522
|
}
|
523
523
|
// Some classes elect to not take an options argument so check the arity
|
@@ -527,7 +527,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
|
527
527
|
} else {
|
528
528
|
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
529
529
|
}
|
530
|
-
if (Yes == out->opts->trace) {
|
530
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
531
531
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
532
532
|
}
|
533
533
|
|
@@ -1464,7 +1464,7 @@ static DumpFunc rails_funcs[] = {
|
|
1464
1464
|
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1465
1465
|
int type = rb_type(obj);
|
1466
1466
|
|
1467
|
-
if (Yes == out->opts->trace) {
|
1467
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1468
1468
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
1469
1469
|
}
|
1470
1470
|
if (MAX_DEPTH < depth) {
|
@@ -1475,14 +1475,14 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1475
1475
|
|
1476
1476
|
if (NULL != f) {
|
1477
1477
|
f(obj, depth, out, as_ok);
|
1478
|
-
if (Yes == out->opts->trace) {
|
1478
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1479
1479
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
1480
1480
|
}
|
1481
1481
|
return;
|
1482
1482
|
}
|
1483
1483
|
}
|
1484
1484
|
oj_dump_nil(Qnil, depth, out, false);
|
1485
|
-
if (Yes == out->opts->trace) {
|
1485
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1486
1486
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
1487
1487
|
}
|
1488
1488
|
}
|
data/ext/oj/saj2.c
CHANGED
@@ -289,7 +289,7 @@ static void add_float_key_loc(ojParser p) {
|
|
289
289
|
}
|
290
290
|
|
291
291
|
static void add_big(ojParser p) {
|
292
|
-
rb_funcall((
|
292
|
+
rb_funcall(((Delegate)p->ctx)->handler,
|
293
293
|
oj_add_value_id,
|
294
294
|
2,
|
295
295
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
@@ -297,7 +297,7 @@ static void add_big(ojParser p) {
|
|
297
297
|
}
|
298
298
|
|
299
299
|
static void add_big_loc(ojParser p) {
|
300
|
-
rb_funcall((
|
300
|
+
rb_funcall(((Delegate)p->ctx)->handler,
|
301
301
|
oj_add_value_id,
|
302
302
|
4,
|
303
303
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
@@ -307,7 +307,7 @@ static void add_big_loc(ojParser p) {
|
|
307
307
|
}
|
308
308
|
|
309
309
|
static void add_big_key(ojParser p) {
|
310
|
-
rb_funcall((
|
310
|
+
rb_funcall(((Delegate)p->ctx)->handler,
|
311
311
|
oj_add_value_id,
|
312
312
|
2,
|
313
313
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
data/ext/oj/wab.c
CHANGED
@@ -266,7 +266,7 @@ static DumpFunc wab_funcs[] = {
|
|
266
266
|
void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
267
267
|
int type = rb_type(obj);
|
268
268
|
|
269
|
-
if (Yes == out->opts->trace) {
|
269
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
270
270
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
271
271
|
}
|
272
272
|
if (MAX_DEPTH < depth) {
|
@@ -277,7 +277,7 @@ void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
|
277
277
|
|
278
278
|
if (NULL != f) {
|
279
279
|
f(obj, depth, out, false);
|
280
|
-
if (Yes == out->opts->trace) {
|
280
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
281
281
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
282
282
|
}
|
283
283
|
return;
|
data/lib/oj/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -19,10 +19,16 @@ require 'pp'
|
|
19
19
|
require 'oj'
|
20
20
|
|
21
21
|
|
22
|
-
|
22
|
+
def verify_gc_compaction
|
23
23
|
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
24
24
|
# move objects around, helping to find object movement bugs.
|
25
|
-
GC.verify_compaction_references(
|
25
|
+
if defined?(GC.verify_compaction_references) == 'method' && !(RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/)
|
26
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.2.0")
|
27
|
+
GC.verify_compaction_references(expand_heap: true, toward: :empty)
|
28
|
+
else
|
29
|
+
GC.verify_compaction_references(double_heap: true, toward: :empty)
|
30
|
+
end
|
31
|
+
end
|
26
32
|
end
|
27
33
|
|
28
34
|
|
@@ -24,6 +24,8 @@ class JSONParserTest < Test::Unit::TestCase
|
|
24
24
|
end if defined?(Encoding::UTF_16)
|
25
25
|
|
26
26
|
def test_error_message_encoding
|
27
|
+
omit 'TruffleRuby causes NameError(<uninitialized constant JSON::Ext>)' if RUBY_ENGINE == 'truffleruby'
|
28
|
+
|
27
29
|
bug10705 = '[ruby-core:67386] [Bug #10705]'
|
28
30
|
json = ".\"\xE2\x88\x9A\"".force_encoding(Encoding::UTF_8)
|
29
31
|
e = assert_raise(JSON::ParserError) {
|
@@ -15,10 +15,14 @@ else
|
|
15
15
|
require 'oj'
|
16
16
|
Oj.mimic_JSON
|
17
17
|
|
18
|
+
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
19
|
+
# move objects around, helping to find object movement bugs.
|
18
20
|
if defined?(GC.verify_compaction_references) == 'method'
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.2.0")
|
22
|
+
GC.verify_compaction_references(expand_heap: true, toward: :empty)
|
23
|
+
else
|
24
|
+
GC.verify_compaction_references(double_heap: true, toward: :empty)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
data/test/test_custom.rb
CHANGED
@@ -200,6 +200,8 @@ class CustomJuice < Minitest::Test
|
|
200
200
|
end
|
201
201
|
|
202
202
|
def test_deep_nest
|
203
|
+
skip 'TruffleRuby causes SEGV' if RUBY_ENGINE == 'truffleruby'
|
204
|
+
|
203
205
|
begin
|
204
206
|
n = 10000
|
205
207
|
Oj.strict_load('[' * n + ']' * n)
|
@@ -258,6 +260,8 @@ class CustomJuice < Minitest::Test
|
|
258
260
|
end
|
259
261
|
|
260
262
|
def test_object
|
263
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
264
|
+
|
261
265
|
obj = Jeez.new(true, 58)
|
262
266
|
json = Oj.dump(obj, create_id: "^o", use_to_json: false, use_as_json: false, use_to_hash: false)
|
263
267
|
assert_equal(%|{"x":true,"y":58,"_z":"true"}|, json)
|
@@ -403,11 +407,15 @@ class CustomJuice < Minitest::Test
|
|
403
407
|
end
|
404
408
|
|
405
409
|
def test_range
|
410
|
+
skip 'TruffleRuby fails this spec' if RUBY_ENGINE == 'truffleruby'
|
411
|
+
|
406
412
|
obj = 3..8
|
407
413
|
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
408
414
|
end
|
409
415
|
|
410
416
|
def test_date
|
417
|
+
skip 'TruffleRuby causes SEGV' if RUBY_ENGINE == 'truffleruby'
|
418
|
+
|
411
419
|
obj = Date.new(2017, 1, 5)
|
412
420
|
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
413
421
|
end
|
@@ -437,6 +445,8 @@ class CustomJuice < Minitest::Test
|
|
437
445
|
end
|
438
446
|
|
439
447
|
def test_datetime
|
448
|
+
skip 'TruffleRuby causes SEGV' if RUBY_ENGINE == 'truffleruby'
|
449
|
+
|
440
450
|
obj = DateTime.new(2017, 1, 5, 10, 20, 30)
|
441
451
|
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
442
452
|
end
|
@@ -480,6 +490,8 @@ class CustomJuice < Minitest::Test
|
|
480
490
|
end
|
481
491
|
|
482
492
|
def test_time
|
493
|
+
skip 'TruffleRuby fails this spec' if RUBY_ENGINE == 'truffleruby'
|
494
|
+
|
483
495
|
obj = Time.now()
|
484
496
|
dump_load_dump(obj, false, :time_format => :unix, :create_id => "^o", :create_additions => true)
|
485
497
|
dump_load_dump(obj, false, :time_format => :unix_zone, :create_id => "^o", :create_additions => true)
|
data/test/test_file.rb
CHANGED
@@ -125,13 +125,16 @@ class FileJuice < Minitest::Test
|
|
125
125
|
|
126
126
|
# Time
|
127
127
|
def test_time_object
|
128
|
+
skip 'TruffleRuby fails this spec' if RUBY_ENGINE == 'truffleruby'
|
129
|
+
|
128
130
|
t = Time.now()
|
129
131
|
Oj.default_options = { :mode => :object, :time_format => :unix_zone }
|
130
132
|
dump_and_load(t, false)
|
131
133
|
end
|
132
134
|
def test_time_object_early
|
133
|
-
|
134
|
-
|
135
|
+
skip 'Windows does not support dates before 1970.' if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
|
136
|
+
skip 'TruffleRuby fails this spec' if RUBY_ENGINE == 'truffleruby'
|
137
|
+
|
135
138
|
t = Time.xmlschema("1954-01-05T00:00:00.123456")
|
136
139
|
Oj.default_options = { :mode => :object, :time_format => :unix_zone }
|
137
140
|
dump_and_load(t, false)
|
@@ -166,6 +169,8 @@ class FileJuice < Minitest::Test
|
|
166
169
|
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
167
170
|
elsif 'jruby' == $ruby
|
168
171
|
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
172
|
+
elsif 'truffleruby' == $ruby
|
173
|
+
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
169
174
|
else
|
170
175
|
assert_equal(%{{"^u":["Range",1,7,false]}}, json)
|
171
176
|
end
|
data/test/test_gc.rb
CHANGED
@@ -26,10 +26,12 @@ class GCTest < Minitest::Test
|
|
26
26
|
|
27
27
|
def setup
|
28
28
|
@default_options = Oj.default_options
|
29
|
+
GC.stress = true
|
29
30
|
end
|
30
31
|
|
31
32
|
def teardown
|
32
33
|
Oj.default_options = @default_options
|
34
|
+
GC.stress = false
|
33
35
|
end
|
34
36
|
|
35
37
|
# if no crash then the GC marking is working
|
@@ -41,9 +43,20 @@ class GCTest < Minitest::Test
|
|
41
43
|
end
|
42
44
|
|
43
45
|
def test_parse_object_gc
|
46
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
47
|
+
|
44
48
|
g = Goo.new(0, nil)
|
45
49
|
100.times { |i| g = Goo.new(i, g) }
|
46
50
|
json = Oj.dump(g, :mode => :object)
|
47
51
|
Oj.object_load(json)
|
48
52
|
end
|
53
|
+
|
54
|
+
def test_parse_gc
|
55
|
+
json = '{"a":"Alpha","b":true,"c":12345,"d":[true,[false,[-123456789,null],3.9676,["Something else.",false],null]],"e":{"zero":null,"one":1,"two":2,"three":[3],"four":[0,1,2,3,4]},"f":null,"h":{"a":{"b":{"c":{"d":{"e":{"f":{"g":null}}}}}}},"i":[[[[[[[null]]]]]]]}'
|
56
|
+
|
57
|
+
50.times do
|
58
|
+
data = Oj.load(json)
|
59
|
+
assert_equal(json, Oj.dump(data))
|
60
|
+
end
|
61
|
+
end
|
49
62
|
end
|
data/test/test_integer_range.rb
CHANGED
@@ -23,18 +23,24 @@ class IntegerRangeTest < Minitest::Test
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_range
|
26
|
+
skip 'TruffleRuby fails this spec with `ArgumentError: :integer_range must be a range of Fixnum.`' if RUBY_ENGINE == 'truffleruby'
|
27
|
+
|
26
28
|
test = {s: 0, s2: -1, s3: 1, u: -2, u2: 2, u3: 9007199254740993}
|
27
29
|
exp = '{"s":0,"s2":-1,"s3":1,"u":"-2","u2":"2","u3":"9007199254740993"}'
|
28
30
|
assert_equal(exp, Oj.dump(test, integer_range: (-1..1)))
|
29
31
|
end
|
30
32
|
|
31
33
|
def test_bignum
|
34
|
+
skip 'TruffleRuby fails this spec with `ArgumentError: :integer_range must be a range of Fixnum.`' if RUBY_ENGINE == 'truffleruby'
|
35
|
+
|
32
36
|
test = {u: -10000000000000000000, u2: 10000000000000000000}
|
33
37
|
exp = '{"u":"-10000000000000000000","u2":"10000000000000000000"}'
|
34
38
|
assert_equal(exp, Oj.dump(test, integer_range: (-1..1)))
|
35
39
|
end
|
36
40
|
|
37
41
|
def test_valid_modes
|
42
|
+
skip 'TruffleRuby fails this spec with `ArgumentError: :integer_range must be a range of Fixnum.`' if RUBY_ENGINE == 'truffleruby'
|
43
|
+
|
38
44
|
test = {safe: 0, unsafe: 9007199254740993}
|
39
45
|
exp = '{"safe":0,"unsafe":"9007199254740993"}'
|
40
46
|
|
data/test/test_object.rb
CHANGED
@@ -224,7 +224,7 @@ class ObjectJuice < Minitest::Test
|
|
224
224
|
#=begin
|
225
225
|
if '3.1.0' <= RUBY_VERSION && !(RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/)
|
226
226
|
#Oj::debug_odd("teardown before GC.verify_compaction_references")
|
227
|
-
|
227
|
+
verify_gc_compaction
|
228
228
|
#Oj::debug_odd("teardown after GC.verify_compaction_references")
|
229
229
|
end
|
230
230
|
#=end
|
@@ -461,6 +461,8 @@ class ObjectJuice < Minitest::Test
|
|
461
461
|
end
|
462
462
|
|
463
463
|
def test_json_module_object
|
464
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
465
|
+
|
464
466
|
obj = One::Two::Three::Deep.new()
|
465
467
|
dump_and_load(obj, false)
|
466
468
|
end
|
@@ -631,11 +633,15 @@ class ObjectJuice < Minitest::Test
|
|
631
633
|
end
|
632
634
|
|
633
635
|
def test_json_object
|
636
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
637
|
+
|
634
638
|
obj = Jeez.new(true, 58)
|
635
639
|
dump_and_load(obj, false)
|
636
640
|
end
|
637
641
|
|
638
642
|
def test_json_object_create_deep
|
643
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
644
|
+
|
639
645
|
obj = One::Two::Three::Deep.new()
|
640
646
|
dump_and_load(obj, false)
|
641
647
|
end
|
@@ -672,6 +678,8 @@ class ObjectJuice < Minitest::Test
|
|
672
678
|
end
|
673
679
|
|
674
680
|
def test_json_anonymous_struct
|
681
|
+
skip 'TruffleRuby fails this spec with `TypeError: allocator undefined for Class`' if RUBY_ENGINE == 'truffleruby'
|
682
|
+
|
675
683
|
s = Struct.new(:x, :y)
|
676
684
|
obj = s.new(1, 2)
|
677
685
|
json = Oj.dump(obj, :indent => 2, :mode => :object)
|
@@ -694,6 +702,8 @@ class ObjectJuice < Minitest::Test
|
|
694
702
|
end
|
695
703
|
|
696
704
|
def test_json_object_object
|
705
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
706
|
+
|
697
707
|
obj = Jeez.new(true, 58)
|
698
708
|
json = Oj.dump(obj, mode: :object, indent: 2, ignore_under: true)
|
699
709
|
assert(%{{
|
@@ -713,6 +723,8 @@ class ObjectJuice < Minitest::Test
|
|
713
723
|
end
|
714
724
|
|
715
725
|
def test_to_hash_object_object
|
726
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
727
|
+
|
716
728
|
obj = Jazz.new(true, 58)
|
717
729
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
718
730
|
assert(%{{
|
@@ -732,6 +744,8 @@ class ObjectJuice < Minitest::Test
|
|
732
744
|
end
|
733
745
|
|
734
746
|
def test_as_json_object_object
|
747
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
748
|
+
|
735
749
|
obj = Orange.new(true, 58)
|
736
750
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
737
751
|
assert(%{{
|
@@ -751,6 +765,8 @@ class ObjectJuice < Minitest::Test
|
|
751
765
|
end
|
752
766
|
|
753
767
|
def test_object_object_no_cache
|
768
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
769
|
+
|
754
770
|
obj = Jam.new(true, 58)
|
755
771
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
756
772
|
assert(%{{
|
@@ -779,6 +795,8 @@ class ObjectJuice < Minitest::Test
|
|
779
795
|
end
|
780
796
|
|
781
797
|
def test_exception
|
798
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
799
|
+
|
782
800
|
err = nil
|
783
801
|
begin
|
784
802
|
raise StandardError.new('A Message')
|
@@ -809,6 +827,8 @@ class ObjectJuice < Minitest::Test
|
|
809
827
|
end
|
810
828
|
|
811
829
|
def test_exception_subclass
|
830
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
831
|
+
|
812
832
|
err = nil
|
813
833
|
begin
|
814
834
|
raise SubX.new
|
@@ -830,6 +850,8 @@ class ObjectJuice < Minitest::Test
|
|
830
850
|
json = Oj.dump(1..7, :mode => :object, :indent => 0)
|
831
851
|
if 'rubinius' == $ruby
|
832
852
|
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
853
|
+
elsif 'truffleruby' == $ruby
|
854
|
+
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
833
855
|
else
|
834
856
|
assert_equal(%{{"^u":["Range",1,7,false]}}, json)
|
835
857
|
end
|
@@ -895,6 +917,8 @@ class ObjectJuice < Minitest::Test
|
|
895
917
|
end
|
896
918
|
|
897
919
|
def test_circular_object
|
920
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
921
|
+
|
898
922
|
obj = Jeez.new(nil, 58)
|
899
923
|
obj.x = obj
|
900
924
|
json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
|
@@ -903,6 +927,8 @@ class ObjectJuice < Minitest::Test
|
|
903
927
|
end
|
904
928
|
|
905
929
|
def test_circular_object2
|
930
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
931
|
+
|
906
932
|
obj = Jam.new(nil, 58)
|
907
933
|
obj.x = obj
|
908
934
|
json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
|
@@ -925,6 +951,8 @@ class ObjectJuice < Minitest::Test
|
|
925
951
|
end
|
926
952
|
|
927
953
|
def test_circular
|
954
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
955
|
+
|
928
956
|
h = { 'a' => 7 }
|
929
957
|
obj = Jeez.new(h, 58)
|
930
958
|
obj.x['b'] = obj
|
@@ -935,6 +963,8 @@ class ObjectJuice < Minitest::Test
|
|
935
963
|
end
|
936
964
|
|
937
965
|
def test_circular2
|
966
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
967
|
+
|
938
968
|
h = { 'a' => 7 }
|
939
969
|
obj = Jam.new(h, 58)
|
940
970
|
obj.x['b'] = obj
|
@@ -947,6 +977,8 @@ class ObjectJuice < Minitest::Test
|
|
947
977
|
end
|
948
978
|
|
949
979
|
def test_omit_nil
|
980
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
981
|
+
|
950
982
|
jam = Jam.new({'a' => 1, 'b' => nil }, nil)
|
951
983
|
|
952
984
|
json = Oj.dump(jam, :omit_nil => true, :mode => :object)
|
@@ -1001,16 +1033,22 @@ class ObjectJuice < Minitest::Test
|
|
1001
1033
|
end
|
1002
1034
|
|
1003
1035
|
def test_auto_string
|
1036
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
1037
|
+
|
1004
1038
|
s = AutoStrung.new("Pete", true)
|
1005
1039
|
dump_and_load(s, false)
|
1006
1040
|
end
|
1007
1041
|
|
1008
1042
|
def test_auto_array
|
1043
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
1044
|
+
|
1009
1045
|
a = AutoArray.new([1, 'abc', nil], true)
|
1010
1046
|
dump_and_load(a, false)
|
1011
1047
|
end
|
1012
1048
|
|
1013
1049
|
def test_auto_hash
|
1050
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
1051
|
+
|
1014
1052
|
h = AutoHash.new(nil, true)
|
1015
1053
|
h['a'] = 1
|
1016
1054
|
h['b'] = 2
|
data/test/test_parser_saj.rb
CHANGED
@@ -149,6 +149,17 @@ class SajTest < Minitest::Test
|
|
149
149
|
assert_equal((12345.6789e7 * 10000).to_i, (handler.calls[0][1] * 10000).to_i)
|
150
150
|
end
|
151
151
|
|
152
|
+
def test_bignum
|
153
|
+
handler = AllSaj.new()
|
154
|
+
json = %{-11.899999999999999}
|
155
|
+
p = Oj::Parser.new(:saj)
|
156
|
+
p.handler = handler
|
157
|
+
p.parse(json)
|
158
|
+
assert_equal(1, handler.calls.size)
|
159
|
+
assert_equal(:add_value, handler.calls[0][0])
|
160
|
+
assert_equal(-118999, (handler.calls[0][1] * 10000).to_i)
|
161
|
+
end
|
162
|
+
|
152
163
|
def test_array_empty
|
153
164
|
handler = AllSaj.new()
|
154
165
|
json = %{[]}
|
data/test/test_scp.rb
CHANGED
@@ -320,8 +320,8 @@ class ScpTest < Minitest::Test
|
|
320
320
|
end
|
321
321
|
|
322
322
|
def test_pipe
|
323
|
-
|
324
|
-
|
323
|
+
skip ' Windows does not support fork' if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
|
324
|
+
skip 'TruffleRuby fails this spec with `NotImplementedError: fork is not available`' if RUBY_ENGINE == 'truffleruby'
|
325
325
|
|
326
326
|
handler = AllHandler.new()
|
327
327
|
json = %{{"one":true,"two":false}}
|
@@ -357,8 +357,8 @@ class ScpTest < Minitest::Test
|
|
357
357
|
end
|
358
358
|
|
359
359
|
def test_pipe_close
|
360
|
-
|
361
|
-
|
360
|
+
skip 'Windows does not support fork' if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
|
361
|
+
skip 'TruffleRuby fails this spec with `NotImplementedError: fork is not available`' if RUBY_ENGINE == 'truffleruby'
|
362
362
|
|
363
363
|
json = %{{"one":true,"two":false}}
|
364
364
|
IO.pipe do |read_io, write_io|
|
data/test/test_strict.rb
CHANGED
data/test/test_wab.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.13.
|
4
|
+
version: 3.13.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07
|
11
|
+
date: 2022-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|