PERL_CONTEXT *cx;
SV** newsp;
const bool oldcatch = CATCH_GET;
+ I32 old_savestack_ix = PL_savestack_ix;
- SAVETMPS;
SAVEOP();
CATCH_SET(TRUE);
PL_secondgv = MUTABLE_GV(SvREFCNT_inc(
gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV)
));
+ /* make sure the GP isn't removed out from under us for
+ * the SAVESPTR() */
+ save_gp(PL_firstgv, 0);
+ save_gp(PL_secondgv, 0);
+ /* we don't want modifications localized */
+ GvINTRO_off(PL_firstgv);
+ GvINTRO_off(PL_secondgv);
SAVESPTR(GvSV(PL_firstgv));
SAVESPTR(GvSV(PL_secondgv));
}
PUSHBLOCK(cx, CXt_NULL, PL_stack_base);
if (!(flags & OPf_SPECIAL)) {
cx->cx_type = CXt_SUB;
- /* If our comparison routine is already active (CvDEPTH is
- * is not 0), then PUSHSUB does not increase the refcount,
- * so we have to do it ourselves, because the LEAVESUB fur-
- * ther down lowers it. */
- if (CvDEPTH(cv)) SvREFCNT_inc_simple_void_NN(cv);
PUSHSUB(cx);
if (!is_xsub) {
PADLIST * const padlist = CvPADLIST(cv);
PERL_STACK_OVERFLOW_CHECK();
pad_push(padlist, CvDEPTH(cv));
}
- SAVECOMPPAD();
PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv));
if (hasargs) {
cx->blk_sub.savearray = GvAV(PL_defgv);
GvAV(PL_defgv) = MUTABLE_AV(SvREFCNT_inc_simple(av));
- CX_CURPAD_SAVE(cx->blk_sub);
- cx->blk_sub.argarray = av;
}
}
}
+ else {
+ /* mimic PUSHSUB. Note that we're cheating and using a
+ * CXt_NULL block as a CXt_SUB block */
+ cx->cx_u.cx_blk.blku_old_tmpsfloor = PL_tmps_floor;
+ PL_tmps_floor = PL_tmps_ix;
+ }
+ cx->cx_u.cx_blk.blku_old_savestack_ix = old_savestack_ix;
+
cx->cx_type |= CXp_MULTICALL;
start = p1 - max;
POPSUB(cx, sv);
LEAVESUB(sv);
}
+ else
+ /* mimic POPSUB */
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
+
POPBLOCK(cx,PL_curpm);
PL_stack_sp = newsp;
POPSTACK;