Re: [patch] optimized constant subs are cool, teach B::Concise about them
[p5sagit/p5-mst-13.2.git] / pp.c
diff --git a/pp.c b/pp.c
index b260ff1..3221277 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -1,7 +1,7 @@
 /*    pp.c
  *
  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -191,10 +191,10 @@ PP(pp_rv2gv)
            if ((PL_op->op_flags & OPf_SPECIAL) &&
                !(PL_op->op_flags & OPf_MOD))
            {
-               SV * const temp = (SV*)gv_fetchsv(sv, FALSE, SVt_PVGV);
+               SV * const temp = (SV*)gv_fetchsv(sv, 0, SVt_PVGV);
                if (!temp
                    && (!is_gv_magical_sv(sv,0)
-                       || !(sv = (SV*)gv_fetchsv(sv, TRUE, SVt_PVGV)))) {
+                       || !(sv = (SV*)gv_fetchsv(sv, GV_ADD, SVt_PVGV)))) {
                    RETSETUNDEF;
                }
                sv = temp;
@@ -202,7 +202,14 @@ PP(pp_rv2gv)
            else {
                if (PL_op->op_private & HINT_STRICT_REFS)
                    DIE(aTHX_ PL_no_symref_sv, sv, "a symbol");
-               sv = (SV*)gv_fetchsv(sv, TRUE, SVt_PVGV);
+               if ((PL_op->op_private & (OPpLVAL_INTRO|OPpDONT_INIT_GV))
+                   == OPpDONT_INIT_GV) {
+                   /* We are the target of a coderef assignment.  Return
+                      the scalar unchanged, and let pp_sasssign deal with
+                      things.  */
+                   RETURN;
+               }
+               sv = (SV*)gv_fetchsv(sv, GV_ADD, SVt_PVGV);
            }
        }
     }
@@ -214,7 +221,7 @@ PP(pp_rv2gv)
 
 PP(pp_rv2sv)
 {
-    GV *gv = Nullgv;
+    GV *gv = NULL;
     dSP; dTOPss;
 
     if (SvROK(sv)) {
@@ -254,16 +261,16 @@ PP(pp_rv2sv)
            if ((PL_op->op_flags & OPf_SPECIAL) &&
                !(PL_op->op_flags & OPf_MOD))
            {
-               gv = (GV*)gv_fetchsv(sv, FALSE, SVt_PV);
+               gv = (GV*)gv_fetchsv(sv, 0, SVt_PV);
                if (!gv
                    && (!is_gv_magical_sv(sv, 0)
-                       || !(gv = (GV*)gv_fetchsv(sv, TRUE, SVt_PV))))
+                       || !(gv = (GV*)gv_fetchsv(sv, GV_ADD, SVt_PV))))
                {
                    RETSETUNDEF;
                }
            }
            else {
-               gv = (GV*)gv_fetchsv(sv, TRUE, SVt_PV);
+               gv = (GV*)gv_fetchsv(sv, GV_ADD, SVt_PV);
            }
        }
        sv = GvSVn(gv);
@@ -292,7 +299,7 @@ PP(pp_av2arylen)
     if (!*sv) {
        *sv = NEWSV(0,0);
        sv_upgrade(*sv, SVt_PVMG);
-       sv_magic(*sv, (SV*)av, PERL_MAGIC_arylen, Nullch, 0);
+       sv_magic(*sv, (SV*)av, PERL_MAGIC_arylen, NULL, 0);
     }
     SETs(*sv);
     RETURN;
@@ -305,7 +312,7 @@ PP(pp_pos)
     if (PL_op->op_flags & OPf_MOD || LVRET) {
        if (SvTYPE(TARG) < SVt_PVLV) {
            sv_upgrade(TARG, SVt_PVLV);
-           sv_magic(TARG, Nullsv, PERL_MAGIC_pos, Nullch, 0);
+           sv_magic(TARG, NULL, PERL_MAGIC_pos, NULL, 0);
        }
 
        LvTYPE(TARG) = '.';
@@ -337,10 +344,15 @@ PP(pp_rv2cv)
     dSP;
     GV *gv;
     HV *stash;
-
+    const I32 flags = (PL_op->op_flags & OPf_SPECIAL)
+       ? 0
+       : ((PL_op->op_private & (OPpLVAL_INTRO|OPpMAY_RETURN_CONSTANT)) == OPpMAY_RETURN_CONSTANT)
+           ? GV_ADD|GV_NOEXPAND
+           : GV_ADD;
     /* We usually try to add a non-existent subroutine in case of AUTOLOAD. */
     /* (But not in defined().) */
-    CV *cv = sv_2cv(TOPs, &stash, &gv, !(PL_op->op_flags & OPf_SPECIAL));
+
+    CV *cv = sv_2cv(TOPs, &stash, &gv, flags);
     if (cv) {
        if (CvCLONE(cv))
            cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
@@ -351,6 +363,9 @@ PP(pp_rv2cv)
                DIE(aTHX_ "Can't modify non-lvalue subroutine call");
        }
     }
+    else if ((flags == (GV_ADD|GV_NOEXPAND)) && gv && SvROK(gv)) {
+       cv = (CV*)gv;
+    }    
     else
        cv = (CV*)&PL_sv_undef;
     SETs((SV*)cv);
@@ -363,9 +378,8 @@ PP(pp_prototype)
     CV *cv;
     HV *stash;
     GV *gv;
-    SV *ret;
+    SV *ret = &PL_sv_undef;
 
-    ret = &PL_sv_undef;
     if (SvPOK(TOPs) && SvCUR(TOPs) >= 7) {
        const char * const s = SvPVX_const(TOPs);
        if (strnEQ(s, "CORE::", 6)) {
@@ -416,7 +430,7 @@ PP(pp_prototype)
            }
        }
     }
-    cv = sv_2cv(TOPs, &stash, &gv, FALSE);
+    cv = sv_2cv(TOPs, &stash, &gv, 0);
     if (cv && SvPOK(cv))
        ret = sv_2mortal(newSVpvn(SvPVX_const(cv), SvCUR(cv)));
   set:
@@ -541,9 +555,9 @@ PP(pp_gelem)
     SV *sv = POPs;
     const char * const elem = SvPV_nolen_const(sv);
     GV * const gv = (GV*)POPs;
-    SV * tmpRef = Nullsv;
+    SV * tmpRef = NULL;
 
-    sv = Nullsv;
+    sv = NULL;
     if (elem) {
        /* elem will always be NUL terminated.  */
        const char * const second_letter = elem + 1;
@@ -584,7 +598,8 @@ PP(pp_gelem)
            break;
        case 'P':
            if (strEQ(second_letter, "ACKAGE")) {
-               const HEK *hek = HvNAME_HEK(GvSTASH(gv));
+               const HV * const stash = GvSTASH(gv);
+               const HEK * const hek = stash ? HvNAME_HEK(stash) : NULL;
                sv = hek ? newSVhek(hek) : newSVpvn("__ANON__", 8);
            }
            break;
@@ -665,7 +680,7 @@ PP(pp_study)
 
     SvSCREAM_on(sv);
     /* piggyback on m//g magic */
-    sv_magic(sv, Nullsv, PERL_MAGIC_regex_global, Nullch, 0);
+    sv_magic(sv, NULL, PERL_MAGIC_regex_global, NULL, 0);
     RETPUSHYES;
 }
 
@@ -780,7 +795,7 @@ PP(pp_undef)
     default:
        if (SvTYPE(sv) >= SVt_PV && SvPVX_const(sv) && SvLEN(sv)) {
            SvPV_free(sv);
-           SvPV_set(sv, Nullch);
+           SvPV_set(sv, NULL);
            SvLEN_set(sv, 0);
        }
        SvOK_off(sv);
@@ -1034,7 +1049,7 @@ PP(pp_multiply)
            } else if (!ahigh && !bhigh) {
                /* eg 32 bit is at most 0xFFFF * 0xFFFF == 0xFFFE0001
                   so the unsigned multiply cannot overflow.  */
-               UV product = alow * blow;
+               const UV product = alow * blow;
                if (auvok == buvok) {
                    /* -ve * -ve or +ve * +ve gives a +ve result.  */
                    SP--;
@@ -1435,7 +1450,7 @@ PP(pp_repeat)
            if (count < 1)
                SvCUR_set(TARG, 0);
            else {
-               STRLEN max = (UV)count * len;
+               const STRLEN max = (UV)count * len;
                if (len > ((MEM_SIZE)~0)/count)
                     Perl_croak(aTHX_ oom_string_extend);
                MEM_WRAP_CHECK_1(max, char, oom_string_extend);
@@ -1588,11 +1603,11 @@ PP(pp_left_shift)
     {
       const IV shift = POPi;
       if (PL_op->op_private & HINT_INTEGER) {
-       IV i = TOPi;
+       const IV i = TOPi;
        SETi(i << shift);
       }
       else {
-       UV u = TOPu;
+       const UV u = TOPu;
        SETu(u << shift);
       }
       RETURN;
@@ -2274,7 +2289,7 @@ PP(pp_negate)
            SETn(-SvNV(sv));
        else if (SvPOKp(sv)) {
            STRLEN len;
-           const char *s = SvPV_const(sv, len);
+           const char * const s = SvPV_const(sv, len);
            if (isIDFIRST(*s)) {
                sv_setpvn(TARG, "-", 1);
                sv_catsv(TARG, sv);
@@ -2903,7 +2918,7 @@ PP(pp_substr)
     const char *tmps;
     const I32 arybase = PL_curcop->cop_arybase;
     SV *repl_sv = NULL;
-    const char *repl = 0;
+    const char *repl = NULL;
     STRLEN repl_len;
     const int num_args = PL_op->op_private & 7;
     bool repl_need_utf8_upgrade = FALSE;
@@ -3037,7 +3052,7 @@ PP(pp_substr)
 
            if (SvTYPE(TARG) < SVt_PVLV) {
                sv_upgrade(TARG, SVt_PVLV);
-               sv_magic(TARG, Nullsv, PERL_MAGIC_substr, Nullch, 0);
+               sv_magic(TARG, NULL, PERL_MAGIC_substr, NULL, 0);
            }
            else
                SvOK_off(TARG);
@@ -3071,7 +3086,7 @@ PP(pp_vec)
            TARG = sv_newmortal();
        if (SvTYPE(TARG) < SVt_PVLV) {
            sv_upgrade(TARG, SVt_PVLV);
-           sv_magic(TARG, Nullsv, PERL_MAGIC_vec, Nullch, 0);
+           sv_magic(TARG, NULL, PERL_MAGIC_vec, NULL, 0);
        }
        LvTYPE(TARG) = 'v';
        if (LvTARG(TARG) != src) {
@@ -3093,7 +3108,7 @@ PP(pp_index)
     dSP; dTARGET;
     SV *big;
     SV *little;
-    SV *temp = Nullsv;
+    SV *temp = NULL;
     I32 offset;
     I32 retval;
     const char *tmps;
@@ -3156,7 +3171,7 @@ PP(pp_rindex)
     dSP; dTARGET;
     SV *big;
     SV *little;
-    SV *temp = Nullsv;
+    SV *temp = NULL;
     STRLEN blen;
     STRLEN llen;
     I32 offset;
@@ -3809,7 +3824,7 @@ PP(pp_exists)
     if (PL_op->op_private & OPpEXISTS_SUB) {
        GV *gv;
        SV * const sv = POPs;
-       CV * const cv = sv_2cv(sv, &hv, &gv, FALSE);
+       CV * const cv = sv_2cv(sv, &hv, &gv, 0);
        if (cv)
            RETPUSHYES;
        if (gv && isGV(gv) && GvCV(gv) && !GvCVGEN(gv))
@@ -4003,7 +4018,7 @@ PP(pp_splice)
     I32 newlen;
     I32 after;
     I32 diff;
-    SV **tmparyval = 0;
+    SV **tmparyval = NULL;
     const MAGIC * const mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied);
 
     if (mg) {