Skip to content

Commit

Permalink
* vm_insnhelper.c (vm_throw): fix "return" process from "lambda".
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
ko1 committed Jun 19, 2008
1 parent 33e5cfe commit c3e619c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 16 deletions.
8 changes: 8 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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]
Expand Down
17 changes: 17 additions & 0 deletions bootstraptest/pending.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,20 @@ def a
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
}
14 changes: 14 additions & 0 deletions bootstraptest/test_proc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,17 @@ def def12
def12
$x
}, '[ruby-core:17164]'

assert_equal 'ok', %q{
def m
pr = proc{
proc{
return :ok
}
}.call
pr.call
:ng
end
m()
}

34 changes: 18 additions & 16 deletions vm_insnhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit c3e619c

Please sign in to comment.