summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-08-24 23:27:35 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-08-24 23:27:35 +0000
commit382ed4285ae504c34a002536b922c0ca7cbd0a33 (patch)
tree9a1bc1144916ef28276df925b307f7515d874cbd /vm.c
parent7a3f54edb1656a7ad068c54e4084123beef2aafa (diff)
* 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/branches/ruby_1_9_3@33063 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/vm.c b/vm.c
index 3147ae4c73..4805e286e7 100644
--- a/vm.c
+++ b/vm.c
@@ -415,6 +415,23 @@ vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp,
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
/* TODO */
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;
}