1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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:
ko1 2008-06-19 02:46:02 +00:00
parent 33e5cfee7b
commit c3e619c83d
4 changed files with 57 additions and 16 deletions

View file

@ -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>
* test/etc/test_etc.rb: avoid infinite loop. [ruby-dev:35158]

View file

@ -13,3 +13,20 @@ assert_equal 'A', %q{
B.new.a = 'B'
A.new.a
}, '[ruby-core:17019]'
assert_equal 'ok', %q{
def m
lambda{
proc{
return :ng1
}
}.call.call
:ng2
end
begin
m()
rescue LocalJumpError
:ok
end
}

View file

@ -364,3 +364,17 @@ assert_equal 'ok', %q{
def12
$x
}, '[ruby-core:17164]'
assert_equal 'ok', %q{
def m
pr = proc{
proc{
return :ok
}
}.call
pr.call
:ng
end
m()
}

View file

@ -1279,34 +1279,36 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
else if (state == TAG_RETURN) {
rb_control_frame_t *cfp = GET_CFP();
VALUE *dfp = GET_DFP();
int is_orphan = 1;
VALUE * const lfp = GET_LFP();
/**
* check orphan:
*/
/* check orphan and get dfp */
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) {
/* in lambda */
is_orphan = 0;
break;
}
VALUE *tdfp = dfp;
if (GET_LFP() == dfp && cfp->iseq->type == ISEQ_TYPE_METHOD) {
is_orphan = 0;
break;
while (lfp != tdfp) {
if (cfp->dfp == tdfp) {
/* 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);
}
if (is_orphan) {
vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
}
vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
valid_return:
pt = dfp;
}
else {