Fix tcsh hack in Configure
[p5sagit/p5-mst-13.2.git] / pp_hot.c
index 7f9f513..7cc8655 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -160,8 +160,7 @@ PP(pp_sassign)
     }
     if (tainting && tainted && !SvTAINTED(left))
        TAINT_NOT;
-    SvSetSV(right, left);
-    SvSETMAGIC(right);
+    SvSetMagicSV(right, left);
     SETs(right);
     RETURN;
 }
@@ -221,7 +220,7 @@ PP(pp_padsv)
        if (op->op_private & OPpLVAL_INTRO)
            SAVECLEARSV(curpad[op->op_targ]);
         else if (op->op_private & OPpDEREF)
-           vivify_ref(curpad[op->op_targ], op->op_flags & OPpDEREF);
+           vivify_ref(curpad[op->op_targ], op->op_private & OPpDEREF);
     }
     RETURN;
 }
@@ -237,7 +236,7 @@ PP(pp_eq)
     dSP; tryAMAGICbinSET(eq,0); 
     {
       dPOPnv;
-      SETs((TOPn == value) ? &sv_yes : &sv_no);
+      SETs(boolSV(TOPn == value));
       RETURN;
     }
 }
@@ -590,6 +589,7 @@ PP(pp_aassign)
     register SV *sv;
     register AV *ary;
 
+    I32 gimme;
     HV *hash;
     I32 i;
     int magic;
@@ -744,7 +744,16 @@ PP(pp_aassign)
        tainting |= (uid && (euid != uid || egid != gid));
     }
     delaymagic = 0;
-    if (GIMME == G_ARRAY) {
+
+    gimme = GIMME_V;
+    if (gimme == G_VOID)
+       SP = firstrelem - 1;
+    else if (gimme == G_SCALAR) {
+       dTARGET;
+       SP = firstrelem;
+       SETi(lastrelem - firstrelem + 1);
+    }
+    else {
        if (ary || hash)
            SP = lastrelem;
        else
@@ -752,15 +761,8 @@ PP(pp_aassign)
        lelem = firstlelem + (relem - firstrelem);
        while (relem <= SP)
            *relem++ = (lelem <= lastlelem) ? *lelem++ : &sv_undef;
-       RETURN;
-    }
-    else {
-       dTARGET;
-       SP = firstrelem;
-               
-       SETi(lastrelem - firstrelem + 1);
-       RETURN;
     }
+    RETURN;
 }
 
 PP(pp_match)
@@ -816,7 +818,8 @@ PP(pp_match)
     }
     if (!rx->nparens && !global)
        gimme = G_SCALAR;                       /* accidental array context? */
-    safebase = (((gimme == G_ARRAY) || global) && !sawampersand);
+    safebase = (((gimme == G_ARRAY) || global || !rx->nparens)
+               && !sawampersand);
     if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
        SAVEINT(multiline);
        multiline = pm->op_pmflags & PMf_MULTILINE;
@@ -825,7 +828,7 @@ PP(pp_match)
 play_it_again:
     if (global && rx->startp[0]) {
        t = s = rx->endp[0];
-       if (s >= strend)
+       if ((s + rx->minlen) > strend)
            goto nope;
        if (update_minmatch++)
            minmatch = (s == rx->startp[0]);
@@ -976,6 +979,7 @@ do_readline()
     PerlIO *fp;
     register IO *io = GvIO(last_in_gv);
     register I32 type = op->op_type;
+    I32 gimme = GIMME_V;
     MAGIC *mg;
 
     if (SvMAGICAL(last_in_gv) && (mg = mg_find((SV*)last_in_gv, 'q'))) {
@@ -983,11 +987,11 @@ do_readline()
        XPUSHs(mg->mg_obj);
        PUTBACK;
        ENTER;
-       perl_call_method("READLINE", GIMME);
+       perl_call_method("READLINE", gimme);
        LEAVE;
        SPAGAIN;
-       if (GIMME == G_SCALAR)
-           SvSetSV_nosteal(TARG, TOPs);
+       if (gimme == G_SCALAR)
+           SvSetMagicSV_nosteal(TARG, TOPs);
        RETURN;
     }
     fp = Nullfp;
@@ -1134,17 +1138,13 @@ do_readline()
     if (!fp) {
        if (dowarn && io && !(IoFLAGS(io) & IOf_START))
            warn("Read on closed filehandle <%s>", GvENAME(last_in_gv));
-       if (GIMME == G_SCALAR) {
+       if (gimme == G_SCALAR) {
            (void)SvOK_off(TARG);
            PUSHTARG;
        }
        RETURN;
     }
-    if (GIMME == G_ARRAY) {
-       sv = sv_2mortal(NEWSV(57, 80));
-       offset = 0;
-    }
-    else {
+    if (gimme == G_SCALAR) {
        sv = TARG;
        if (SvROK(sv))
            sv_unref(sv);
@@ -1157,6 +1157,10 @@ do_readline()
        else
            offset = 0;
     }
+    else {
+       sv = sv_2mortal(NEWSV(57, 80));
+       offset = 0;
+    }
     for (;;) {
        if (!sv_gets(sv, fp, offset)) {
            PerlIO_clearerr(fp);
@@ -1168,9 +1172,10 @@ do_readline()
                IoFLAGS(io) |= IOf_START;
            }
            else if (type == OP_GLOB) {
-               (void)do_close(last_in_gv, FALSE);
+               if (do_close(last_in_gv, FALSE) & ~0xFF)
+                   warn("internal error: glob failed");
            }
-           if (GIMME == G_SCALAR) {
+           if (gimme == G_SCALAR) {
                (void)SvOK_off(TARG);
                PUSHTARG;
            }
@@ -1203,7 +1208,7 @@ do_readline()
                continue;
            }
        }
-       if (GIMME == G_ARRAY) {
+       if (gimme == G_ARRAY) {
            if (SvLEN(sv) - SvCUR(sv) > 20) {
                SvLEN_set(sv, SvCUR(sv)+1);
                Renew(SvPVX(sv), SvLEN(sv), char);
@@ -1211,7 +1216,7 @@ do_readline()
            sv = sv_2mortal(NEWSV(58, 80));
            continue;
        }
-       else if (!tmplen && SvLEN(sv) - SvCUR(sv) > 80) {
+       else if (gimme == G_SCALAR && !tmplen && SvLEN(sv) - SvCUR(sv) > 80) {
            /* try to reclaim a bit of scalar space (only on 1st alloc) */
            if (SvCUR(sv) < 60)
                SvLEN_set(sv, 80);
@@ -1227,19 +1232,14 @@ PP(pp_enter)
 {
     dSP;
     register CONTEXT *cx;
-    I32 gimme;
-
-    /*
-     * We don't just use the GIMME macro here because it assumes there's
-     * already a context, which ain't necessarily so at initial startup.
-     */
+    I32 gimme = OP_GIMME(op, -1);
 
-    if (op->op_flags & OPf_KNOW)
-       gimme = op->op_flags & OPf_LIST;
-    else if (cxstack_ix >= 0)
-       gimme = cxstack[cxstack_ix].blk_gimme;
-    else
-       gimme = G_SCALAR;
+    if (gimme == -1) {
+       if (cxstack_ix >= 0)
+           gimme = cxstack[cxstack_ix].blk_gimme;
+       else
+           gimme = G_SCALAR;
+    }
 
     ENTER;
 
@@ -1306,31 +1306,30 @@ PP(pp_leave)
 
     POPBLOCK(cx,newpm);
 
-    if (op->op_flags & OPf_KNOW)
-       gimme = op->op_flags & OPf_LIST;
-    else if (cxstack_ix >= 0)
-       gimme = cxstack[cxstack_ix].blk_gimme;
-    else
-       gimme = G_SCALAR;
+    gimme = OP_GIMME(op, -1);
+    if (gimme == -1) {
+       if (cxstack_ix >= 0)
+           gimme = cxstack[cxstack_ix].blk_gimme;
+       else
+           gimme = G_SCALAR;
+    }
 
-    if (gimme == G_SCALAR) {
-       if (op->op_private & OPpLEAVE_VOID)
-           SP = newsp;
+    if (gimme == G_VOID)
+       SP = newsp;
+    else if (gimme == G_SCALAR) {
+       MARK = newsp + 1;
+       if (MARK <= SP)
+           if (SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP))
+               *MARK = TOPs;
+           else
+               *MARK = sv_mortalcopy(TOPs);
        else {
-           MARK = newsp + 1;
-           if (MARK <= SP)
-               if (SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP))
-                   *MARK = TOPs;
-               else
-                   *MARK = sv_mortalcopy(TOPs);
-           else {
-               MEXTEND(mark,0);
-               *MARK = &sv_undef;
-           }
-           SP = MARK;
+           MEXTEND(mark,0);
+           *MARK = &sv_undef;
        }
+       SP = MARK;
     }
-    else {
+    else if (gimme == G_ARRAY) {
        for (mark = newsp + 1; mark <= SP; mark++)
            if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP)))
                *mark = sv_mortalcopy(*mark);
@@ -1413,8 +1412,8 @@ PP(pp_subst)
     int force_on_match = 0;
     I32 oldsave = savestack_ix;
 
-    if (pm->op_pmflags & PMf_CONST)    /* known replacement string? */
-       dstr = POPs;
+    /* known replacement string? */
+    dstr = (pm->op_pmflags & PMf_CONST) ? POPs : Nullsv;
     if (op->op_flags & OPf_STACKED)
        TARG = POPs;
     else {
@@ -1483,10 +1482,10 @@ PP(pp_subst)
     once = !(rpm->op_pmflags & PMf_GLOBAL);
 
     /* known replacement string? */
-    c = (rpm->op_pmflags & PMf_CONST) ? SvPV(dstr, clen) : Nullch;
+    c = dstr ? SvPV(dstr, clen) : Nullch;
 
     /* can do inplace substitution? */
-    if (c && clen <= rx->minlen) {
+    if (c && clen <= rx->minlen && safebase) {
        if (! pregexec(rx, s, strend, orig, 0,
                       SvSCREAM(TARG) ? TARG : Nullsv, safebase)) {
            PUSHs(&sv_no);
@@ -1498,8 +1497,6 @@ PP(pp_subst)
            s = SvPV_force(TARG, len);
            goto force_it;
        }
-       if (rx->subbase)        /* oops, no we can't */
-           goto long_way;
        d = s;
        curpm = pm;
        SvSCREAM_off(TARG);     /* disable possible screamer */
@@ -1580,7 +1577,6 @@ PP(pp_subst)
 
     if (pregexec(rx, s, strend, orig, 0,
                 SvSCREAM(TARG) ? TARG : Nullsv, safebase)) {
-    long_way:
        if (force_on_match) {
            force_on_match = 0;
            s = SvPV_force(TARG, len);
@@ -1633,13 +1629,12 @@ PP(pp_subst)
        LEAVE_SCOPE(oldsave);
        RETURN;
     }
-
-    PUSHs(&sv_no);
-    LEAVE_SCOPE(oldsave);
-    RETURN;
+    goto ret_no;
 
 nope:
     ++BmUSEFUL(pm->op_pmshort);
+
+ret_no:
     PUSHs(&sv_no);
     LEAVE_SCOPE(oldsave);
     RETURN;
@@ -1657,18 +1652,19 @@ PP(pp_grepwhile)
     /* All done yet? */
     if (stack_base + *markstack_ptr > sp) {
        I32 items;
+       I32 gimme = GIMME_V;
 
        LEAVE;                                  /* exit outer scope */
        (void)POPMARK;                          /* pop src */
        items = --*markstack_ptr - markstack_ptr[-1];
        (void)POPMARK;                          /* pop dst */
        SP = stack_base + POPMARK;              /* pop original mark */
-       if (GIMME != G_ARRAY) {
+       if (gimme == G_SCALAR) {
            dTARGET;
            XPUSHi(items);
-           RETURN;
        }
-       SP += items;
+       else if (gimme == G_ARRAY)
+           SP += items;
        RETURN;
     }
     else {
@@ -1708,7 +1704,7 @@ PP(pp_leavesub)
        }
        SP = MARK;
     }
-    else {
+    else if (gimme == G_ARRAY) {
        for (MARK = newsp + 1; MARK <= SP; MARK++) {
            if (!SvTEMP(*MARK))
                *MARK = sv_mortalcopy(*MARK);
@@ -1791,7 +1787,9 @@ PP(pp_entersub)
            goto retry;
        }
        /* should call AUTOLOAD now? */
-       if ((autogv = gv_autoload(GvESTASH(gv), GvNAME(gv), GvNAMELEN(gv)))) {
+       if ((autogv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv),
+                                  FALSE)))
+       {
            cv = GvCV(autogv);
            goto retry;
        }
@@ -1801,7 +1799,7 @@ PP(pp_entersub)
        DIE("Undefined subroutine &%s called", SvPVX(subname));
     }
 
-    gimme = GIMME;
+    gimme = GIMME_V;
     if ((op->op_private & OPpENTERSUB_DB) && GvCV(DBsub) && !CvNODEBUG(cv)) {
        SV *oldsv = sv;
        sv = GvSV(DBsub);
@@ -2067,61 +2065,64 @@ PP(pp_method)
     SV* sv;
     SV* ob;
     GV* gv;
-    SV* nm;
+    HV* stash;
+    char* name;
+    char* packname;
+    STRLEN packlen;
 
-    nm = TOPs;
+    name = SvPV(TOPs, na);
     sv = *(stack_base + TOPMARK + 1);
     
-    gv = 0;
     if (SvGMAGICAL(sv))
         mg_get(sv);
     if (SvROK(sv))
        ob = (SV*)SvRV(sv);
     else {
        GV* iogv;
-       char* packname = 0;
-       STRLEN packlen;
 
+       packname = Nullch;
        if (!SvOK(sv) ||
            !(packname = SvPV(sv, packlen)) ||
            !(iogv = gv_fetchpv(packname, FALSE, SVt_PVIO)) ||
            !(ob=(SV*)GvIO(iogv)))
        {
-           char *name = SvPV(nm, na);
-           HV *stash;
-           if (!packname || !isALPHA(*packname))
-DIE("Can't call method \"%s\" without a package or object reference", name);
-           if (!(stash = gv_stashpvn(packname, packlen, FALSE))) {
-               if (gv_stashpvn("UNIVERSAL", 9, FALSE))
-                   stash = gv_stashpvn(packname, packlen, TRUE);
-               else
-                   DIE("Can't call method \"%s\" in empty package \"%s\"",
-                       name, packname);
-           }
-           gv = gv_fetchmethod(stash,name);
-           if (!gv)
-               DIE("Can't locate object method \"%s\" via package \"%s\"",
-                   name, packname);
-           SETs(isGV(gv) ? (SV*)GvCV(gv) : (SV*)gv);
-           RETURN;
+           if (!packname || !isIDFIRST(*packname))
+  DIE("Can't call method \"%s\" without a package or object reference", name);
+           stash = gv_stashpvn(packname, packlen, TRUE);
+           goto fetch;
        }
        *(stack_base + TOPMARK + 1) = sv_2mortal(newRV((SV*)iogv));
     }
 
-    if (!ob || !SvOBJECT(ob)) {
-       char *name = SvPV(nm, na);
+    if (!ob || !SvOBJECT(ob))
        DIE("Can't call method \"%s\" on unblessed reference", name);
-    }
 
-    if (!gv) {         /* nothing cached */
-       char *name = SvPV(nm, na);
-       gv = gv_fetchmethod(SvSTASH(ob),name);
-       if (!gv)
-           DIE("Can't locate object method \"%s\" via package \"%s\"",
-               name, HvNAME(SvSTASH(ob)));
-    }
+    stash = SvSTASH(ob);
+
+  fetch:
+    gv = gv_fetchmethod(stash, name);
+    if (!gv) {
+       char* leaf = name;
+       char* sep = Nullch;
+       char* p;
 
+       for (p = name; *p; p++) {
+           if (*p == '\'')
+               sep = p, leaf = p + 1;
+           else if (*p == ':' && *(p + 1) == ':')
+               sep = p, leaf = p + 2;
+       }
+       if (!sep || ((sep - name) == 5 && strnEQ(name, "SUPER", 5))) {
+           packname = HvNAME(sep ? curcop->cop_stash : stash);
+           packlen = strlen(packname);
+       }
+       else {
+           packname = name;
+           packlen = sep - name;
+       }
+       DIE("Can't locate object method \"%s\" via package \"%.*s\"",
+           leaf, (int)packlen, packname);
+    }
     SETs(isGV(gv) ? (SV*)GvCV(gv) : (SV*)gv);
     RETURN;
 }
-