summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-06-08 18:46:50 +0100
committerDavid Mitchell <davem@iabyn.com>2015-06-19 08:44:17 +0100
commit988f25b6b104e36f72d842293f189b1317528547 (patch)
treeb211ca6644588302fa712f668403a5c94afac2b6 /pp_ctl.c
parent334112121fd381e21666f72ab06d79ef94f3f6a6 (diff)
downloadperl-988f25b6b104e36f72d842293f189b1317528547.tar.gz
pp_return: simplify arg handling code
pp_return() only needs to do the extra arg handling associated with the args not being at the base of the stack frame. For example for (1,2) { return 3,4 } has to cope with 1,2,3,4 being on the stack. Apart from handling junk, everything else - in particular pushing &PL_sv_undef in scalar context if there are no return args - is already done by Perl_pp_leavesub, which pp_return tail calls. So reduce what pp_return does to the bare minimum. This makes one less conditional branch in a few cases.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 211f0bf862..007c073869 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2456,15 +2456,27 @@ PP(pp_return)
else {
SV **oldsp = PL_stack_base + cx->blk_oldsp;
if (oldsp != MARK) {
- /* shift return args to base of call stack frame */
+ /* Handle extra junk on the stack. For example,
+ * for (1,2) { return 3,4 }
+ * leaves 1,2,3,4 on the stack. In list context we
+ * have to splice out the 1,2; In scalar context for
+ * for (1,2) { return }
+ * we need to set sp = oldsp so that pp_leavesub knows
+ * to push &PL_sv_undef onto the stack.
+ * Note that in pp_return we only do the extra processing
+ * required to handle junk; everything else we leave to
+ * pp_leavesub.
+ */
SSize_t nargs = SP - MARK;
if (nargs) {
- if (cx->blk_gimme == G_ARRAY)
+ if (cx->blk_gimme == G_ARRAY) {
+ /* shift return args to base of call stack frame */
Move(MARK + 1, oldsp + 1, nargs, SV**);
- else if (cx->blk_gimme == G_SCALAR)
- oldsp[1] = *SP;
+ PL_stack_sp = oldsp + nargs;
+ }
}
- PL_stack_sp = oldsp + nargs;
+ else
+ PL_stack_sp = oldsp;
}
/* fall through to a normal sub exit */
return Perl_pp_leavesub(aTHX);