summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2018-01-19 13:47:53 -0800
committerFather Chrysostomos <sprout@cpan.org>2018-01-19 14:09:44 -0800
commitfd77b29b3be4108adb4a74b9c274599eaf228cb3 (patch)
tree07866df2d141cfba4bd6238eca517391d2a0420e /pp_hot.c
parentbcfce88b64155612fcd6af40e88805fe32c25b7f (diff)
downloadperl-fd77b29b3be4108adb4a74b9c274599eaf228cb3.tar.gz
Don’t vivify elems when putting array on stack
6661956a2 was a little too powerful, and, in addition to fixing the bug that @_ did not properly alias nonexistent elements, also broke other uses of nonexistent array elements. (See the tests added.) This commit changes it so that putting @a on the stack does not vivify all ‘holes’ in @a, but creates defelem (deferred element) scalars, but only in lvalue context.
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/pp_hot.c b/pp_hot.c
index d479ecf218..1bc453a457 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1163,8 +1163,12 @@ S_pushav(pTHX_ AV* const av)
if (UNLIKELY(SvRMAGICAL(av))) {
PADOFFSET i;
for (i=0; i < (PADOFFSET)maxarg; i++) {
- SV ** const svp = av_fetch(av, i, TRUE);
- SP[i+1] = svp ? *svp : &PL_sv_undef;
+ SV ** const svp = av_fetch(av, i, FALSE);
+ SP[i+1] = LIKELY(svp)
+ ? *svp
+ : UNLIKELY(PL_op->op_flags & OPf_MOD)
+ ? newSVavdefelem(av,i,1)
+ : &PL_sv_undef;
}
}
else {
@@ -1173,7 +1177,11 @@ S_pushav(pTHX_ AV* const av)
SV *sv = AvARRAY(av)[i];
if (!LIKELY(sv))
AvARRAY(av)[i] = sv = newSV(0);
- SP[i+1] = sv;
+ SP[i+1] = LIKELY(sv)
+ ? sv
+ : UNLIKELY(PL_op->op_flags & OPf_MOD)
+ ? newSVavdefelem(av,i,1)
+ : &PL_sv_undef;
}
}
SP += maxarg;