pm = cx->blk_oldpm, \
gimme = cx->blk_gimme; \
DEBUG_l( PerlIO_printf(PerlIO_stderr(), "Leaving block %ld, type %s\n", \
- (long)cxstack_ix+1,block_type[cx->cx_type]); )
+ (long)cxstack_ix+1,block_type[CxTYPE(cx)]); )
/* Continue a block elsewhere (NEXT and REDO). */
#define TOPBLOCK(cx) cx = &cxstack[cxstack_ix], \
rxres_free(&cx->sb_rxres)
struct context {
- I32 cx_type; /* what kind of context this is */
+ U32 cx_type; /* what kind of context this is */
union {
struct block cx_blk;
struct subst cx_subst;
} cx_u;
};
+
+#define CXTYPEMASK 0xff
#define CXt_NULL 0
#define CXt_SUB 1
#define CXt_EVAL 2
#define CXt_SUBST 4
#define CXt_BLOCK 5
+/* private flags for CXt_EVAL */
+#define CXp_REAL 0x00000100 /* truly eval'', not a lookalike */
+
+#define CxTYPE(c) ((c)->cx_type & CXTYPEMASK)
+#define CxREALEVAL(c) (((c)->cx_type & (CXt_EVAL|CXp_REAL)) == (CXt_EVAL|CXp_REAL))
+
#define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc()))
/* "gimme" values */
CV *bcv;
for (bcv = startcv;
bcv && bcv != cv && !CvCLONE(bcv);
- bcv = CvOUTSIDE(bcv)) {
+ bcv = CvOUTSIDE(bcv))
+ {
if (CvANON(bcv))
CvCLONE_on(bcv);
else {
- if (ckWARN(WARN_CLOSURE) && !CvUNIQUE(cv))
+ if (ckWARN(WARN_CLOSURE)
+ && !CvUNIQUE(bcv) && !CvUNIQUE(cv))
+ {
warner(WARN_CLOSURE,
"Variable \"%s\" may be unavailable",
name);
+ }
break;
}
}
for (i = cx_ix; i >= 0; i--) {
cx = &cxstack[i];
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
default:
if (i == 0 && saweval) {
seq = cxstack[saweval].blk_oldcop->cop_seq;
case CXt_EVAL:
switch (cx->blk_eval.old_op_type) {
case OP_ENTEREVAL:
- saweval = i;
+ if (CxREALEVAL(cx))
+ saweval = i;
break;
case OP_REQUIRE:
/* require must have its own scope */
SV *sv;
SV **svp = AvARRAY(PL_comppad_name);
U32 seq = PL_cop_seqmax;
+ PERL_CONTEXT *cx;
#ifdef USE_THREADS
/*
}
}
+ /* Check if if we're in an eval'', and adjust seq to be the eval's
+ * seq number */
+ if (cxstack_ix >= 0) {
+ cx = &cxstack[cxstack_ix];
+ if (CxREALEVAL(cx))
+ seq = cx->blk_oldcop->cop_seq;
+ }
+
/* See if it's in a nested scope */
off = pad_findlex(name, 0, seq, CvOUTSIDE(PL_compcv), cxstack_ix, 0);
if (off) {
for (i = cxstack_ix; i >= 0; i--) {
cx = &cxstack[i];
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
case CXt_SUBST:
if (ckWARN(WARN_UNSAFE))
warner(WARN_UNSAFE, "Exiting substitution via %s",
register PERL_CONTEXT *cx;
for (i = startingblock; i >= 0; i--) {
cx = &cxstk[i];
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
default:
continue;
case CXt_EVAL:
register PERL_CONTEXT *cx;
for (i = startingblock; i >= 0; i--) {
cx = &cxstack[i];
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
default:
continue;
case CXt_EVAL:
register PERL_CONTEXT *cx;
for (i = startingblock; i >= 0; i--) {
cx = &cxstack[i];
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
case CXt_SUBST:
if (ckWARN(WARN_UNSAFE))
warner(WARN_UNSAFE, "Exiting substitution via %s",
while (cxstack_ix > cxix) {
cx = &cxstack[cxstack_ix];
DEBUG_l(PerlIO_printf(Perl_debug_log, "Unwinding block %ld, type %s\n",
- (long) cxstack_ix, block_type[cx->cx_type]));
+ (long) cxstack_ix, block_type[CxTYPE(cx)]));
/* Note: we don't need to restore the base context info till the end. */
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
case CXt_SUBST:
POPSUBST(cx);
continue; /* not break */
dounwind(cxix);
POPBLOCK(cx,PL_curpm);
- if (cx->cx_type != CXt_EVAL) {
+ if (CxTYPE(cx) != CXt_EVAL) {
PerlIO_printf(PerlIO_stderr(), "panic: die %s", message);
my_exit(1);
}
}
cx = &ccstack[cxix];
- if (ccstack[cxix].cx_type == CXt_SUB) {
+ if (CxTYPE(cx) == CXt_SUB) {
dbcxix = dopoptosub_at(ccstack, cxix - 1);
/* We expect that ccstack[dbcxix] is CXt_SUB, anyway, the
field below is defined for any cx. */
PUSHs(sv_2mortal(newSViv((I32)cx->blk_oldcop->cop_line)));
if (!MAXARG)
RETURN;
- if (cx->cx_type == CXt_SUB) { /* So is ccstack[dbcxix]. */
+ if (CxTYPE(cx) == CXt_SUB) { /* So is ccstack[dbcxix]. */
sv = NEWSV(49, 0);
gv_efullname3(sv, CvGV(ccstack[cxix].blk_sub.cv), Nullch);
PUSHs(sv_2mortal(sv));
PUSHs(&PL_sv_undef);
else
PUSHs(sv_2mortal(newSViv(gimme & G_ARRAY)));
- if (cx->cx_type == CXt_EVAL) {
+ if (CxTYPE(cx) == CXt_EVAL) {
if (cx->blk_eval.old_op_type == OP_ENTEREVAL) {
PUSHs(cx->blk_eval.cur_text);
PUSHs(&PL_sv_no);
PUSHs(&PL_sv_yes);
}
}
- else if (cx->cx_type == CXt_SUB &&
+ else if (CxTYPE(cx) == CXt_SUB &&
cx->blk_sub.hasargs &&
PL_curcop->cop_stash == PL_debstash)
{
dounwind(cxix);
POPBLOCK(cx,newpm);
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
case CXt_SUB:
POPSUB1(cx); /* Delay POPSUB2 until stack values are safe */
popsub2 = TRUE;
dounwind(cxix);
POPBLOCK(cx,newpm);
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
case CXt_LOOP:
POPLOOP1(cx); /* Delay POPLOOP2 until stack values are safe */
pop2 = CXt_LOOP;
if (cxix < cxstack_ix)
dounwind(cxix);
TOPBLOCK(cx);
- if (cx->cx_type == CXt_EVAL && cx->blk_eval.old_op_type == OP_ENTEREVAL)
+ if (CxTYPE(cx) == CXt_EVAL && cx->blk_eval.old_op_type == OP_ENTEREVAL)
DIE("Can't goto subroutine from an eval-string");
mark = PL_stack_sp;
- if (cx->cx_type == CXt_SUB &&
+ if (CxTYPE(cx) == CXt_SUB &&
cx->blk_sub.hasargs) { /* put @_ back onto stack */
AV* av = cx->blk_sub.argarray;
Copy(AvARRAY(av), PL_stack_sp, items, SV*);
PL_stack_sp += items;
}
- if (cx->cx_type == CXt_SUB &&
+ if (CxTYPE(cx) == CXt_SUB &&
!(CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth))
SvREFCNT_dec(cx->blk_sub.cv);
oldsave = PL_scopestack[PL_scopestack_ix - 1];
else {
AV* padlist = CvPADLIST(cv);
SV** svp = AvARRAY(padlist);
- if (cx->cx_type == CXt_EVAL) {
+ if (CxTYPE(cx) == CXt_EVAL) {
PL_in_eval = cx->blk_eval.old_in_eval;
PL_eval_root = cx->blk_eval.old_eval_root;
cx->cx_type = CXt_SUB;
*enterops = 0;
for (ix = cxstack_ix; ix >= 0; ix--) {
cx = &cxstack[ix];
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
case CXt_EVAL:
gotoprobe = PL_eval_root; /* XXX not good for nested eval */
break;
SAVEI32(PL_max_intro_pending);
caller = PL_compcv;
- for (i = cxstack_ix; i >= 0; i--) {
+ for (i = cxstack_ix - 1; i >= 0; i--) {
PERL_CONTEXT *cx = &cxstack[i];
- if (cx->cx_type == CXt_EVAL)
+ if (CxTYPE(cx) == CXt_EVAL)
break;
- else if (cx->cx_type == CXt_SUB) {
+ else if (CxTYPE(cx) == CXt_SUB) {
caller = cx->blk_sub.cv;
break;
}
}
push_return(PL_op->op_next);
- PUSHBLOCK(cx, CXt_EVAL, SP);
+ PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP);
PUSHEVAL(cx, 0, PL_compiling.cop_filegv);
/* prepare to compile string */
{
#ifdef DEBUGGING
dTHR;
- PerlIO_printf(Perl_debug_log, "CX %ld = %s\n", (long)(cx - cxstack), block_type[cx->cx_type]);
- if (cx->cx_type != CXt_SUBST) {
+ PerlIO_printf(Perl_debug_log, "CX %ld = %s\n", (long)(cx - cxstack), block_type[CxTYPE(cx)]);
+ if (CxTYPE(cx) != CXt_SUBST) {
PerlIO_printf(Perl_debug_log, "BLK_OLDSP = %ld\n", (long)cx->blk_oldsp);
PerlIO_printf(Perl_debug_log, "BLK_OLDCOP = 0x%lx\n", (long)cx->blk_oldcop);
PerlIO_printf(Perl_debug_log, "BLK_OLDMARKSP = %ld\n", (long)cx->blk_oldmarksp);
PerlIO_printf(Perl_debug_log, "BLK_OLDPM = 0x%lx\n", (long)cx->blk_oldpm);
PerlIO_printf(Perl_debug_log, "BLK_GIMME = %s\n", cx->blk_gimme ? "LIST" : "SCALAR");
}
- switch (cx->cx_type) {
+ switch (CxTYPE(cx)) {
case CXt_NULL:
case CXt_BLOCK:
break;