1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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
This commit is contained in:
ko1 2015-12-16 06:38:52 +00:00
parent c4fdfabcc8
commit 5dc676a5cf
3 changed files with 42 additions and 7 deletions

View file

@ -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]

View file

@ -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

15
vm.c
View file

@ -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);