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
|
||
}
|