Created
August 27, 2011 06:22
-
-
Save k-tsj/1175062 to your computer and use it in GitHub Desktop.
kludge fix for Bug #5234
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/proc.c b/proc.c | |
index 299a220..0a98207 100644 | |
--- a/proc.c | |
+++ b/proc.c | |
@@ -418,6 +418,7 @@ proc_new(VALUE klass, int is_lambda) | |
} | |
procval = rb_vm_make_proc(th, block, klass); | |
+ rb_rewrite_dfp_in_errinfo(th, cfp); | |
if (is_lambda) { | |
rb_proc_t *proc; | |
diff --git a/vm.c b/vm.c | |
index c9c2e2b..db3d416 100644 | |
--- a/vm.c | |
+++ b/vm.c | |
@@ -410,22 +410,7 @@ vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp, | |
/* 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)); | |
- } | |
- } | |
- } | |
- } | |
+ rb_rewrite_dfp_in_errinfo(th, cfp); | |
} | |
return envval; | |
} | |
@@ -488,6 +473,28 @@ rb_vm_make_env_object(rb_thread_t * th, rb_control_frame_t *cfp) | |
return envval; | |
} | |
+VALUE | |
+rb_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp) | |
+{ | |
+ /* rewrite dfp in errinfo to point to heap */ | |
+ if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) && | |
+ (cfp->iseq->type == ISEQ_TYPE_RESCUE || | |
+ cfp->iseq->type == ISEQ_TYPE_ENSURE)) { | |
+ VALUE errinfo = cfp->dfp[-2]; /* #$! */ | |
+ 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)); | |
+ } | |
+ } | |
+ } | |
+ } | |
+} | |
+ | |
void | |
rb_vm_stack_to_heap(rb_thread_t *th) | |
{ | |
diff --git a/vm_core.h b/vm_core.h | |
index 269e22d..8181ca5 100644 | |
--- a/vm_core.h | |
+++ b/vm_core.h | |
@@ -649,6 +649,7 @@ VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, | |
int argc, const VALUE *argv, const rb_block_t *blockptr); | |
VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass); | |
VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp); | |
+VALUE rb_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp); | |
void rb_vm_inc_const_missing_count(void); | |
void rb_vm_gvl_destroy(rb_vm_t *vm); | |
VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment