ruby-changes:32029
From: nobu <ko1@a...>
Date: Tue, 10 Dec 2013 14:17:25 +0900 (JST)
Subject: [ruby-changes:32029] nobu:r44108 (trunk): gc.c: check arguments first
nobu 2013-12-10 14:17:19 +0900 (Tue, 10 Dec 2013) New Revision: 44108 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44108 Log: gc.c: check arguments first * gc.c (wmap_aset): check if both arguments are able to finalize before setting finalizers. Modified files: trunk/gc.c trunk/test/ruby/test_weakmap.rb Index: gc.c =================================================================== --- gc.c (revision 44107) +++ gc.c (revision 44108) @@ -1904,6 +1904,15 @@ should_be_callable(VALUE block) https://github.com/ruby/ruby/blob/trunk/gc.c#L1904 rb_obj_classname(block)); } } +static void +should_be_finalizable(VALUE obj) +{ + rb_check_frozen(obj); + if (!FL_ABLE(obj)) { + rb_raise(rb_eArgError, "cannot define finalizer for %s", + rb_obj_classname(obj)); + } +} /* * call-seq: @@ -1920,7 +1929,7 @@ define_final(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/gc.c#L1929 VALUE obj, block; rb_scan_args(argc, argv, "11", &obj, &block); - rb_check_frozen(obj); + should_be_finalizable(obj); if (argc == 1) { block = rb_block_proc(); } @@ -1938,10 +1947,6 @@ define_final0(VALUE obj, VALUE block) https://github.com/ruby/ruby/blob/trunk/gc.c#L1947 VALUE table; st_data_t data; - if (!FL_ABLE(obj)) { - rb_raise(rb_eArgError, "cannot define finalizer for %s", - rb_obj_classname(obj)); - } RBASIC(obj)->flags |= FL_FINALIZE; block = rb_ary_new3(2, INT2FIX(rb_safe_level()), block); @@ -1962,7 +1967,7 @@ define_final0(VALUE obj, VALUE block) https://github.com/ruby/ruby/blob/trunk/gc.c#L1967 VALUE rb_define_finalizer(VALUE obj, VALUE block) { - rb_check_frozen(obj); + should_be_finalizable(obj); should_be_callable(block); return define_final0(obj, block); } @@ -6479,8 +6484,10 @@ wmap_aset(VALUE self, VALUE wmap, VALUE https://github.com/ruby/ruby/blob/trunk/gc.c#L6484 struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); - rb_define_finalizer(orig, w->final); - rb_define_finalizer(wmap, w->final); + should_be_finalizable(orig); + should_be_finalizable(wmap); + define_final0(orig, w->final); + define_final0(wmap, w->final); if (st_lookup(w->obj2wmap, (st_data_t)orig, &data)) { rids = (VALUE)data; } Index: test/ruby/test_weakmap.rb =================================================================== --- test/ruby/test_weakmap.rb (revision 44107) +++ test/ruby/test_weakmap.rb (revision 44108) @@ -14,6 +14,20 @@ class TestWeakMap < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_weakmap.rb#L14 assert_not_same(x, @wm["FOO".downcase]) end + def test_aset_const + x = Object.new + assert_raise(ArgumentError) {@wm[true] = x} + assert_raise(ArgumentError) {@wm[false] = x} + assert_raise(ArgumentError) {@wm[nil] = x} + assert_raise(RuntimeError) {@wm[42] = x} + assert_raise(RuntimeError) {@wm[:foo] = x} + assert_raise(ArgumentError) {@wm[x] = true} + assert_raise(ArgumentError) {@wm[x] = false} + assert_raise(ArgumentError) {@wm[x] = nil} + assert_raise(RuntimeError) {@wm[x] = 42} + assert_raise(RuntimeError) {@wm[x] = :foo} + end + def test_include? m = __callee__[/test_(.*)/, 1] x = Object.new -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/