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:
parent
f5e2904471
commit
f3c81b4e90
2 changed files with 16 additions and 3 deletions
13
gc.c
13
gc.c
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue