Commit 9f2e27e801 for perl

commit 9f2e27e801d2895e24ceb8dda686d58e8628b736
Author: Paul Evans <leonerd@leonerd.org.uk>
Date:   Wed Oct 7 17:22:31 2026 +0100

    Add sv_magicv2_remove_by_shape()

diff --git a/embed.fnc b/embed.fnc
index 5c2bc6cc67..2058bb2433 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -4549,6 +4549,9 @@ p	|void	|parser_free_nexttoke_ops				\
 RTi	|bool	|should_warn_nl |NN const char *pv
 Mp	|bool	|sv_has_valuemagic					\
 				|NN const SV *sv
+Adpx	|void	|sv_magicv2_remove_by_shape				\
+				|NN SV *sv				\
+				|enum MagicShape shape
 # if defined(PERL_DEBUG_READONLY_OPS)
 ep	|void	|Slab_to_ro	|NN OPSLAB *slab
 ep	|void	|Slab_to_rw	|NN OPSLAB * const slab
diff --git a/embed.h b/embed.h
index adce942b91..9dec7aa656 100644
--- a/embed.h
+++ b/embed.h
@@ -979,6 +979,7 @@
 #   define sv_setsv_cow(a,b)                    Perl_sv_setsv_cow(aTHX_ a,b)
 # endif
 # if defined(PERL_CORE)
+#   define sv_magicv2_remove_by_shape(a,b)      Perl_sv_magicv2_remove_by_shape(aTHX_ a,b)
 #   define PerlLIO_dup2_cloexec(a,b)            Perl_PerlLIO_dup2_cloexec(aTHX_ a,b)
 #   define PerlLIO_dup_cloexec(a)               Perl_PerlLIO_dup_cloexec(aTHX_ a)
 #   define PerlLIO_open3_cloexec(a,b,c)         Perl_PerlLIO_open3_cloexec(aTHX_ a,b,c)
diff --git a/proto.h b/proto.h
index b6ee43aecb..7ad89638c6 100644
--- a/proto.h
+++ b/proto.h
@@ -11234,6 +11234,15 @@ Perl_sv_has_valuemagic(pTHX_ const SV *sv)
                   PERL_UNUSED_CONTEXT_FOR_ARGS_ASSERT;  \
     } STMT_END

+PERL_CALLCONV void
+Perl_sv_magicv2_remove_by_shape(pTHX_ SV *sv, enum MagicShape shape)
+        Perl_attribute_nonnull_aTHX
+        Perl_attribute_nonnull(pTHX_1);
+# define PERL_ARGS_ASSERT_SV_MAGICV2_REMOVE_BY_SHAPE \
+     STMT_START { Perl_assert_aTHX; assert(sv);         \
+                  PERL_UNUSED_CONTEXT_FOR_ARGS_ASSERT;  \
+    } STMT_END
+
 # if defined(PERL_DEBUG_READONLY_OPS)
 PERL_CALLCONV void
 Perl_Slab_to_ro(pTHX_ OPSLAB *slab)
diff --git a/sv.c b/sv.c
index 5fc3cc13eb..556b4636f3 100644
--- a/sv.c
+++ b/sv.c
@@ -7043,6 +7043,30 @@ Perl_sv_magicv2_remove_by_funcs(pTHX_ SV *sv, const struct MagicFunctions *funcs
     S_sv_magicv2_remove(aTHX_ sv, &S_filter_mgv2_by_funcs, funcs);
 }

+static bool
+S_filter_mgv2_by_shape(pTHX_ MAGIC *mg, const void *key)
+{
+    return MgFUNCS(mg)->shape == PTR2IV(key);
+}
+
+/*
+=for apidoc sv_magicv2_remove_by_shape
+
+Removes every magic attachment on the SV whose functions structure has the
+given shape. This is equivalent to calling C<sv_magicv2_remove> on each of
+them in turn, invoking any C<free> trigger functions and decrementing any
+associated SV refcounts.
+
+=cut
+*/
+
+void
+Perl_sv_magicv2_remove_by_shape(pTHX_ SV *sv, enum MagicShape shape)
+{
+    PERL_ARGS_ASSERT_SV_MAGICV2_REMOVE_BY_SHAPE;
+    S_sv_magicv2_remove(aTHX_ sv, &S_filter_mgv2_by_shape, INT2PTR(void *,shape));
+}
+
 #if defined(PERL_USE_VALUEMAGIC)

 static bool