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

ruby-changes:37604

From: ktsj <ko1@a...>
Date: Sun, 22 Feb 2015 16:05:23 +0900 (JST)
Subject: [ruby-changes:37604] ktsj:r49685 (trunk): * vm_insnhelper.c (rb_vm_rewrite_cref_stack): copy nd_refinements

ktsj	2015-02-22 16:05:14 +0900 (Sun, 22 Feb 2015)

  New Revision: 49685

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

  Log:
    * vm_insnhelper.c (rb_vm_rewrite_cref_stack): copy nd_refinements
      of orignal crefs. It fixes segmentation fault when calling
      refined method in duplicate module. [ruby-dev:48878] [Bug #10885]
    
    * vm_core.h, class.c: change accordingly.
    
    * test/ruby/test_refinement.rb: add a test for above.

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/test/ruby/test_refinement.rb
    trunk/vm_core.h
    trunk/vm_insnhelper.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 49684)
+++ ChangeLog	(revision 49685)
@@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Feb 22 15:56:06 2015  Kazuki Tsujimoto  <kazuki@c...>
+
+	* vm_insnhelper.c (rb_vm_rewrite_cref_stack): copy nd_refinements
+	  of orignal crefs. It fixes segmentation fault when calling
+	  refined method in duplicate module. [ruby-dev:48878] [Bug #10885]
+
+	* vm_core.h, class.c: change accordingly.
+
+	* test/ruby/test_refinement.rb: add a test for above.
+
 Sun Feb 22 10:43:37 2015  Koichi Sasada  <ko1@a...>
 
 	* gc.c (rb_objspace_call_finalizer): control GC execution during
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 49684)
+++ vm_core.h	(revision 49685)
@@ -1003,6 +1003,8 @@ void rb_gc_mark_machine_stack(rb_thread_ https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1003
 
 int rb_autoloading_value(VALUE mod, ID id, VALUE* value);
 
+void rb_vm_rewrite_cref_stack(NODE *node, VALUE old_klass, VALUE new_klass, NODE **new_cref_ptr);
+
 #define sysstack_error GET_VM()->special_exceptions[ruby_error_sysstack]
 
 #define RUBY_CONST_ASSERT(expr) (1/!!(expr)) /* expr must be a compile-time constant */
Index: class.c
===================================================================
--- class.c	(revision 49684)
+++ class.c	(revision 49685)
@@ -241,25 +241,6 @@ rb_class_new(VALUE super) https://github.com/ruby/ruby/blob/trunk/class.c#L241
 }
 
 static void
-rewrite_cref_stack(NODE *node, VALUE old_klass, VALUE new_klass, NODE **new_cref_ptr)
-{
-    NODE *new_node;
-    while (node) {
-	if (node->nd_clss == old_klass) {
-	    new_node = NEW_CREF(new_klass);
-	    RB_OBJ_WRITE(new_node, &new_node->nd_next, node->nd_next);
-	    *new_cref_ptr = new_node;
-	    return;
-	}
-	new_node = NEW_CREF(node->nd_clss);
-	node = node->nd_next;
-	*new_cref_ptr = new_node;
-	new_cref_ptr = &new_node->nd_next;
-    }
-    *new_cref_ptr = NULL;
-}
-
-static void
 clone_method(VALUE klass, ID mid, const rb_method_entry_t *me)
 {
     VALUE newiseqval;
@@ -268,7 +249,7 @@ clone_method(VALUE klass, ID mid, const https://github.com/ruby/ruby/blob/trunk/class.c#L249
 	NODE *new_cref;
 	newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass);
 	GetISeqPtr(newiseqval, iseq);
-	rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass, &new_cref);
+	rb_vm_rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass, &new_cref);
 	RB_OBJ_WRITE(iseq->self, &iseq->cref_stack, new_cref);
 	rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
 	RB_GC_GUARD(newiseqval);
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 49684)
+++ vm_insnhelper.c	(revision 49685)
@@ -264,6 +264,27 @@ rb_vm_get_cref(const rb_iseq_t *iseq, co https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L264
     return cref;
 }
 
+void
+rb_vm_rewrite_cref_stack(NODE *node, VALUE old_klass, VALUE new_klass, NODE **new_cref_ptr)
+{
+    NODE *new_node;
+    while (node) {
+	if (node->nd_clss == old_klass) {
+	    new_node = NEW_CREF(new_klass);
+	    COPY_CREF_OMOD(new_node, node);
+	    RB_OBJ_WRITE(new_node, &new_node->nd_next, node->nd_next);
+	    *new_cref_ptr = new_node;
+	    return;
+	}
+	new_node = NEW_CREF(node->nd_clss);
+	COPY_CREF_OMOD(new_node, node);
+	node = node->nd_next;
+	*new_cref_ptr = new_node;
+	new_cref_ptr = &new_node->nd_next;
+    }
+    *new_cref_ptr = NULL;
+}
+
 static NODE *
 vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
 {
Index: test/ruby/test_refinement.rb
===================================================================
--- test/ruby/test_refinement.rb	(revision 49684)
+++ test/ruby/test_refinement.rb	(revision 49685)
@@ -1400,6 +1400,34 @@ class TestRefinement < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L1400
     INPUT
   end
 
+  def test_call_refined_method_in_duplicate_module
+    bug10885 = '[ruby-dev:48878]'
+    assert_in_out_err([], <<-INPUT, [], [], bug10885)
+      module M
+        refine Object do
+          def raise
+            # do nothing
+          end
+        end
+
+        class << self
+          using M
+          def m0
+            raise
+          end
+        end
+
+        using M
+        def M.m1
+          raise
+        end
+      end
+
+      M.dup.m0
+      M.dup.m1
+    INPUT
+  end
+
   private
 
   def eval_using(mod, s)

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

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