Skip to content

Commit

Permalink
pp_return: simplify arg handling code
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
iabyn committed Jun 19, 2015
1 parent 3341121 commit 988f25b
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions pp_ctl.c
Expand Up @@ -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);
Expand Down

0 comments on commit 988f25b

Please sign in to comment.