* vm_insnhelper.c (vm_throw): fix "return" process from "lambda".
* bootstraptest/test_proc.rb: add a test. * bootstraptest/pending.rb: add a pending bug. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17421 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
33e5cfee7b
commit
c3e619c83d
@ -1,3 +1,11 @@
|
|||||||
|
Thu Jun 19 11:40:55 2008 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* vm_insnhelper.c (vm_throw): fix "return" process from "lambda".
|
||||||
|
|
||||||
|
* bootstraptest/test_proc.rb: add a test.
|
||||||
|
|
||||||
|
* bootstraptest/pending.rb: add a pending bug.
|
||||||
|
|
||||||
Thu Jun 19 00:33:40 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
Thu Jun 19 00:33:40 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
* test/etc/test_etc.rb: avoid infinite loop. [ruby-dev:35158]
|
* test/etc/test_etc.rb: avoid infinite loop. [ruby-dev:35158]
|
||||||
|
@ -13,3 +13,20 @@ assert_equal 'A', %q{
|
|||||||
B.new.a = 'B'
|
B.new.a = 'B'
|
||||||
A.new.a
|
A.new.a
|
||||||
}, '[ruby-core:17019]'
|
}, '[ruby-core:17019]'
|
||||||
|
|
||||||
|
assert_equal 'ok', %q{
|
||||||
|
def m
|
||||||
|
lambda{
|
||||||
|
proc{
|
||||||
|
return :ng1
|
||||||
|
}
|
||||||
|
}.call.call
|
||||||
|
:ng2
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
m()
|
||||||
|
rescue LocalJumpError
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
}
|
||||||
|
@ -364,3 +364,17 @@ assert_equal 'ok', %q{
|
|||||||
def12
|
def12
|
||||||
$x
|
$x
|
||||||
}, '[ruby-core:17164]'
|
}, '[ruby-core:17164]'
|
||||||
|
|
||||||
|
assert_equal 'ok', %q{
|
||||||
|
def m
|
||||||
|
pr = proc{
|
||||||
|
proc{
|
||||||
|
return :ok
|
||||||
|
}
|
||||||
|
}.call
|
||||||
|
pr.call
|
||||||
|
:ng
|
||||||
|
end
|
||||||
|
m()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1279,34 +1279,36 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
|
|||||||
else if (state == TAG_RETURN) {
|
else if (state == TAG_RETURN) {
|
||||||
rb_control_frame_t *cfp = GET_CFP();
|
rb_control_frame_t *cfp = GET_CFP();
|
||||||
VALUE *dfp = GET_DFP();
|
VALUE *dfp = GET_DFP();
|
||||||
int is_orphan = 1;
|
VALUE * const lfp = GET_LFP();
|
||||||
|
|
||||||
/**
|
/* check orphan and get dfp */
|
||||||
* check orphan:
|
|
||||||
*/
|
|
||||||
while ((VALUE *) cfp < th->stack + th->stack_size) {
|
while ((VALUE *) cfp < th->stack + th->stack_size) {
|
||||||
if (dfp == cfp->dfp) {
|
if (cfp->lfp == lfp) {
|
||||||
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
|
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
|
||||||
/* in lambda */
|
VALUE *tdfp = dfp;
|
||||||
is_orphan = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GET_LFP() == dfp && cfp->iseq->type == ISEQ_TYPE_METHOD) {
|
while (lfp != tdfp) {
|
||||||
is_orphan = 0;
|
if (cfp->dfp == tdfp) {
|
||||||
break;
|
/* in lambda */
|
||||||
|
dfp = cfp->dfp;
|
||||||
|
goto valid_return;
|
||||||
|
}
|
||||||
|
tdfp = GC_GUARDED_PTR_REF((VALUE *)*dfp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dfp = GC_GUARDED_PTR_REF(dfp[0]);
|
if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_METHOD) {
|
||||||
|
dfp = lfp;
|
||||||
|
goto valid_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_orphan) {
|
vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
|
||||||
vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
valid_return:
|
||||||
pt = dfp;
|
pt = dfp;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user