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

ruby-changes:24733

From: tenderlove <ko1@a...>
Date: Thu, 23 Aug 2012 01:51:19 +0900 (JST)
Subject: [ruby-changes:24733] tenderlove:r36784 (trunk): * insns.def: search up the cf stack for an object that is an instance

tenderlove	2012-08-23 01:51:08 +0900 (Thu, 23 Aug 2012)

  New Revision: 36784

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

  Log:
    * insns.def: search up the cf stack for an object that is an instance
      of the recipient class.  Fixes [ruby-core:47186]
    
    * test/ruby/test_super.rb: related test.

  Modified files:
    trunk/ChangeLog
    trunk/insns.def
    trunk/test/ruby/test_super.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 36783)
+++ ChangeLog	(revision 36784)
@@ -1,3 +1,10 @@
+Thu Aug 23 01:46:53 2012  Aaron Patterson <aaron@t...>
+
+	* insns.def: search up the cf stack for an object that is an instance
+	  of the recipient class.  Fixes [ruby-core:47186]
+
+	* test/ruby/test_super.rb: related test.
+
 Wed Aug 22 19:46:24 2012  Tadayoshi Funaba  <tadf@d...>
 
 	* ext/date/date_core.c: [ruby-core:47266].
Index: insns.def
===================================================================
--- insns.def	(revision 36783)
+++ insns.def	(revision 36784)
@@ -1034,11 +1034,17 @@
 
     flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
 
+    klass = GET_CFP()->klass;
+    if (!NIL_P(RCLASS_REFINED_CLASS(klass))) {
+	klass = RCLASS_REFINED_CLASS(klass);
+    }
+
     recv = Qundef;
     while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
-	if ((VM_EP_LEP_P(cfp->ep) && cfp->iseq &&
+	if (((VM_EP_LEP_P(cfp->ep) && cfp->iseq &&
 	     cfp->iseq->type == ISEQ_TYPE_METHOD) ||
-	    (cfp->me && cfp->me->def->type == VM_METHOD_TYPE_BMETHOD)) {
+	    (cfp->me && cfp->me->def->type == VM_METHOD_TYPE_BMETHOD)) &&
+            rb_obj_is_kind_of(cfp->self, klass)) {
 	    recv = cfp->self;
 	    break;
 	}
@@ -1047,13 +1053,6 @@
     if (recv == Qundef) {
 	rb_raise(rb_eNoMethodError, "super called outside of method");
     }
-    klass = GET_CFP()->klass;
-    if (!NIL_P(RCLASS_REFINED_CLASS(klass))) {
-	klass = RCLASS_REFINED_CLASS(klass);
-    }
-    if (!rb_obj_is_kind_of(recv, klass)) {
-	rb_raise(rb_eNoMethodError, "can't find the method for super, which may be called in an orphan block");
-    }
     vm_search_superclass(GET_CFP(), GET_ISEQ(), TOPN(num), &id, &klass);
 
     ip = GET_ISEQ();
Index: test/ruby/test_super.rb
===================================================================
--- test/ruby/test_super.rb	(revision 36783)
+++ test/ruby/test_super.rb	(revision 36784)
@@ -322,4 +322,16 @@
       obj.foo.call
     end
   end
+
+  def test_yielding_super
+    a = Class.new { def yielder; yield; end }
+    x = Class.new { define_singleton_method(:hello) { 'hi' } }
+    y = Class.new(x) {
+      define_singleton_method(:hello) {
+        m = a.new
+        m.yielder { super() }
+      }
+    }
+    assert_equal 'hi', y.hello
+  end
 end

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

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