summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2020-10-19 14:54:59 +0100
committerDavid Mitchell <davem@iabyn.com>2020-10-23 14:25:52 +0100
commit032a49194dbdca7f62038e1b4af134d72972ecd8 (patch)
tree162fac0720de09a915c6bfc0b30f8c1039129240 /mg.c
parenta457b73cb378d9c4e10ffbacfc9a472be9395057 (diff)
downloadperl-032a49194dbdca7f62038e1b4af134d72972ecd8.tar.gz
add Perl_magic_freeutf8() magic vtable method
S_mg_free_struct() has a workaround to free mg->mg_ptr in PERL_MAGIC_utf8 even if mg_len is zero. 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_utf8.
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/mg.c b/mg.c
index c7088f8446..4f199af423 100644
--- a/mg.c
+++ b/mg.c
@@ -555,7 +555,7 @@ S_mg_free_struct(pTHX_ SV *sv, MAGIC *mg)
vtbl->svt_free(aTHX_ sv, mg);
if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) {
- if (mg->mg_len > 0 || mg->mg_type == PERL_MAGIC_utf8)
+ if (mg->mg_len > 0)
Safefree(mg->mg_ptr);
else if (mg->mg_len == HEf_SVKEY)
SvREFCNT_dec(MUTABLE_SV(mg->mg_ptr));
@@ -2675,6 +2675,22 @@ Perl_magic_setutf8(pTHX_ SV *sv, MAGIC *mg)
}
int
+Perl_magic_freeutf8(pTHX_ SV *sv, MAGIC *mg)
+{
+ PERL_ARGS_ASSERT_MAGIC_FREEUTF8;
+ PERL_UNUSED_ARG(sv);
+
+ /* utf8 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_utf8 && mg->mg_len >= -1);
+ Safefree(mg->mg_ptr);
+ mg->mg_ptr = NULL;
+ return 0;
+}
+
+
+int
Perl_magic_setlvref(pTHX_ SV *sv, MAGIC *mg)
{
const char *bad = NULL;