summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2004-07-15 12:47:50 +0000
committerNicholas Clark <nick@ccl4.org>2004-07-15 12:47:50 +0000
commite682d7b7fae5a50c5afb147f913a4e88d7261606 (patch)
tree644c399b397737feec6637e4339926ef7c874e65 /op.c
parentd46f46af75970be4ecf8811cc8d1ad9bcd7df36c (diff)
downloadperl-e682d7b7fae5a50c5afb147f913a4e88d7261606.tar.gz
for (reverse @foo) now iterates in reverse in place.
p4raw-id: //depot/perl@23115
Diffstat (limited to 'op.c')
-rw-r--r--op.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/op.c b/op.c
index e9ea2e5254..ea714ebee9 100644
--- a/op.c
+++ b/op.c
@@ -6719,7 +6719,7 @@ Perl_peep(pTHX_ register OP *o)
}
case OP_REVERSE: {
- OP *ourmark, *theirmark, *ourlast, *iter, *expushmark;
+ OP *ourmark, *theirmark, *ourlast, *iter, *expushmark, *rv2av;
OP *gvop = NULL;
LISTOP *enter, *exlist;
o->op_opt = 1;
@@ -6786,6 +6786,15 @@ Perl_peep(pTHX_ register OP *o)
if (!ourlast || ourlast->op_next != o)
break;
+ rv2av = ourmark->op_sibling;
+ if (rv2av && rv2av->op_type == OP_RV2AV && rv2av->op_sibling == 0
+ && rv2av->op_flags == (OPf_WANT_LIST | OPf_KIDS)
+ && enter->op_flags == (OPf_WANT_LIST | OPf_KIDS)) {
+ /* We're just reversing a single array. */
+ rv2av->op_flags = OPf_WANT_SCALAR | OPf_KIDS | OPf_REF;
+ enter->op_flags |= OPf_STACKED;
+ }
+
/* We don't have control over who points to theirmark, so sacrifice
ours. */
theirmark->op_next = ourmark->op_next;