diff options
author | Dave Mitchell <davem@fdisolutions.com> | 2005-06-22 21:42:54 +0000 |
---|---|---|
committer | Dave Mitchell <davem@fdisolutions.com> | 2005-06-22 21:42:54 +0000 |
commit | 0cbee0a449cc4e11ef8db851c20b026c8f9ff45e (patch) | |
tree | b8f64d28537d653564df5df9d38f0c44680e8a51 /mg.c | |
parent | 666e7e7967a0bc59b1f44ec2961661c439aad50c (diff) | |
download | perl-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.c | 62 |
1 files changed, 62 insertions, 0 deletions
@@ -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>. |