summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2004-07-14 20:55:30 +0000
committerNicholas Clark <nick@ccl4.org>2004-07-14 20:55:30 +0000
commitef3e5ea91ec4f974a02ae36f5bcc9e91bcab852f (patch)
tree5afdbe2673bff0daa51e96345a9c7c541aaaff79 /pp_hot.c
parentab7ee80f77caf2fe052e7d3d8de31097ada2baae (diff)
downloadperl-ef3e5ea91ec4f974a02ae36f5bcc9e91bcab852f.tar.gz
Optimise foreach my $i (reverse ...)
foreach without a lexical iterator not yet optimised p4raw-id: //depot/perl@23108
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/pp_hot.c b/pp_hot.c
index 382030db0d..4157736753 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1886,19 +1886,39 @@ PP(pp_iter)
}
/* iterate array */
- if (cx->blk_loop.iterix >= (av == PL_curstack ? cx->blk_oldsp : AvFILL(av)))
- RETPUSHNO;
+ if (PL_op->op_private & OPpITER_REVERSED) {
+ /* In reverse, use itermax as the min :-) */
+ if (cx->blk_loop.iterix <= 0)
+ RETPUSHNO;
- if (SvMAGICAL(av) || AvREIFY(av)) {
- SV **svp = av_fetch(av, ++cx->blk_loop.iterix, FALSE);
- if (svp)
- sv = *svp;
- else
- sv = Nullsv;
+ if (SvMAGICAL(av) || AvREIFY(av)) {
+ SV **svp = av_fetch(av, cx->blk_loop.iterix--, FALSE);
+ if (svp)
+ sv = *svp;
+ else
+ sv = Nullsv;
+ }
+ else {
+ sv = AvARRAY(av)[cx->blk_loop.iterix--];
+ }
}
else {
- sv = AvARRAY(av)[++cx->blk_loop.iterix];
+ if (cx->blk_loop.iterix >= (av == PL_curstack ? cx->blk_oldsp :
+ AvFILL(av)))
+ RETPUSHNO;
+
+ if (SvMAGICAL(av) || AvREIFY(av)) {
+ SV **svp = av_fetch(av, ++cx->blk_loop.iterix, FALSE);
+ if (svp)
+ sv = *svp;
+ else
+ sv = Nullsv;
+ }
+ else {
+ sv = AvARRAY(av)[++cx->blk_loop.iterix];
+ }
}
+
if (sv && SvREFCNT(sv) == 0) {
*itersvp = Nullsv;
Perl_croak(aTHX_ "Use of freed value in iteration");