summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-06-11 09:57:43 +0100
committerDavid Mitchell <davem@iabyn.com>2015-06-19 08:44:18 +0100
commit1ef2b70a7cb09564d92d47d3d76af07c36455485 (patch)
tree7e8247ad0e29cff558add51f50975a508acc4b88 /pp_ctl.c
parent7051b8c3d4558ca104e4fd0a9b39141e79a8e67c (diff)
downloadperl-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.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 434fe63f70..ec921b86c1 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -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) {