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

ruby-changes:33486

From: nobu <ko1@a...>
Date: Fri, 11 Apr 2014 15:05:35 +0900 (JST)
Subject: [ruby-changes:33486] nobu:r45565 (trunk): proc.c: fix super in bound UnboundMethod

nobu	2014-04-11 15:05:28 +0900 (Fri, 11 Apr 2014)

  New Revision: 45565

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

  Log:
    proc.c: fix super in bound UnboundMethod
    
    * proc.c (rb_method_call_with_block, umethod_bind): call with
      IClass including the module for a module instance method.
      [ruby-core:61936] [Bug #9721]
    * vm_insnhelper.c (vm_search_super_method): allow bound
      UnboundMethod case.

  Modified files:
    trunk/ChangeLog
    trunk/proc.c
    trunk/test/ruby/test_super.rb
    trunk/vm_insnhelper.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 45564)
+++ ChangeLog	(revision 45565)
@@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Apr 11 15:05:26 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* proc.c (rb_method_call_with_block, umethod_bind): call with
+	  IClass including the module for a module instance method.
+	  [ruby-core:61936] [Bug #9721]
+
+	* vm_insnhelper.c (vm_search_super_method): allow bound
+	  UnboundMethod case.
+
 Fri Apr 11 12:02:30 2014  NARUSE, Yui  <naruse@r...>
 
 	* addr2line.c (rb_dump_backtrace_with_lines): set base address
Index: proc.c
===================================================================
--- proc.c	(revision 45564)
+++ proc.c	(revision 45565)
@@ -1891,6 +1891,7 @@ rb_method_call_with_block(int argc, VALU https://github.com/ruby/ruby/blob/trunk/proc.c#L1891
     if ((state = EXEC_TAG()) == 0) {
 	rb_thread_t *th = GET_THREAD();
 	rb_block_t *block = 0;
+	VALUE defined_class;
 
 	if (!NIL_P(pass_procval)) {
 	    rb_proc_t *pass_proc;
@@ -1900,7 +1901,9 @@ rb_method_call_with_block(int argc, VALU https://github.com/ruby/ruby/blob/trunk/proc.c#L1901
 
 	th->passed_block = block;
 	VAR_INITIALIZED(data);
-	result = rb_vm_call(th, data->recv, data->id,  argc, argv, data->me, data->defined_class);
+	defined_class = data->defined_class;
+	if (BUILTIN_TYPE(defined_class) == T_MODULE) defined_class = data->rclass;
+	result = rb_vm_call(th, data->recv, data->id, argc, argv, data->me, defined_class);
     }
     POP_TAG();
     if (safe >= 0)
@@ -2006,6 +2009,7 @@ umethod_bind(VALUE method, VALUE recv) https://github.com/ruby/ruby/blob/trunk/proc.c#L2009
 {
     struct METHOD *data, *bound;
     VALUE methclass;
+    VALUE rclass;
 
     TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
 
@@ -2027,8 +2031,12 @@ umethod_bind(VALUE method, VALUE recv) https://github.com/ruby/ruby/blob/trunk/proc.c#L2031
     bound->me = ALLOC(rb_method_entry_t);
     *bound->me = *data->me;
     if (bound->me->def) bound->me->def->alias_count++;
+    rclass = CLASS_OF(recv);
+    if (BUILTIN_TYPE(bound->defined_class) == T_MODULE) {
+	rclass = rb_include_class_new(methclass, rclass);
+    }
     bound->recv = recv;
-    bound->rclass = CLASS_OF(recv);
+    bound->rclass = rclass;
     data->ume = ALLOC(struct unlinked_method_entry_list_entry);
 
     return method;
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 45564)
+++ vm_insnhelper.c	(revision 45565)
@@ -2034,6 +2034,7 @@ vm_search_super_method(rb_thread_t *th, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2034
     }
 
     if (BUILTIN_TYPE(current_defined_class) != T_MODULE &&
+	BUILTIN_TYPE(current_defined_class) != T_ICLASS && /* bound UnboundMethod */
 	!FL_TEST(current_defined_class, RMODULE_INCLUDED_INTO_REFINEMENT) &&
 	!rb_obj_is_kind_of(ci->recv, current_defined_class)) {
 	VALUE m = RB_TYPE_P(current_defined_class, T_ICLASS) ?
Index: test/ruby/test_super.rb
===================================================================
--- test/ruby/test_super.rb	(revision 45564)
+++ test/ruby/test_super.rb	(revision 45565)
@@ -452,4 +452,28 @@ class TestSuper < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_super.rb#L452
       m.call
     end
   end
+
+  def test_super_in_module_unbound_method
+    bug9721 = '[ruby-core:61936] [Bug #9721]'
+
+    a = Module.new do
+      def foo(result)
+        result << "A"
+      end
+    end
+
+    b = Module.new do
+      def foo(result)
+        result << "B"
+        super
+      end
+    end
+
+    m = b.instance_method(:foo).bind(Object.new.extend(a))
+    result = []
+    assert_nothing_raised(NoMethodError, bug9721) do
+      m.call(result)
+    end
+    assert_equal(%w[B A], result, bug9721)
+  end
 end

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

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