From 28a53cf7cd9c0c3a0f11de678bff4e1d5d0c301a Mon Sep 17 00:00:00 2001 From: Peter Ohler Date: Sat, 12 Feb 2022 21:13:25 -0500 Subject: [PATCH] Make date replacement test in order --- ext/oj/dump_object.c | 2 +- ext/oj/odd.c | 14 +++++++++++--- test/test_object.rb | 13 ++++++------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ext/oj/dump_object.c b/ext/oj/dump_object.c index ab424287..985cf963 100644 --- a/ext/oj/dump_object.c +++ b/ext/oj/dump_object.c @@ -446,7 +446,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) { assure_size(out, size); name = rb_id2name(*idp); nlen = strlen(name); - if (0 != *fp) { + if (NULL != *fp) { v = (*fp)(obj); } else if (0 == strchr(name, '.')) { v = rb_funcall(obj, *idp, 0); diff --git a/ext/oj/odd.c b/ext/oj/odd.c index cc1bea6b..45b0e9b0 100644 --- a/ext/oj/odd.c +++ b/ext/oj/odd.c @@ -14,7 +14,6 @@ static ID to_f_id; static ID numerator_id; static ID denominator_id; static ID rational_id; -static VALUE rational_class; static void set_class(Odd odd, const char *classname) { const char **np; @@ -23,7 +22,9 @@ static void set_class(Odd odd, const char *classname) { odd->classname = classname; odd->clen = strlen(classname); odd->clas = rb_const_get(rb_cObject, rb_intern(classname)); + rb_gc_register_address(&odd->clas); odd->create_obj = odd->clas; + rb_gc_register_address(&odd->create_obj); odd->create_op = rb_intern("new"); odd->is_module = (T_MODULE == rb_type(odd->clas)); odd->raw = 0; @@ -55,7 +56,6 @@ void oj_odd_init() { numerator_id = rb_intern("numerator"); denominator_id = rb_intern("denominator"); rational_id = rb_intern("Rational"); - rational_class = rb_const_get(rb_cObject, rational_id); memset(_odds, 0, sizeof(_odds)); odd = odds; @@ -183,15 +183,23 @@ void oj_reg_odd(VALUE clas, ID * ap; AttrGetFunc *fp; + for (odd = odds + odd_cnt - 1; odds <= odd; odd--) { + rb_gc_unregister_address(&odd->clas); + rb_gc_unregister_address(&odd->create_obj); + } if (_odds == odds) { odds = ALLOC_N(struct _odd, odd_cnt + 1); - memcpy(odds, _odds, sizeof(struct _odd) * odd_cnt); } else { REALLOC_N(odds, struct _odd, odd_cnt + 1); } + for (odd = odds + odd_cnt - 1; odds <= odd; odd--) { + rb_gc_register_address(&odd->clas); + rb_gc_register_address(&odd->create_obj); + } odd = odds + odd_cnt; odd->clas = clas; + rb_gc_register_address(&odd->clas); if (NULL == (odd->classname = strdup(rb_class2name(clas)))) { rb_raise(rb_eNoMemError, "for attribute name."); } diff --git a/test/test_object.rb b/test/test_object.rb index 7dcb7679..fdc487c2 100755 --- a/test/test_object.rb +++ b/test/test_object.rb @@ -221,6 +221,7 @@ def setup def teardown Oj.default_options = @default_options + GC.verify_compaction_references(double_heap: true, toward: :empty) end def test_nil @@ -948,6 +949,11 @@ def test_omit_nil def test_odd_date dump_and_load(Date.new(2012, 6, 19), false) + + Oj.register_odd(Date, Date, :jd, :jd) + json = Oj.dump(Date.new(2015, 3, 7), :mode => :object) + assert_equal(%|{"^O":"Date","jd":2457089}|, json) + dump_and_load(Date.new(2012, 6, 19), false) end def test_odd_datetime @@ -972,13 +978,6 @@ def test_odd_string dump_and_load(s, false) end - def test_odd_date_replaced - Oj.register_odd(Date, Date, :jd, :jd) - json = Oj.dump(Date.new(2015, 3, 7), :mode => :object) - assert_equal(%|{"^O":"Date","jd":2457089}|, json) - dump_and_load(Date.new(2012, 6, 19), false) - end - def test_odd_raw Oj.register_odd_raw(Raw, Raw, :create, :to_json) json = Oj.dump(Raw.new(%|{"a":1}|), :mode => :object)