summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-09-05 14:39:47 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-09-06 06:18:08 -0700
commit31c61addb4e0d00f3deb63c5f58bff0ecb6b6969 (patch)
tree0768d8905f1985a22229c676643d1bbe4e557d20 /pp.c
parent9bc7f50b6c983278ffa7b722240000d38037e149 (diff)
downloadperl-31c61addb4e0d00f3deb63c5f58bff0ecb6b6969.tar.gz
Make pp_splice handle nonexistent array elements
Commit ce0d59f changed AVs to use NULLs for nonexistent elements. pp_splice needs to take that into account and avoid pushing NULLs on to the stack.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/pp.c b/pp.c
index a913ec0c6f..6fc6c9fa42 100644
--- a/pp.c
+++ b/pp.c
@@ -4975,14 +4975,18 @@ PP(pp_splice)
MARK = ORIGMARK + 1;
if (GIMME == G_ARRAY) { /* copy return vals to stack */
+ const bool real = cBOOL(AvREAL(ary));
MEXTEND(MARK, length);
- Copy(AvARRAY(ary)+offset, MARK, length, SV*);
- if (AvREAL(ary)) {
+ if (real)
EXTEND_MORTAL(length);
- for (i = length, dst = MARK; i; i--) {
+ for (i = 0, dst = MARK; i < length; i++) {
+ if ((*dst = AvARRAY(ary)[i+offset])) {
+ if (real)
sv_2mortal(*dst); /* free them eventually */
- dst++;
}
+ else
+ *dst = &PL_sv_undef;
+ dst++;
}
MARK += length - 1;
}
@@ -5068,13 +5072,16 @@ PP(pp_splice)
MARK = ORIGMARK + 1;
if (GIMME == G_ARRAY) { /* copy return vals to stack */
if (length) {
- Copy(tmparyval, MARK, length, SV*);
- if (AvREAL(ary)) {
+ const bool real = cBOOL(AvREAL(ary));
+ if (real)
EXTEND_MORTAL(length);
- for (i = length, dst = MARK; i; i--) {
+ for (i = 0, dst = MARK; i < length; i++) {
+ if ((*dst = tmparyval[i])) {
+ if (real)
sv_2mortal(*dst); /* free them eventually */
- dst++;
}
+ else *dst = &PL_sv_undef;
+ dst++;
}
}
MARK += length - 1;