summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--method.h2
-rw-r--r--proc.c2
-rw-r--r--test/ruby/test_refinement.rb17
-rw-r--r--vm_insnhelper.c4
-rw-r--r--vm_method.c17
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 <shugo@ruby-lang.org>
+
+ * 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 <drbrain@segment7.net>
* 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) &&