summaryrefslogtreecommitdiff
path: root/pad.c
diff options
context:
space:
mode:
authorPaul "LeoNerd" Evans <leonerd@leonerd.org.uk>2022-08-09 12:55:04 +0100
committerPaul Evans <leonerd@leonerd.org.uk>2022-08-16 17:28:08 +0100
commitb234f9dcb641654e4ddd801437d93f1ef78dd587 (patch)
treefe2f734574317464ec4f9fe542ac0cb4e3a39a87 /pad.c
parent938a8fef42c0cf461c486eba602142cd2626e2d4 (diff)
downloadperl-b234f9dcb641654e4ddd801437d93f1ef78dd587.tar.gz
Define a CvREFCOUNTED_ANYSV flag
If this flag is set, then the CvXSUBANY(cv).any_sv pointer will have its reference count decremented when the CV itself is freed. This is useful for XS extensions that wish to store extra data in here. Without this flag, such extensions have to resort to using magic with a 'free' function to perform this work.
Diffstat (limited to 'pad.c')
-rw-r--r--pad.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/pad.c b/pad.c
index f999cb324a..61bacc2376 100644
--- a/pad.c
+++ b/pad.c
@@ -457,8 +457,11 @@ Perl_cv_undef_flags(pTHX_ CV *cv, U32 flags)
Safefree(padlist);
CvPADLIST_set(&cvbody, NULL);
}
- else if (CvISXSUB(&cvbody))
+ else if (CvISXSUB(&cvbody)) {
+ if (CvREFCOUNTED_ANYSV(&cvbody))
+ SvREFCNT_dec(CvXSUBANY(&cvbody).any_sv);
CvHSCXT(&cvbody) = NULL;
+ }
/* else is (!CvISXSUB(&cvbody) && !CvPADLIST(&cvbody)) {do nothing;} */
@@ -2201,6 +2204,8 @@ S_cv_clone(pTHX_ CV *proto, CV *cv, CV *outside, HV *cloned)
if (UNLIKELY(CvISXSUB(proto))) {
CvXSUB(cv) = CvXSUB(proto);
CvXSUBANY(cv) = CvXSUBANY(proto);
+ if (CvREFCOUNTED_ANYSV(cv))
+ SvREFCNT_inc(CvXSUBANY(cv).any_sv);
}
else {
OP_REFCNT_LOCK;