break;
case CXt_EVAL:
POPEVAL(cx);
- LEAVE_SCOPE(cx->blk_eval.old_savestack_ix);
- PL_tmps_floor = cx->blk_eval.old_tmpsfloor;
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
break;
case CXt_LOOP_LAZYIV:
case CXt_LOOP_LAZYSV:
case CXt_LOOP_PLAIN:
POPLOOP(cx);
break;
+ case CXt_WHEN:
+ POPWHEN(cx);
+ break;
+ case CXt_GIVEN:
+ POPGIVEN(cx);
+ break;
case CXt_NULL:
break;
case CXt_FORMAT:
*++newsp = &PL_sv_undef;
PL_stack_sp = newsp;
- LEAVE_SCOPE(cx->blk_eval.old_savestack_ix);
- PL_tmps_floor = cx->blk_eval.old_tmpsfloor;
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
if (optype == OP_REQUIRE) {
assert (PL_curcop == oldcop);
PUSHBLOCK(cx, CXt_SUB, SP);
PUSHSUB_DB(cx);
cx->blk_sub.retop = PL_op->op_next;
- cx->blk_sub.old_savestack_ix = PL_savestack_ix;
+ cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix;
SAVEI32(PL_debug);
PL_debug = 0;
dSP; dMARK;
PERL_CONTEXT *cx;
const I32 gimme = GIMME_V;
- void *itervar; /* location of the iteration variable */
+ 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;
SAVETMPS;
if (PL_op->op_targ) { /* "my" variable */
- itervar = &PAD_SVl(PL_op->op_targ);
+ itervarp = &PAD_SVl(PL_op->op_targ);
+ itersave = *(SV**)itervarp;
+ assert(itersave);
if (PL_op->op_private & OPpLVAL_INTRO) { /* for my $x (...) */
/* the SV currently in the pad slot is never live during
* iteration (the slot is always aliased to one of the items)
* so it's always stale */
- SvPADSTALE_on(*(SV**)itervar);
+ SvPADSTALE_on(itersave);
}
- itersave = SvREFCNT_inc(*(SV**)itervar);
- assert(itersave);
- }
- else if (LIKELY(isGV(TOPs))) { /* symbol table variable */
- GV * const gv = MUTABLE_GV(POPs);
- SV** svp = &GvSV(gv);
- itersave = SvREFCNT_inc(*svp);
- *svp = newSV(0);
- itervar = (void *)gv;
+ SvREFCNT_inc_simple_void_NN(itersave);
+ cxtype |= CXp_FOR_PAD;
}
else {
SV * const sv = POPs;
- assert(SvTYPE(sv) == SVt_PVMG);
- assert(SvMAGIC(sv));
- assert(SvMAGIC(sv)->mg_type == PERL_MAGIC_lvref);
- itervar = (void *)sv;
- cxtype |= CXp_FOR_LVREF;
- itersave = NULL;
+ itervarp = (void *)sv;
+ if (LIKELY(isGV(sv))) { /* symbol table variable */
+ SV** svp = &GvSV(sv);
+ itersave = *svp;
+ if (LIKELY(itersave))
+ SvREFCNT_inc_simple_void_NN(itersave);
+ else
+ *svp = newSV(0);
+ cxtype |= 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;
+ }
}
if (PL_op->op_private & OPpITER_DEF)
ENTER_with_name("loop2");
PUSHBLOCK(cx, cxtype, SP);
- PUSHLOOP_FOR(cx, itervar, itersave, MARK);
+ PUSHLOOP_FOR(cx, itervarp, itersave, MARK);
if (PL_op->op_flags & OPf_STACKED) {
SV *maybe_ary = POPs;
if (SvTYPE(maybe_ary) != SVt_PVAV) {
SvREFCNT_inc_NN(sv_2mortal(MUTABLE_SV(arg)));
assert(PL_scopestack_ix == cx->blk_oldscopesp);
- LEAVE_SCOPE(cx->blk_sub.old_savestack_ix);
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
AV* av = MUTABLE_AV(PAD_SVl(0));
POPEVAL(cx);
namesv = cx->blk_eval.old_namesv;
/* POPBLOCK has rendered LEAVE_with_name("evalcomp") unnecessary */
- LEAVE_SCOPE(cx->blk_eval.old_savestack_ix);
- PL_tmps_floor = cx->blk_eval.old_tmpsfloor;
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
}
errsv = ERRSV;
/* switch to eval mode */
PUSHBLOCK(cx, CXt_EVAL, SP);
PUSHEVAL(cx, name);
- cx->blk_eval.old_savestack_ix = old_savestack_ix;
+ cx->cx_u.cx_blk.blku_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->blk_eval.old_savestack_ix = old_savestack_ix;
+ cx->cx_u.cx_blk.blku_old_savestack_ix = old_savestack_ix;
cx->blk_eval.retop = PL_op->op_next;
/* prepare to compile string */
SvPVX_const(namesv),
SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
G_DISCARD);
- LEAVE_SCOPE(cx->blk_eval.old_savestack_ix);
- PL_tmps_floor = cx->blk_eval.old_tmpsfloor;
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ 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 {
- LEAVE_SCOPE(cx->blk_eval.old_savestack_ix);
- PL_tmps_floor = cx->blk_eval.old_tmpsfloor;
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
if (!keep)
CLEAR_ERRSV();
}
POPBLOCK(cx,newpm);
POPEVAL(cx);
PL_curpm = newpm;
- LEAVE_SCOPE(cx->blk_eval.old_savestack_ix);
- PL_tmps_floor = cx->blk_eval.old_tmpsfloor;
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
PERL_UNUSED_VAR(newsp);
PERL_UNUSED_VAR(gimme);
PERL_UNUSED_VAR(optype);
PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
PUSHEVAL(cx, 0);
- cx->blk_eval.old_savestack_ix = PL_savestack_ix;
+ cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix;
PL_in_eval = EVAL_INEVAL;
if (flags & G_KEEPERR)
SVs_PADTMP|SVs_TEMP, FALSE);
PL_curpm = newpm; /* Don't pop $1 et al till now */
- LEAVE_SCOPE(cx->blk_eval.old_savestack_ix);
- PL_tmps_floor = cx->blk_eval.old_tmpsfloor;
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
CLEAR_ERRSV();
RETURNOP(retop);
dSP;
PERL_CONTEXT *cx;
const I32 gimme = GIMME_V;
+ SV *origsv = DEFSV;
+ SV *newsv = POPs;
ENTER_with_name("given");
SAVETMPS;
assert(!PL_op->op_targ); /* used to be set for lexical $_ */
- SAVE_DEFSV;
- DEFSV_set(POPs);
+ GvSV(PL_defgv) = SvREFCNT_inc(newsv);
PUSHBLOCK(cx, CXt_GIVEN, SP);
- PUSHGIVEN(cx);
+ PUSHGIVEN(cx, origsv);
RETURN;
}
PERL_UNUSED_CONTEXT;
POPBLOCK(cx,newpm);
+ POPGIVEN(cx);
assert(CxTYPE(cx) == CXt_GIVEN);
SP = (gimme == G_VOID)
POPBLOCK(cx,newpm);
assert(CxTYPE(cx) == CXt_WHEN);
+ POPWHEN(cx);
SP = (gimme == G_VOID)
? newsp