From 29756c5e94c6f273c6b1a1103d9c0b12570566ea Mon Sep 17 00:00:00 2001 From: shugo Date: Sun, 9 Dec 2012 08:48:34 +0000 Subject: [PATCH] * vm_insnhelper.c (vm_call_opt_send): Kernel#send should not use refinements. * proc.c (mnew): Kernel#method, Kernel#public_method, Module#instance_method, and Module#public_instance_method should not use refinements. * vm_method.c (rb_method_boundp): Kernel#respond_to? should not use refinements. * test/ruby/test_refinement.rb: related test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38279 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 14 ++++++++++++++ method.h | 2 ++ proc.c | 2 +- test/ruby/test_refinement.rb | 17 ++++++++--------- vm_insnhelper.c | 4 +++- vm_method.c | 17 ++++++++++++++++- 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index a910c1cece..7b7b647c43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Sun Dec 9 17:36:59 2012 Shugo Maeda + + * vm_insnhelper.c (vm_call_opt_send): Kernel#send should not use + refinements. + + * proc.c (mnew): Kernel#method, Kernel#public_method, + Module#instance_method, and Module#public_instance_method should + not use refinements. + + * vm_method.c (rb_method_boundp): Kernel#respond_to? should not use + refinements. + + * test/ruby/test_refinement.rb: related test. + Sun Dec 9 06:19:04 2012 Eric Hodel * lib/rdoc/markdown/entities.rb: Added documentation. diff --git a/method.h b/method.h index b6d20916fb..f8ceb84ff9 100644 --- a/method.h +++ b/method.h @@ -102,6 +102,8 @@ rb_method_entry_t *rb_resolve_refined_method(VALUE refinements, VALUE *defined_class_ptr); rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr); +rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id, + VALUE *defined_class_ptr); rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *define_class_ptr); rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex); diff --git a/proc.c b/proc.c index 9c5f810a79..b66c6c6e94 100644 --- a/proc.c +++ b/proc.c @@ -917,7 +917,7 @@ mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope) rb_method_flag_t flag = NOEX_UNDEF; again: - me = rb_method_entry_with_refinements(klass, id, &defined_class); + me = rb_method_entry_without_refinements(klass, id, &defined_class); if (UNDEFINED_METHOD_ENTRY_P(me)) { ID rmiss = rb_intern("respond_to_missing?"); VALUE sym = ID2SYM(id); diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index a956535f60..97f6db9303 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -129,18 +129,18 @@ class TestRefinement < Test::Unit::TestCase assert_raise(NoMethodError) { foo.z } end - def test_new_method_by_send + def test_send_should_not_use_refinements foo = Foo.new assert_raise(NoMethodError) { foo.send(:z) } - assert_equal("FooExt#z", FooExtClient.send_z_on(foo)) + assert_raise(NoMethodError) { FooExtClient.send_z_on(foo) } assert_raise(NoMethodError) { foo.send(:z) } end - def test_new_method_by_method_object + def test_method_should_not_use_refinements foo = Foo.new - assert_raise(NoMethodError) { foo.send(:z) } - assert_equal("FooExt#z", FooExtClient.method_z(foo).call) - assert_raise(NoMethodError) { foo.send(:z) } + assert_raise(NameError) { foo.method(:z) } + assert_raise(NameError) { FooExtClient.method_z(foo) } + assert_raise(NameError) { foo.method(:z) } end def test_no_local_rebinding @@ -249,10 +249,9 @@ class TestRefinement < Test::Unit::TestCase end end - def test_respond_to? - assert_equal(false, 1.respond_to?(:foo)) - assert_equal(true, eval_using(FixnumFooExt, "1.respond_to?(:foo)")) + def test_respond_to_should_not_use_refinements assert_equal(false, 1.respond_to?(:foo)) + assert_equal(false, eval_using(FixnumFooExt, "1.respond_to?(:foo)")) end module StringCmpExt diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 5743654953..f2c8c40e8c 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1597,7 +1597,9 @@ vm_call_opt_send(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *c if (i > 0) { MEMMOVE(&TOPN(i), &TOPN(i-1), VALUE, i); } - ci->me = rb_method_entry(CLASS_OF(ci->recv), ci->mid, &ci->defined_class); + ci->me = + rb_method_entry_without_refinements(CLASS_OF(ci->recv), + ci->mid, &ci->defined_class); ci->argc -= 1; DEC_SP(1); diff --git a/vm_method.c b/vm_method.c index 2db6000691..d33681ac3f 100644 --- a/vm_method.c +++ b/vm_method.c @@ -629,6 +629,21 @@ rb_method_entry_with_refinements(VALUE klass, ID id, return me; } +rb_method_entry_t * +rb_method_entry_without_refinements(VALUE klass, ID id, + VALUE *defined_class_ptr) +{ + VALUE defined_class; + rb_method_entry_t *me = rb_method_entry(klass, id, &defined_class); + + if (me && me->def->type == VM_METHOD_TYPE_REFINED) { + me = me->def->body.orig_me; + } + if (defined_class_ptr) + *defined_class_ptr = defined_class; + return me; +} + static void remove_method(VALUE klass, ID mid) { @@ -753,7 +768,7 @@ int rb_method_boundp(VALUE klass, ID id, int ex) { rb_method_entry_t *me = - rb_method_entry_with_refinements(klass, id, 0); + rb_method_entry_without_refinements(klass, id, 0); if (me != 0) { if ((ex & ~NOEX_RESPONDS) &&