зеркало из https://github.com/github/ruby.git
* 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:
Родитель
1cf13e0785
Коммит
29756c5e94
14
ChangeLog
14
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.
|
||||
|
|
2
method.h
2
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);
|
||||
|
|
2
proc.c
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);
|
||||
|
||||
|
|
17
vm_method.c
17
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) &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче