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

ruby-changes:41104

From: shugo <ko1@a...>
Date: Fri, 18 Dec 2015 11:32:24 +0900 (JST)
Subject: [ruby-changes:41104] shugo:r53179 (trunk): * vm_method.c (rb_method_entry_make, check_override_opt_method):

shugo	2015-12-18 11:32:17 +0900 (Fri, 18 Dec 2015)

  New Revision: 53179

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

  Log:
    * vm_method.c (rb_method_entry_make, check_override_opt_method):
      should check whether a newly created method override a optimize
      method in case the method is defined in a prepended module of a
      built-in class.
      [ruby-core:72226] [Bug #11836]

  Modified files:
    trunk/ChangeLog
    trunk/test/ruby/test_module.rb
    trunk/vm_method.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 53178)
+++ ChangeLog	(revision 53179)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Dec 18 11:24:48 2015  Shugo Maeda  <shugo@r...>
+
+	* vm_method.c (rb_method_entry_make, check_override_opt_method):
+	  should check whether a newly created method override a optimize
+	  method in case the method is defined in a prepended module of a
+	  built-in class.
+	  [ruby-core:72226] [Bug #11836]
+
 Fri Dec 11 06:39:30 2015  KOSAKI Motohiro  <kosaki.motohiro@g...>
 
 	* vm.c (vm_exec): call RUBY_DTRACE_CMETHOD_RETURN_HOOK instead of
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 53178)
+++ vm_method.c	(revision 53179)
@@ -25,6 +25,7 @@ https://github.com/ruby/ruby/blob/trunk/vm_method.c#L25
 #define GLOBAL_METHOD_CACHE(c,m) (rb_bug("global method cache disabled improperly"), NULL)
 #endif
 
+static int vm_redefinition_check_flag(VALUE klass);
 static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass);
 
 #define object_id           idObject_id
@@ -468,6 +469,22 @@ rb_add_refined_method_entry(VALUE refine https://github.com/ruby/ruby/blob/trunk/vm_method.c#L469
     }
 }
 
+static void
+check_override_opt_method(VALUE klass, VALUE arg)
+{
+    ID mid = (ID)arg;
+    const rb_method_entry_t *me, *newme;
+
+    if (vm_redefinition_check_flag(klass)) {
+	me = lookup_method_table(RCLASS_ORIGIN(klass), mid);
+	if (me) {
+	    newme = rb_method_entry(klass, mid);
+	    if (newme != me) rb_vm_check_redefinition_opt_method(me, me->owner);
+	}
+    }
+    rb_class_foreach_subclass(klass, check_override_opt_method, (VALUE)mid);
+}
+
 /*
  * klass->method_table[mid] = method_entry(defined_class, visi, def)
  *
@@ -579,6 +596,11 @@ rb_method_entry_make(VALUE klass, ID mid https://github.com/ruby/ruby/blob/trunk/vm_method.c#L596
 
     VM_ASSERT(me->def != NULL);
 
+    /* check optimized method override by a prepended module */
+    if (RB_TYPE_P(klass, T_MODULE)) {
+	check_override_opt_method(klass, (VALUE)mid);
+    }
+
     return me;
 }
 
Index: test/ruby/test_module.rb
===================================================================
--- test/ruby/test_module.rb	(revision 53178)
+++ test/ruby/test_module.rb	(revision 53179)
@@ -1711,6 +1711,24 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L1711
     assert_equal(0, 1 / 2)
   end
 
+  def test_override_optmethod_after_prepend
+    bug11836 = '[ruby-core:72226] [Bug #11836]'
+    assert_separately [], %{
+      module M
+      end
+      class Fixnum
+        prepend M
+      end
+      module M
+        def /(other)
+          quo(other)
+        end
+      end
+      assert_equal(1 / 2r, 1 / 2, "#{bug11836}")
+    }, ignore_stderr: true
+    assert_equal(0, 1 / 2)
+  end
+
   def test_prepend_visibility
     bug8005 = '[ruby-core:53106] [Bug #8005]'
     c = Class.new do

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

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