* 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
This commit is contained in:
shugo 2012-12-09 08:48:34 +00:00
Родитель 1cf13e0785
Коммит 29756c5e94
6 изменённых файлов: 44 добавлений и 12 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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);

2
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);

Просмотреть файл

@ -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

Просмотреть файл

@ -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);

Просмотреть файл

@ -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) &&