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

ruby-changes:29308

From: ktsj <ko1@a...>
Date: Mon, 17 Jun 2013 21:47:38 +0900 (JST)
Subject: [ruby-changes:29308] ktsj:r41360 (trunk): * include/ruby/ruby.h, vm_eval.c (rb_funcall_with_block):

ktsj	2013-06-17 21:47:26 +0900 (Mon, 17 Jun 2013)

  New Revision: 41360

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

  Log:
    * include/ruby/ruby.h, vm_eval.c (rb_funcall_with_block):
      new function to invoke a method with a block passed
      as an argument.
    
    * string.c (sym_call): use the above function to avoid
      a block sharing. [ruby-dev:47438] [Bug #8531]
    
    * vm_insnhelper.c (vm_yield_with_cfunc): don't set block
      in the frame.
    
    * test/ruby/test_symbol.rb (TestSymbol#test_block_given_to_proc):
      run related tests.

  Modified files:
    trunk/ChangeLog
    trunk/include/ruby/ruby.h
    trunk/string.c
    trunk/test/ruby/test_symbol.rb
    trunk/vm_eval.c
    trunk/vm_insnhelper.c

Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 41359)
+++ include/ruby/ruby.h	(revision 41360)
@@ -1480,6 +1480,7 @@ VALUE rb_funcallv_public(VALUE, ID, int, https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1480
 #define rb_funcall2 rb_funcallv
 #define rb_funcall3 rb_funcallv_public
 VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE*);
+VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE*, VALUE);
 int rb_scan_args(int, const VALUE*, const char*, ...);
 VALUE rb_call_super(int, const VALUE*);
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 41359)
+++ ChangeLog	(revision 41360)
@@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Jun 17 21:42:18 2013  Kazuki Tsujimoto  <kazuki@c...>
+
+	* include/ruby/ruby.h, vm_eval.c (rb_funcall_with_block):
+	  new function to invoke a method with a block passed
+	  as an argument.
+
+	* string.c (sym_call): use the above function to avoid
+	  a block sharing. [ruby-dev:47438] [Bug #8531]
+
+	* vm_insnhelper.c (vm_yield_with_cfunc): don't set block
+	  in the frame.
+
+	* test/ruby/test_symbol.rb (TestSymbol#test_block_given_to_proc):
+	  run related tests.
+
 Mon Jun 17 21:33:27 2013  Kazuki Tsujimoto  <kazuki@c...>
 
 	* include/ruby/intern.h, proc.c (rb_method_call_with_block):
Index: string.c
===================================================================
--- string.c	(revision 41359)
+++ string.c	(revision 41360)
@@ -8213,7 +8213,7 @@ sym_to_sym(VALUE sym) https://github.com/ruby/ruby/blob/trunk/string.c#L8213
 }
 
 static VALUE
-sym_call(VALUE args, VALUE sym, int argc, VALUE *argv)
+sym_call(VALUE args, VALUE sym, int argc, VALUE *argv, VALUE passed_proc)
 {
     VALUE obj;
 
@@ -8221,7 +8221,7 @@ sym_call(VALUE args, VALUE sym, int argc https://github.com/ruby/ruby/blob/trunk/string.c#L8221
 	rb_raise(rb_eArgError, "no receiver given");
     }
     obj = argv[0];
-    return rb_funcall_passing_block(obj, (ID)sym, argc - 1, argv + 1);
+    return rb_funcall_with_block(obj, (ID)sym, argc - 1, argv + 1, passed_proc);
 }
 
 /*
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 41359)
+++ vm_eval.c	(revision 41360)
@@ -830,6 +830,23 @@ rb_funcall_passing_block(VALUE recv, ID https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L830
     return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
 }
 
+VALUE
+rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE pass_procval)
+{
+    if (!NIL_P(pass_procval)) {
+	rb_thread_t *th = GET_THREAD();
+	rb_block_t *block = 0;
+
+	rb_proc_t *pass_proc;
+	GetProcPtr(pass_procval, pass_proc);
+	block = &pass_proc->block;
+
+	th->passed_block = block;
+    }
+
+    return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
+}
+
 static VALUE
 send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
 {
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 41359)
+++ vm_insnhelper.c	(revision 41360)
@@ -2076,7 +2076,6 @@ vm_yield_with_cfunc(rb_thread_t *th, con https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2076
     NODE *ifunc = (NODE *) block->iseq;
     VALUE val, arg, blockarg;
     int lambda = block_proc_is_lambda(block->proc);
-    rb_control_frame_t *cfp;
 
     if (lambda) {
 	arg = rb_ary_new4(argc, argv);
@@ -2100,13 +2099,10 @@ vm_yield_with_cfunc(rb_thread_t *th, con https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2099
 	blockarg = Qnil;
     }
 
-    cfp = vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
-			0, VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
-			th->cfp->sp, 1, 0);
+    vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
+		  0, VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
+		  th->cfp->sp, 1, 0);
 
-    if (blockargptr) {
-	VM_CF_LEP(cfp)[0] = VM_ENVVAL_BLOCK_PTR(blockargptr);
-    }
     val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, argc, argv, blockarg);
 
     th->cfp++;
Index: test/ruby/test_symbol.rb
===================================================================
--- test/ruby/test_symbol.rb	(revision 41359)
+++ test/ruby/test_symbol.rb	(revision 41360)
@@ -128,7 +128,6 @@ class TestSymbol < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_symbol.rb#L128
 
   def test_block_given_to_proc
     bug8531 = '[Bug #8531]'
-    skip bug8531
     m = :m_block_given?.to_proc
     assert(!m.call(self), "#{bug8531} without block")
     assert(m.call(self) {}, "#{bug8531} with block")

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

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