This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Abstract all the accesses to cop_arybase (apart from ByteLoader)
[perl5.git] / pp_hot.c
index 8d590ca..8cb2364 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -146,7 +146,7 @@ PP(pp_sassign)
                SvUPGRADE((SV *)gv, SVt_RV);
                SvROK_on(gv);
                SvRV_set(gv, value);
-               SvREFCNT_inc(value);
+               SvREFCNT_inc_simple_void(value);
                SETs(right);
                RETURN;
            }
@@ -162,7 +162,7 @@ PP(pp_sassign)
            /* We've been returned a constant rather than a full subroutine,
               but they expect a subroutine reference to apply.  */
            ENTER;
-           SvREFCNT_inc(SvRV(cv));
+           SvREFCNT_inc_void(SvRV(cv));
            /* newCONSTSUB takes a reference count on the passed in SV
               from us.  We set the name to NULL, otherwise we get into
               all sorts of fun as the reference to our new sub is
@@ -208,7 +208,7 @@ PP(pp_concat)
     dPOPTOPssrl;
     bool lbyte;
     STRLEN rlen;
-    const char *rpv = 0;
+    const char *rpv = NULL;
     bool rbyte = FALSE;
     bool rcopied = FALSE;
 
@@ -350,21 +350,27 @@ PP(pp_eq)
                     ivp = *--SP;
                 }
                 iv = SvIVX(ivp);
-                if (iv < 0) {
+               if (iv < 0)
                     /* As uv is a UV, it's >0, so it cannot be == */
                     SETs(&PL_sv_no);
-                    RETURN;
-                }
-               /* we know iv is >= 0 */
-               SETs(boolSV((UV)iv == SvUVX(uvp)));
+               else
+                   /* we know iv is >= 0 */
+                   SETs(boolSV((UV)iv == SvUVX(uvp)));
                RETURN;
            }
        }
     }
 #endif
     {
+#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
+      dPOPTOPnnrl;
+      if (Perl_isnan(left) || Perl_isnan(right))
+         RETSETNO;
+      SETs(boolSV(left == right));
+#else
       dPOPnv;
       SETs(boolSV(TOPn == value));
+#endif
       RETURN;
     }
 }
@@ -1405,8 +1411,12 @@ play_it_again:
                if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG))
                    mg = mg_find(TARG, PERL_MAGIC_regex_global);
                if (!mg) {
-                   sv_magic(TARG, NULL, PERL_MAGIC_regex_global, NULL, 0);
-                   mg = mg_find(TARG, PERL_MAGIC_regex_global);
+#ifdef PERL_OLD_COPY_ON_WRITE
+                   if (SvIsCOW(TARG))
+                       sv_force_normal_flags(TARG, 0);
+#endif
+                   mg = sv_magicext(TARG, NULL, PERL_MAGIC_regex_global,
+                                    &PL_vtbl_mglob, NULL, 0);
                }
                if (rx->startp[0] != -1) {
                    mg->mg_len = rx->endp[0];
@@ -1435,8 +1445,12 @@ play_it_again:
            else
                mg = NULL;
            if (!mg) {
-               sv_magic(TARG, NULL, PERL_MAGIC_regex_global, NULL, 0);
-               mg = mg_find(TARG, PERL_MAGIC_regex_global);
+#ifdef PERL_OLD_COPY_ON_WRITE
+               if (SvIsCOW(TARG))
+                   sv_force_normal_flags(TARG, 0);
+#endif
+               mg = sv_magicext(TARG, NULL, PERL_MAGIC_regex_global,
+                                &PL_vtbl_mglob, NULL, 0);
            }
            if (rx->startp[0] != -1) {
                mg->mg_len = rx->endp[0];
@@ -1611,6 +1625,9 @@ Perl_do_readline(pTHX)
        sv = TARG;
        if (SvROK(sv))
            sv_unref(sv);
+       else if (isGV_with_GP(sv)) {
+           SvPV_force_nolen(sv);
+       }
        SvUPGRADE(sv, SVt_PV);
        tmplen = SvLEN(sv);     /* remember if already alloced */
        if (!tmplen && !SvREADONLY(sv))
@@ -1698,16 +1715,17 @@ Perl_do_readline(pTHX)
                continue;
            }
        } else if (SvUTF8(sv)) { /* OP_READLINE, OP_RCATLINE */
-            const U8 * const s = (const U8*)SvPVX_const(sv) + offset;
-            const STRLEN len = SvCUR(sv) - offset;
-            const U8 *f;
-            
-            if (ckWARN(WARN_UTF8) &&
-                   !is_utf8_string_loc(s, len, &f))
-                 /* Emulate :encoding(utf8) warning in the same case. */
-                 Perl_warner(aTHX_ packWARN(WARN_UTF8),
-                             "utf8 \"\\x%02X\" does not map to Unicode",
-                             f < (U8*)SvEND(sv) ? *f : 0);
+            if (ckWARN(WARN_UTF8)) {
+               const U8 * const s = (const U8*)SvPVX_const(sv) + offset;
+               const STRLEN len = SvCUR(sv) - offset;
+               const U8 *f;
+
+               if (!is_utf8_string_loc(s, len, &f))
+                   /* Emulate :encoding(utf8) warning in the same case. */
+                   Perl_warner(aTHX_ packWARN(WARN_UTF8),
+                               "utf8 \"\\x%02X\" does not map to Unicode",
+                               f < (U8*)SvEND(sv) ? *f : 0);
+            }
        }
        if (gimme == G_ARRAY) {
            if (SvLEN(sv) - SvCUR(sv) > 20) {
@@ -1760,32 +1778,28 @@ PP(pp_helem)
     const U32 hash = (SvIsCOW_shared_hash(keysv)) ? SvSHARED_HASH(keysv) : 0;
     I32 preeminent = 0;
 
-    if (SvTYPE(hv) == SVt_PVHV) {
-       if (PL_op->op_private & OPpLVAL_INTRO) {
-           MAGIC *mg;
-           HV *stash;
-           /* does the element we're localizing already exist? */
-           preeminent =  
-               /* can we determine whether it exists? */
-               (    !SvRMAGICAL(hv)
-                 || mg_find((SV*)hv, PERL_MAGIC_env)
-                 || (     (mg = mg_find((SV*)hv, PERL_MAGIC_tied))
-                       /* Try to preserve the existenceness of a tied hash
-                        * element by using EXISTS and DELETE if possible.
-                        * Fallback to FETCH and STORE otherwise */
-                       && (stash = SvSTASH(SvRV(SvTIED_obj((SV*)hv, mg))))
-                       && gv_fetchmethod_autoload(stash, "EXISTS", TRUE)
-                       && gv_fetchmethod_autoload(stash, "DELETE", TRUE)
-                   )
-               ) ? hv_exists_ent(hv, keysv, 0) : 1;
-
-       }
-       he = hv_fetch_ent(hv, keysv, lval && !defer, hash);
-       svp = he ? &HeVAL(he) : NULL;
-    }
-    else {
+    if (SvTYPE(hv) != SVt_PVHV)
        RETPUSHUNDEF;
-    }
+
+    if (PL_op->op_private & OPpLVAL_INTRO) {
+       MAGIC *mg;
+       HV *stash;
+       /* does the element we're localizing already exist? */
+       preeminent = /* can we determine whether it exists? */
+           (    !SvRMAGICAL(hv)
+               || mg_find((SV*)hv, PERL_MAGIC_env)
+               || (     (mg = mg_find((SV*)hv, PERL_MAGIC_tied))
+                       /* Try to preserve the existenceness of a tied hash
+                       * element by using EXISTS and DELETE if possible.
+                       * Fallback to FETCH and STORE otherwise */
+                   && (stash = SvSTASH(SvRV(SvTIED_obj((SV*)hv, mg))))
+                   && gv_fetchmethod_autoload(stash, "EXISTS", TRUE)
+                   && gv_fetchmethod_autoload(stash, "DELETE", TRUE)
+               )
+           ) ? hv_exists_ent(hv, keysv, 0) : 1;
+    }
+    he = hv_fetch_ent(hv, keysv, lval && !defer, hash);
+    svp = he ? &HeVAL(he) : NULL;
     if (lval) {
        if (!svp || *svp == &PL_sv_undef) {
            SV* lv;
@@ -1798,7 +1812,7 @@ PP(pp_helem)
            LvTYPE(lv) = 'y';
            sv_magic(lv, key2 = newSVsv(keysv), PERL_MAGIC_defelem, NULL, 0);
            SvREFCNT_dec(key2); /* sv_magic() increments refcount */
-           LvTARG(lv) = SvREFCNT_inc(hv);
+           LvTARG(lv) = SvREFCNT_inc_simple(hv);
            LvTARGLEN(lv) = 1;
            PUSHs(lv);
            RETURN;
@@ -1810,7 +1824,8 @@ PP(pp_helem)
                if (!preeminent) {
                    STRLEN keylen;
                    const char * const key = SvPV_const(keysv, keylen);
-                   SAVEDELETE(hv, savepvn(key,keylen), keylen);
+                   SAVEDELETE(hv, savepvn(key,keylen),
+                              SvUTF8(keysv) ? -(I32)keylen : keylen);
                } else
                    save_helem(hv, keysv, svp);
             }
@@ -2004,14 +2019,14 @@ PP(pp_iter)
            LvTYPE(lv) = 'y';
            sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
        }
-       LvTARG(lv) = SvREFCNT_inc(av);
+       LvTARG(lv) = SvREFCNT_inc_simple(av);
        LvTARGOFF(lv) = cx->blk_loop.iterix;
        LvTARGLEN(lv) = (STRLEN)UV_MAX;
        sv = (SV*)lv;
     }
 
     oldsv = *itersvp;
-    *itersvp = SvREFCNT_inc(sv);
+    *itersvp = SvREFCNT_inc_simple_NN(sv);
     SvREFCNT_dec(oldsv);
 
     RETPUSHYES;
@@ -2022,7 +2037,6 @@ PP(pp_subst)
     dVAR; dSP; dTARG;
     register PMOP *pm = cPMOP;
     PMOP *rpm = pm;
-    register SV *dstr;
     register char *s;
     char *strend;
     register char *m;
@@ -2048,7 +2062,7 @@ PP(pp_subst)
     SV *nsv = NULL;
 
     /* known replacement string? */
-    dstr = (pm->op_pmflags & PMf_CONST) ? POPs : NULL;
+    register SV *dstr = (pm->op_pmflags & PMf_CONST) ? POPs : NULL;
     if (PL_op->op_flags & OPf_STACKED)
        TARG = POPs;
     else if (PL_op->op_private & OPpTARGET_MY)
@@ -2512,7 +2526,7 @@ PP(pp_leavesublv)
                else {
                    /* Can be a localized value subject to deletion. */
                    PL_tmps_stack[++PL_tmps_ix] = *mark;
-                   (void)SvREFCNT_inc(*mark);
+                   SvREFCNT_inc_void(*mark);
                }
            }
        }
@@ -2549,7 +2563,7 @@ PP(pp_leavesublv)
                else {                  /* Can be a localized value
                                         * subject to deletion. */
                    PL_tmps_stack[++PL_tmps_ix] = *mark;
-                   (void)SvREFCNT_inc(*mark);
+                   SvREFCNT_inc_void(*mark);
                }
            }
            else {                      /* Should not happen? */
@@ -2581,7 +2595,7 @@ PP(pp_leavesublv)
                else {
                    /* Can be a localized value subject to deletion. */
                    PL_tmps_stack[++PL_tmps_ix] = *mark;
-                   (void)SvREFCNT_inc(*mark);
+                   SvREFCNT_inc_void(*mark);
                }
            }
        }
@@ -2643,13 +2657,12 @@ S_get_db_sub(pTHX_ SV **svp, CV *cv)
 
     save_item(dbsv);
     if (!PERLDB_SUB_NN) {
-       GV *gv = CvGV(cv);
+       GV * const gv = CvGV(cv);
 
        if ( (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED))
             || strEQ(GvNAME(gv), "END")
             || ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */
-                !( (SvTYPE(*svp) == SVt_PVGV) && (GvCV((GV*)*svp) == cv)
-                   && (gv = (GV*)*svp) ))) {
+                !( (SvTYPE(*svp) == SVt_PVGV) && (GvCV((GV*)*svp) == cv) ))) {
            /* Use GV from the stack as a fallback. */
            /* GV is potentially non-unique, or contain different CV. */
            SV * const tmp = newRV((SV*)cv);
@@ -2817,7 +2830,7 @@ try_autoload:
                AvREIFY_on(av);
            }
            cx->blk_sub.savearray = GvAV(PL_defgv);
-           GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
+           GvAV(PL_defgv) = (AV*)SvREFCNT_inc_simple(av);
            CX_CURPAD_SAVE(cx->blk_sub);
            cx->blk_sub.argarray = av;
            ++MARK;
@@ -2926,7 +2939,7 @@ PP(pp_aelem)
     if (SvROK(elemsv) && !SvGAMAGIC(elemsv) && ckWARN(WARN_MISC))
        Perl_warner(aTHX_ packWARN(WARN_MISC), "Use of reference \"%"SVf"\" as array index", elemsv);
     if (elem > 0)
-       elem -= PL_curcop->cop_arybase;
+       elem -= CopARYBASE_get(PL_curcop);
     if (SvTYPE(av) != SVt_PVAV)
        RETPUSHUNDEF;
     svp = av_fetch(av, elem, lval && !defer);
@@ -2952,7 +2965,7 @@ PP(pp_aelem)
            sv_upgrade(lv, SVt_PVLV);
            LvTYPE(lv) = 'y';
            sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
-           LvTARG(lv) = SvREFCNT_inc(av);
+           LvTARG(lv) = SvREFCNT_inc_simple(av);
            LvTARGOFF(lv) = elem;
            LvTARGLEN(lv) = 1;
            PUSHs(lv);
@@ -3080,7 +3093,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
            if (!stash)
                packsv = sv;
             else {
-               SV* ref = newSViv(PTR2IV(stash));
+               SV* const ref = newSViv(PTR2IV(stash));
                hv_store(PL_stashcache, packname, packlen, ref, 0);
            }
            goto fetch;