/* PL_tainted must be correctly set for this mg_set */
SvSETMAGIC(TARG);
TAINT_NOT;
- LEAVE_SCOPE(cx->sb_oldsave);
+
+ CX_LEAVE_SCOPE(cx);
POPSUBST(cx);
+ CX_POP(cx);
+
PERL_ASYNC_CHECK();
RETURNOP(pm->op_next);
NOT_REACHED; /* NOTREACHED */
/* diag_listed_as: Exiting subroutine via %s */
Perl_ck_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
context_name[CxTYPE(cx)], OP_NAME(PL_op));
- if (CxTYPE(cx) == CXt_NULL)
+ if (CxTYPE(cx) == CXt_NULL) /* sort BLOCK */
return -1;
break;
case CXt_LOOP_LAZYIV:
/* diag_listed_as: Exiting subroutine via %s */
Perl_ck_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
context_name[CxTYPE(cx)], OP_NAME(PL_op));
- if ((CxTYPE(cx)) == CXt_NULL)
+ if ((CxTYPE(cx)) == CXt_NULL) /* sort BLOCK */
return -1;
break;
case CXt_LOOP_LAZYIV:
void
Perl_dounwind(pTHX_ I32 cxix)
{
- I32 optype;
-
if (!PL_curstackinfo) /* can happen if die during thread cloning */
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. */
+
+ CX_LEAVE_SCOPE(cx);
+
switch (CxTYPE(cx)) {
case CXt_SUBST:
POPSUBST(cx);
- continue; /* not break */
+ break;
case CXt_SUB:
- POPSUB(cx,sv);
- LEAVESUB(sv);
+ POPSUB(cx);
break;
case CXt_EVAL:
POPEVAL(cx);
- PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
break;
case CXt_BLOCK:
POPBASICBLK(cx);
POPGIVEN(cx);
break;
case CXt_NULL:
+ /* there isn't a POPNULL ! */
break;
case CXt_FORMAT:
POPFORMAT(cx);
}
cxstack_ix--;
}
- PERL_UNUSED_VAR(optype);
}
void
++PL_parser->error_count;
}
+
+
+/* pop the cx, undef or delete the %INC entry, then croak.
+ * require0 indicates that the require didn't return a true value */
+
+void
+S_undo_inc_then_croak(pTHX_ PERL_CONTEXT *cx, SV *err, bool require0)
+{
+ const char *fmt;
+ HV *inc_hv = GvHVn(PL_incgv);
+ SV *namesv = cx->blk_eval.old_namesv;
+ I32 klen = SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv);
+ const char *key = SvPVX_const(namesv);
+
+ CX_POP(cx);
+
+ if (require0) {
+ (void)hv_delete(inc_hv, key, klen, G_DISCARD);
+ fmt = "%"SVf" did not return a true value";
+ err = namesv;
+ }
+ else {
+ (void)hv_store(inc_hv, key, klen, &PL_sv_undef, 0);
+ fmt = "%"SVf"Compilation failed in require";
+ err = err ? err : newSVpvs_flags("Unknown error\n", SVs_TEMP);
+ }
+
+ /* note that unlike pp_entereval, pp_require isn't
+ * supposed to trap errors. So now that we've popped the
+ * EVAL that pp_require pushed, and processed the error
+ * message, rethrow the error */
+ Perl_croak(aTHX_ fmt, SVfARG(err));
+}
+
+
void
Perl_die_unwind(pTHX_ SV *msv)
{
}
if (cxix >= 0) {
- I32 optype;
- SV *namesv;
PERL_CONTEXT *cx;
SV **newsp;
I32 gimme;
-#ifdef DEBUGGING
- COP *oldcop;
-#endif
JMPENV *restartjmpenv;
OP *restartop;
cx = &cxstack[cxstack_ix];
assert(CxTYPE(cx) == CXt_EVAL);
+
+ /* return false to the caller of eval */
newsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
-
if (gimme == G_SCALAR)
*++newsp = &PL_sv_undef;
PL_stack_sp = newsp;
-
- if (CxTYPE(cx) != CXt_EVAL) {
- STRLEN msglen;
- const char* message = SvPVx_const(exceptsv, msglen);
- PerlIO_write(Perl_error_log, (const char *)"panic: die ", 11);
- PerlIO_write(Perl_error_log, message, msglen);
- my_exit(1);
- }
-
- POPBLOCK(cx,PL_curpm);
+ CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
- namesv = cx->blk_eval.old_namesv;
-#ifdef DEBUGGING
- oldcop = cx->blk_oldcop;
-#endif
+ POPBLOCK(cx);
+
restartjmpenv = cx->blk_eval.cur_top_env;
restartop = cx->blk_eval.retop;
+ if (CxOLD_OP_TYPE(cx) == OP_REQUIRE) {
+ S_undo_inc_then_croak(aTHX_ cx, exceptsv, FALSE);
+ NOT_REACHED; /* NOTREACHED */
+ }
+ CX_POP(cx);
- 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),
- SvPVX_const(namesv),
- SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
- &PL_sv_undef, 0);
- /* note that unlike pp_entereval, pp_require isn't
- * supposed to trap errors. So now that we've popped the
- * EVAL that pp_require pushed, and processed the error
- * message, rethrow the error */
- Perl_croak(aTHX_ "%"SVf"Compilation failed in require",
- SVfARG(exceptsv ? exceptsv : newSVpvs_flags("Unknown error\n",
- SVs_TEMP)));
- }
if (!(in_eval & EVAL_KEEPERR))
sv_setsv(ERRSV, exceptsv);
PL_restartjmpenv = restartjmpenv;
PUSHBLOCK(cx, CXt_SUB, SP);
PUSHSUB_DB(cx);
cx->blk_sub.retop = PL_op->op_next;
- cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix;
+ cx->cx_old_savestack_ix = PL_savestack_ix;
SAVEI32(PL_debug);
PL_debug = 0;
/* 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;
I32 gimme;
- if (PL_op->op_flags & OPf_SPECIAL) {
- cx = &cxstack[cxstack_ix];
- cx->blk_oldpm = PL_curpm; /* fake block should preserve $1 et al */
- }
-
cx = &cxstack[cxstack_ix];
assert(CxTYPE(cx) == CXt_BLOCK);
+
+ if (PL_op->op_flags & OPf_SPECIAL)
+ cx->blk_oldpm = PL_curpm; /* fake block should preserve $1 et al */
+
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);
+ CX_LEAVE_SCOPE(cx);
POPBASICBLK(cx);
+ POPBLOCK(cx);
+ CX_POP(cx);
- 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;
- PMOP *newpm;
SV **mark;
cx = &cxstack[cxstack_ix];
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);
+ CX_LEAVE_SCOPE(cx);
POPLOOP(cx); /* Stack values are safe: release loop vars ... */
- PL_curpm = newpm; /* ... and pop $1 et al */
+ POPBLOCK(cx);
+ CX_POP(cx);
return NORMAL;
}
dSP;
SV **newsp;
SV **mark;
- PMOP *newpm;
I32 gimme;
PERL_CONTEXT *cx;
- SV *sv;
bool ref;
const char *what = NULL;
+ OP *retop;
cx = &cxstack[cxstack_ix];
assert(CxTYPE(cx) == CXt_SUB);
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);
- cxstack_ix--;
- PL_curpm = cx->blk_oldpm;
- LEAVESUB(sv);
Perl_croak(aTHX_
"Can't return %s from lvalue subroutine", what
);
}
PUTBACK;
- POPBLOCK(cx,newpm);
- cxstack_ix++; /* preserve cx entry on stack for use by POPSUB */
- POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */
- cxstack_ix--;
- PL_curpm = newpm; /* ... and pop $1 et al */
- LEAVESUB(sv);
+ CX_LEAVE_SCOPE(cx);
+ POPSUB(cx); /* Stack values are safe: release CV and @_ ... */
+ POPBLOCK(cx);
+ retop = cx->blk_sub.retop;
+ CX_POP(cx);
- return cx->blk_sub.retop;
+ return retop;
}
assert(cxstack_ix >= 0);
if (cxix < cxstack_ix) {
if (cxix < 0) {
- if (!CxMULTICALL(cxstack))
+ if (!( PL_curstackinfo->si_type == PERLSI_SORT
+ || ( PL_curstackinfo->si_type == PERLSI_MULTICALL
+ && (cxstack[0].cx_type & CXp_SUB_RE_FAKE))
+ )
+ )
DIE(aTHX_ "Can't return outside a subroutine");
- /* We must be in a sort block, which is a CXt_NULL not a
- * CXt_SUB. Handle specially. */
+ /* We must be in:
+ * a sort block, which is a CXt_NULL not a CXt_SUB;
+ * or a /(?{...})/ block.
+ * Handle specially. */
+ assert(CxTYPE(&cxstack[0]) == CXt_NULL
+ || ( CxTYPE(&cxstack[0]) == CXt_SUB
+ && (cxstack[0].cx_type & CXp_SUB_RE_FAKE)));
if (cxstack_ix > 0) {
/* See comment below about context popping. Since we know
* we're scalar and not lvalue, we can preserve the return
* 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);
+ cx = &cxstack[cxix]; /* CX stack may have been realloced */
}
else {
/* Like in the branch above, we need to handle any extra junk on
PP(pp_last)
{
PERL_CONTEXT *cx;
- OP *nextop = NULL;
- PMOP *newpm;
+ OP* nextop;
S_unwind_loop(aTHX_ "last");
- POPBLOCK(cx,newpm);
- cxstack_ix++; /* temporarily protect top context */
+ cx = &cxstack[cxstack_ix];
+
assert(
CxTYPE(cx) == CXt_LOOP_LAZYIV
|| CxTYPE(cx) == CXt_LOOP_LAZYSV
|| CxTYPE(cx) == CXt_LOOP_PLAIN
);
PL_stack_sp = PL_stack_base + cx->blk_loop.resetsp;
- nextop = cx->blk_loop.my_op->op_lastop->op_next;
TAINT_NOT;
- cxstack_ix--;
/* Stack values are safe: */
+ CX_LEAVE_SCOPE(cx);
POPLOOP(cx); /* release loop vars ... */
- PL_curpm = newpm; /* ... and pop $1 et al */
+ POPBLOCK(cx);
+ nextop = cx->blk_loop.my_op->op_lastop->op_next;
+ CX_POP(cx);
return nextop;
}
TOPBLOCK(cx);
SPAGAIN;
- /* partial unrolled POPSUB(): */
-
/* protect @_ during save stack unwind. */
if (arg)
SvREFCNT_inc_NN(sv_2mortal(MUTABLE_SV(arg)));
CX_LEAVE_SCOPE(cx);
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))[
* this is a POPBLOCK(), less all the stuff we already did
* for TOPBLOCK() earlier */
PL_curcop = cx->blk_oldcop;
- cxstack_ix--;
+ CX_POP(cx);
/* Push a mark for the start of arglist */
PUSHMARK(mark);
if (yystatus || PL_parser->error_count || !PL_eval_root) {
PERL_CONTEXT *cx;
- I32 optype; /* Used by POPEVAL. */
- SV *namesv;
- SV *errsv = NULL;
-
- cx = NULL;
- namesv = NULL;
- PERL_UNUSED_VAR(optype);
+ SV *errsv;
+ PL_op = saveop;
/* note that if yystatus == 3, then the EVAL CX block has already
* been popped, and various vars restored */
- PL_op = saveop;
if (yystatus != 3) {
if (PL_eval_root) {
op_free(PL_eval_root);
PL_eval_root = NULL;
}
SP = PL_stack_base + POPMARK; /* pop original mark */
- POPBLOCK(cx,PL_curpm);
+ cx = &cxstack[cxstack_ix];
+ CX_LEAVE_SCOPE(cx);
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;
+ POPBLOCK(cx);
+ if (in_require) {
+ S_undo_inc_then_croak(aTHX_ cx, ERRSV, FALSE);
+ NOT_REACHED; /* NOTREACHED */
+ }
+ CX_POP(cx);
}
errsv = ERRSV;
if (in_require) {
- if (!cx) {
- /* If cx is still NULL, it means that we didn't go in the
- * POPEVAL branch. */
- cx = &cxstack[cxstack_ix];
- assert(CxTYPE(cx) == CXt_EVAL);
- namesv = cx->blk_eval.old_namesv;
- }
- (void)hv_store(GvHVn(PL_incgv),
- SvPVX_const(namesv),
- SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
- &PL_sv_undef, 0);
- Perl_croak(aTHX_ "%"SVf"Compilation failed in require",
- SVfARG(errsv
- ? errsv
- : newSVpvs_flags("Unknown error\n", SVs_TEMP)));
- }
- else {
- if (!*(SvPV_nolen_const(errsv))) {
- sv_setpvs(errsv, "Compilation error");
- }
+ assert(yystatus == 3);
+ cx = &cxstack[cxstack_ix];
+ assert(CxTYPE(cx) == CXt_EVAL);
+ S_undo_inc_then_croak(aTHX_ cx, errsv, FALSE);
+ NOT_REACHED; /* NOTREACHED */
}
+
+ if (!*(SvPV_nolen_const(errsv)))
+ sv_setpvs(errsv, "Compilation error");
+
if (gimme != G_ARRAY) PUSHs(&PL_sv_undef);
PUTBACK;
return FALSE;
/* switch to eval mode */
PUSHBLOCK(cx, CXt_EVAL, SP);
PUSHEVAL(cx, name);
- cx->cx_u.cx_blk.blku_old_savestack_ix = old_savestack_ix;
+ cx->cx_old_savestack_ix = old_savestack_ix;
cx->blk_eval.retop = PL_op->op_next;
SAVECOPLINE(&PL_compiling);
PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP);
PUSHEVAL(cx, 0);
- cx->cx_u.cx_blk.blku_old_savestack_ix = old_savestack_ix;
+ cx->cx_old_savestack_ix = old_savestack_ix;
cx->blk_eval.retop = PL_op->op_next;
/* prepare to compile string */
{
dSP;
SV **newsp;
- PMOP *newpm;
I32 gimme;
PERL_CONTEXT *cx;
OP *retop;
I32 optype;
- SV *namesv;
CV *evalcv;
/* grab this value before POPEVAL restores old PL_in_eval */
bool keep = cBOOL(PL_in_eval & EVAL_KEEPERR);
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);
- POPBLOCK(cx,newpm);
+ if (gimme != G_VOID) {
+ PUTBACK;
+ leave_common(newsp, newsp, gimme, SVs_TEMP, FALSE);
+ SPAGAIN;
+ }
+ /* the POPEVAL does a leavescope, which frees the optree associated
+ * with eval, which if it frees the nextstate associated with
+ * PL_curcop, sets PL_curcop to NULL. Which can mess up freeing a
+ * regex when running under 'use re Debug' because it needs PL_curcop
+ * to get the current hints. So restore it early.
+ */
+ PL_curcop = cx->blk_oldcop;
+ CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
- namesv = cx->blk_eval.old_namesv;
+ POPBLOCK(cx);
retop = cx->blk_eval.retop;
evalcv = cx->blk_eval.cv;
+ optype = CxOLD_OP_TYPE(cx);
- PL_curpm = newpm; /* Don't pop $1 et al till now */
#ifdef DEBUGGING
assert(CvDEPTH(evalcv) == 1);
!(gimme == G_SCALAR ? SvTRUE(*SP) : SP > newsp))
{
/* Unassume the success we assumed earlier. */
- (void)hv_delete(GvHVn(PL_incgv),
- 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));
+ S_undo_inc_then_croak(aTHX_ cx, NULL, TRUE);
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();
}
+ CX_POP(cx);
+
+ if (!keep)
+ CLEAR_ERRSV();
+
RETURNOP(retop);
}
void
Perl_delete_eval_scope(pTHX)
{
- PMOP *newpm;
PERL_CONTEXT *cx;
- I32 optype;
- POPBLOCK(cx,newpm);
+ cx = &cxstack[cxstack_ix];
+ CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
- PL_curpm = newpm;
- PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
- PERL_UNUSED_VAR(optype);
+ POPBLOCK(cx);
+ CX_POP(cx);
}
/* Common-ish code salvaged from Perl_call_sv and pp_entertry, because it was
PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
PUSHEVAL(cx, 0);
- cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix;
+ cx->cx_old_savestack_ix = PL_savestack_ix;
PL_in_eval = EVAL_INEVAL;
if (flags & G_KEEPERR)
PP(pp_leavetry)
{
- dSP;
SV **newsp;
- PMOP *newpm;
I32 gimme;
PERL_CONTEXT *cx;
- I32 optype;
OP *retop;
PERL_ASYNC_CHECK();
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);
- POPBLOCK(cx,newpm);
- retop = cx->blk_eval.retop;
+ if (gimme == G_VOID)
+ PL_stack_sp = newsp;
+ else
+ leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
+ CX_LEAVE_SCOPE(cx);
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;
+ POPBLOCK(cx);
+ retop = cx->blk_eval.retop;
+ CX_POP(cx);
CLEAR_ERRSV();
- RETURNOP(retop);
+ return retop;
}
PP(pp_entergiven)
PP(pp_leavegiven)
{
- dSP;
PERL_CONTEXT *cx;
I32 gimme;
SV **newsp;
- PMOP *newpm;
PERL_UNUSED_CONTEXT;
cx = &cxstack[cxstack_ix];
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);
- POPBLOCK(cx,newpm);
- POPGIVEN(cx);
- assert(CxTYPE(cx) == CXt_GIVEN);
+ if (gimme == G_VOID)
+ PL_stack_sp = newsp;
+ else
+ leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
- PL_curpm = newpm; /* Don't pop $1 et al till now */
+ CX_LEAVE_SCOPE(cx);
+ POPGIVEN(cx);
+ POPBLOCK(cx);
+ CX_POP(cx);
- 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;
}
}
PP(pp_continue)
{
- dSP;
I32 cxix;
PERL_CONTEXT *cx;
- PMOP *newpm;
-
+ OP *nextop;
cxix = dopoptowhen(cxstack_ix);
if (cxix < 0)
if (cxix < cxstack_ix)
dounwind(cxix);
- POPBLOCK(cx,newpm);
+ cx = &cxstack[cxstack_ix];
assert(CxTYPE(cx) == CXt_WHEN);
+ PL_stack_sp = PL_stack_base + cx->blk_oldsp;
+ CX_LEAVE_SCOPE(cx);
POPWHEN(cx);
+ POPBLOCK(cx);
+ nextop = cx->blk_givwhen.leave_op->op_next;
+ CX_POP(cx);
- SP = PL_stack_base + cx->blk_oldsp;
- PL_curpm = newpm; /* pop $1 et al */
-
- RETURNOP(cx->blk_givwhen.leave_op->op_next);
+ return nextop;
}
PP(pp_break)