diff options
author | David Mitchell <davem@iabyn.com> | 2015-06-11 09:57:43 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2015-06-19 08:44:18 +0100 |
commit | 1ef2b70a7cb09564d92d47d3d76af07c36455485 (patch) | |
tree | 7e8247ad0e29cff558add51f50975a508acc4b88 /pp_ctl.c | |
parent | 7051b8c3d4558ca104e4fd0a9b39141e79a8e67c (diff) | |
download | perl-1ef2b70a7cb09564d92d47d3d76af07c36455485.tar.gz |
pp_return: move 'die on require fail' later
In pp_leaveeval the test to die on require not returning a true value
is done late, after the return args have been processed, while in
pp_return it is checked *before* the args are processed. Move the test in
pp_return to after the args to make it more like pp_leaveeval. This is a
preparatory step in making pp_return eventually tail call pp_leaveeval.
It probably doesn't make any difference whether it's done early or late
(although arguably dying early is infinitesimally more efficient); but
since pp_leaveeval is going to be overwhelmingly a more common way of
returning from a require than pp_return, its seems prudent to to not mess
with the most widely used code path.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 24 |
1 files changed, 14 insertions, 10 deletions
@@ -2491,16 +2491,6 @@ PP(pp_return) POPEVAL(cx); namesv = cx->blk_eval.old_namesv; retop = cx->blk_eval.retop; - if (optype == OP_REQUIRE && - (MARK == SP || (gimme == G_SCALAR && !SvTRUE(*SP))) ) - { - /* Unassume the success we assumed earlier. */ - (void)hv_delete(GvHVn(PL_incgv), - SvPVX_const(namesv), - SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv), - G_DISCARD); - DIE(aTHX_ "%"SVf" did not return a true value", SVfARG(namesv)); - } break; case CXt_FORMAT: retop = cx->blk_sub.retop; @@ -2521,7 +2511,21 @@ PP(pp_return) } PL_stack_sp = newsp; + if (CxTYPE(cx) == CXt_EVAL) { + if (optype == OP_REQUIRE && + !(gimme == G_SCALAR ? SvTRUE(*PL_stack_sp) : PL_stack_sp > PL_stack_base + cx->blk_oldsp) ) + { + /* Unassume the success we assumed earlier. */ + (void)hv_delete(GvHVn(PL_incgv), + SvPVX_const(namesv), + SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv), + G_DISCARD); + DIE(aTHX_ "%"SVf" did not return a true value", SVfARG(namesv)); + } + } + LEAVE; + PL_curpm = newpm; /* ... and pop $1 et al */ if (clear_errsv) { |