1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Frozen objects in WeakMap

* gc.c (wmap_aset): bypass check for frozen and allow frozen
  object in WeakMap.  [Bug #13498]
This commit is contained in:
Nobuyoshi Nakada 2019-06-23 00:31:16 +09:00
parent f5e2904471
commit f3c81b4e90
No known key found for this signature in database
GPG key ID: 4BC7D6DF58D8DF60
2 changed files with 16 additions and 3 deletions

13
gc.c
View file

@ -2937,13 +2937,20 @@ should_be_callable(VALUE block)
rb_obj_class(block)); rb_obj_class(block));
} }
} }
static void static void
should_be_finalizable(VALUE obj) should_be_finalizable_internal(VALUE obj)
{ {
if (!FL_ABLE(obj)) { if (!FL_ABLE(obj)) {
rb_raise(rb_eArgError, "cannot define finalizer for %s", rb_raise(rb_eArgError, "cannot define finalizer for %s",
rb_obj_classname(obj)); rb_obj_classname(obj));
} }
}
static void
should_be_finalizable(VALUE obj)
{
should_be_finalizable_internal(obj);
rb_check_frozen(obj); rb_check_frozen(obj);
} }
@ -10399,8 +10406,8 @@ wmap_aset(VALUE self, VALUE wmap, VALUE orig)
struct weakmap *w; struct weakmap *w;
TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
should_be_finalizable(orig); should_be_finalizable_internal(orig);
should_be_finalizable(wmap); should_be_finalizable_internal(wmap);
define_final0(orig, w->final); define_final0(orig, w->final);
define_final0(wmap, w->final); define_final0(wmap, w->final);
st_update(w->obj2wmap, (st_data_t)orig, wmap_aset_update, wmap); st_update(w->obj2wmap, (st_data_t)orig, wmap_aset_update, wmap);

View file

@ -141,4 +141,10 @@ class TestWeakMap < Test::Unit::TestCase
assert_equal(2, @wm.__send__(m)) assert_equal(2, @wm.__send__(m))
end end
alias test_length test_size alias test_length test_size
def test_frozen_object
o = Object.new.freeze
assert_nothing_raised(FrozenError) {@wm[o] = 'foo'}
assert_nothing_raised(FrozenError) {@wm['foo'] = o}
end
end end