GV * dfoutgv;
};
+/* return a pointer to the current context */
+
+#define CX_CUR() (&cxstack[cxstack_ix])
+
/* free all savestack items back to the watermark of the specified context */
#define CX_LEAVE_SCOPE(cx) LEAVE_SCOPE(cx->blk_oldsaveix)
* uses it - because after doing cxstack_ix--, any ties, exceptions etc
* may overwrite the current stack frame */
# define CX_POP(cx) \
- assert(&cxstack[cxstack_ix] == cx); \
+ assert(CX_CUR() == cx); \
cxstack_ix--; \
cx = NULL;
#else
Perl_deb(aTHX_ "CX %ld %s %s (scope %ld,%ld) (save %ld,%ld) at %s:%d\n",\
(long)cxstack_ix, \
action, \
- PL_block_type[CxTYPE(&cxstack[cxstack_ix])], \
+ PL_block_type[CxTYPE(CX_CUR())], \
(long)PL_scopestack_ix, \
- (long)(cxstack[cxstack_ix].blk_oldscopesp), \
+ (long)(CX_CUR()->blk_oldscopesp), \
(long)PL_savestack_ix, \
- (long)(cxstack[cxstack_ix].blk_oldsaveix), \
+ (long)(CX_CUR()->blk_oldsaveix), \
__FILE__, __LINE__));
/* Enter a block. */
-#define PUSHBLOCK(cx,t,sp) CXINC, cx = &cxstack[cxstack_ix], \
+#define PUSHBLOCK(cx,t,sp) CXINC, cx = CX_CUR(), \
cx->cx_type = t, \
cx->blk_oldsp = sp - PL_stack_base, \
cx->blk_oldcop = PL_curcop, \
/* Continue a block elsewhere (NEXT and REDO). */
#define TOPBLOCK(cx) \
DEBUG_CX("TOP"); \
- cx = &cxstack[cxstack_ix], \
+ cx = CX_CUR(), \
PL_stack_sp = PL_stack_base + cx->blk_oldsp, \
PL_markstack_ptr = PL_markstack + cx->blk_oldmarksp, \
PL_scopestack_ix = cx->blk_oldscopesp, \
#define sb_rx cx_u.cx_subst.sbu_rx
#ifdef PERL_CORE
-# define PUSHSUBST(cx) CXINC, cx = &cxstack[cxstack_ix], \
+# define PUSHSUBST(cx) CXINC, cx = CX_CUR(), \
cx->blk_oldsaveix = oldsave, \
cx->sb_iters = iters, \
cx->sb_maxiters = maxiters, \
#define POP_MULTICALL \
STMT_START { \
- cx = &cxstack[cxstack_ix]; \
+ cx = CX_CUR(); \
CX_LEAVE_SCOPE(cx); \
POPSUB_COMMON(cx); \
newsp = PL_stack_base + cx->blk_oldsp; \
CV * const _nOnclAshIngNamE_ = the_cv; \
CV * const cv = _nOnclAshIngNamE_; \
PADLIST * const padlist = CvPADLIST(cv); \
- cx = &cxstack[cxstack_ix]; \
+ cx = CX_CUR(); \
assert(CxMULTICALL(cx)); \
POPSUB_COMMON(cx); \
cx->cx_type = (CXt_SUB|CXp_MULTICALL|flags); \
((PL_in_eval & EVAL_KEEPERR)
? OPf_SPECIAL : 0), o);
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_EVAL);
if ((cx->blk_gimme & G_WANT) == G_VOID)
* may or may not have already been popped */
if (cxstack_ix > old_cxix) {
assert(cxstack_ix == old_cxix + 1);
- assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
+ assert(CxTYPE(CX_CUR()) == CXt_EVAL);
delete_eval_scope();
}
if (ret)
* may or may not have already been popped */
if (cxstack_ix > old_cxix) {
assert(cxstack_ix == old_cxix + 1);
- assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
+ assert(CxTYPE(CX_CUR()) == CXt_EVAL);
delete_eval_scope();
}
JMPENV_POP;
to return. nextstate usually does this on sub entry, but we need
to run the next op with the caller's hints, so we cannot have a
nextstate. */
- SP = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;
+ SP = PL_stack_base + CX_CUR()->blk_oldsp;
if(!maxargs) RETURN;
);
PUSHs(SvRV(*svp));
if (opnum == OP_UNDEF && SvRV(*svp) == (SV *)PL_defgv
- && cxstack[cxstack_ix].cx_type & CXp_HASARGS) {
+ && CX_CUR()->cx_type & CXp_HASARGS) {
/* Undo @_ localisation, so that sub exit does not undo
part of our undeffing. */
- PERL_CONTEXT *cx = &cxstack[cxstack_ix];
+ PERL_CONTEXT *cx = CX_CUR();
assert(CxHASARGS(cx));
POPSUB_ARGS(cx);;
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;
return;
while (cxstack_ix > cxix) {
- PERL_CONTEXT *cx = &cxstack[cxstack_ix];
- DEBUG_CX("UNWIND"); \
+ PERL_CONTEXT *cx = CX_CUR();
+ DEBUG_CX("UNWIND");
/* Note: we don't need to restore the base context info till the end. */
CX_LEAVE_SCOPE(cx);
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 */
{
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();
SV **newsp;
I32 gimme;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_BLOCK);
if (PL_op->op_flags & OPf_SPECIAL)
SV **newsp;
SV **mark;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE_is_LOOP(cx));
mark = PL_stack_base + cx->blk_oldsp;
newsp = CxTYPE(cx) == CXt_LOOP_LIST
const char *what = NULL;
OP *retop;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_SUB);
if (CxMULTICALL(cx)) {
S_unwind_loop(aTHX_ "last");
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE_is_LOOP(cx));
PL_stack_sp = PL_stack_base
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;
}
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:
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));
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);
errsv = ERRSV;
if (in_require) {
if (yystatus == 3) {
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_EVAL);
namesv = cx->blk_eval.old_namesv;
}
PERL_ASYNC_CHECK();
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_EVAL);
newsp = PL_stack_base + cx->blk_oldsp;
{
PERL_CONTEXT *cx;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
POPBLOCK(cx);
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;
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;
I32 gimme;
SV **newsp;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_WHEN);
gimme = cx->blk_gimme;
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);
{
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();
return NORMAL;
PERL_CONTEXT *cx;
PERL_ASYNC_CHECK();
TAINT_NOT; /* Each statement is presumed innocent */
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
PL_stack_sp = PL_stack_base + cx->blk_oldsp;
FREETMPS;
if (!(PL_op->op_flags & OPf_SPECIAL)) {
SV **itersvp;
SV *retsv;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
itersvp = CxITERVAR(cx);
switch (CxTYPE(cx)) {
PERL_CONTEXT *cx;
OP *retop;
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_SUB);
if (CxMULTICALL(cx)) {
sort_flags);
/* Reset cx, in case the context stack has been reallocated. */
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
PL_stack_sp = PL_stack_base + cx->blk_oldsp;
PP(pp_leavewrite)
{
dSP;
- GV * const gv = cxstack[cxstack_ix].blk_format.gv;
+ GV * const gv = CX_CUR()->blk_format.gv;
IO * const io = GvIOp(gv);
PerlIO *ofp;
PerlIO *fp;
}
forget_top:
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_FORMAT);
SP = PL_stack_base + cx->blk_oldsp; /* ignore retval of formline */
CX_LEAVE_SCOPE(cx);
SV *linestr;
char *bufend;
char * const olds = s;
- PERL_CONTEXT * const cx = &cxstack[cxstack_ix];
+ PERL_CONTEXT * const cx = CX_CUR();
/* These two fields are not set until an inner lexing scope is
entered. But we need them set here. */
shared->ls_bufptr = s;