зеркало из https://github.com/github/ruby.git
* vm.c (vm_make_env_each): work around to solve Bug #2729.
fixes: Bug #2729 a patch from Kazuki Tsujimoto <kazuki@callcc.net> This problem is caused by changing dfp (dynamic env pointer) from saved dfp. Saved dfp is pointed env in VM stack. However, the dfp can be moved because VM copies env from VM stack to the heap. At this copying, dfp was also changed. To solve this problem, I'll try to change throw mechanism (not save target dfp, but save target cfp). * bootstraptest/test_flow.rb: add a test for above. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33064 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
85e24491a6
Коммит
ef039de560
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
Thu Aug 25 08:19:43 2011 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* vm.c (vm_make_env_each): work around to solve Bug #2729.
|
||||||
|
fixes: Bug #2729
|
||||||
|
a patch from Kazuki Tsujimoto <kazuki@callcc.net>
|
||||||
|
This problem is caused by changing dfp (dynamic env pointer)
|
||||||
|
from saved dfp. Saved dfp is pointed env in VM stack. However,
|
||||||
|
the dfp can be moved because VM copies env from VM stack to
|
||||||
|
the heap. At this copying, dfp was also changed. To solve this
|
||||||
|
problem, I'll try to change throw mechanism (not save target dfp,
|
||||||
|
but save target cfp).
|
||||||
|
|
||||||
|
* bootstraptest/test_flow.rb: add a test for above.
|
||||||
|
|
||||||
Thu Aug 25 07:57:33 2011 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
Thu Aug 25 07:57:33 2011 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
||||||
|
|
||||||
* numeric.c (int_round): Fix Integer#round [ruby-core:39096]
|
* numeric.c (int_round): Fix Integer#round [ruby-core:39096]
|
||||||
|
|
|
@ -517,6 +517,19 @@ assert_equal %Q{ENSURE\n}, %q{
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
e = Bug2728.new
|
e = Bug2728.new
|
||||||
|
}],
|
||||||
|
['[ruby-core:28132]', %q{
|
||||||
|
class Bug2729
|
||||||
|
include Enumerable
|
||||||
|
def each
|
||||||
|
begin
|
||||||
|
yield :foo
|
||||||
|
ensure
|
||||||
|
proc {}.call
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
e = Bug2729.new
|
||||||
}]].each do |bug, src|
|
}]].each do |bug, src|
|
||||||
assert_equal "foo", src + %q{e.detect {true}}, bug
|
assert_equal "foo", src + %q{e.detect {true}}, bug
|
||||||
assert_equal "true", src + %q{e.any? {true}}, bug
|
assert_equal "true", src + %q{e.any? {true}}, bug
|
||||||
|
|
17
vm.c
17
vm.c
|
@ -409,6 +409,23 @@ vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp,
|
||||||
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
env->block.iseq = 0;
|
env->block.iseq = 0;
|
||||||
|
} else {
|
||||||
|
/* rewrite dfp in errinfo to point to heap */
|
||||||
|
if (cfp->iseq->type == ISEQ_TYPE_RESCUE ||
|
||||||
|
cfp->iseq->type == ISEQ_TYPE_ENSURE) {
|
||||||
|
VALUE errinfo = env->env[0]; /* #$! */
|
||||||
|
if (RB_TYPE_P(errinfo, T_NODE)) {
|
||||||
|
VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(errinfo);
|
||||||
|
if (! ENV_IN_HEAP_P(th, escape_dfp)) {
|
||||||
|
VALUE dfpval = *escape_dfp;
|
||||||
|
if (CLASS_OF(dfpval) == rb_cEnv) {
|
||||||
|
rb_env_t *dfpenv;
|
||||||
|
GetEnvPtr(dfpval, dfpenv);
|
||||||
|
SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(dfpenv->env + dfpenv->local_size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return envval;
|
return envval;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче