summaryrefslogtreecommitdiff
path: root/cop.h
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-10-19 17:04:02 +0100
committerDavid Mitchell <davem@iabyn.com>2016-02-03 09:18:31 +0000
commita7db2e35a577614d7a6eaf05114b2d6224f0ab33 (patch)
treee0040f23a2d8b2ccd7efbc9312e86d79c82ac3c9 /cop.h
parentf09cca8c5bdd6f39d80f8c49d87abde4e16255ab (diff)
downloadperl-a7db2e35a577614d7a6eaf05114b2d6224f0ab33.tar.gz
make POPSUB re-entrant safe
Diffstat (limited to 'cop.h')
-rw-r--r--cop.h16
1 files changed, 12 insertions, 4 deletions
diff --git a/cop.h b/cop.h
index 09fd2a64f9..f6280a9ec4 100644
--- a/cop.h
+++ b/cop.h
@@ -832,11 +832,18 @@ struct block_loop {
#define POPLOOP(cx) \
if (CxTYPE(cx) == CXt_LOOP_LAZYSV) { \
- SvREFCNT_dec_NN(cx->blk_loop.state_u.lazysv.cur); \
- SvREFCNT_dec_NN(cx->blk_loop.state_u.lazysv.end); \
+ SV *sv = cx->blk_loop.state_u.lazysv.cur; \
+ cx->blk_loop.state_u.lazysv.cur = NULL; \
+ SvREFCNT_dec_NN(sv); \
+ sv = cx->blk_loop.state_u.lazysv.end; \
+ cx->blk_loop.state_u.lazysv.end = NULL; \
+ SvREFCNT_dec_NN(sv); \
} \
- else if (CxTYPE(cx) == CXt_LOOP_ARY) \
- SvREFCNT_dec(cx->blk_loop.state_u.ary.ary); \
+ else if (CxTYPE(cx) == CXt_LOOP_ARY) { \
+ AV *av = cx->blk_loop.state_u.ary.ary; \
+ cx->blk_loop.state_u.ary.ary = NULL; \
+ SvREFCNT_dec(av); \
+ } \
if (cx->cx_type & (CXp_FOR_PAD|CXp_FOR_GV)) { \
SV *cursv; \
SV **svp = (cx)->blk_loop.itervar_u.svp; \
@@ -844,6 +851,7 @@ struct block_loop {
svp = &GvSV((GV*)svp); \
cursv = *svp; \
*svp = cx->blk_loop.itersave; \
+ cx->blk_loop.itersave = NULL; \
SvREFCNT_dec(cursv); \
}