This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
factor common code into POPSUB_ARGS()
authorDavid Mitchell <davem@iabyn.com>
Thu, 15 Oct 2015 14:50:08 +0000 (15:50 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 08:59:44 +0000 (08:59 +0000)
Some code that is common to POPSUB() and pp_coreargs, extract out
into a common macro. (There's some almost identical code in pp_goto,
so add a note there).

This makes pp_coreargs slightly less efficient, since it now tests for
AvREAL(av), when that should never be true. But it's not exactly hot code.

cop.h
pp.c
pp_ctl.c

diff --git a/cop.h b/cop.h
index c0cfab2..57b56d8 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -655,6 +655,23 @@ struct block_format {
     CvDEPTH((const CV*)cx->blk_sub.cv) = cx->blk_sub.olddepth;          \
     SvREFCNT_dec_NN(cx->blk_sub.cv);
 
+/* handle the @_ part of leaving a sub */
+
+#define POPSUB_ARGS(cx) \
+    STMT_START {                                                       \
+        AV *av;                                                         \
+        assert(AvARRAY(MUTABLE_AV(                                      \
+            PadlistARRAY(CvPADLIST(cx->blk_sub.cv))[                    \
+                    CvDEPTH(cx->blk_sub.cv)])) == PL_curpad);           \
+        POP_SAVEARRAY();                                               \
+        /* abandon @_ if it got reified */                             \
+        av = MUTABLE_AV(PAD_SVl(0));                                    \
+        if (UNLIKELY(AvREAL(av)))                                      \
+            clear_defarray(av, 0);                                      \
+        else {                                                         \
+            CLEAR_ARGARRAY(av);                                                \
+        }                                                              \
+    } STMT_END
 
 #define POPSUB(cx)                                                     \
     STMT_START {                                                       \
@@ -668,18 +685,7 @@ struct block_format {
                CopSTASHPV((COP*)CvSTART((const CV*)cx->blk_sub.cv)));  \
                                                                        \
        if (CxHASARGS(cx)) {                                            \
-            AV *av;                                                     \
-            assert(AvARRAY(MUTABLE_AV(                                  \
-                PadlistARRAY(CvPADLIST(cx->blk_sub.cv))[                \
-                        CvDEPTH(cx->blk_sub.cv)])) == PL_curpad);       \
-           POP_SAVEARRAY();                                            \
-           /* abandon @_ if it got reified */                          \
-            av = MUTABLE_AV(PAD_SVl(0));                                \
-           if (UNLIKELY(AvREAL(av)))                                   \
-                clear_defarray(av, 0);                                  \
-           else {                                                      \
-               CLEAR_ARGARRAY(av);                                     \
-           }                                                           \
+            POPSUB_ARGS(cx);                                            \
        }                                                               \
         }                                                               \
         POPSUB_COMMON(cx);                                              \
diff --git a/pp.c b/pp.c
index 61b1b29..ac8498e 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -6440,23 +6440,11 @@ PP(pp_coreargs)
            if (opnum == OP_UNDEF && SvRV(*svp) == (SV *)PL_defgv
             && cxstack[cxstack_ix].cx_type & CXp_HASARGS) {
                /* Undo @_ localisation, so that sub exit does not undo
-                  part of our undeffing.
-                   this corresponds to the part of POPSUB that
-                   does @_ cleanup */
+                  part of our undeffing. */
                PERL_CONTEXT *cx = &cxstack[cxstack_ix];
 
                 assert(CxHASARGS(cx));
-                {
-                    AV *av;
-                    assert(AvARRAY(MUTABLE_AV(
-                        PadlistARRAY(CvPADLIST(cx->blk_sub.cv))[
-                                CvDEPTH(cx->blk_sub.cv)])) == PL_curpad);
-                    POP_SAVEARRAY();
-                    av = MUTABLE_AV(PAD_SVl(0));
-                    assert(!AvREAL(av));
-                    CLEAR_ARGARRAY(av);
-                }
-
+                POPSUB_ARGS(cx);;
                cx->cx_type &= ~CXp_HASARGS;
            }
          }
index 8985116..13205fe 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2771,9 +2771,8 @@ PP(pp_goto)
            assert(PL_scopestack_ix == cx->blk_oldscopesp);
             CX_LEAVE_SCOPE(cx);
 
-            /* partial unrolled POPSUB(): */
-
            if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
+                /* this is POPSUB_ARGS() with minor variations */
                AV* av = MUTABLE_AV(PAD_SVl(0));
                 assert(AvARRAY(MUTABLE_AV(
                     PadlistARRAY(CvPADLIST(cx->blk_sub.cv))[