diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-09-05 14:39:47 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-09-06 06:18:08 -0700 |
commit | 31c61addb4e0d00f3deb63c5f58bff0ecb6b6969 (patch) | |
tree | 0768d8905f1985a22229c676643d1bbe4e557d20 /pp.c | |
parent | 9bc7f50b6c983278ffa7b722240000d38037e149 (diff) | |
download | perl-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.c | 23 |
1 files changed, 15 insertions, 8 deletions
@@ -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; |