summaryrefslogtreecommitdiff
path: root/regcomp.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2021-09-23 12:32:33 +0000
committerNicholas Clark <nick@ccl4.org>2021-09-26 07:25:58 +0000
commit9d0d3060891a4223d5d68d86737f0e4f6c4f1c70 (patch)
treeb5db9dd338ba4963d88cbf94dee093c49ce702b4 /regcomp.c
parentd978f0698f3cdb11f60c849e5ec37c62f82c731a (diff)
downloadperl-9d0d3060891a4223d5d68d86737f0e4f6c4f1c70.tar.gz
Add comments describing how PVLVs store REGEXPs by reference
Diffstat (limited to 'regcomp.c')
-rw-r--r--regcomp.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/regcomp.c b/regcomp.c
index 6c3f0c9767..a713406101 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -21924,6 +21924,16 @@ Perl_reg_temp_copy(pTHX_ REGEXP *dsv, REGEXP *ssv)
* we allocate here */
REGEXP *temp = (REGEXP *)newSV_type(SVt_REGEXP);
assert(!SvPVX(dsv));
+ /* We "steal" the body from the newly allocated SV temp, changing
+ * the pointer in its HEAD to NULL. We then change its type to
+ * SVt_NULL so that when we immediately release its only reference,
+ * no memory deallocation happens.
+ *
+ * The body will eventually be freed (from the PVLV) either in
+ * Perl_sv_force_normal_flags() (if the PVLV is "downgraded" and
+ * the regexp body needs to be removed)
+ * or in Perl_sv_clear() (if the PVLV still holds the pointer until
+ * the PVLV itself is deallocated). */
((XPV*)SvANY(dsv))->xpv_len_u.xpvlenu_rx = temp->sv_any;
temp->sv_any = NULL;
SvFLAGS(temp) = (SvFLAGS(temp) & ~SVTYPEMASK) | SVt_NULL;