The thread begun by
[p5sagit/p5-mst-13.2.git] / pp_hot.c
index d2eef9b..ede5342 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -107,7 +107,6 @@ PP(pp_and)
 PP(pp_sassign)
 {
     djSP; dPOPTOPssrl;
-    MAGIC *mg;
 
     if (PL_op->op_private & OPpASSIGN_BACKWARDS) {
        SV *temp;
@@ -147,22 +146,36 @@ PP(pp_concat)
     dPOPTOPssrl;
     STRLEN len;
     char *s;
+    bool left_utf = DO_UTF8(left);
+    bool right_utf = DO_UTF8(right);
 
     if (TARG != left) {
+       if (right_utf && !left_utf)
+           sv_utf8_upgrade(left);
        s = SvPV(left,len);
+       SvUTF8_off(TARG);
        if (TARG == right) {
+           if (left_utf && !right_utf)
+               sv_utf8_upgrade(right);
            sv_insert(TARG, 0, 0, s, len);
+           if (left_utf || right_utf)
+               SvUTF8_on(TARG);
            SETs(TARG);
            RETURN;
        }
        sv_setpvn(TARG,s,len);
     }
-    else if (SvGMAGICAL(TARG))
+    else if (SvGMAGICAL(TARG)) {
        mg_get(TARG);
+       if (right_utf && !left_utf)
+           sv_utf8_upgrade(left);
+    }
     else if (!SvOK(TARG) && SvTYPE(TARG) <= SVt_PVMG) {
        sv_setpv(TARG, "");     /* Suppress warning. */
        s = SvPV_force(TARG, len);
     }
+    if (left_utf && !right_utf)
+       sv_utf8_upgrade(right);
     s = SvPV(right,len);
     if (SvOK(TARG)) {
 #if defined(PERL_Y2KWARN)
@@ -177,19 +190,12 @@ PP(pp_concat)
            }
        }
 #endif
-       if (DO_UTF8(right))
-           sv_utf8_upgrade(TARG);
        sv_catpvn(TARG,s,len);
-       if (!IN_BYTE) {
-           if (SvUTF8(right))
-               SvUTF8_on(TARG);
-       }
-       else if (!SvUTF8(right)) {
-           SvUTF8_off(TARG);
-       }
     }
     else
        sv_setpvn(TARG,s,len);  /* suppress warning */
+    if (left_utf || right_utf)
+       SvUTF8_on(TARG);
     SETTARG;
     RETURN;
   }
@@ -335,7 +341,7 @@ PP(pp_print)
        gv = (GV*)*++MARK;
     else
        gv = PL_defoutgv;
-    if (mg = SvTIED_mg((SV*)gv, 'q')) {
+    if ((mg = SvTIED_mg((SV*)gv, 'q'))) {
        if (MARK == ORIGMARK) {
            /* If using default handle then we need to make space to 
             * pass object as 1st arg, so move other args up ...
@@ -456,7 +462,7 @@ PP(pp_rv2av)
            
            if (SvTYPE(sv) != SVt_PVGV) {
                char *sym;
-               STRLEN n_a;
+               STRLEN len;
 
                if (SvGMAGICAL(sv)) {
                    mg_get(sv);
@@ -475,13 +481,17 @@ PP(pp_rv2av)
                    }
                    RETSETUNDEF;
                }
-               sym = SvPV(sv,n_a);
+               sym = SvPV(sv,len);
                if ((PL_op->op_flags & OPf_SPECIAL) &&
                    !(PL_op->op_flags & OPf_MOD))
                {
                    gv = (GV*)gv_fetchpv(sym, FALSE, SVt_PVAV);
-                   if (!gv)
+                   if (!gv
+                       && (!is_gv_magical(sym,len,0)
+                           || !(gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVAV))))
+                   {
                        RETSETUNDEF;
+                   }
                }
                else {
                    if (PL_op->op_private & HINT_STRICT_REFS)
@@ -556,7 +566,7 @@ PP(pp_rv2hv)
            
            if (SvTYPE(sv) != SVt_PVGV) {
                char *sym;
-               STRLEN n_a;
+               STRLEN len;
 
                if (SvGMAGICAL(sv)) {
                    mg_get(sv);
@@ -575,13 +585,17 @@ PP(pp_rv2hv)
                    }
                    RETSETUNDEF;
                }
-               sym = SvPV(sv,n_a);
+               sym = SvPV(sv,len);
                if ((PL_op->op_flags & OPf_SPECIAL) &&
                    !(PL_op->op_flags & OPf_MOD))
                {
                    gv = (GV*)gv_fetchpv(sym, FALSE, SVt_PVHV);
-                   if (!gv)
+                   if (!gv
+                       && (!is_gv_magical(sym,len,0)
+                           || !(gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVHV))))
+                   {
                        RETSETUNDEF;
+                   }
                }
                else {
                    if (PL_op->op_private & HINT_STRICT_REFS)
@@ -626,7 +640,6 @@ S_do_maybe_phash(pTHX_ AV *ary, SV **lelem, SV **firstlelem, SV **relem,
                 SV **lastrelem)
 {
     OP *leftop;
-    SV *tmpstr;
     I32 i;
 
     leftop = ((BINOP*)PL_op)->op_last;
@@ -655,7 +668,7 @@ S_do_maybe_phash(pTHX_ AV *ary, SV **lelem, SV **firstlelem, SV **relem,
            sv_setsv(tmpstr,relem[1]);  /* value */
            relem[1] = tmpstr;
            if (avhv_store_ent(ary,relem[0],tmpstr,0))
-               SvREFCNT_inc(tmpstr);
+               (void)SvREFCNT_inc(tmpstr);
            if (SvMAGICAL(ary) != 0 && SvSMAGICAL(tmpstr))
                mg_set(tmpstr);
            relem += 2;
@@ -689,7 +702,7 @@ S_do_oddball(pTHX_ HV *hash, SV **relem, SV **firstrelem)
            /* pseudohash */
            tmpstr = sv_newmortal();
            if (avhv_store_ent((AV*)hash,*relem,tmpstr,0))
-               SvREFCNT_inc(tmpstr);
+               (void)SvREFCNT_inc(tmpstr);
            if (SvMAGICAL(hash) && SvSMAGICAL(tmpstr))
                mg_set(tmpstr);
        }
@@ -737,7 +750,7 @@ PP(pp_aassign)
        EXTEND_MORTAL(lastrelem - firstrelem + 1);
        for (relem = firstrelem; relem <= lastrelem; relem++) {
            /*SUPPRESS 560*/
-           if (sv = *relem) {
+           if ((sv = *relem)) {
                TAINT_NOT;      /* Each item is independent */
                *relem = sv_mortalcopy(sv);
            }
@@ -979,7 +992,7 @@ PP(pp_match)
     truebase = t = s;
 
     /* XXXX What part of this is needed with true \G-support? */
-    if (global = pm->op_pmflags & PMf_GLOBAL) {
+    if ((global = pm->op_pmflags & PMf_GLOBAL)) {
        rx->startp[0] = -1;
        if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
            MAGIC* mg = mg_find(TARG, 'g');
@@ -1023,7 +1036,8 @@ play_it_again:
             && !PL_sawampersand 
             && ((rx->reganch & ROPT_NOSCAN)
                 || !((rx->reganch & RE_INTUIT_TAIL)
-                     && (r_flags & REXEC_SCREAM))))
+                     && (r_flags & REXEC_SCREAM)))
+            && !SvROK(TARG))   /* Cannot trust since INTUIT cannot guess ^ */
            goto yup;
     }
     if (CALLREGEXEC(aTHX_ rx, s, strend, truebase, minmatch, TARG, NULL, r_flags))
@@ -1059,6 +1073,10 @@ play_it_again:
                len = rx->endp[i] - rx->startp[i];
                s = rx->startp[i] + truebase;
                sv_setpvn(*SP, s, len);
+               if ((pm->op_pmdynflags & PMdf_UTF8) && !IN_BYTE) {
+                   SvUTF8_on(*SP);
+                   sv_utf8_downgrade(*SP, TRUE);
+               }
            }
        }
        if (global) {
@@ -1157,7 +1175,7 @@ Perl_do_readline(pTHX)
     I32 gimme = GIMME_V;
     MAGIC *mg;
 
-    if (mg = SvTIED_mg((SV*)PL_last_in_gv, 'q')) {
+    if ((mg = SvTIED_mg((SV*)PL_last_in_gv, 'q'))) {
        PUSHMARK(SP);
        XPUSHs(SvTIED_obj((SV*)PL_last_in_gv, mg));
        PUTBACK;
@@ -1659,9 +1677,9 @@ PP(pp_iter)
 
     SvREFCNT_dec(*itersvp);
 
-    if (sv = (SvMAGICAL(av)) 
-           ? *av_fetch(av, ++cx->blk_loop.iterix, FALSE) 
-           : AvARRAY(av)[++cx->blk_loop.iterix])
+    if ((sv = SvMAGICAL(av)
+             ? *av_fetch(av, ++cx->blk_loop.iterix, FALSE) 
+             : AvARRAY(av)[++cx->blk_loop.iterix]))
        SvTEMP_off(sv);
     else
        sv = &PL_sv_undef;
@@ -1712,7 +1730,6 @@ PP(pp_subst)
     STRLEN len;
     int force_on_match = 0;
     I32 oldsave = PL_savestack_ix;
-    I32 update_minmatch = 1;
 
     /* known replacement string? */
     dstr = (pm->op_pmflags & PMf_CONST) ? POPs : Nullsv;
@@ -1818,7 +1835,7 @@ PP(pp_subst)
                SvCUR_set(TARG, m - s);
            }
            /*SUPPRESS 560*/
-           else if (i = m - s) {       /* faster from front */
+           else if ((i = m - s)) {     /* faster from front */
                d -= clen;
                m = d;
                sv_chop(TARG, d-i);
@@ -1847,7 +1864,7 @@ PP(pp_subst)
                rxtainted |= RX_MATCH_TAINTED(rx);
                m = rx->startp[0] + orig;
                /*SUPPRESS 560*/
-               if (i = m - s) {
+               if ((i = m - s)) {
                    if (s != d)
                        Move(s, d, i, char);
                    d += i;
@@ -1870,7 +1887,7 @@ PP(pp_subst)
            SPAGAIN;
            PUSHs(sv_2mortal(newSViv((I32)iters)));
        }
-       (void)SvPOK_only(TARG);
+       (void)SvPOK_only_UTF8(TARG);
        TAINT_IF(rxtainted);
        if (SvSMAGICAL(TARG)) {
            PUTBACK;
@@ -2015,8 +2032,10 @@ PP(pp_leavesub)
                    sv_2mortal(*MARK);
                }
                else {
+                   sv = SvREFCNT_inc(TOPs);    /* FREETMPS could clobber it */
                    FREETMPS;
-                   *MARK = sv_mortalcopy(TOPs);
+                   *MARK = sv_mortalcopy(sv);
+                   SvREFCNT_dec(sv);
                }
            }
            else
@@ -2145,7 +2164,6 @@ PP(pp_leavesublv)
                        : "an uninitialized value");
                }
                else {
-                   mortalize:
                    /* Can be a localized value subject to deletion. */
                    PL_tmps_stack[++PL_tmps_ix] = *mark;
                    (void)SvREFCNT_inc(*mark);
@@ -2165,8 +2183,10 @@ PP(pp_leavesublv)
                        sv_2mortal(*MARK);
                    }
                    else {
+                       sv = SvREFCNT_inc(TOPs); /* FREETMPS could clobber it */
                        FREETMPS;
-                       *MARK = sv_mortalcopy(TOPs);
+                       *MARK = sv_mortalcopy(sv);
+                       SvREFCNT_dec(sv);
                    }
                }
                else
@@ -2223,8 +2243,8 @@ S_get_db_sub(pTHX_ SV **svp, CV *cv)
        }
     }
     else {
-       SvUPGRADE(dbsv, SVt_PVIV);
-       SvIOK_on(dbsv);
+       (void)SvUPGRADE(dbsv, SVt_PVIV);
+       (void)SvIOK_on(dbsv);
        SAVEIV(SvIVX(dbsv));
        SvIVX(dbsv) = PTR2IV(cv);       /* Do it the quickest way  */
     }
@@ -2795,7 +2815,6 @@ PP(pp_method_named)
 STATIC SV *
 S_method_common(pTHX_ SV* meth, U32* hashp)
 {
-    djSP;
     SV* sv;
     SV* ob;
     GV* gv;