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:
parent
dd4cec36ca
commit
25f5dd6799
4 changed files with 50 additions and 10 deletions
12
ChangeLog
12
ChangeLog
|
@ -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>
|
Sat Nov 14 02:19:16 2015 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* method.h: constify rb_cref_t::scope_visi;
|
* method.h: constify rb_cref_t::scope_visi;
|
||||||
|
|
|
@ -919,4 +919,21 @@ class TestMethod < Test::Unit::TestCase
|
||||||
assert_equal(456, b.local_variable_get(:bar))
|
assert_equal(456, b.local_variable_get(:bar))
|
||||||
assert_equal([:bar, :foo], b.local_variables.sort)
|
assert_equal([:bar, :foo], b.local_variables.sort)
|
||||||
end
|
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
|
end
|
||||||
|
|
21
vm.c
21
vm.c
|
@ -2340,22 +2340,25 @@ static void
|
||||||
vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval,
|
vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval,
|
||||||
rb_num_t is_singleton, rb_cref_t *cref)
|
rb_num_t is_singleton, rb_cref_t *cref)
|
||||||
{
|
{
|
||||||
VALUE klass = CREF_CLASS(cref);
|
VALUE klass;
|
||||||
const rb_scope_visibility_t *scope_visi = CREF_SCOPE_VISI(cref);
|
rb_method_visibility_t visi;
|
||||||
rb_method_visibility_t visi = scope_visi->method_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)) {
|
if (NIL_P(klass)) {
|
||||||
rb_raise(rb_eTypeError, "no class/module to add method");
|
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);
|
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);
|
klass = rb_singleton_class(klass);
|
||||||
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, METHOD_VISI_PUBLIC);
|
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, METHOD_VISI_PUBLIC);
|
||||||
}
|
}
|
||||||
|
|
10
vm_method.c
10
vm_method.c
|
@ -1045,7 +1045,15 @@ rb_scope_visibility_get(void)
|
||||||
static int
|
static int
|
||||||
rb_scope_module_func_check(void)
|
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
|
static void
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue