diff --git a/vm.c b/vm.c index 3c1e8b4..63514f5 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; }