Bug #4648 » return_from_class_frame.patch
| vm_insnhelper.c | ||
|---|---|---|
|
rb_control_frame_t *cfp = GET_CFP();
|
||
|
VALUE *dfp = GET_DFP();
|
||
|
VALUE *lfp = GET_LFP();
|
||
|
int in_class_frame = 0;
|
||
|
/* check orphan and get dfp */
|
||
|
while ((VALUE *) cfp < th->stack + th->stack_size) {
|
||
| ... | ... | |
|
lfp = cfp->lfp;
|
||
|
}
|
||
|
if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_CLASS) {
|
||
|
in_class_frame = 1;
|
||
|
lfp = 0;
|
||
|
}
|
||
| ... | ... | |
|
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
|
||
|
VALUE *tdfp = dfp;
|
||
|
if (in_class_frame) {
|
||
|
/* lambda {class A; ... return ...; end} */
|
||
|
dfp = cfp->dfp;
|
||
|
goto valid_return;
|
||
|
}
|
||
|
while (lfp != tdfp) {
|
||
|
if (cfp->dfp == tdfp) {
|
||
|
/* in lambda */
|
||
| bootstraptest/test_proc.rb | ||
|---|---|---|
|
raise "ok"
|
||
|
}
|
||
|
assert_equal 'ok', %q{
|
||
|
lambda do
|
||
|
class A
|
||
|
class B
|
||
|
proc{return :ng}.call
|
||
|
end
|
||
|
end
|
||
|
end.call
|
||
|
:ok
|
||
|
}
|
||
|
assert_equal 'ok', %q{
|
||
|
$proc = proc{return}
|
||
|
begin
|
||
|
lambda do
|
||
|
class A
|
||
|
class B
|
||
|
$proc.call
|
||
|
end
|
||
|
end
|
||
|
end.call
|
||
|
:ng
|
||
|
rescue LocalJumpError
|
||
|
:ok
|
||
|
end
|
||
|
}
|
||