summaryrefslogtreecommitdiff
path: root/cop.h
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2008-01-26 16:03:03 +0000
committerNicholas Clark <nick@ccl4.org>2008-01-26 16:03:03 +0000
commitd28d780685cbd952928da9c691e2b5bae129457a (patch)
tree316de049483c61cc8ada459d5e6b6462fbd1f77d /cop.h
parent9a98d8a1ee5dd7f1caa95f2ec5ab0341e0b4f8d1 (diff)
downloadperl-d28d780685cbd952928da9c691e2b5bae129457a.tar.gz
As itersave points to the initial CxITERVAR(), and the state of
SvPADMY() does not change over the duration of the scope, we can perform conditional actions at loop push time. For the non-pad case, a reference to the initial CxITERVAR() is already held on the scope stack thanks to SAVEGENERICSV(*svp); in pp_enteriter. So there is no need to save another reference to it in itersave - it's not going away. p4raw-id: //depot/perl@33076
Diffstat (limited to 'cop.h')
-rw-r--r--cop.h17
1 files changed, 7 insertions, 10 deletions
diff --git a/cop.h b/cop.h
index 359abd61ff..ca9dae286e 100644
--- a/cop.h
+++ b/cop.h
@@ -469,14 +469,15 @@ struct block_loop {
: (SV**)NULL)
# define CX_ITERDATA_SET(cx,idata) \
CX_CURPAD_SAVE(cx->blk_loop); \
- if ((cx->blk_loop.iterdata = (idata))) \
+ if ((cx->blk_loop.iterdata = (idata)) && SvPADMY(*CxITERVAR(cx))) \
cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx)); \
else \
cx->blk_loop.itersave = NULL;
#else
# define CxITERVAR(c) ((c)->blk_loop.itervar)
# define CX_ITERDATA_SET(cx,ivar) \
- if ((cx->blk_loop.itervar = (SV**)(ivar))) \
+ if ((cx->blk_loop.itervar = (SV**)(ivar)) \
+ && SvPADMY(*CxITERVAR(cx))) \
cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx)); \
else \
cx->blk_loop.itersave = NULL;
@@ -515,14 +516,10 @@ struct block_loop {
SvREFCNT_dec(cx->blk_loop.state_u.lazysv.end); \
} \
if (cx->blk_loop.itersave) { \
- if (SvPADMY(cx->blk_loop.itersave)) { \
- SV ** const s_v_p = CxITERVAR(cx); \
- sv_2mortal(*s_v_p); \
- *s_v_p = cx->blk_loop.itersave; \
- } \
- else { \
- SvREFCNT_dec(cx->blk_loop.itersave); \
- } \
+ SV ** const s_v_p = CxITERVAR(cx); \
+ assert(SvPADMY(cx->blk_loop.itersave)); \
+ sv_2mortal(*s_v_p); \
+ *s_v_p = cx->blk_loop.itersave; \
} \
if (CxTYPE(cx) == CXt_LOOP_FOR) \
SvREFCNT_dec(cx->blk_loop.state_u.ary.ary);