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

ruby-changes:26372

From: charliesome <ko1@a...>
Date: Mon, 17 Dec 2012 18:49:14 +0900 (JST)
Subject: [ruby-changes:26372] charliesome:r38423 (trunk): * class.c (rewrite_cref_stack, clone_method): rewrite a method's cref

charliesome	2012-12-17 18:49:00 +0900 (Mon, 17 Dec 2012)

  New Revision: 38423

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

  Log:
    * class.c (rewrite_cref_stack, clone_method): rewrite a method's cref
      stack when cloning into a new class to allow lexical const lookup to
      work as expected [ruby-core:47834] [Bug #7107]
    * test/ruby/test_class.rb (class TestClass): related test

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/test/ruby/test_class.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38422)
+++ ChangeLog	(revision 38423)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Dec 17 18:03:34 2012  Charlie Somerville  <charlie@c...>
+
+	* class.c (rewrite_cref_stack, clone_method): rewrite a method's cref
+	  stack when cloning into a new class to allow lexical const lookup to
+	  work as expected [ruby-core:47834] [Bug #7107]
+	* test/ruby/test_class.rb (class TestClass): related test
+
 Mon Dec 17 13:56:55 2012  KOSAKI Motohiro  <kosaki.motohiro@g...>
 
 	* io.c (io_flush_buffer_sync2): avoid to return 0. because
Index: class.c
===================================================================
--- class.c	(revision 38422)
+++ class.c	(revision 38423)
@@ -121,6 +121,23 @@ rb_class_new(VALUE super) https://github.com/ruby/ruby/blob/trunk/class.c#L121
     return rb_class_boot(super);
 }
 
+static NODE*
+rewrite_cref_stack(NODE *node, VALUE old_klass, VALUE new_klass)
+{
+    NODE *new_node;
+    if (!node) {
+	return NULL;
+    }
+    if (node->nd_clss == old_klass) {
+	new_node = NEW_CREF(new_klass);
+	new_node->nd_next = node->nd_next;
+    } else {
+	new_node = NEW_CREF(node->nd_clss);
+	new_node->nd_next = rewrite_cref_stack(node->nd_next, old_klass, new_klass);
+    }
+    return new_node;
+}
+
 static void
 clone_method(VALUE klass, ID mid, const rb_method_entry_t *me)
 {
@@ -129,6 +146,7 @@ clone_method(VALUE klass, ID mid, const https://github.com/ruby/ruby/blob/trunk/class.c#L146
 	rb_iseq_t *iseq;
 	newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass);
 	GetISeqPtr(newiseqval, iseq);
+	iseq->cref_stack = rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass);
 	rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
 	RB_GC_GUARD(newiseqval);
     }
Index: test/ruby/test_class.rb
===================================================================
--- test/ruby/test_class.rb	(revision 38422)
+++ test/ruby/test_class.rb	(revision 38423)
@@ -285,4 +285,18 @@ class TestClass < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_class.rb#L285
       p A.superclass
     RUBY
   end
+
+  module M
+    C = 1
+
+    def self.m
+      C
+    end
+  end
+
+  def test_constant_access_from_method_in_cloned_module # [ruby-core:47834]
+    m = M.dup
+    assert_equal 1, m::C
+    assert_equal 1, m.m
+  end
 end

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

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