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:
parent
33e5cfee7b
commit
c3e619c83d
4 changed files with 57 additions and 16 deletions
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue