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 { \
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); \
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;
}
}
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))[