[前][次][番号順一覧][スレッド一覧]

ruby-changes:40481

From: ko1 <ko1@a...>
Date: Sat, 14 Nov 2015 02:38:19 +0900 (JST)
Subject: [ruby-changes:40481] ko1:r52562 (trunk): * vm.c (vm_define_method): do not use current CREF immediately,

ko1	2015-11-14 02:38:12 +0900 (Sat, 14 Nov 2015)

  New Revision: 52562

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52562

  Log:
    * 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.

  Modified files:
    trunk/ChangeLog
    trunk/test/ruby/test_method.rb
    trunk/vm.c
    trunk/vm_method.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 52561)
+++ ChangeLog	(revision 52562)
@@ -1,3 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Nov 14 02:34:43 2015  Koichi Sasada  <ko1@a...>
+
+	* 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@a...>
 
 	* method.h: constify rb_cref_t::scope_visi;
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 52561)
+++ vm_method.c	(revision 52562)
@@ -1045,7 +1045,15 @@ rb_scope_visibility_get(void) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1045
 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
Index: vm.c
===================================================================
--- vm.c	(revision 52561)
+++ vm.c	(revision 52562)
@@ -2340,22 +2340,25 @@ static void https://github.com/ruby/ruby/blob/trunk/vm.c#L2340
 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 (NIL_P(klass)) {
-	rb_raise(rb_eTypeError, "no class/module to add method");
+    if (!is_singleton) {
+	klass = obj;
+	visi = rb_scope_visibility_get();
     }
-
-    if (is_singleton) {
+    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");
+    }
+
     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);
     }
Index: test/ruby/test_method.rb
===================================================================
--- test/ruby/test_method.rb	(revision 52561)
+++ test/ruby/test_method.rb	(revision 52562)
@@ -919,4 +919,21 @@ class TestMethod < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_method.rb#L919
     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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]