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

ruby-changes:27829

From: nobu <ko1@a...>
Date: Sat, 23 Mar 2013 17:40:05 +0900 (JST)
Subject: [ruby-changes:27829] nobu:r39881 (trunk): vm_eval.c: preserve passed_block

nobu	2013-03-23 17:39:55 +0900 (Sat, 23 Mar 2013)

  New Revision: 39881

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

  Log:
    vm_eval.c: preserve passed_block
    
    * vm_eval.c (check_funcall_respond_to): preserve passed_block, which
      is modified in vm_call0_body() via vm_call0(), and caused a bug of
      rb_check_funcall() by false negative result of rb_block_given_p().
      re-fix [ruby-core:53650] [Bug #8153].
      [ruby-core:53653] [Bug #8154]

  Modified files:
    trunk/ChangeLog
    trunk/array.c
    trunk/vm_eval.c

Index: array.c
===================================================================
--- array.c	(revision 39880)
+++ array.c	(revision 39881)
@@ -17,7 +17,6 @@ https://github.com/ruby/ruby/blob/trunk/array.c#L17
 #include "ruby/encoding.h"
 #include "internal.h"
 #include "probes.h"
-#include "node.h"
 #include "id.h"
 
 #ifndef ARRAY_DEBUG
@@ -3033,11 +3032,11 @@ rb_ary_delete_if(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L3032
 }
 
 static VALUE
-take_i(VALUE i, VALUE args, int argc, VALUE *argv)
+take_i(VALUE val, VALUE *args, int argc, VALUE *argv)
 {
-    NODE *memo = RNODE(args);
-    rb_ary_push(memo->u1.value, rb_enum_values_pack(argc, argv));
-    if (--memo->u3.cnt == 0) rb_iter_break();
+    if (args[1]-- == 0) rb_iter_break();
+    if (argc > 1) val = rb_ary_new4(argc, argv);
+    rb_ary_push(args[0], val);
     return Qnil;
 }
 
@@ -3045,19 +3044,18 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L3044
 take_items(VALUE obj, long n)
 {
     VALUE result = rb_check_array_type(obj);
-    NODE *memo;
+    VALUE args[2];
 
     if (!NIL_P(result)) return rb_ary_subseq(result, 0, n);
-    if (!rb_respond_to(obj, idEach)) {
-	rb_raise(rb_eTypeError, "wrong argument type %s (must respond to :each)",
-	    rb_obj_classname(obj));
-    }
     result = rb_ary_new2(n);
-    memo = NEW_MEMO(result, 0, n);
-    rb_block_call(obj, idEach, 0, 0, take_i, (VALUE)memo);
+    args[0] = result; args[1] = (VALUE)n;
+    if (rb_check_block_call(obj, idEach, 0, 0, take_i, (VALUE)args) == Qundef)
+        rb_raise(rb_eTypeError, "wrong argument type %s (must respond to :each)",
+            rb_obj_classname(obj));
     return result;
 }
 
+
 /*
  *  call-seq:
  *     ary.zip(arg, ...)                  -> new_ary
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 39880)
+++ ChangeLog	(revision 39881)
@@ -1,7 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
-Sat Mar 23 07:30:31 2013  Marc-Andre Lafortune  <ruby-core@m...>
+Sat Mar 23 17:39:49 2013  Nobuyoshi Nakada  <nobu@r...>
 
-	* array.c: Avoid zip bug by not using obsolete rb_check_block_call
-	  [Bug #8153]
+	* vm_eval.c (check_funcall_respond_to): preserve passed_block, which
+	  is modified in vm_call0_body() via vm_call0(), and caused a bug of
+	  rb_check_funcall() by false negative result of rb_block_given_p().
+	  re-fix [ruby-core:53650] [Bug #8153].
+	  [ruby-core:53653] [Bug #8154]
 
 Fri Mar 22 17:48:34 2013  Nobuyoshi Nakada  <nobu@r...>
 
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 39880)
+++ vm_eval.c	(revision 39881)
@@ -358,7 +358,8 @@ check_funcall_respond_to(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L358
     const rb_method_entry_t *me = rb_method_entry(klass, idRespond_to, &defined_class);
 
     if (me && !(me->flag & NOEX_BASIC)) {
-	VALUE args[2];
+	const rb_block_t *passed_block = th->passed_block;
+	VALUE args[2], result;
 	int arity = rb_method_entry_arity(me);
 
 	if (arity > 2)
@@ -368,7 +369,9 @@ check_funcall_respond_to(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L369
 
 	args[0] = ID2SYM(mid);
 	args[1] = Qtrue;
-	if (!RTEST(vm_call0(th, recv, idRespond_to, arity, args, me, defined_class))) {
+	result = vm_call0(th, recv, idRespond_to, arity, args, me, defined_class);
+	th->passed_block = passed_block;
+	if (!RTEST(result)) {
 	    return FALSE;
 	}
     }

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

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