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

ruby-changes:44950

From: nobu <ko1@a...>
Date: Thu, 8 Dec 2016 14:16:38 +0900 (JST)
Subject: [ruby-changes:44950] nobu:r57023 (trunk): vm_insnhelper.c: zsuper in refinements

nobu	2016-12-08 14:16:33 +0900 (Thu, 08 Dec 2016)

  New Revision: 57023

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

  Log:
    vm_insnhelper.c: zsuper in refinements
    
    * vm_insnhelper.c (vm_call_zsuper): prevent infinite recursion
      zsuper in refinements.  [ruby-core:77161] [Bug #12729]

  Modified files:
    trunk/test/ruby/test_refinement.rb
    trunk/vm_insnhelper.c
Index: test/ruby/test_refinement.rb
===================================================================
--- test/ruby/test_refinement.rb	(revision 57022)
+++ test/ruby/test_refinement.rb	(revision 57023)
@@ -1789,6 +1789,27 @@ class TestRefinement < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L1789
     end;
   end
 
+  def test_public_in_refine
+    assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+    begin;
+      bug12729 = '[ruby-core:77161] [Bug #12729]'
+
+      class Cow
+        private
+        def moo() "Moo"; end
+      end
+
+      module PublicCows
+        refine(Cow) {
+          public :moo
+        }
+      end
+
+      using PublicCows
+      assert_equal("Moo", Cow.new.moo, bug12729)
+    end;
+  end
+
   private
 
   def eval_using(mod, s)
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 57022)
+++ vm_insnhelper.c	(revision 57023)
@@ -2016,18 +2016,20 @@ vm_call_method_missing(rb_thread_t *th, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2016
     return vm_call_method(th, reg_cfp, calling, ci, cc);
 }
 
+static const rb_callable_method_entry_t *refined_method_callable_without_refinement(const rb_callable_method_entry_t *me);
 static VALUE
 vm_call_zsuper(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE klass)
 {
     klass = RCLASS_SUPER(klass);
     cc->me = klass ? rb_callable_method_entry(klass, ci->mid) : NULL;
 
-    if (cc->me != NULL) {
-	return vm_call_method_each_type(th, cfp, calling, ci, cc);
-    }
-    else {
+    if (!cc->me) {
 	return vm_call_method_nome(th, cfp, calling, ci, cc);
     }
+    if (cc->me->def->type == VM_METHOD_TYPE_REFINED) {
+	cc->me = refined_method_callable_without_refinement(cc->me);
+    }
+    return vm_call_method_each_type(th, cfp, calling, ci, cc);
 }
 
 static inline VALUE
@@ -2121,6 +2123,11 @@ refined_method_callable_without_refineme https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2123
     }
 
     VM_ASSERT(callable_method_entry_p(cme));
+
+    if (UNDEFINED_METHOD_ENTRY_P(cme)) {
+	cme = NULL;
+    }
+
     return cme;
 }
 
@@ -2218,10 +2225,6 @@ vm_call_method_each_type(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2225
 	no_refinement_dispatch:
 	  if (cc->me->def->body.refined.orig_me) {
 	      cc->me = refined_method_callable_without_refinement(cc->me);
-
-	      if (UNDEFINED_METHOD_ENTRY_P(cc->me)) {
-		  cc->me = NULL;
-	      }
 	      return vm_call_method(th, cfp, calling, ci, cc);
 	  }
 	  else {

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

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