This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_return: simplify arg handling code
authorDavid Mitchell <davem@iabyn.com>
Mon, 8 Jun 2015 17:46:50 +0000 (18:46 +0100)
committerDavid Mitchell <davem@iabyn.com>
Fri, 19 Jun 2015 07:44:17 +0000 (08:44 +0100)
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.

pp_ctl.c

index 211f0bf..007c073 100644 (file)
--- 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);