1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* vm.c (vm_define_method): do not use current CREF immediately,

but check CREF in environment or methods. Methods defined in methods
  should be public.
  [Bug #11571]

* vm_method.c (rb_scope_module_func_check): check CREF in env or me.
  if CREF is contained by `me', then return FALSE.

* test/ruby/test_method.rb: add a test.




git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52562 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2015-11-13 17:38:12 +00:00
parent dd4cec36ca
commit 25f5dd6799
4 changed files with 50 additions and 10 deletions

View file

@ -1,3 +1,15 @@
Sat Nov 14 02:34:43 2015 Koichi Sasada <ko1@atdot.net>
* vm.c (vm_define_method): do not use current CREF immediately,
but check CREF in environment or methods. Methods defined in methods
should be public.
[Bug #11571]
* vm_method.c (rb_scope_module_func_check): check CREF in env or me.
if CREF is contained by `me', then return FALSE.
* test/ruby/test_method.rb: add a test.
Sat Nov 14 02:19:16 2015 Koichi Sasada <ko1@atdot.net>
* method.h: constify rb_cref_t::scope_visi;

View file

@ -919,4 +919,21 @@ class TestMethod < Test::Unit::TestCase
assert_equal(456, b.local_variable_get(:bar))
assert_equal([:bar, :foo], b.local_variables.sort)
end
class MethodInMethodClass
def m1
def m2
end
end
private
end
def test_method_in_method_visibility_should_be_public
assert_equal([:m1].sort, MethodInMethodClass.public_instance_methods(false).sort)
assert_equal([].sort, MethodInMethodClass.private_instance_methods(false).sort)
MethodInMethodClass.new.m1
assert_equal([:m1, :m2].sort, MethodInMethodClass.public_instance_methods(false).sort)
assert_equal([].sort, MethodInMethodClass.private_instance_methods(false).sort)
end
end

21
vm.c
View file

@ -2340,22 +2340,25 @@ static void
vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval,
rb_num_t is_singleton, rb_cref_t *cref)
{
VALUE klass = CREF_CLASS(cref);
const rb_scope_visibility_t *scope_visi = CREF_SCOPE_VISI(cref);
rb_method_visibility_t visi = scope_visi->method_visi;
VALUE klass;
rb_method_visibility_t visi;
if (!is_singleton) {
klass = obj;
visi = rb_scope_visibility_get();
}
else { /* singleton */
klass = rb_singleton_class(obj); /* class and frozen checked in this API */
visi = METHOD_VISI_PUBLIC;
}
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class/module to add method");
}
if (is_singleton) {
klass = rb_singleton_class(obj); /* class and frozen checked in this API */
visi = METHOD_VISI_PUBLIC;
}
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi);
if (!is_singleton && scope_visi->module_func) {
if (!is_singleton && rb_scope_module_func_check()) {
klass = rb_singleton_class(klass);
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, METHOD_VISI_PUBLIC);
}

View file

@ -1045,7 +1045,15 @@ rb_scope_visibility_get(void)
static int
rb_scope_module_func_check(void)
{
return CREF_SCOPE_VISI(rb_vm_cref())->module_func;
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (!vm_env_cref_by_cref(cfp->ep)) {
return FALSE;
}
else {
return CREF_SCOPE_VISI(rb_vm_cref())->module_func;
}
}
static void