Commit e7774f94ae for perl
commit e7774f94ae63ef642f57e0ff0872100a1809e096
Author: Paul Evans <leonerd@leonerd.org.uk>
Date: Fri Oct 9 14:06:33 2026 +0100
Rename magicv2_localize_copy to just magicv2_copy; add other variants
There's nothing specific about localizing in the behaviour of this
function, so by removing that part of its name it indicates it could be
useful in other situations (I intend to use it in the "clone_cv" trigger
of the upcoming CODE-shaped magic).
While we're here, it's also useful to add the other two variants of how
to handle the AUXSV pointer; one that always increments, and one that
always weakens.
diff --git a/embed.fnc b/embed.fnc
index 22990f7aa3..0fe795fe44 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -2273,7 +2273,14 @@ p |int |magic_setvec |NN SV *sv \
|NN MAGIC *mg
p |U32 |magic_sizepack |NN SV *sv \
|NN MAGIC *mg
-Adp |MAGIC *|magicv2_localize_copy \
+Adp |MAGIC *|magicv2_copy |NN SV *nsv \
+ |NN SV *osv \
+ |NN MAGIC *omg
+Adp |MAGIC *|magicv2_copy_inc_auxsv \
+ |NN SV *nsv \
+ |NN SV *osv \
+ |NN MAGIC *omg
+Adp |MAGIC *|magicv2_copy_weak_auxsv \
|NN SV *nsv \
|NN SV *osv \
|NN MAGIC *omg
diff --git a/embed.h b/embed.h
index 68aeb583db..b85a42b705 100644
--- a/embed.h
+++ b/embed.h
@@ -364,7 +364,9 @@
# define looks_like_number(a) Perl_looks_like_number(aTHX_ a)
# define lsbit_pos32 Perl_lsbit_pos32
# define magic_dump(a) Perl_magic_dump(aTHX_ a)
-# define magicv2_localize_copy(a,b,c) Perl_magicv2_localize_copy(aTHX_ a,b,c)
+# define magicv2_copy(a,b,c) Perl_magicv2_copy(aTHX_ a,b,c)
+# define magicv2_copy_inc_auxsv(a,b,c) Perl_magicv2_copy_inc_auxsv(aTHX_ a,b,c)
+# define magicv2_copy_weak_auxsv(a,b,c) Perl_magicv2_copy_weak_auxsv(aTHX_ a,b,c)
# define markstack_grow() Perl_markstack_grow(aTHX)
# define mess_sv(a,b) Perl_mess_sv(aTHX_ a,b)
# define mg_clear(a) Perl_mg_clear(aTHX_ a)
diff --git a/ext/XS-APItest/APItest_magicv2.inc b/ext/XS-APItest/APItest_magicv2.inc
index cfee08843e..6e5b904c15 100644
--- a/ext/XS-APItest/APItest_magicv2.inc
+++ b/ext/XS-APItest/APItest_magicv2.inc
@@ -67,7 +67,7 @@ static const struct ScalarVarMagicFunctions magicfuncs_container_empty = {
.shape = MGv2s_SCALARVAR,
.debug_name = "XS::APItest/container_empty",
- .localize_mg = &Perl_magicv2_localize_copy,
+ .localize_mg = &Perl_magicv2_copy,
};
static const struct ScalarVarMagicFunctions magicfuncs_with_keyiv = {
@@ -76,7 +76,7 @@ static const struct ScalarVarMagicFunctions magicfuncs_with_keyiv = {
.flags = MGv2f_WITH_KEYIV,
.debug_name = "XS::APItest/with_keyiv",
- .localize_mg = &Perl_magicv2_localize_copy,
+ .localize_mg = &Perl_magicv2_copy,
};
static const struct ScalarVarMagicFunctions magicfuncs_with_keysv = {
@@ -85,7 +85,7 @@ static const struct ScalarVarMagicFunctions magicfuncs_with_keysv = {
.flags = MGv2f_WITH_KEYSV,
.debug_name = "XS::APItest/with_keysv",
- .localize_mg = &Perl_magicv2_localize_copy,
+ .localize_mg = &Perl_magicv2_copy,
};
static const struct MagicFunctions magicfuncs_inc_on_free = {
@@ -111,7 +111,7 @@ static const struct ScalarVarMagicFunctions magicfuncs_userstruct = {
.debug_name = "XS::APItest/userstruct",
.user_size = sizeof(struct TwoIVs),
- .localize_mg = &Perl_magicv2_localize_copy,
+ .localize_mg = &Perl_magicv2_copy,
};
static const struct ScalarVarMagicFunctions magicfuncs_grab_before_get = {
@@ -127,7 +127,7 @@ static const struct ScalarVarMagicFunctions magicfuncs_inc_after_set = {
.shape = MGv2s_SCALARVAR,
.debug_name = "XS::APItest/inc_after_set",
- .localize_mg = &Perl_magicv2_localize_copy,
+ .localize_mg = &Perl_magicv2_copy,
.post_set = &magicfunc_inc_after_set,
};
diff --git a/mg.c b/mg.c
index 14a8c8e62b..6acc8c9526 100644
--- a/mg.c
+++ b/mg.c
@@ -237,11 +237,11 @@ operation on a variable with this magic attached. It is passed a pointer to
the new SV that was created as part of the localisation operation. If it
wishes the magic to also apply to the new SV it can copy itself there.
-A convenient API function, L</magicv2_localize_copy>, is provided to cover
-simple cases. It may be sufficient simply to use this function directly
-(remember to include the C<Perl_> prefix on its name):
+A convenient API function, L</magicv2_copy>, is provided to cover simple
+cases. It may be sufficient simply to use this function directly (remember to
+include the C<Perl_> prefix on its name):
- .localize_mg = &Perl_magicv2_localize_copy,
+ .localize_mg = &Perl_magicv2_copy,
If more complex behaviour is required, provide your own function here. You
may call the provided function to perform the basic copy operation first,
@@ -1004,7 +1004,7 @@ Perl_mg_localize(pTHX_ SV *sv, SV *nsv, bool setmagic)
}
/*
-=for apidoc magicv2_localize_copy
+=for apidoc magicv2_copy
Intended to be called as the C<localize_mg> trigger function of a
C<ScalarVarMagicFunctions>, C<ArrayVarMagicFunctions> or
@@ -1044,13 +1044,23 @@ area is bytewise copied.
=back
+=for apidoc magicv2_copy_inc_auxsv
+
+A variant of L</magicv2_copy> which always clears the C<MgWEAK_AUXSV> flag and
+increments the reference count on C<MgAUXSV>.
+
+=for apidoc magicv2_copy_weak_auxsv
+
+A variant of L</magicv2_copy> which always sets the C<MgWEAK_AUXSV> flag and
+does not increment the reference count on C<MgAUXSV>.
+
=cut
*/
MAGIC *
-Perl_magicv2_localize_copy(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
+Perl_magicv2_copy(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
{
- PERL_ARGS_ASSERT_MAGICV2_LOCALIZE_COPY;
+ PERL_ARGS_ASSERT_MAGICV2_COPY;
PERL_UNUSED_ARG(osv);
MAGIC *nmg = sv_magicv2_attach(nsv, MgFUNCS(omg), MgFLAGS(omg));
@@ -1059,6 +1069,30 @@ Perl_magicv2_localize_copy(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
return nmg;
}
+MAGIC *
+Perl_magicv2_copy_inc_auxsv(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
+{
+ PERL_ARGS_ASSERT_MAGICV2_COPY_INC_AUXSV;
+ PERL_UNUSED_ARG(osv);
+
+ MAGIC *nmg = sv_magicv2_attach(nsv, MgFUNCS(omg), MgFLAGS(omg));
+ mgv2_copy(omg, nmg, MGv2f_COPY_AUXSV_INC);
+
+ return nmg;
+}
+
+MAGIC *
+Perl_magicv2_copy_weak_auxsv(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
+{
+ PERL_ARGS_ASSERT_MAGICV2_COPY_WEAK_AUXSV;
+ PERL_UNUSED_ARG(osv);
+
+ MAGIC *nmg = sv_magicv2_attach(nsv, MgFUNCS(omg), MgFLAGS(omg));
+ mgv2_copy(omg, nmg, MGv2f_COPY_AUXSV_WEAKLY);
+
+ return nmg;
+}
+
void
Perl_mg_free_struct(pTHX_ SV *sv, MAGIC *mg)
{
diff --git a/pod/perlguts.pod b/pod/perlguts.pod
index 0bf94c183b..6962bf3d77 100644
--- a/pod/perlguts.pod
+++ b/pod/perlguts.pod
@@ -2158,15 +2158,16 @@ C<localize_mg> trigger function on the C<ScalarVarMagicFunctions>,
C<ArrayVarMagicFunctions> and C<HashVarMagicFunctions> structures.
In many cases, it is entirely sufficient for localisation purposes to call the
-the L<perlapi/magicv2_localize_copy> function. You can use this function
-directly in your magic functions structure by setting its address as that of
-the C<localize_mg> trigger. Remember that it needs to point to the actual
-function and not the API compatibility wrapper macro, so remember to include
-the leading C<Perl_...> prefix on its name:
+the L<perlapi/magicv2_copy> function, or its two variants
+L<perlapi/magicv2_copy_inc_auxsv> or L<perlapi/magicv2_copy_weak_auxsv>. You
+can use this function directly in your magic functions structure by setting
+its address as that of the C<localize_mg> trigger. Remember that it needs to
+point to the actual function and not the API compatibility wrapper macro, so
+remember to include the leading C<Perl_...> prefix on its name:
const struct ScalarVarMagicFunctions magic_funcs = {
...,
- .localize_mg = &Perl_magicv2_localize_copy,
+ .localize_mg = &Perl_magicv2_copy,
};
If your magic makes use of the pointer area or the C<MgUSERSTRUCT> area to
@@ -2179,7 +2180,7 @@ stored pointers.
static MAGIC *
S_magic_localize(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
{
- MAGIC *nmg = magicv2_localize_copy(nsv, osv, omg);
+ MAGIC *nmg = magicv2_copy(nsv, osv, omg);
SvREFCNT_inc(MgUSERSTRUCT(mg, struct MyExtraData)->othersv);
diff --git a/proto.h b/proto.h
index d2be87bfdf..8b0598b7b4 100644
--- a/proto.h
+++ b/proto.h
@@ -4430,12 +4430,34 @@ Perl_magic_wipepack(pTHX_ SV *sv, MAGIC *mg)
} STMT_END
PERL_CALLCONV MAGIC *
-Perl_magicv2_localize_copy(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
+Perl_magicv2_copy(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
Perl_attribute_nonnull_aTHX
Perl_attribute_nonnull(pTHX_1)
Perl_attribute_nonnull(pTHX_2)
Perl_attribute_nonnull(pTHX_3);
-#define PERL_ARGS_ASSERT_MAGICV2_LOCALIZE_COPY \
+#define PERL_ARGS_ASSERT_MAGICV2_COPY \
+ STMT_START { Perl_assert_aTHX; assert(nsv); assert(osv); assert(omg); \
+ PERL_UNUSED_CONTEXT_FOR_ARGS_ASSERT; \
+ } STMT_END
+
+PERL_CALLCONV MAGIC *
+Perl_magicv2_copy_inc_auxsv(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
+ Perl_attribute_nonnull_aTHX
+ Perl_attribute_nonnull(pTHX_1)
+ Perl_attribute_nonnull(pTHX_2)
+ Perl_attribute_nonnull(pTHX_3);
+#define PERL_ARGS_ASSERT_MAGICV2_COPY_INC_AUXSV \
+ STMT_START { Perl_assert_aTHX; assert(nsv); assert(osv); assert(omg); \
+ PERL_UNUSED_CONTEXT_FOR_ARGS_ASSERT; \
+ } STMT_END
+
+PERL_CALLCONV MAGIC *
+Perl_magicv2_copy_weak_auxsv(pTHX_ SV *nsv, SV *osv, MAGIC *omg)
+ Perl_attribute_nonnull_aTHX
+ Perl_attribute_nonnull(pTHX_1)
+ Perl_attribute_nonnull(pTHX_2)
+ Perl_attribute_nonnull(pTHX_3);
+#define PERL_ARGS_ASSERT_MAGICV2_COPY_WEAK_AUXSV \
STMT_START { Perl_assert_aTHX; assert(nsv); assert(osv); assert(omg); \
PERL_UNUSED_CONTEXT_FOR_ARGS_ASSERT; \
} STMT_END