summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2005-06-22 21:42:54 +0000
committerDave Mitchell <davem@fdisolutions.com>2005-06-22 21:42:54 +0000
commit0cbee0a449cc4e11ef8db851c20b026c8f9ff45e (patch)
treeb8f64d28537d653564df5df9d38f0c44680e8a51 /mg.c
parent666e7e7967a0bc59b1f44ec2961661c439aad50c (diff)
downloadperl-0cbee0a449cc4e11ef8db851c20b026c8f9ff45e.tar.gz
handle magic in local correctly
the local SV now gets a copy of any container magic, and no value magic; in the past the whole magic chain was either shared or moved p4raw-id: //depot/perl@24942
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/mg.c b/mg.c
index bd5acdfe57..366961984f 100644
--- a/mg.c
+++ b/mg.c
@@ -381,6 +381,68 @@ Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen)
}
/*
+=for apidoc mg_localize
+
+Copy some of the magic from an existing SV to new localized version of
+that SV. Container magic (eg %ENV, $1, tie) gets copied, value magic
+doesn't (eg taint, pos).
+
+=cut
+*/
+
+void
+Perl_mg_localize(pTHX_ SV *sv, SV *nsv)
+{
+ MAGIC *mg;
+ for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
+ const MGVTBL* const vtbl = mg->mg_virtual;
+ switch (mg->mg_type) {
+ /* value magic types: don't copy */
+ case PERL_MAGIC_bm:
+ case PERL_MAGIC_fm:
+ case PERL_MAGIC_regex_global:
+ case PERL_MAGIC_nkeys:
+#ifdef USE_LOCALE_COLLATE
+ case PERL_MAGIC_collxfrm:
+#endif
+ case PERL_MAGIC_qr:
+ case PERL_MAGIC_taint:
+ case PERL_MAGIC_vec:
+ case PERL_MAGIC_vstring:
+ case PERL_MAGIC_utf8:
+ case PERL_MAGIC_substr:
+ case PERL_MAGIC_defelem:
+ case PERL_MAGIC_arylen:
+ case PERL_MAGIC_pos:
+ case PERL_MAGIC_backref:
+ case PERL_MAGIC_arylen_p:
+ case PERL_MAGIC_rhash:
+ case PERL_MAGIC_symtab:
+ continue;
+ }
+
+ if ((mg->mg_flags & MGf_COPY) && vtbl->svt_copy) {
+ /* XXX calling the copy method is probably not correct. DAPM */
+ (void)CALL_FPTR(vtbl->svt_copy)(aTHX_ sv, mg, nsv,
+ mg->mg_ptr, mg->mg_len);
+ }
+ else {
+ sv_magicext(nsv, mg->mg_obj, mg->mg_type, vtbl,
+ mg->mg_ptr, mg->mg_len);
+ }
+ /* container types should remain read-only across localization */
+ SvFLAGS(nsv) |= SvREADONLY(sv);
+ }
+
+ if (SvTYPE(nsv) >= SVt_PVMG && SvMAGIC(nsv)) {
+ SvFLAGS(nsv) |= SvMAGICAL(sv);
+ PL_localizing = 1;
+ SvSETMAGIC(nsv);
+ PL_localizing = 0;
+ }
+}
+
+/*
=for apidoc mg_free
Free any magic storage used by the SV. See C<sv_magic>.