summaryrefslogtreecommitdiff
path: root/cop.h
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1999-10-09 00:41:02 +0000
committerGurusamy Sarathy <gsar@cpan.org>1999-10-09 00:41:02 +0000
commitb0d9ce3858aa1d5f16f24f50ca1172e6eb75fcd9 (patch)
treea7de3bee889a19e08ea369636a8e8b53b0bacb28 /cop.h
parenta8bba7fac320f0a7f553e9a133cddd65ef2a66c7 (diff)
downloadperl-b0d9ce3858aa1d5f16f24f50ca1172e6eb75fcd9.tar.gz
POPSUB() gave up the refcount to the CV before LEAVE had a chance to
clear entries in the CV's pad, leading to coredumps when CV had no other references to it; this is a slightly edited version of the patch suggested by Russel O'Connor <roconnor@world.std.com> p4raw-id: //depot/perl@4321
Diffstat (limited to 'cop.h')
-rw-r--r--cop.h17
1 files changed, 12 insertions, 5 deletions
diff --git a/cop.h b/cop.h
index 88749fbf98..457aeb4fab 100644
--- a/cop.h
+++ b/cop.h
@@ -62,7 +62,8 @@ struct block_sub {
} STMT_END
#endif /* USE_THREADS */
-#define POPSUB(cx) \
+#define POPSUB(cx,sv) \
+ STMT_START { \
if (cx->blk_sub.hasargs) { \
POPSAVEARRAY(); \
/* abandon @_ if it got reified */ \
@@ -75,10 +76,16 @@ struct block_sub {
PL_curpad[0] = (SV*)cx->blk_sub.argarray; \
} \
} \
- if (cx->blk_sub.cv) { \
- if (!(CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth)) \
- SvREFCNT_dec(cx->blk_sub.cv); \
- }
+ sv = (SV*)cx->blk_sub.cv; \
+ if (sv && (CvDEPTH((CV*)sv) = cx->blk_sub.olddepth)) \
+ sv = Nullsv; \
+ } STMT_END
+
+#define LEAVESUB(sv) \
+ STMT_START { \
+ if (sv) \
+ SvREFCNT_dec(sv); \
+ } STMT_END
#define POPFORMAT(cx) \
setdefout(cx->blk_sub.dfoutgv); \