PP(pp_substcont)
{
dSP;
- PERL_CONTEXT *cx = &cxstack[cxstack_ix];
+ PERL_CONTEXT *cx = CX_CUR();
PMOP * const pm = (PMOP*) cLOGOP->op_other;
SV * const dstr = cx->sb_dstr;
char *s = cx->sb_s;
NULL, /* CXt_WHEN never actually needs "block" */
NULL, /* CXt_BLOCK never actually needs "block" */
NULL, /* CXt_GIVEN never actually needs "block" */
- NULL, /* CXt_LOOP_FOR never actually needs "loop" */
NULL, /* CXt_LOOP_PLAIN never actually needs "loop" */
- NULL, /* CXt_LOOP_LAZYSV never actually needs "loop" */
NULL, /* CXt_LOOP_LAZYIV never actually needs "loop" */
+ NULL, /* CXt_LOOP_LAZYSV never actually needs "loop" */
+ NULL, /* CXt_LOOP_LIST never actually needs "loop" */
+ NULL, /* CXt_LOOP_ARY never actually needs "loop" */
"subroutine",
"format",
"eval",
if (CxTYPE(cx) == CXt_NULL) /* sort BLOCK */
return -1;
break;
+ case CXt_LOOP_PLAIN:
case CXt_LOOP_LAZYIV:
case CXt_LOOP_LAZYSV:
- case CXt_LOOP_FOR:
- case CXt_LOOP_PLAIN:
+ case CXt_LOOP_LIST:
+ case CXt_LOOP_ARY:
{
STRLEN cx_label_len = 0;
U32 cx_label_flags = 0;
if ((CxTYPE(cx)) == CXt_NULL) /* sort BLOCK */
return -1;
break;
+ case CXt_LOOP_PLAIN:
case CXt_LOOP_LAZYIV:
case CXt_LOOP_LAZYSV:
- case CXt_LOOP_FOR:
- case CXt_LOOP_PLAIN:
+ case CXt_LOOP_LIST:
+ case CXt_LOOP_ARY:
DEBUG_l( Perl_deb(aTHX_ "(dopoptoloop(): found loop at cx=%ld)\n", (long)i));
return i;
}
DEBUG_l( Perl_deb(aTHX_ "(dopoptogivenfor(): found given at cx=%ld)\n", (long)i));
return i;
case CXt_LOOP_PLAIN:
- assert(!CxFOREACHDEF(cx));
+ assert(!(cx->cx_type & CXp_FOR_DEF));
break;
case CXt_LOOP_LAZYIV:
case CXt_LOOP_LAZYSV:
- case CXt_LOOP_FOR:
- if (CxFOREACHDEF(cx)) {
+ case CXt_LOOP_LIST:
+ case CXt_LOOP_ARY:
+ if (cx->cx_type & CXp_FOR_DEF) {
DEBUG_l( Perl_deb(aTHX_ "(dopoptogivenfor(): found foreach at cx=%ld)\n", (long)i));
return i;
}
return;
while (cxstack_ix > cxix) {
- PERL_CONTEXT *cx = &cxstack[cxstack_ix];
- DEBUG_CX("UNWIND"); \
+ PERL_CONTEXT *cx = CX_CUR();
+
+ CX_DEBUG(cx, "UNWIND");
/* Note: we don't need to restore the base context info till the end. */
CX_LEAVE_SCOPE(cx);
case CXt_BLOCK:
POPBASICBLK(cx);
break;
+ case CXt_LOOP_PLAIN:
case CXt_LOOP_LAZYIV:
case CXt_LOOP_LAZYSV:
- case CXt_LOOP_FOR:
- case CXt_LOOP_PLAIN:
+ case CXt_LOOP_LIST:
+ case CXt_LOOP_ARY:
POPLOOP(cx);
break;
case CXt_WHEN:
-/* pop the cx, undef or delete the %INC entry, then croak.
+/* undef or delete the $INC{namesv} 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)
+static void
+S_undo_inc_then_croak(pTHX_ SV *namesv, 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 = 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));
}
}
if (cxix >= 0) {
+ SV *namesv = NULL;
PERL_CONTEXT *cx;
SV **newsp;
I32 gimme;
if (cxix < cxstack_ix)
dounwind(cxix);
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_EVAL);
/* return false to the caller of eval */
CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
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);
+ if (CxOLD_OP_TYPE(cx) == OP_REQUIRE)
+ namesv = cx->blk_eval.old_namesv;
+ CX_POP(cx);
+
+ if (namesv) {
+ /* 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, process the error message
+ * and rethrow the error */
+ S_undo_inc_then_croak(aTHX_ namesv, exceptsv, FALSE);
NOT_REACHED; /* NOTREACHED */
}
- CX_POP(cx);
if (!(in_eval & EVAL_KEEPERR))
sv_setsv(ERRSV, exceptsv);
RETURN;
}
- DEBUG_CX("CALLER");
+ CX_DEBUG(cx, "CALLER");
assert(CopSTASH(cx->blk_oldcop));
stash_hek = SvTYPE(CopSTASH(cx->blk_oldcop)) == SVt_PVHV
? HvNAME_HEK((HV*)CopSTASH(cx->blk_oldcop))
{
PL_curcop = (COP*)PL_op;
TAINT_NOT; /* Each statement is presumed innocent */
- PL_stack_sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;
+ PL_stack_sp = PL_stack_base + CX_CUR()->blk_oldsp;
FREETMPS;
PERL_ASYNC_CHECK();
PUSHBLOCK(cx, CXt_SUB, SP);
PUSHSUB_DB(cx);
cx->blk_sub.retop = PL_op->op_next;
- cx->cx_old_savestack_ix = PL_savestack_ix;
+ cx->blk_oldsaveix = PL_savestack_ix;
SAVEI32(PL_debug);
PL_debug = 0;
return NORMAL;
}
-/* 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..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
- SVs_PADTMP since its optree gets immediately freed, freeing its padtmps
- at the same time.
-
- Also, taintedness is cleared.
-*/
-
-STATIC void
-S_leave_common(pTHX_ SV **newsp, SV **mark, I32 gimme,
- U32 flags, bool lvalue)
-{
- dSP;
- PERL_ARGS_ASSERT_LEAVE_COMMON;
-
- TAINT_NOT;
- if (gimme == G_SCALAR) {
- if (MARK < SP)
- *++newsp = (SvFLAGS(*SP) & flags)
- ? *SP
- : lvalue
- ? sv_2mortal(SvREFCNT_inc_simple_NN(*SP))
- : sv_mortalcopy(*SP);
- else {
- EXTEND(newsp, 1);
- *++newsp = &PL_sv_undef;
- }
- }
- else if (gimme == G_ARRAY) {
- /* in case LEAVE wipes old return values */
- while (++MARK <= SP) {
- if (SvFLAGS(*MARK) & flags)
- *++newsp = *MARK;
- else {
- *++newsp = lvalue
- ? sv_2mortal(SvREFCNT_inc_simple_NN(*MARK))
- : sv_mortalcopy(*MARK);
- TAINT_NOT; /* Each item is independent */
- }
- }
- /* When this function was called with MARK == newsp, we reach this
- * point with SP == newsp. */
- }
-
- PL_stack_sp = newsp;
-}
-
PP(pp_enter)
{
SV **newsp;
I32 gimme;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_BLOCK);
if (PL_op->op_flags & OPf_SPECIAL)
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP,
- PL_op->op_private & OPpLVALUE);
+ leave_adjust_stacks(newsp, newsp, gimme,
+ PL_op->op_private & OPpLVALUE ? 3 : 1);
CX_LEAVE_SCOPE(cx);
POPBASICBLK(cx);
const I32 gimme = GIMME_V;
void *itervarp; /* GV or pad slot of the iteration variable */
SV *itersave; /* the old var in the iterator var slot */
- U8 cxtype = CXt_LOOP_FOR;
+ U8 cxflags = 0;
if (PL_op->op_targ) { /* "my" variable */
itervarp = &PAD_SVl(PL_op->op_targ);
SvPADSTALE_on(itersave);
}
SvREFCNT_inc_simple_void_NN(itersave);
- cxtype |= CXp_FOR_PAD;
+ cxflags = CXp_FOR_PAD;
}
else {
SV * const sv = POPs;
SvREFCNT_inc_simple_void_NN(itersave);
else
*svp = newSV(0);
- cxtype |= CXp_FOR_GV;
+ cxflags = CXp_FOR_GV;
}
else { /* LV ref: for \$foo (...) */
assert(SvTYPE(sv) == SVt_PVMG);
assert(SvMAGIC(sv));
assert(SvMAGIC(sv)->mg_type == PERL_MAGIC_lvref);
itersave = NULL;
- cxtype |= CXp_FOR_LVREF;
+ cxflags = CXp_FOR_LVREF;
}
}
if (PL_op->op_private & OPpITER_DEF)
- cxtype |= CXp_FOR_DEF;
+ cxflags |= CXp_FOR_DEF;
- PUSHBLOCK(cx, cxtype, SP);
- PUSHLOOP_FOR(cx, itervarp, itersave, MARK);
+ PUSHBLOCK(cx, cxflags, MARK);
+ PUSHLOOP_FOR(cx, itervarp, itersave);
if (PL_op->op_flags & OPf_STACKED) {
SV *maybe_ary = POPs;
if (SvTYPE(maybe_ary) != SVt_PVAV) {
dPOPss;
SV * const right = maybe_ary;
- if (UNLIKELY(cxtype & CXp_FOR_LVREF))
+ if (UNLIKELY(cxflags & CXp_FOR_LVREF))
DIE(aTHX_ "Assigned value is not a reference");
SvGETMAGIC(sv);
SvGETMAGIC(right);
if (RANGE_IS_NUMERIC(sv,right)) {
- cx->cx_type &= ~CXTYPEMASK;
cx->cx_type |= CXt_LOOP_LAZYIV;
- /* Make sure that no-one re-orders cop.h and breaks our
- assumptions */
- assert(CxTYPE(cx) == CXt_LOOP_LAZYIV);
if (S_outside_integer(aTHX_ sv) ||
S_outside_integer(aTHX_ right))
DIE(aTHX_ "Range iterator outside integer range");
cx->blk_loop.state_u.lazyiv.cur = SvIV_nomg(sv);
cx->blk_loop.state_u.lazyiv.end = SvIV_nomg(right);
-#ifdef DEBUGGING
- /* for correct -Dstv display */
- cx->blk_oldsp = sp - PL_stack_base;
-#endif
}
else {
- cx->cx_type &= ~CXTYPEMASK;
cx->cx_type |= CXt_LOOP_LAZYSV;
- /* Make sure that no-one re-orders cop.h and breaks our
- assumptions */
- assert(CxTYPE(cx) == CXt_LOOP_LAZYSV);
cx->blk_loop.state_u.lazysv.cur = newSVsv(sv);
cx->blk_loop.state_u.lazysv.end = right;
SvREFCNT_inc(right);
}
}
else /* SvTYPE(maybe_ary) == SVt_PVAV */ {
+ cx->cx_type |= CXt_LOOP_ARY;
cx->blk_loop.state_u.ary.ary = MUTABLE_AV(maybe_ary);
SvREFCNT_inc(maybe_ary);
cx->blk_loop.state_u.ary.ix =
AvFILL(cx->blk_loop.state_u.ary.ary) + 1 :
-1;
}
+ /* EXTEND(SP, 1) not needed in this branch because we just did POPs */
}
else { /* iterating over items on the stack */
- cx->blk_loop.state_u.ary.ary = NULL; /* means to use the stack */
- if (PL_op->op_private & OPpITER_REVERSED) {
- cx->blk_loop.state_u.ary.ix = cx->blk_oldsp + 1;
- }
- else {
- cx->blk_loop.state_u.ary.ix = MARK - PL_stack_base;
- }
+ cx->cx_type |= CXt_LOOP_LIST;
+ cx->blk_oldsp = SP - PL_stack_base;
+ cx->blk_loop.state_u.stack.basesp = MARK - PL_stack_base;
+ cx->blk_loop.state_u.stack.ix =
+ (PL_op->op_private & OPpITER_REVERSED)
+ ? cx->blk_oldsp + 1
+ : cx->blk_loop.state_u.stack.basesp;
+ /* pre-extend stack so pp_iter doesn't have to check every time
+ * it pushes yes/no */
+ EXTEND(SP, 1);
}
RETURN;
const I32 gimme = GIMME_V;
PUSHBLOCK(cx, CXt_LOOP_PLAIN, SP);
- PUSHLOOP_PLAIN(cx, SP);
+ PUSHLOOP_PLAIN(cx);
RETURN;
}
SV **newsp;
SV **mark;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE_is_LOOP(cx));
mark = PL_stack_base + cx->blk_oldsp;
- newsp = PL_stack_base + cx->blk_loop.resetsp;
+ newsp = CxTYPE(cx) == CXt_LOOP_LIST
+ ? PL_stack_base + cx->blk_loop.state_u.stack.basesp
+ : mark;
gimme = cx->blk_gimme;
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, MARK, gimme, SVs_PADTMP|SVs_TEMP,
- PL_op->op_private & OPpLVALUE);
+ leave_adjust_stacks(MARK, newsp, gimme,
+ PL_op->op_private & OPpLVALUE ? 3 : 1);
CX_LEAVE_SCOPE(cx);
POPLOOP(cx); /* Stack values are safe: release loop vars ... */
PP(pp_leavesublv)
{
- dSP;
- SV **newsp;
- SV **mark;
I32 gimme;
PERL_CONTEXT *cx;
- bool ref;
- const char *what = NULL;
+ SV **oldsp;
OP *retop;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_SUB);
if (CxMULTICALL(cx)) {
return 0;
}
- newsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
- TAINT_NOT;
+ oldsp = PL_stack_base + cx->blk_oldsp; /* last arg of previous frame */
- mark = newsp + 1;
-
- ref = !!(CxLVAL(cx) & OPpENTERSUB_INARGS);
- if (gimme == G_SCALAR) {
- if (CxLVAL(cx) && !ref) { /* Leave it as it is if we can. */
- if (MARK <= SP) {
- if ((SvPADTMP(TOPs) || SvREADONLY(TOPs)) &&
- !SvSMAGICAL(TOPs)) {
- what =
- SvREADONLY(TOPs) ? (TOPs == &PL_sv_undef) ? "undef"
- : "a readonly value" : "a temporary";
- }
- else goto copy_sv;
- }
- else {
- /* sub:lvalue{} will take us here. */
- what = "undef";
- }
- croak:
- Perl_croak(aTHX_
- "Can't return %s from lvalue subroutine", what
- );
- }
- if (MARK <= SP) {
- copy_sv:
- if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) {
- if (!SvPADTMP(*SP)) {
- *MARK = SvREFCNT_inc(*SP);
- FREETMPS;
- sv_2mortal(*MARK);
- }
- else {
- /* FREETMPS could clobber it */
- SV *sv = SvREFCNT_inc(*SP);
- FREETMPS;
- *MARK = sv_mortalcopy(sv);
- SvREFCNT_dec(sv);
- }
- }
- else
- *MARK =
- SvPADTMP(*SP)
- ? sv_mortalcopy(*SP)
- : !SvTEMP(*SP)
- ? sv_2mortal(SvREFCNT_inc_simple_NN(*SP))
- : *SP;
- }
- else {
- MEXTEND(MARK, 0);
- *MARK = &PL_sv_undef;
- }
- SP = MARK;
+ if (gimme == G_VOID)
+ PL_stack_sp = oldsp;
+ else {
+ U8 lval = CxLVAL(cx);
+ bool is_lval = (lval && !(lval & OPpENTERSUB_INARGS));
+ const char *what = NULL;
+
+ if (gimme == G_SCALAR) {
+ if (is_lval) {
+ /* check for bad return arg */
+ if (oldsp < PL_stack_sp) {
+ SV *sv = *PL_stack_sp;
+ if ((SvPADTMP(sv) || SvREADONLY(sv))) {
+ what =
+ SvREADONLY(sv) ? (sv == &PL_sv_undef) ? "undef"
+ : "a readonly value" : "a temporary";
+ }
+ else goto ok;
+ }
+ else {
+ /* sub:lvalue{} will take us here. */
+ what = "undef";
+ }
+ croak:
+ Perl_croak(aTHX_
+ "Can't return %s from lvalue subroutine", what);
+ }
- if (CxLVAL(cx) & OPpDEREF) {
- SvGETMAGIC(TOPs);
- if (!SvOK(TOPs)) {
- TOPs = vivify_ref(TOPs, CxLVAL(cx) & OPpDEREF);
- }
- }
- }
- else if (gimme == G_ARRAY) {
- assert (!(CxLVAL(cx) & OPpDEREF));
- if (ref || !CxLVAL(cx))
- for (; MARK <= SP; MARK++)
- *MARK =
- SvFLAGS(*MARK) & SVs_PADTMP
- ? sv_mortalcopy(*MARK)
- : SvTEMP(*MARK)
- ? *MARK
- : sv_2mortal(SvREFCNT_inc_simple_NN(*MARK));
- else for (; MARK <= SP; MARK++) {
- if (*MARK != &PL_sv_undef
- && (SvPADTMP(*MARK) || SvREADONLY(*MARK))
- ) {
- /* Might be flattened array after $#array = */
- what = SvREADONLY(*MARK)
- ? "a readonly value" : "a temporary";
- goto croak;
- }
- else if (!SvTEMP(*MARK))
- *MARK = sv_2mortal(SvREFCNT_inc_simple_NN(*MARK));
- }
+ ok:
+ leave_adjust_stacks(oldsp, oldsp, gimme, is_lval ? 3 : 2);
+
+ if (lval & OPpDEREF) {
+ /* lval_sub()->{...} and similar */
+ dSP;
+ SvGETMAGIC(TOPs);
+ if (!SvOK(TOPs)) {
+ TOPs = vivify_ref(TOPs, CxLVAL(cx) & OPpDEREF);
+ }
+ PUTBACK;
+ }
+ }
+ else {
+ assert(gimme == G_ARRAY);
+ assert (!(lval & OPpDEREF));
+
+ if (is_lval) {
+ /* scan for bad return args */
+ SV **p;
+ for (p = PL_stack_sp; p > oldsp; p--) {
+ SV *sv = *p;
+ /* the PL_sv_undef exception is to allow things like
+ * this to work, where PL_sv_undef acts as 'skip'
+ * placeholder on the LHS of list assigns:
+ * sub foo :lvalue { undef }
+ * ($a, undef, foo(), $b) = 1..4;
+ */
+ if (sv != &PL_sv_undef && (SvPADTMP(sv) || SvREADONLY(sv)))
+ {
+ /* Might be flattened array after $#array = */
+ what = SvREADONLY(sv)
+ ? "a readonly value" : "a temporary";
+ goto croak;
+ }
+ }
+ }
+
+ leave_adjust_stacks(oldsp, oldsp, gimme, is_lval ? 3 : 2);
+ }
}
- PUTBACK;
CX_LEAVE_SCOPE(cx);
POPSUB(cx); /* Stack values are safe: release CV and @_ ... */
* We may also need to shift the args down; for example,
* for (1,2) { return 3,4 }
* leaves 1,2,3,4 on the stack. Both these actions can be done by
- * leave_common(). By calling it with lvalue=TRUE, we just bump
- * the ref count and mortalise the args that need it. The "scan
- * the args and maybe copy them" process will be repeated by
- * whoever we tail-call (e.g. pp_leaveeval), where any copying etc
- * will be done. That is to say, in this code path two scans of
- * the args will be done; the first just shifts and preserves; the
- * second is the "real" arg processing, based on the type of
- * return.
+ * leave_adjust_stacks(). By calling it with and lvalue "pass
+ * all" action, we just bump the ref count and mortalise the args
+ * that need it, do a FREETMPS. The "scan the args and maybe copy
+ * them" process will be repeated by whoever we tail-call (e.g.
+ * pp_leaveeval), where any copying etc will be done. That is to
+ * say, in this code path two scans of the args will be done; the
+ * first just shifts and preserves; the second is the "real" arg
+ * processing, based on the type of return.
*/
cx = &cxstack[cxix];
PUTBACK;
- leave_common(PL_stack_base + cx->blk_oldsp, MARK,
- cx->blk_gimme, SVs_TEMP|SVs_PADTMP, TRUE);
+ if (cx->blk_gimme != G_VOID)
+ leave_adjust_stacks(MARK, PL_stack_base + cx->blk_oldsp,
+ cx->blk_gimme, 3);
SPAGAIN;
dounwind(cxix);
cx = &cxstack[cxix]; /* CX stack may have been realloced */
S_unwind_loop(aTHX_ "last");
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
- assert(
- CxTYPE(cx) == CXt_LOOP_LAZYIV
- || CxTYPE(cx) == CXt_LOOP_LAZYSV
- || CxTYPE(cx) == CXt_LOOP_FOR
- || CxTYPE(cx) == CXt_LOOP_PLAIN
- );
- PL_stack_sp = PL_stack_base + cx->blk_loop.resetsp;
+ assert(CxTYPE_is_LOOP(cx));
+ PL_stack_sp = PL_stack_base
+ + (CxTYPE(cx) == CXt_LOOP_LIST
+ ? cx->blk_loop.state_u.stack.basesp
+ : cx->blk_oldsp
+ );
TAINT_NOT;
S_unwind_loop(aTHX_ "next");
+ cx = CX_CUR();
TOPBLOCK(cx);
PL_curcop = cx->blk_oldcop;
PERL_ASYNC_CHECK();
if (redo_op->op_type == OP_ENTER) {
/* pop one less context to avoid $x being freed in while (my $x..) */
cxstack_ix++;
- assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_BLOCK);
+ assert(CxTYPE(CX_CUR()) == CXt_BLOCK);
redo_op = redo_op->op_next;
}
+ cx = CX_CUR();
TOPBLOCK(cx);
CX_LEAVE_SCOPE(cx);
FREETMPS;
if (cxix < cxstack_ix) {
dounwind(cxix);
}
+ cx = CX_CUR();
TOPBLOCK(cx);
SPAGAIN;
break;
}
/* else fall through */
- case CXt_LOOP_LAZYIV:
- case CXt_LOOP_LAZYSV:
- case CXt_LOOP_FOR:
- case CXt_LOOP_PLAIN:
+ case CXt_LOOP_PLAIN:
+ case CXt_LOOP_LAZYIV:
+ case CXt_LOOP_LAZYSV:
+ case CXt_LOOP_LIST:
+ case CXt_LOOP_ARY:
case CXt_GIVEN:
case CXt_WHEN:
gotoprobe = OpSIBLING(cx->blk_oldcop);
if (ix < 0)
DIE(aTHX_ "panic: docatch: illegal ix=%ld", (long)ix);
dounwind(ix);
+ cx = CX_CUR();
TOPBLOCK(cx);
}
switch (ret) {
case 0:
assert(cxstack_ix >= 0);
- assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
- cxstack[cxstack_ix].blk_eval.cur_top_env = PL_top_env;
+ assert(CxTYPE(CX_CUR()) == CXt_EVAL);
+ CX_CUR()->blk_eval.cur_top_env = PL_top_env;
redo_body:
CALLRUNOPS(aTHX);
break;
int ret;
dJMPENV;
- assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
+ assert(CxTYPE(CX_CUR()) == CXt_EVAL);
JMPENV_PUSH(ret);
switch (ret) {
case 0:
*/
STATIC bool
-S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
+S_doeval_compile(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
{
dSP;
OP * const saveop = PL_op;
evalcv = MUTABLE_CV(newSV_type(SVt_PVCV));
CvEVAL_on(evalcv);
- assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
- cxstack[cxstack_ix].blk_eval.cv = evalcv;
- cxstack[cxstack_ix].blk_gimme = gimme;
+ assert(CxTYPE(CX_CUR()) == CXt_EVAL);
+ CX_CUR()->blk_eval.cv = evalcv;
+ CX_CUR()->blk_gimme = gimme;
CvOUTSIDE_SEQ(evalcv) = seq;
CvOUTSIDE(evalcv) = MUTABLE_CV(SvREFCNT_inc_simple(outside));
yystatus = (!in_require && CATCH_GET) ? S_try_yyparse(aTHX_ GRAMPROG) : yyparse(GRAMPROG);
if (yystatus || PL_parser->error_count || !PL_eval_root) {
+ SV *namesv = NULL; /* initialise to avoid compiler warning */
PERL_CONTEXT *cx;
SV *errsv;
PL_eval_root = NULL;
}
SP = PL_stack_base + POPMARK; /* pop original mark */
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
POPBLOCK(cx);
- if (in_require) {
- S_undo_inc_then_croak(aTHX_ cx, ERRSV, FALSE);
- NOT_REACHED; /* NOTREACHED */
- }
+ if (in_require)
+ namesv = cx->blk_eval.old_namesv;
CX_POP(cx);
}
errsv = ERRSV;
if (in_require) {
- assert(yystatus == 3);
- cx = &cxstack[cxstack_ix];
- assert(CxTYPE(cx) == CXt_EVAL);
- S_undo_inc_then_croak(aTHX_ cx, errsv, FALSE);
+ if (yystatus == 3) {
+ cx = CX_CUR();
+ assert(CxTYPE(cx) == CXt_EVAL);
+ namesv = cx->blk_eval.old_namesv;
+ }
+ S_undo_inc_then_croak(aTHX_ namesv, errsv, FALSE);
NOT_REACHED; /* NOTREACHED */
}
/* switch to eval mode */
PUSHBLOCK(cx, CXt_EVAL, SP);
PUSHEVAL(cx, name);
- cx->cx_old_savestack_ix = old_savestack_ix;
+ cx->blk_oldsaveix = old_savestack_ix;
cx->blk_eval.retop = PL_op->op_next;
SAVECOPLINE(&PL_compiling);
PUTBACK;
- if (doeval(gimme, NULL, PL_curcop->cop_seq, NULL))
+ if (doeval_compile(gimme, NULL, PL_curcop->cop_seq, NULL))
op = DOCATCH(PL_eval_start);
else
op = PL_op->op_next;
PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP);
PUSHEVAL(cx, 0);
- cx->cx_old_savestack_ix = old_savestack_ix;
+ cx->blk_oldsaveix = old_savestack_ix;
cx->blk_eval.retop = PL_op->op_next;
/* prepare to compile string */
PUTBACK;
- if (doeval(gimme, runcv, seq, saved_hh)) {
+ if (doeval_compile(gimme, runcv, seq, saved_hh)) {
if (was != PL_breakable_sub_gen /* Some subs defined here. */
? PERLDB_LINE_OR_SAVESRC
: PERLDB_SAVESRC_NOSUBS) {
return DOCATCH(PL_eval_start);
} else {
/* We have already left the scope set up earlier thanks to the LEAVE
- in doeval(). */
+ in doeval_compile(). */
if (was != PL_breakable_sub_gen /* Some subs defined here. */
? PERLDB_LINE_OR_SAVESRC
: PERLDB_SAVESRC_INVALID) {
PP(pp_leaveeval)
{
- dSP;
SV **newsp;
I32 gimme;
PERL_CONTEXT *cx;
OP *retop;
- I32 optype;
+ SV *namesv = NULL;
CV *evalcv;
/* grab this value before POPEVAL restores old PL_in_eval */
bool keep = cBOOL(PL_in_eval & EVAL_KEEPERR);
PERL_ASYNC_CHECK();
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_EVAL);
+
newsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
- if (gimme != G_VOID) {
- PUTBACK;
- leave_common(newsp, newsp, gimme, SVs_TEMP, FALSE);
- SPAGAIN;
- }
+ /* did require return a false value? */
+ if ( CxOLD_OP_TYPE(cx) == OP_REQUIRE
+ && !(gimme == G_SCALAR
+ ? SvTRUE(*PL_stack_sp)
+ : PL_stack_sp > newsp)
+ )
+ namesv = cx->blk_eval.old_namesv;
+
+ if (gimme == G_VOID)
+ PL_stack_sp = newsp;
+ else
+ leave_adjust_stacks(newsp, newsp, gimme, 0);
+
/* 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
* to get the current hints. So restore it early.
*/
PL_curcop = cx->blk_oldcop;
+
CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
POPBLOCK(cx);
retop = cx->blk_eval.retop;
evalcv = cx->blk_eval.cv;
- optype = CxOLD_OP_TYPE(cx);
-
+ CX_POP(cx);
#ifdef DEBUGGING
assert(CvDEPTH(evalcv) == 1);
#endif
CvDEPTH(evalcv) = 0;
- if (optype == OP_REQUIRE &&
- !(gimme == G_SCALAR ? SvTRUE(*SP) : SP > newsp))
- {
+ if (namesv) { /* require returned false */
/* Unassume the success we assumed earlier. */
- S_undo_inc_then_croak(aTHX_ cx, NULL, TRUE);
+ S_undo_inc_then_croak(aTHX_ namesv, NULL, TRUE);
NOT_REACHED; /* NOTREACHED */
}
- CX_POP(cx);
-
if (!keep)
CLEAR_ERRSV();
- RETURNOP(retop);
+ return retop;
}
/* Common code for Perl_call_sv and Perl_fold_constants, put here to keep it
{
PERL_CONTEXT *cx;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
POPBLOCK(cx);
PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
PUSHEVAL(cx, 0);
- cx->cx_old_savestack_ix = PL_savestack_ix;
+ cx->blk_oldsaveix = PL_savestack_ix;
PL_in_eval = EVAL_INEVAL;
if (flags & G_KEEPERR)
PERL_ASYNC_CHECK();
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_EVAL);
newsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
+ leave_adjust_stacks(newsp, newsp, gimme, 1);
CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
POPBLOCK(cx);
SV **newsp;
PERL_UNUSED_CONTEXT;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_GIVEN);
newsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
+ leave_adjust_stacks(newsp, newsp, gimme, 1);
CX_LEAVE_SCOPE(cx);
POPGIVEN(cx);
I32 gimme;
SV **newsp;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_WHEN);
gimme = cx->blk_gimme;
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
+ leave_adjust_stacks(newsp, newsp, gimme, 1);
+
/* pop the WHEN, BLOCK and anything else before the GIVEN/FOR */
assert(cxix < cxstack_ix);
dounwind(cxix);
if (CxFOREACH(cx)) {
/* emulate pp_next. Note that any stack(s) cleanup will be
* done by the pp_unstack which op_nextop should point to */
+ cx = CX_CUR();
TOPBLOCK(cx);
PL_curcop = cx->blk_oldcop;
return cx->blk_loop.my_op->op_nextop;
if (cxix < cxstack_ix)
dounwind(cxix);
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_WHEN);
PL_stack_sp = PL_stack_base + cx->blk_oldsp;
CX_LEAVE_SCOPE(cx);
dounwind(cxix);
/* Restore the sp at the time we entered the given block */
+ cx = CX_CUR();
TOPBLOCK(cx);
return cx->blk_givwhen.leave_op;