summaryrefslogtreecommitdiff
path: root/dist
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2011-04-24 16:37:17 +0100
committerNicholas Clark <nick@ccl4.org>2011-06-12 11:25:48 +0200
commit93bad3fd55489cbd2d3157da1fcb3b524e960dd2 (patch)
tree295d059c38869a4b8ca10c2b9b6a8479748e1ffd /dist
parent464a08e7ffded0873dfb1539fceae173c22a1090 (diff)
downloadperl-93bad3fd55489cbd2d3157da1fcb3b524e960dd2.tar.gz
Split OP_AELEMFAST_LEX out from OP_AELEMFAST.
6a077020aea1c5f0 extended the OP_AELEMFAST optimisation to lexical arrays. Previously OP_AELEMFAST was only used as an optimisation for OP_GV, which is a PADOP/SVOP. However, by reusing the same opcode, and signalling (pad) lexical vs package, it introduced a myriad of special cases, because OP_PADAV is a BASEOP (not a PADOP), whilst OP_AELEMFAST is a PADOP/SVOP (which is larger). Using two OP numbers allows each variant to have the correct OP flags in PL_opargs. Both can continue to share the same C code.
Diffstat (limited to 'dist')
-rw-r--r--dist/B-Deparse/Deparse.pm27
-rw-r--r--dist/B-Deparse/t/deparse.t7
2 files changed, 22 insertions, 12 deletions
diff --git a/dist/B-Deparse/Deparse.pm b/dist/B-Deparse/Deparse.pm
index e3079ad20b..7496525a78 100644
--- a/dist/B-Deparse/Deparse.pm
+++ b/dist/B-Deparse/Deparse.pm
@@ -2917,22 +2917,25 @@ sub pp_gv {
return $self->gv_name($gv);
}
+sub pp_aelemfast_lex {
+ my $self = shift;
+ my($op, $cx) = @_;
+ my $name = $self->padname($op->targ);
+ $name =~ s/^@/\$/;
+ return $name . "[" . ($op->private + $self->{'arybase'}) . "]";
+}
+
sub pp_aelemfast {
my $self = shift;
my($op, $cx) = @_;
- my $name;
- if ($op->flags & OPf_SPECIAL) { # optimised PADAV
- $name = $self->padname($op->targ);
- $name =~ s/^@/\$/;
- }
- else {
- my $gv = $self->gv_or_padgv($op);
- $name = $self->gv_name($gv);
- $name = $self->{'curstash'}."::$name"
- if $name !~ /::/ && $self->lex_in_scope('@'.$name);
- $name = '$' . $name;
- }
+ # optimised PADAV, pre 5.15
+ return $self->pp_aelemfast_lex(@_) if ($op->flags & OPf_SPECIAL);
+ my $gv = $self->gv_or_padgv($op);
+ my $name = $self->gv_name($gv);
+ $name = $self->{'curstash'}."::$name"
+ if $name !~ /::/ && $self->lex_in_scope('@'.$name);
+ $name = '$' . $name;
return $name . "[" . ($op->private + $self->{'arybase'}) . "]";
}
diff --git a/dist/B-Deparse/t/deparse.t b/dist/B-Deparse/t/deparse.t
index cb0faadd28..72498465a2 100644
--- a/dist/B-Deparse/t/deparse.t
+++ b/dist/B-Deparse/t/deparse.t
@@ -731,3 +731,10 @@ values $!;
####
# readpipe with complex expression
readpipe $a + $b;
+####
+# aelemfast
+$b::a[0] = 1;
+####
+# aelemfast for a lexical
+my @a;
+$a[0] = 1;