summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2020-10-19 16:01:49 +0100
committerDavid Mitchell <davem@iabyn.com>2020-10-23 14:25:52 +0100
commit02a48966c3f10e905b24f9bd307fa31c05060908 (patch)
tree5e53a6e6b781f76381e6e386114fc9ea60dac581 /mg.c
parent032a49194dbdca7f62038e1b4af134d72972ecd8 (diff)
downloadperl-02a48966c3f10e905b24f9bd307fa31c05060908.tar.gz
add Perl_magic_freemglob() magic vtable method
S_mg_free_struct() has a workaround to never free mg->mg_ptr for PERL_MAGIC_regex_global. Move this logic into a new magic vtable free method instead, so that S_mg_free_struct() (which gets called for every type of magic) doesn't have the overhead of checking every time for mg->mg_type == PERL_MAGIC_regex_global. [ No, I don't know why PERL_MAGIC_regex_global's vtable and methods are suffixed mglob rather than regex_global or vice versa ]
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/mg.c b/mg.c
index 4f199af423..d14b2eb88c 100644
--- a/mg.c
+++ b/mg.c
@@ -554,12 +554,10 @@ S_mg_free_struct(pTHX_ SV *sv, MAGIC *mg)
if (vtbl && vtbl->svt_free)
vtbl->svt_free(aTHX_ sv, mg);
- if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) {
- if (mg->mg_len > 0)
- Safefree(mg->mg_ptr);
- else if (mg->mg_len == HEf_SVKEY)
- SvREFCNT_dec(MUTABLE_SV(mg->mg_ptr));
- }
+ if (mg->mg_len > 0)
+ Safefree(mg->mg_ptr);
+ else if (mg->mg_len == HEf_SVKEY)
+ SvREFCNT_dec(MUTABLE_SV(mg->mg_ptr));
if (mg->mg_flags & MGf_REFCOUNTED)
SvREFCNT_dec(mg->mg_obj);
@@ -2600,6 +2598,23 @@ Perl_magic_setmglob(pTHX_ SV *sv, MAGIC *mg)
return 0;
}
+
+int
+Perl_magic_freemglob(pTHX_ SV *sv, MAGIC *mg)
+{
+ PERL_ARGS_ASSERT_MAGIC_FREEMGLOB;
+ PERL_UNUSED_ARG(sv);
+
+ /* glob magic uses mg_len as a string length rather than a buffer
+ * length, so we need to free even with mg_len == 0: hence we can't
+ * rely on standard magic free handling */
+ assert(mg->mg_type == PERL_MAGIC_regex_global && mg->mg_len >= -1);
+ Safefree(mg->mg_ptr);
+ mg->mg_ptr = NULL;
+ return 0;
+}
+
+
int
Perl_magic_setuvar(pTHX_ SV *sv, MAGIC *mg)
{