diff options
author | Vincent Pit <perl@profvince.com> | 2009-07-25 00:43:56 +0200 |
---|---|---|
committer | Vincent Pit <perl@profvince.com> | 2009-07-25 23:26:06 +0200 |
commit | 75d34a09f38381e487470136b539a7fba0f02b44 (patch) | |
tree | e95f445ae544e45ed74cdaace574f50591d435d5 | |
parent | 91d1c79f6c648258e3465cf0cdbe8df3ab262de1 (diff) | |
download | perl-75d34a09f38381e487470136b539a7fba0f02b44.tar.gz |
Add a new SAVEf_KEEPOLDELEM flag to save_scalar_at() and save_{a,h}elem_flags()
When set, save_scalar_at() doesn't replace the given SV by a fresh new one. local magic is not called in this case.
-rw-r--r-- | scope.c | 15 | ||||
-rw-r--r-- | scope.h | 1 |
2 files changed, 13 insertions, 3 deletions
@@ -167,11 +167,14 @@ STATIC SV * S_save_scalar_at(pTHX_ SV **sptr, const U32 flags) { dVAR; - SV * const osv = *sptr; - register SV * const sv = *sptr = newSV(0); + SV * osv; + register SV *sv; PERL_ARGS_ASSERT_SAVE_SCALAR_AT; + osv = *sptr; + sv = (flags & SAVEf_KEEPOLDELEM) ? osv : (*sptr = newSV(0)); + if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) { if (SvGMAGICAL(osv)) { const bool oldtainted = PL_tainted; @@ -179,8 +182,10 @@ S_save_scalar_at(pTHX_ SV **sptr, const U32 flags) (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT; PL_tainted = oldtainted; } - mg_localize(osv, sv, (flags & SAVEf_SETMAGIC) != 0); + if (!(flags & SAVEf_KEEPOLDELEM)) + mg_localize(osv, sv, (flags & SAVEf_SETMAGIC) != 0); } + return sv; } @@ -586,6 +591,8 @@ Perl_save_aelem_flags(pTHX_ AV *av, I32 idx, SV **sptr, const U32 flags) if (!AvREAL(av) && AvREIFY(av)) SvREFCNT_inc_void(*sptr); save_scalar_at(sptr, flags); /* XXX - FIXME - see #60360 */ + if (flags & SAVEf_KEEPOLDELEM) + return; sv = *sptr; /* If we're localizing a tied array element, this new sv * won't actually be stored in the array - so it won't get @@ -610,6 +617,8 @@ Perl_save_helem_flags(pTHX_ HV *hv, SV *key, SV **sptr, const U32 flags) SSPUSHPTR(SvREFCNT_inc(*sptr)); SSPUSHINT(SAVEt_HELEM); save_scalar_at(sptr, flags); + if (flags & SAVEf_KEEPOLDELEM) + return; sv = *sptr; /* If we're localizing a tied hash element, this new sv * won't actually be stored in the hash - so it won't get @@ -57,6 +57,7 @@ #define SAVEt_ADELETE 46 #define SAVEf_SETMAGIC 1 +#define SAVEf_KEEPOLDELEM 2 #define save_aelem(av,idx,sptr) save_aelem_flags(av,idx,sptr,SAVEf_SETMAGIC) #define save_helem(hv,key,sptr) save_helem_flags(hv,key,sptr,SAVEf_SETMAGIC) |