summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Pit <perl@profvince.com>2009-07-25 00:43:56 +0200
committerVincent Pit <perl@profvince.com>2009-07-25 23:26:06 +0200
commit75d34a09f38381e487470136b539a7fba0f02b44 (patch)
treee95f445ae544e45ed74cdaace574f50591d435d5
parent91d1c79f6c648258e3465cf0cdbe8df3ab262de1 (diff)
downloadperl-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.c15
-rw-r--r--scope.h1
2 files changed, 13 insertions, 3 deletions
diff --git a/scope.c b/scope.c
index 85f1c48f8b..5aaf5def01 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 7bda4c8b5b..77a389de02 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)