diff options
author | David Mitchell <davem@iabyn.com> | 2015-06-09 15:48:15 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2015-06-19 08:44:18 +0100 |
commit | 334ea179145c48d0a781ab77c8b4d619e0036cf6 (patch) | |
tree | d447625ffbf4a288a9d87425522196b671ceb50c | |
parent | 1f0ba93b9eac4ae12dd4b0e2702f798a6cbf224c (diff) | |
download | perl-334ea179145c48d0a781ab77c8b4d619e0036cf6.tar.gz |
pp_return(): tail call pp_leavetry()
When 'return'ing from an eval { BLOCK }, rather than handling it
ourselves, fall through to pp_leavetry(). pp_return() is now only
responsible for popping any extra contexts and junk from the stack.
This helps avoid two different blocks of code doing roughly the same
thing.
The functional changes caused by this commit signify the divergence over
time between pp_leavetry and the try-ish parts of pp_return. After this
commit, a return will:
* now do an PERL_ASYNC_CHECK();
* be smarter about not unnecessarily creating mortal copies
of returned args;
* restore PL_curpm *before* the LEAVE() rather than after.
The first two are probably good things; I'm not sure about the latter; it
may well be a regression, but nothing tests for it. At least it's
consistent now.
-rw-r--r-- | pp_ctl.c | 12 |
1 files changed, 8 insertions, 4 deletions
@@ -2448,7 +2448,9 @@ PP(pp_return) cx = &cxstack[cxix]; - if (CxTYPE(cx) == CXt_SUB) { + if (CxTYPE(cx) == CXt_SUB + || (CxTYPE(cx) == CXt_EVAL && CxTRYBLOCK(cx))) + { SV **oldsp = PL_stack_base + cx->blk_oldsp; if (oldsp != MARK) { /* Handle extra junk on the stack. For example, @@ -2473,6 +2475,8 @@ PP(pp_return) else PL_stack_sp = oldsp; } + if (CxTYPE(cx) == CXt_EVAL) + return Perl_pp_leavetry(aTHX); /* fall through to a normal sub exit */ return CvLVALUE(cx->blk_sub.cv) ? Perl_pp_leavesublv(aTHX) @@ -2487,8 +2491,6 @@ PP(pp_return) POPEVAL(cx); namesv = cx->blk_eval.old_namesv; retop = cx->blk_eval.retop; - if (CxTRYBLOCK(cx)) - break; if (optype == OP_REQUIRE && (MARK == SP || (gimme == G_SCALAR && !SvTRUE(*SP))) ) { @@ -4379,9 +4381,11 @@ PP(pp_leavetry) I32 gimme; PERL_CONTEXT *cx; I32 optype; + OP *retop; PERL_ASYNC_CHECK(); POPBLOCK(cx,newpm); + retop = cx->blk_eval.retop; POPEVAL(cx); PERL_UNUSED_VAR(optype); @@ -4391,7 +4395,7 @@ PP(pp_leavetry) LEAVE_with_name("eval_scope"); CLEAR_ERRSV(); - RETURN; + RETURNOP(retop); } PP(pp_entergiven) |