return;
while (cxstack_ix > cxix) {
- SV *sv;
PERL_CONTEXT *cx = &cxstack[cxstack_ix];
DEBUG_CX("UNWIND"); \
/* Note: we don't need to restore the base context info till the end. */
POPSUBST(cx);
continue; /* not break */
case CXt_SUB:
- POPSUB(cx,sv);
- LEAVESUB(sv);
+ POPSUB(cx);
break;
case CXt_EVAL:
POPEVAL(cx);
- /* FALLTHROUGH */
+ break;
case CXt_BLOCK:
POPBASICBLK(cx);
break;
}
POPBLOCK(cx,PL_curpm);
- LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
POPEVAL(cx);
namesv = cx->blk_eval.old_namesv;
#ifdef DEBUGGING
restartjmpenv = cx->blk_eval.cur_top_env;
restartop = cx->blk_eval.retop;
- PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
-
if (optype == OP_REQUIRE) {
assert (PL_curcop == oldcop);
(void)hv_store(GvHVn(PL_incgv),
/* S_leave_common: Common code that many functions in this file use on
scope exit.
- Process the return args on the stack in the range (mark+1..sp) based on
- context, with any final args starting at newsp+1. Returns the new
- top-of-stack position
+ Process the return args on the stack in the range (mark+1..PL_stack_sp)
+ based on context, with any final args starting at newsp+1.
Args are mortal copied (or mortalied if lvalue) unless its safe to use
as-is, based on whether it has the specified flags. Note that most
callers specify flags as (SVs_PADTMP|SVs_TEMP), while leaveeval skips
Also, taintedness is cleared.
*/
-STATIC SV **
-S_leave_common(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme,
+STATIC void
+S_leave_common(pTHX_ SV **newsp, SV **mark, I32 gimme,
U32 flags, bool lvalue)
{
+ dSP;
PERL_ARGS_ASSERT_LEAVE_COMMON;
TAINT_NOT;
? sv_2mortal(SvREFCNT_inc_simple_NN(*SP))
: sv_mortalcopy(*SP);
else {
- /* MEXTEND() only updates MARK, so reuse it instead of newsp. */
- MARK = newsp;
- MEXTEND(MARK, 1);
- *++MARK = &PL_sv_undef;
- return MARK;
+ EXTEND(newsp, 1);
+ *++newsp = &PL_sv_undef;
}
}
else if (gimme == G_ARRAY) {
* point with SP == newsp. */
}
- return newsp;
+ PL_stack_sp = newsp;
}
+
PP(pp_enter)
{
dSP;
PP(pp_leave)
{
- dSP;
PERL_CONTEXT *cx;
SV **newsp;
PMOP *newpm;
assert(CxTYPE(cx) == CXt_BLOCK);
newsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
- gimme = OP_GIMME(PL_op, (cxstack_ix >= 0) ? gimme : G_SCALAR);
- SP = (gimme == G_VOID)
- ? newsp
- : leave_common(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP,
+ if (gimme == G_VOID)
+ PL_stack_sp = newsp;
+ else
+ leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP,
PL_op->op_private & OPpLVALUE);
POPBLOCK(cx,newpm);
PL_curpm = newpm; /* Don't pop $1 et al till now */
- RETURN;
+ return NORMAL;
}
static bool
PP(pp_leaveloop)
{
- dSP;
PERL_CONTEXT *cx;
I32 gimme;
SV **newsp;
newsp = PL_stack_base + cx->blk_loop.resetsp;
gimme = cx->blk_gimme;
- SP = (gimme == G_VOID)
- ? newsp
- : leave_common(newsp, SP, MARK, gimme, SVs_PADTMP|SVs_TEMP,
+ if (gimme == G_VOID)
+ PL_stack_sp = newsp;
+ else
+ leave_common(newsp, MARK, gimme, SVs_PADTMP|SVs_TEMP,
PL_op->op_private & OPpLVALUE);
- PUTBACK;
POPBLOCK(cx,newpm);
POPLOOP(cx); /* Stack values are safe: release loop vars ... */
PMOP *newpm;
I32 gimme;
PERL_CONTEXT *cx;
- SV *sv;
bool ref;
const char *what = NULL;
ref = !!(CxLVAL(cx) & OPpENTERSUB_INARGS);
if (gimme == G_SCALAR) {
if (CxLVAL(cx) && !ref) { /* Leave it as it is if we can. */
- SV *sv;
if (MARK <= SP) {
if ((SvPADTMP(TOPs) || SvREADONLY(TOPs)) &&
!SvSMAGICAL(TOPs)) {
what = "undef";
}
croak:
- POPSUB(cx,sv);
+ POPSUB(cx);
cxstack_ix--;
PL_curpm = cx->blk_oldpm;
- LEAVESUB(sv);
Perl_croak(aTHX_
"Can't return %s from lvalue subroutine", what
);
POPBLOCK(cx,newpm);
cxstack_ix++; /* preserve cx entry on stack for use by POPSUB */
- POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */
+ POPSUB(cx); /* Stack values are safe: release CV and @_ ... */
cxstack_ix--;
PL_curpm = newpm; /* ... and pop $1 et al */
- LEAVESUB(sv);
return cx->blk_sub.retop;
}
* return.
*/
cx = &cxstack[cxix];
- SP = leave_common(PL_stack_base + cx->blk_oldsp, SP, MARK,
- cx->blk_gimme, SVs_TEMP|SVs_PADTMP, TRUE);
PUTBACK;
+ leave_common(PL_stack_base + cx->blk_oldsp, MARK,
+ cx->blk_gimme, SVs_TEMP|SVs_PADTMP, TRUE);
+ SPAGAIN;
dounwind(cxix);
}
else {
}
TOPBLOCK(cx);
- LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ CX_LEAVE_SCOPE(cx);
FREETMPS;
PL_curcop = cx->blk_oldcop;
PERL_ASYNC_CHECK();
SvREFCNT_inc_NN(sv_2mortal(MUTABLE_SV(arg)));
assert(PL_scopestack_ix == cx->blk_oldscopesp);
- LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ CX_LEAVE_SCOPE(cx);
if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
AV* av = MUTABLE_AV(PAD_SVl(0));
}
SP = PL_stack_base + POPMARK; /* pop original mark */
POPBLOCK(cx,PL_curpm);
- LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
POPEVAL(cx);
namesv = cx->blk_eval.old_namesv;
- /* POPBLOCK has rendered LEAVE_with_name("evalcomp") unnecessary */
- PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
}
errsv = ERRSV;
newsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
- if (gimme != G_VOID)
- SP = leave_common(newsp, SP, newsp, gimme, SVs_TEMP, FALSE);
+ if (gimme != G_VOID) {
+ PUTBACK;
+ leave_common(newsp, newsp, gimme, SVs_TEMP, FALSE);
+ SPAGAIN;
+ }
POPBLOCK(cx,newpm);
- LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
POPEVAL(cx);
namesv = cx->blk_eval.old_namesv;
retop = cx->blk_eval.retop;
SvPVX_const(namesv),
SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
G_DISCARD);
- PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
Perl_die(aTHX_ "%"SVf" did not return a true value", SVfARG(namesv));
NOT_REACHED; /* NOTREACHED */
/* die_unwind() did LEAVE, or we won't be here */
}
else {
- PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
if (!keep)
CLEAR_ERRSV();
}
I32 optype;
POPBLOCK(cx,newpm);
- LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
POPEVAL(cx);
PL_curpm = newpm;
- PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
PERL_UNUSED_VAR(optype);
}
PP(pp_leavetry)
{
- dSP;
SV **newsp;
PMOP *newpm;
I32 gimme;
newsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
- SP = (gimme == G_VOID)
- ? newsp
- : leave_common(newsp, SP, newsp, gimme,
- SVs_PADTMP|SVs_TEMP, FALSE);
+ if (gimme == G_VOID)
+ PL_stack_sp = newsp;
+ else
+ leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
POPBLOCK(cx,newpm);
retop = cx->blk_eval.retop;
- LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
POPEVAL(cx);
PERL_UNUSED_VAR(optype);
PL_curpm = newpm; /* Don't pop $1 et al till now */
- PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
-
CLEAR_ERRSV();
- RETURNOP(retop);
+ return retop;
}
PP(pp_entergiven)
PP(pp_leavegiven)
{
- dSP;
PERL_CONTEXT *cx;
I32 gimme;
SV **newsp;
newsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
- SP = (gimme == G_VOID)
- ? newsp
- : leave_common(newsp, SP, newsp, gimme,
- SVs_PADTMP|SVs_TEMP, FALSE);
+ if (gimme == G_VOID)
+ PL_stack_sp = newsp;
+ else
+ leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
POPBLOCK(cx,newpm);
POPGIVEN(cx);
assert(CxTYPE(cx) == CXt_GIVEN);
PL_curpm = newpm; /* Don't pop $1 et al till now */
- RETURN;
+ return NORMAL;
}
/* Helper routines used by pp_smartmatch */
PP(pp_leavewhen)
{
- dSP;
I32 cxix;
PERL_CONTEXT *cx;
I32 gimme;
PL_op->op_flags & OPf_SPECIAL ? "default" : "when");
newsp = PL_stack_base + cx->blk_oldsp;
- SP = (gimme == G_VOID)
- ? newsp
- : leave_common(newsp, SP, newsp, gimme,
- SVs_PADTMP|SVs_TEMP, FALSE);
+ if (gimme == G_VOID)
+ PL_stack_sp = newsp;
+ else
+ leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
/* pop the WHEN, BLOCK and anything else before the GIVEN/FOR */
assert(cxix < cxstack_ix);
dounwind(cxix);
else {
PERL_ASYNC_CHECK();
assert(cx->blk_givwhen.leave_op->op_type == OP_LEAVEGIVEN);
- RETURNOP(cx->blk_givwhen.leave_op);
+ return cx->blk_givwhen.leave_op;
}
}