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

ruby-changes:19396

From: nagachika <ko1@a...>
Date: Thu, 5 May 2011 15:32:45 +0900 (JST)
Subject: [ruby-changes:19396] Ruby:r31436 (trunk): * eval.c (frame_func_id): __method__ return different name from

nagachika	2011-05-05 15:32:37 +0900 (Thu, 05 May 2011)

  New Revision: 31436

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

  Log:
    * eval.c (frame_func_id): __method__ return different name from
        methods defined by Module#define_method with a same block.
        [ruby-core:35386] fixes #4606
      * eval (method_entry_of_iseq): new helper function. search control
        frame stack for a method entry which has given iseq.
      * test/ruby/test_method.rb: add tests for #4696

  Modified files:
    trunk/ChangeLog
    trunk/eval.c
    trunk/test/ruby/test_method.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31435)
+++ ChangeLog	(revision 31436)
@@ -1,3 +1,12 @@
+Thu May  5 15:03:51 2011  CHIKANAGA Tomoyuki  <nagachika00@g...>
+
+	* eval.c (frame_func_id): __method__ return different name from
+	  methods defined by Module#define_method with a same block.
+	  [ruby-core:35386] fixes #4606
+	* eval (method_entry_of_iseq): new helper function. search control
+	  frame stack for a method entry which has given iseq.
+	* test/ruby/test_method.rb: add tests for #4696
+
 Wed May  4 22:13:09 2011  KOSAKI Motohiro  <kosaki.motohiro@g...>
 
 	* benchmark/bm_vm4_pipe.rb: Reduced iterations. Too slow benchmark
Index: eval.c
===================================================================
--- eval.c	(revision 31435)
+++ eval.c	(revision 31436)
@@ -753,12 +753,27 @@
     return result;
 }
 
+static const rb_method_entry_t *
+method_entry_of_iseq(rb_control_frame_t *cfp, rb_iseq_t *iseq)
+{
+    rb_thread_t *th = GET_THREAD();
+    rb_control_frame_t *cfp_limit;
+
+    cfp_limit = (rb_control_frame_t *)(th->stack + th->stack_size);
+    while (cfp_limit > cfp) {
+	if (cfp->iseq == iseq)
+	    return cfp->me;
+	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+    }
+    return 0;
+}
+
 static ID
 frame_func_id(rb_control_frame_t *cfp)
 {
+    const rb_method_entry_t *me_local;
     rb_iseq_t *iseq = cfp->iseq;
-    if (!iseq) {
-	if (!cfp->me) return 0;
+    if (cfp->me) {
 	return cfp->me->def->original_id;
     }
     while (iseq) {
@@ -767,6 +782,10 @@
 	    if (ifunc->nd_aid) return ifunc->nd_aid;
 	    return rb_intern("<ifunc>");
 	}
+	me_local = method_entry_of_iseq(cfp, iseq);
+	if (me_local) {
+	    return me_local->def->original_id;
+	}
 	if (iseq->defined_method_id) {
 	    return iseq->defined_method_id;
 	}
Index: test/ruby/test_method.rb
===================================================================
--- test/ruby/test_method.rb	(revision 31435)
+++ test/ruby/test_method.rb	(revision 31436)
@@ -92,6 +92,32 @@
     assert_nil(eval("class TestCallee; __method__; end"))
   end
 
+  def test_method_in_define_method_block
+    bug4606 = '[ruby-core:35386]'
+    c = Class.new do
+      [:m1, :m2].each do |m|
+        define_method(m) do
+          __method__
+        end
+      end
+    end
+    assert_equal(:m1, c.new.m1, bug4606)
+    assert_equal(:m2, c.new.m2, bug4606)
+  end
+
+  def test_method_in_block_in_define_method_block
+    bug4606 = '[ruby-core:35386]'
+    c = Class.new do
+      [:m1, :m2].each do |m|
+        define_method(m) do
+          tap { return __method__ }
+        end
+      end
+    end
+    assert_equal(:m1, c.new.m1, bug4606)
+    assert_equal(:m2, c.new.m2, bug4606)
+  end
+
   def test_body
     o = Object.new
     def o.foo; end

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

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