for (reverse @foo) now iterates in reverse in place.
Nicholas Clark [Thu, 15 Jul 2004 12:47:50 +0000 (12:47 +0000)]
p4raw-id: //depot/perl@23115

op.c
pod/perltodo.pod
pp_ctl.c

diff --git a/op.c b/op.c
index e9ea2e5..ea714eb 100644 (file)
--- 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;
index 1560956..0c3e8d6 100644 (file)
@@ -179,15 +179,6 @@ Clean these up. Move them to mathom.c, and don't compile for blead?
 The old perltodo notes "This has been done in places, but needs a thorough
 code review. Also fchdir is available in some platforms."
 
-=head2 foreach reverse
-
-The old perltodo notes that we could optimise foreach to iterate in reverse.
-(instead of making a reversed copy on the stack)
-It seems that cx->blk_loop.itermax could be hijacked to act as a go up/go
-down flag, with cx->blk_loop.iterix primed in pp_enteriter for the go down
-case (ie reverse). However, it looks slightly tricky identifying the shape of
-foreach reverse in the optree in Perl_peep.
-
 =head1 Tests
 
 =head2 Make Schwern poorer
index 1107ad9..0c1067a 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1811,7 +1811,7 @@ PP(pp_enteriter)
            }
        }
        else if (PL_op->op_private & OPpITER_REVERSED) {
-           cx->blk_loop.itermax = 0;
+           cx->blk_loop.itermax = -1;
            cx->blk_loop.iterix = AvFILL(cx->blk_loop.iterary);
 
        }