This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_iter: move RETPUSHYES outside switch
[perl5.git] / pp_hot.c
index 0cf1b7d..0645524 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1695,7 +1695,7 @@ Perl_do_readline(pTHX)
        }
        SvUPGRADE(sv, SVt_PV);
        tmplen = SvLEN(sv);     /* remember if already alloced */
-       if (!tmplen && !SvREADONLY(sv)) {
+       if (!tmplen && !SvREADONLY(sv) && !SvIsCOW(sv)) {
             /* try short-buffering it. Please update t/op/readline.t
             * if you change the growth length.
             */
@@ -1904,11 +1904,11 @@ PP(pp_iter)
 
     EXTEND(SP, 1);
     cx = &cxstack[cxstack_ix];
-    if (!CxTYPE_is_LOOP(cx))
-       DIE(aTHX_ "panic: pp_iter, type=%u", CxTYPE(cx));
-
     itersvp = CxITERVAR(cx);
-    if (CxTYPE(cx) == CXt_LOOP_LAZYSV) {
+
+    switch (CxTYPE(cx)) {
+    case CXt_LOOP_LAZYSV:
+        {
            /* string increment */
            SV* cur = cx->blk_loop.state_u.lazysv.cur;
            SV *end = cx->blk_loop.state_u.lazysv.end;
@@ -1916,7 +1916,9 @@ PP(pp_iter)
               It has SvPVX of "" and SvCUR of 0, which is what we want.  */
            STRLEN maxlen = 0;
            const char *max = SvPV_const(end, maxlen);
-           if (!SvNIOK(cur) && SvCUR(cur) <= maxlen) {
+           if (SvNIOK(cur) || SvCUR(cur) > maxlen)
+                RETPUSHNO;
+
                if (SvREFCNT(*itersvp) == 1 && !SvMAGICAL(*itersvp)) {
                    /* safe to reuse old SV */
                    sv_setsv(*itersvp, cur);
@@ -1934,11 +1936,10 @@ PP(pp_iter)
                    sv_setiv(cur, 0); /* terminate next time */
                else
                    sv_inc(cur);
-               RETPUSHYES;
-           }
-           RETPUSHNO;
-    }
-    else if (CxTYPE(cx) == CXt_LOOP_LAZYIV) {
+            break;
+        }
+
+    case CXt_LOOP_LAZYIV:
        /* integer increment */
        if (cx->blk_loop.state_u.lazyiv.cur > cx->blk_loop.state_u.lazyiv.end)
            RETPUSHNO;
@@ -1963,70 +1964,73 @@ PP(pp_iter)
            cx->blk_loop.state_u.lazyiv.end = IV_MIN;
        } else
            ++cx->blk_loop.state_u.lazyiv.cur;
+        break;
 
-       RETPUSHYES;
-    }
+    case CXt_LOOP_FOR:
 
-    /* iterate array */
-    assert(CxTYPE(cx) == CXt_LOOP_FOR);
-    av = cx->blk_loop.state_u.ary.ary;
-    if (!av) {
-       av_is_stack = TRUE;
-       av = PL_curstack;
-    }
-    if (PL_op->op_private & OPpITER_REVERSED) {
-       if (cx->blk_loop.state_u.ary.ix <= (av_is_stack
-                                   ? cx->blk_loop.resetsp + 1 : 0))
-           RETPUSHNO;
+        /* iterate array */
+        av = cx->blk_loop.state_u.ary.ary;
+        if (!av) {
+            av_is_stack = TRUE;
+            av = PL_curstack;
+        }
+        if (PL_op->op_private & OPpITER_REVERSED) {
+            if (cx->blk_loop.state_u.ary.ix <= (av_is_stack
+                                        ? cx->blk_loop.resetsp + 1 : 0))
+                RETPUSHNO;
+
+            if (SvMAGICAL(av) || AvREIFY(av)) {
+                SV * const * const svp = av_fetch(av, --cx->blk_loop.state_u.ary.ix, FALSE);
+                sv = svp ? *svp : NULL;
+            }
+            else {
+                sv = AvARRAY(av)[--cx->blk_loop.state_u.ary.ix];
+            }
+        }
+        else {
+            if (cx->blk_loop.state_u.ary.ix >= (av_is_stack ? cx->blk_oldsp :
+                                        AvFILL(av)))
+                RETPUSHNO;
+
+            if (SvMAGICAL(av) || AvREIFY(av)) {
+                SV * const * const svp = av_fetch(av, ++cx->blk_loop.state_u.ary.ix, FALSE);
+                sv = svp ? *svp : NULL;
+            }
+            else {
+                sv = AvARRAY(av)[++cx->blk_loop.state_u.ary.ix];
+            }
+        }
 
-       if (SvMAGICAL(av) || AvREIFY(av)) {
-           SV * const * const svp = av_fetch(av, --cx->blk_loop.state_u.ary.ix, FALSE);
-           sv = svp ? *svp : NULL;
-       }
-       else {
-           sv = AvARRAY(av)[--cx->blk_loop.state_u.ary.ix];
-       }
-    }
-    else {
-       if (cx->blk_loop.state_u.ary.ix >= (av_is_stack ? cx->blk_oldsp :
-                                   AvFILL(av)))
-           RETPUSHNO;
+        if (sv && SvIS_FREED(sv)) {
+            *itersvp = NULL;
+            Perl_croak(aTHX_ "Use of freed value in iteration");
+        }
 
-       if (SvMAGICAL(av) || AvREIFY(av)) {
-           SV * const * const svp = av_fetch(av, ++cx->blk_loop.state_u.ary.ix, FALSE);
-           sv = svp ? *svp : NULL;
-       }
-       else {
-           sv = AvARRAY(av)[++cx->blk_loop.state_u.ary.ix];
-       }
-    }
+        if (sv) {
+            SvTEMP_off(sv);
+            SvREFCNT_inc_simple_void_NN(sv);
+        }
+        else
+            sv = &PL_sv_undef;
+        if (!av_is_stack && sv == &PL_sv_undef) {
+            SV *lv = newSV_type(SVt_PVLV);
+            LvTYPE(lv) = 'y';
+            sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
+            LvTARG(lv) = SvREFCNT_inc_simple(av);
+            LvTARGOFF(lv) = cx->blk_loop.state_u.ary.ix;
+            LvTARGLEN(lv) = (STRLEN)UV_MAX;
+            sv = lv;
+        }
 
-    if (sv && SvIS_FREED(sv)) {
-       *itersvp = NULL;
-       Perl_croak(aTHX_ "Use of freed value in iteration");
-    }
+        oldsv = *itersvp;
+        *itersvp = sv;
+        SvREFCNT_dec(oldsv);
+        break;
 
-    if (sv) {
-       SvTEMP_off(sv);
-       SvREFCNT_inc_simple_void_NN(sv);
-    }
-    else
-       sv = &PL_sv_undef;
-    if (!av_is_stack && sv == &PL_sv_undef) {
-       SV *lv = newSV_type(SVt_PVLV);
-       LvTYPE(lv) = 'y';
-       sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
-       LvTARG(lv) = SvREFCNT_inc_simple(av);
-       LvTARGOFF(lv) = cx->blk_loop.state_u.ary.ix;
-       LvTARGLEN(lv) = (STRLEN)UV_MAX;
-       sv = lv;
+    default:
+       DIE(aTHX_ "panic: pp_iter, type=%u", CxTYPE(cx));
     }
-
-    oldsv = *itersvp;
-    *itersvp = sv;
-    SvREFCNT_dec(oldsv);
-
-    RETPUSHYES;
+        RETPUSHYES;
 }
 
 /*