summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-07-15 00:05:57 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-07-15 19:14:22 -0700
commitff44333e5a9d9dca5272bb166df463607ebd3020 (patch)
treec8cf9c78f0393387b4a19478209e1a074cbb9314 /mg.c
parentf4245ada08d64d9ac0a9bc6c6c17e4d10ddcffc2 (diff)
downloadperl-ff44333e5a9d9dca5272bb166df463607ebd3020.tar.gz
Make set-magic handle vstrings properly
Assigning a vstring to a tied variable would result in a plain string in $_[1] in STORE. Assigning a vstring to a magic deferred element would result in a plain string in the aggregate’s actual element. When magic is invoked, the magic flags are temporarily turned off on the sv so that recursive calls to magic don’t happen. This makes it easier to implement functions like Perl_magic_set to read the value of the sv without triggering get-magic. Since vstrings are only considered vstrings when they are SvRMAGICAL, this meant that set-magic would turn vstrings temporarily into plain strings. Subsequent copying (e.g., in STORE) would then fail to copy the vstring magic. This commit changes mg_set to leave the rmagical flag on, since it does not affect the functionaiity of set-magic.
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/mg.c b/mg.c
index 518d1085b4..e56f53db2d 100644
--- a/mg.c
+++ b/mg.c
@@ -90,13 +90,13 @@ struct magic_state {
/* MGS is typedef'ed to struct magic_state in perl.h */
STATIC void
-S_save_magic(pTHX_ I32 mgs_ix, SV *sv)
+S_save_magic_flags(pTHX_ I32 mgs_ix, SV *sv, U32 flags)
{
dVAR;
MGS* mgs;
bool bumped = FALSE;
- PERL_ARGS_ASSERT_SAVE_MAGIC;
+ PERL_ARGS_ASSERT_SAVE_MAGIC_FLAGS;
assert(SvMAGICAL(sv));
@@ -120,12 +120,14 @@ S_save_magic(pTHX_ I32 mgs_ix, SV *sv)
mgs->mgs_ss_ix = PL_savestack_ix; /* points after the saved destructor */
mgs->mgs_bumped = bumped;
- SvMAGICAL_off(sv);
+ SvFLAGS(sv) &= ~flags;
/* Turning READONLY off for a copy-on-write scalar (including shared
hash keys) is a bad idea. */
if (!SvIsCOW(sv)) SvREADONLY_off(sv);
}
+#define save_magic(a,b) save_magic_flags(a,b,SVs_GMG|SVs_SMG|SVs_RMG)
+
/*
=for apidoc mg_magical
@@ -263,7 +265,7 @@ Perl_mg_set(pTHX_ SV *sv)
if (PL_localizing == 2 && sv == DEFSV) return 0;
- save_magic(mgs_ix, sv);
+ save_magic_flags(mgs_ix, sv, SVs_GMG|SVs_SMG); /* leave SVs_RMG on */
for (mg = SvMAGIC(sv); mg; mg = nextmg) {
const MGVTBL* vtbl = mg->mg_virtual;