aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-16 06:38:52 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-16 06:38:52 +0000
commitf77311678258a99302e6fb8ea2d60bc21f2039b2 (patch)
tree1e38869108174aa271b1358f0ef44b6a0e9cca89
parent6319c35c15c452cfe5c050be0a177d82d1351300 (diff)
downloadruby-f77311678258a99302e6fb8ea2d60bc21f2039b2.tar.gz
* vm.c: fix mark miss for proc given as passed block.
[Bug #11750] * vm.c (vm_make_proc_from_block): should return a Proc object if block is given. Previous implementation returns a Proc object only when corresponding Proc object is not available. * vm.c (vm_make_env_each): ditto. * test/ruby/test_proc.rb: add a test for this bug. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53144 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog14
-rw-r--r--test/ruby/test_proc.rb20
-rw-r--r--vm.c15
3 files changed, 42 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 30a9395a4f..b4de39f34b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Wed Dec 16 15:35:13 2015 Koichi Sasada <ko1@atdot.net>
+
+ * vm.c: fix mark miss for proc given as passed block.
+ [Bug #11750]
+
+ * vm.c (vm_make_proc_from_block): should return a Proc object
+ if block is given. Previous implementation returns
+ a Proc object only when corresponding Proc object is not
+ available.
+
+ * vm.c (vm_make_env_each): ditto.
+
+ * test/ruby/test_proc.rb: add a test for this bug.
+
Wed Dec 16 12:24:59 2015 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
* test_struct.rb: Test that initialize is overridable [#11708]
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index fa247f2fc0..b67773b7f8 100644
--- a/test/ruby/test_proc.rb
+++ b/test/ruby/test_proc.rb
@@ -1321,4 +1321,24 @@ class TestProc < Test::Unit::TestCase
def obj.b; binding; end
assert_same(obj, obj.b.receiver, feature8779)
end
+
+ def test_proc_mark
+ assert_normal_exit(<<-'EOS')
+ def f
+ Enumerator.new{
+ 100000.times {|i|
+ yield
+ s = "#{i}"
+ }
+ }
+ end
+
+ def g
+ x = proc{}
+ f(&x)
+ end
+ e = g
+ e.each {}
+ EOS
+ end
end
diff --git a/vm.c b/vm.c
index 5e8d555556..087cba7250 100644
--- a/vm.c
+++ b/vm.c
@@ -559,16 +559,17 @@ check_env_value(VALUE envval)
return Qnil; /* unreachable */
}
-/* return Qfalse if proc was already created */
-static VALUE
-vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block)
+/* return FALSE if proc was already created */
+static int
+vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block, VALUE *procptr)
{
if (!block->proc) {
- block->proc = rb_vm_make_proc(th, block, rb_cProc);
- return block->proc;
+ *procptr = block->proc = rb_vm_make_proc(th, block, rb_cProc);
+ return TRUE;
}
else {
- return Qfalse;
+ *procptr = block->proc;
+ return FALSE;
}
}
@@ -603,7 +604,7 @@ vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
else {
rb_block_t *block = VM_EP_BLOCK_PTR(ep);
- if (block && (blockprocval = vm_make_proc_from_block(th, block)) != Qfalse) {
+ if (block && (vm_make_proc_from_block(th, block, &blockprocval)) != Qfalse) {
rb_proc_t *p;
GetProcPtr(blockprocval, p);
*ep = VM_ENVVAL_BLOCK_PTR(&p->block);