diff options
author | Nicholas Clark <nick@ccl4.org> | 2004-07-14 20:55:30 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2004-07-14 20:55:30 +0000 |
commit | ef3e5ea91ec4f974a02ae36f5bcc9e91bcab852f (patch) | |
tree | 5afdbe2673bff0daa51e96345a9c7c541aaaff79 /pp_hot.c | |
parent | ab7ee80f77caf2fe052e7d3d8de31097ada2baae (diff) | |
download | perl-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.c | 38 |
1 files changed, 29 insertions, 9 deletions
@@ -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"); |