Re: Not OK: perl v5.9.0 +DEVEL17881 on i386-freebsd 4.6-release (UNINSTALLED)
[p5sagit/p5-mst-13.2.git] / pp.c
diff --git a/pp.c b/pp.c
index 15bf351..47e512c 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -17,7 +17,7 @@
 #include "perl.h"
 #include "keywords.h"
 
-/* variations on pp_null */
+#include "reentr.h"
 
 /* XXX I can't imagine anyone who doesn't have this actually _needs_
    it, since pid_t is an integral type.
@@ -27,6 +27,8 @@
 extern Pid_t getpid (void);
 #endif
 
+/* variations on pp_null */
+
 PP(pp_stub)
 {
     dSP;
@@ -45,8 +47,9 @@ PP(pp_scalar)
 PP(pp_padav)
 {
     dSP; dTARGET;
+    I32 gimme;
     if (PL_op->op_private & OPpLVAL_INTRO)
-       SAVECLEARSV(PL_curpad[PL_op->op_targ]);
+       SAVECLEARSV(PAD_SVl(PL_op->op_targ));
     EXTEND(SP, 1);
     if (PL_op->op_flags & OPf_REF) {
        PUSHs(TARG);
@@ -57,12 +60,13 @@ PP(pp_padav)
        PUSHs(TARG);
        RETURN;
     }
-    if (GIMME == G_ARRAY) {
+    gimme = GIMME_V;
+    if (gimme == G_ARRAY) {
        I32 maxarg = AvFILL((AV*)TARG) + 1;
        EXTEND(SP, maxarg);
        if (SvMAGICAL(TARG)) {
            U32 i;
-           for (i=0; i < maxarg; i++) {
+           for (i=0; i < (U32)maxarg; i++) {
                SV **svp = av_fetch((AV*)TARG, i, FALSE);
                SP[i+1] = (svp) ? *svp : &PL_sv_undef;
            }
@@ -72,7 +76,7 @@ PP(pp_padav)
        }
        SP += maxarg;
     }
-    else {
+    else if (gimme == G_SCALAR) {
        SV* sv = sv_newmortal();
        I32 maxarg = AvFILL((AV*)TARG) + 1;
        sv_setiv(sv, maxarg);
@@ -88,7 +92,7 @@ PP(pp_padhv)
 
     XPUSHs(TARG);
     if (PL_op->op_private & OPpLVAL_INTRO)
-       SAVECLEARSV(PL_curpad[PL_op->op_targ]);
+       SAVECLEARSV(PAD_SVl(PL_op->op_targ));
     if (PL_op->op_flags & OPf_REF)
        RETURN;
     else if (LVRET) {
@@ -157,7 +161,7 @@ PP(pp_rv2gv)
                    GV *gv;
                    if (cUNOP->op_targ) {
                        STRLEN len;
-                       SV *namesv = PL_curpad[cUNOP->op_targ];
+                       SV *namesv = PAD_SV(cUNOP->op_targ);
                        name = SvPV(namesv, len);
                        gv = (GV*)NEWSV(0,0);
                        gv_init(gv, CopSTASH(PL_curcop), name, len, 0);
@@ -418,7 +422,7 @@ PP(pp_prototype)
 PP(pp_anoncode)
 {
     dSP;
-    CV* cv = (CV*)PL_curpad[PL_op->op_targ];
+    CV* cv = (CV*)PAD_SV(PL_op->op_targ);
     if (CvCLONE(cv))
        cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
     EXTEND(SP,1);
@@ -762,8 +766,7 @@ PP(pp_undef)
     if (!sv)
        RETPUSHUNDEF;
 
-    if (SvTHINKFIRST(sv))
-       sv_force_normal(sv);
+    SV_CHECK_THINKFIRST_COW_DROP(sv);
 
     switch (SvTYPE(sv)) {
     case SVt_NULL:
@@ -954,6 +957,8 @@ PP(pp_pow)
                             result *= base;
                             /* Only bother to clear the bit if it is set.  */
                             power &= ~bit;
+                           /* Avoid squaring base again if we're done. */
+                           if (power == 0) break;
                         }
                     }
                     SP--;
@@ -1185,7 +1190,7 @@ PP(pp_divide)
                     }
                     /* 2s complement assumption */
                     if (result <= (UV)IV_MIN)
-                        SETi( -result );
+                        SETi( -(IV)result );
                     else {
                         /* It's exact but too negative for IV. */
                         SETn( -(NV)result );
@@ -2680,7 +2685,7 @@ S_seed(pTHX)
     u = (U32)SEED_C1 * when[0] + (U32)SEED_C2 * when[1];
 #else
 #  ifdef HAS_GETTIMEOFDAY
-    gettimeofday(&when,(struct timezone *) 0);
+    PerlProc_gettimeofday(&when,NULL);
     u = (U32)SEED_C1 * when.tv_sec + (U32)SEED_C2 * when.tv_usec;
 #  else
     (void)time(&when);
@@ -3161,7 +3166,7 @@ PP(pp_index)
        sv_pos_u2b(big, &offset, 0);
     if (offset < 0)
        offset = 0;
-    else if (offset > biglen)
+    else if (offset > (I32)biglen)
        offset = biglen;
     if (!(tmps2 = fbm_instr((unsigned char*)tmps + offset,
       (unsigned char*)tmps + biglen, little, 0)))
@@ -3202,7 +3207,7 @@ PP(pp_rindex)
     }
     if (offset < 0)
        offset = 0;
-    else if (offset > blen)
+    else if (offset > (I32)blen)
        offset = blen;
     if (!(tmps2 = rninstr(tmps,  tmps  + offset,
                          tmps2, tmps2 + llen)))
@@ -3241,7 +3246,9 @@ PP(pp_ord)
         argsv = tmpsv;
     }
 
-    XPUSHu(DO_UTF8(argsv) ? utf8_to_uvchr(s, 0) : (*s & 0xff));
+    XPUSHu(DO_UTF8(argsv) ?
+          utf8n_to_uvchr(s, UTF8_MAXLEN, 0, UTF8_ALLOW_ANYUV) :
+          (*s & 0xff));
 
     RETURN;
 }
@@ -3255,7 +3262,7 @@ PP(pp_chr)
     (void)SvUPGRADE(TARG,SVt_PV);
 
     if (value > 255 && !IN_BYTES) {
-       SvGROW(TARG, UNISKIP(value)+1);
+       SvGROW(TARG, (STRLEN)UNISKIP(value)+1);
        tmps = (char*)uvchr_to_utf8_flags((U8*)SvPVX(TARG), value, 0);
        SvCUR_set(TARG, tmps - SvPVX(TARG));
        *tmps = '\0';
@@ -3268,7 +3275,7 @@ PP(pp_chr)
     SvGROW(TARG,2);
     SvCUR_set(TARG, 1);
     tmps = SvPVX(TARG);
-    *tmps++ = value;
+    *tmps++ = (char)value;
     *tmps = '\0';
     (void)SvPOK_only(TARG);
     if (PL_encoding)
@@ -3301,12 +3308,12 @@ PP(pp_crypt)
 #   else
     sv_setpv(TARG, PerlProc_crypt(tmps, SvPV(right, n_a)));
 #   endif
+    SETs(TARG);
+    RETURN;
 #else
     DIE(aTHX_
       "The crypt() function is unimplemented due to excessive paranoia.");
 #endif
-    SETs(TARG);
-    RETURN;
 }
 
 PP(pp_ucfirst)
@@ -3381,7 +3388,7 @@ PP(pp_lcfirst)
        
        tend = uvchr_to_utf8(tmpbuf, uv);
 
-       if (!SvPADTMP(sv) || tend - tmpbuf != ulen || SvREADONLY(sv)) {
+       if (!SvPADTMP(sv) || (STRLEN)(tend - tmpbuf) != ulen || SvREADONLY(sv)) {
            dTARGET;
            sv_setpvn(TARG, (char*)tmpbuf, tend - tmpbuf);
            sv_catpvn(TARG, (char*)(s + ulen), slen - ulen);
@@ -3677,22 +3684,21 @@ PP(pp_each)
     HV *hash = (HV*)POPs;
     HE *entry;
     I32 gimme = GIMME_V;
-    I32 realhv = (SvTYPE(hash) == SVt_PVHV);
 
     PUTBACK;
     /* might clobber stack_sp */
-    entry = realhv ? hv_iternext(hash) : avhv_iternext((AV*)hash);
+    entry = hv_iternext(hash);
     SPAGAIN;
 
     EXTEND(SP, 2);
     if (entry) {
-       PUSHs(hv_iterkeysv(entry));     /* won't clobber stack_sp */
+        SV* sv = hv_iterkeysv(entry);
+       PUSHs(sv);      /* won't clobber stack_sp */
        if (gimme == G_ARRAY) {
            SV *val;
            PUTBACK;
            /* might clobber stack_sp */
-           val = realhv ?
-                 hv_iterval(hash, entry) : avhv_iterval((AV*)hash, entry);
+           val = hv_iterval(hash, entry);
            SPAGAIN;
            PUSHs(val);
        }
@@ -3732,19 +3738,13 @@ PP(pp_delete)
                *MARK = sv ? sv : &PL_sv_undef;
            }
        }
-       else if (hvtype == SVt_PVAV) {
-           if (PL_op->op_flags & OPf_SPECIAL) {        /* array element */
-               while (++MARK <= SP) {
-                   sv = av_delete((AV*)hv, SvIV(*MARK), discard);
-                   *MARK = sv ? sv : &PL_sv_undef;
-               }
-           }
-           else {                                      /* pseudo-hash element */
-               while (++MARK <= SP) {
-                   sv = avhv_delete_ent((AV*)hv, *MARK, discard, 0);
-                   *MARK = sv ? sv : &PL_sv_undef;
-               }
-           }
+       else if (hvtype == SVt_PVAV) {                  /* array element */
+            if (PL_op->op_flags & OPf_SPECIAL) {
+                while (++MARK <= SP) {
+                    sv = av_delete((AV*)hv, SvIV(*MARK), discard);
+                    *MARK = sv ? sv : &PL_sv_undef;
+                }
+            }
        }
        else
            DIE(aTHX_ "Not a HASH reference");
@@ -3765,7 +3765,7 @@ PP(pp_delete)
            if (PL_op->op_flags & OPf_SPECIAL)
                sv = av_delete((AV*)hv, SvIV(keysv), discard);
            else
-               sv = avhv_delete_ent((AV*)hv, keysv, discard, 0);
+               DIE(aTHX_ "panic: avhv_delete no longer supported");
        }
        else
            DIE(aTHX_ "Not a HASH reference");
@@ -3805,8 +3805,6 @@ PP(pp_exists)
            if (av_exists((AV*)hv, SvIV(tmpsv)))
                RETPUSHYES;
        }
-       else if (avhv_exists_ent((AV*)hv, tmpsv, 0))    /* pseudo-hash element */
-           RETPUSHYES;
     }
     else {
        DIE(aTHX_ "Not a HASH reference");
@@ -3819,42 +3817,53 @@ PP(pp_hslice)
     dSP; dMARK; dORIGMARK;
     register HV *hv = (HV*)POPs;
     register I32 lval = (PL_op->op_flags & OPf_MOD || LVRET);
-    I32 realhv = (SvTYPE(hv) == SVt_PVHV);
+    bool localizing = PL_op->op_private & OPpLVAL_INTRO ? TRUE : FALSE;
+    bool other_magic = FALSE;
+
+    if (localizing) {
+        MAGIC *mg;
+        HV *stash;
+
+        other_magic = 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));
+    }
+
+    while (++MARK <= SP) {
+        SV *keysv = *MARK;
+        SV **svp;
+        HE *he;
+        bool preeminent = FALSE;
+
+        if (localizing) {
+            preeminent = SvRMAGICAL(hv) && !other_magic ? 1 :
+                hv_exists_ent(hv, keysv, 0);
+        }
 
-    if (!realhv && PL_op->op_private & OPpLVAL_INTRO)
-       DIE(aTHX_ "Can't localize pseudo-hash element");
+        he = hv_fetch_ent(hv, keysv, lval, 0);
+        svp = he ? &HeVAL(he) : 0;
 
-    if (realhv || SvTYPE(hv) == SVt_PVAV) {
-       while (++MARK <= SP) {
-           SV *keysv = *MARK;
-           SV **svp;
-           I32 preeminent = SvRMAGICAL(hv) ? 1 :
-                               realhv ? hv_exists_ent(hv, keysv, 0)
-                                      : avhv_exists_ent((AV*)hv, keysv, 0);
-           if (realhv) {
-               HE *he = hv_fetch_ent(hv, keysv, lval, 0);
-               svp = he ? &HeVAL(he) : 0;
-           }
-           else {
-               svp = avhv_fetch_ent((AV*)hv, keysv, lval, 0);
-           }
-           if (lval) {
-               if (!svp || *svp == &PL_sv_undef) {
-                   STRLEN n_a;
-                   DIE(aTHX_ PL_no_helem, SvPV(keysv, n_a));
-               }
-               if (PL_op->op_private & OPpLVAL_INTRO) {
-                   if (preeminent)
-                       save_helem(hv, keysv, svp);
-                   else {
-                       STRLEN keylen;
-                       char *key = SvPV(keysv, keylen);
-                       SAVEDELETE(hv, savepvn(key,keylen), keylen);
-                   }
+        if (lval) {
+            if (!svp || *svp == &PL_sv_undef) {
+                STRLEN n_a;
+                DIE(aTHX_ PL_no_helem, SvPV(keysv, n_a));
+            }
+            if (localizing) {
+                if (preeminent)
+                    save_helem(hv, keysv, svp);
+                else {
+                    STRLEN keylen;
+                    char *key = SvPV(keysv, keylen);
+                    SAVEDELETE(hv, savepvn(key,keylen), keylen);
                 }
-           }
-           *MARK = svp ? *svp : &PL_sv_undef;
-       }
+            }
+        }
+        *MARK = svp ? *svp : &PL_sv_undef;
     }
     if (GIMME != G_ARRAY) {
        MARK = ORIGMARK;
@@ -4301,7 +4310,7 @@ PP(pp_reverse)
                        while (down > up) {
                            tmp = *up;
                            *up++ = *down;
-                           *down-- = tmp;
+                           *down-- = (char)tmp;
                        }
                    }
                }
@@ -4311,7 +4320,7 @@ PP(pp_reverse)
            while (down > up) {
                tmp = *up;
                *up++ = *down;
-               *down-- = tmp;
+               *down-- = (char)tmp;
            }
            (void)SvPOK_only_UTF8(TARG);
        }
@@ -4365,17 +4374,13 @@ PP(pp_split)
 
     if (pm->op_pmreplroot) {
 #ifdef USE_ITHREADS
-       ary = GvAVn((GV*)PL_curpad[INT2PTR(PADOFFSET, pm->op_pmreplroot)]);
+       ary = GvAVn((GV*)PAD_SVl(INT2PTR(PADOFFSET, pm->op_pmreplroot)));
 #else
        ary = GvAVn((GV*)pm->op_pmreplroot);
 #endif
     }
     else if (gimme != G_ARRAY)
-#ifdef USE_5005THREADS
-       ary = (AV*)PL_curpad[0];
-#else
        ary = GvAVn(PL_defgv);
-#endif /* USE_5005THREADS */
     else
        ary = Nullav;
     if (ary && (gimme != G_ARRAY || (pm->op_pmflags & PMf_ONCE))) {
@@ -4541,7 +4546,7 @@ PP(pp_split)
                (void)SvUTF8_on(dstr);
            XPUSHs(dstr);
            if (rx->nparens) {
-               for (i = 1; i <= rx->nparens; i++) {
+               for (i = 1; i <= (I32)rx->nparens; i++) {
                    s = rx->startp[i] + orig;
                    m = rx->endp[i] + orig;
 
@@ -4583,8 +4588,12 @@ PP(pp_split)
        iters++;
     }
     else if (!origlimit) {
-       while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0))
-           iters--, SP--;
+       while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0)) {
+           if (TOPs && !make_mortal)
+               sv_2mortal(TOPs);
+           iters--;
+           SP--;
+       }
     }
 
     if (realarray) {
@@ -4631,25 +4640,6 @@ PP(pp_split)
     RETPUSHUNDEF;
 }
 
-#ifdef USE_5005THREADS
-void
-Perl_unlock_condpair(pTHX_ void *svv)
-{
-    MAGIC *mg = mg_find((SV*)svv, PERL_MAGIC_mutex);
-
-    if (!mg)
-       Perl_croak(aTHX_ "panic: unlock_condpair unlocking non-mutex");
-    MUTEX_LOCK(MgMUTEXP(mg));
-    if (MgOWNER(mg) != thr)
-       Perl_croak(aTHX_ "panic: unlock_condpair unlocking mutex that we don't own");
-    MgOWNER(mg) = 0;
-    COND_SIGNAL(MgOWNERCONDP(mg));
-    DEBUG_S(PerlIO_printf(Perl_debug_log, "0x%"UVxf": unlock 0x%"UVxf"\n",
-                         PTR2UV(thr), PTR2UV(svv)));
-    MUTEX_UNLOCK(MgMUTEXP(mg));
-}
-#endif /* USE_5005THREADS */
-
 PP(pp_lock)
 {
     dSP;
@@ -4666,15 +4656,5 @@ PP(pp_lock)
 
 PP(pp_threadsv)
 {
-#ifdef USE_5005THREADS
-    dSP;
-    EXTEND(SP, 1);
-    if (PL_op->op_private & OPpLVAL_INTRO)
-       PUSHs(*save_threadsv(PL_op->op_targ));
-    else
-       PUSHs(THREADSV(PL_op->op_targ));
-    RETURN;
-#else
     DIE(aTHX_ "tried to access per-thread data in non-threaded perl");
-#endif /* USE_5005THREADS */
 }