Bug #6460 ยป 6460-1_9_3.patch
bootstraptest/test_flow.rb | ||
---|---|---|
end
|
||
end
|
||
e = Bug5234.new
|
||
}],
|
||
['[ruby-dev:45656]', %q{
|
||
class Bug6460
|
||
include Enumerable
|
||
def each
|
||
begin
|
||
yield :foo
|
||
ensure
|
||
1.times { Proc.new }
|
||
end
|
||
end
|
||
end
|
||
e = Bug6460.new
|
||
}]].each do |bug, src|
|
||
assert_equal "foo", src + %q{e.detect {true}}, bug
|
||
assert_equal "true", src + %q{e.any? {true}}, bug
|
proc.c | ||
---|---|---|
}
|
||
procval = rb_vm_make_proc(th, block, klass);
|
||
rb_vm_rewrite_dfp_in_errinfo(th, cfp);
|
||
if (is_lambda) {
|
||
rb_proc_t *proc;
|
vm.c | ||
---|---|---|
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
||
/* TODO */
|
||
env->block.iseq = 0;
|
||
} else {
|
||
rb_vm_rewrite_dfp_in_errinfo(th, cfp);
|
||
}
|
||
return envval;
|
||
}
|
||
... | ... | |
}
|
||
envval = vm_make_env_each(th, cfp, cfp->dfp, cfp->lfp);
|
||
rb_vm_rewrite_dfp_in_errinfo(th);
|
||
if (PROCDEBUG) {
|
||
check_env_value(envval);
|
||
... | ... | |
}
|
||
void
|
||
rb_vm_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));
|
||
rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th)
|
||
{
|
||
rb_control_frame_t *cfp = th->cfp;
|
||
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, 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));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||
}
|
||
}
|
||
vm_core.h | ||
---|---|---|
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);
|
||
void rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp);
|
||
void rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th);
|
||
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,
|