From: Vincent Pit Date: Fri, 24 Jul 2009 22:43:56 +0000 (+0200) Subject: Add a new SAVEf_KEEPOLDELEM flag to save_scalar_at() and save_{a,h}elem_flags() X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=75d34a09f38381e487470136b539a7fba0f02b44;p=p5sagit%2Fp5-mst-13.2.git 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. --- diff --git a/scope.c b/scope.c index 85f1c48..5aaf5de 100644 --- a/scope.c +++ b/scope.c @@ -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 diff --git a/scope.h b/scope.h index 7bda4c8..77a389d 100644 --- a/scope.h +++ b/scope.h @@ -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)