Add a new field, defsv_save, to struct block_givwhen, and use this
to save the previous $_ in 'when(expr)' rather than saving it on the save
stack.
Also add POPWHEN and POPGIVEN macros. The former is a no-op for now.
/* given/when context */
struct block_givwhen {
OP *leave_op;
/* given/when context */
struct block_givwhen {
OP *leave_op;
+ SV *defsv_save; /* the original $_ */
cx->blk_givwhen.leave_op = cLOGOP->op_other;
cx->blk_givwhen.leave_op = cLOGOP->op_other;
-#define PUSHWHEN PUSHGIVEN
+#define PUSHGIVEN(cx, orig_var) \
+ PUSHWHEN(cx); \
+ cx->blk_givwhen.defsv_save = orig_var;
+
+#define POPWHEN(cx) \
+ NOOP;
+
+#define POPGIVEN(cx) \
+ SvREFCNT_dec(GvSV(PL_defgv)); \
+ GvSV(PL_defgv) = cx->blk_givwhen.defsv_save;
+
/* context common to subroutines, evals and loops */
struct block {
/* context common to subroutines, evals and loops */
struct block {
case CXt_LOOP_PLAIN:
POPLOOP(cx);
break;
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:
case CXt_NULL:
break;
case CXt_FORMAT:
dSP;
PERL_CONTEXT *cx;
const I32 gimme = GIMME_V;
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 $_ */
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);
PUSHBLOCK(cx, CXt_GIVEN, SP);
PERL_UNUSED_CONTEXT;
POPBLOCK(cx,newpm);
PERL_UNUSED_CONTEXT;
POPBLOCK(cx,newpm);
assert(CxTYPE(cx) == CXt_GIVEN);
SP = (gimme == G_VOID)
assert(CxTYPE(cx) == CXt_GIVEN);
SP = (gimme == G_VOID)
POPBLOCK(cx,newpm);
assert(CxTYPE(cx) == CXt_WHEN);
POPBLOCK(cx,newpm);
assert(CxTYPE(cx) == CXt_WHEN);
SP = (gimme == G_VOID)
? newsp
SP = (gimme == G_VOID)
? newsp