diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-09-21 14:03:38 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-09-21 16:20:35 -0700 |
commit | aa033da5beef46547ce2956efe7bb08631416a08 (patch) | |
tree | 1736720517e609f6e90636187ae7cf7bb03764d8 /op.c | |
parent | c1ea5c9a3b172026c5c9a42377fea67a4e1aaeb7 (diff) | |
download | perl-aa033da5beef46547ce2956efe7bb08631416a08.tar.gz |
Another faulty padrange assumption
Commit 7601007 was not sufficient. There are two places where the
padrange optimisation tries to combine multiple padranges.
When a padrange op is created in rpeep, the code first checks whether
the previous op is already a padrange, so the two can be combined, as
in this case:
my ($a,$b,$c);
my ($d,$e,$f);
Then the code checks whether it can swallow up any singletons follow-
ing it, optimising cases like this:
my ($v,$w,$x);
my $y;
Commit 7601007 fixed the latter, which was assuming that $x and $y
would have contiguous pad offsets.
This commit fixes the former code, which assumed $c and $d would have
contiguous offsets.
This was causing assertion failures or crashes for Devel::CallParser
0.001 (0.002 works around it), because Devel::CallParser creates new
pad entries when the second ‘my’ keyword is encountered, causing the
pad offsets not to be contiguous.
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 9 |
1 files changed, 7 insertions, 2 deletions
@@ -11265,9 +11265,14 @@ Perl_rpeep(pTHX_ OP *o) old_count = (oldoldop->op_private & OPpPADRANGE_COUNTMASK); - assert(oldoldop->op_targ + old_count == base); - if (old_count < OPpPADRANGE_COUNTMASK - count) { + /* Do not assume pad offsets for $c and $d are con- + tiguous in + my ($a,$b,$c); + my ($d,$e,$f); + */ + if ( oldoldop->op_targ + old_count == base + && old_count < OPpPADRANGE_COUNTMASK - count) { base = oldoldop->op_targ; count += old_count; reuse = 1; |