Update copyrights for files modified in 2006
[p5sagit/p5-mst-13.2.git] / pp_hot.c
index f9a0a9f..7b12cec 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1,7 +1,7 @@
 /*    pp_hot.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.
@@ -116,6 +116,59 @@ PP(pp_sassign)
     }
     if (PL_tainting && PL_tainted && !SvTAINTED(left))
        TAINT_NOT;
+    if (PL_op->op_private & OPpASSIGN_CV_TO_GV) {
+       SV *cv = SvRV(left);
+       const U32 cv_type = SvTYPE(cv);
+       const U32 gv_type = SvTYPE(right);
+       bool got_coderef = cv_type == SVt_PVCV || cv_type == SVt_PVFM;
+
+       if (!got_coderef) {
+           assert(SvROK(cv));
+       }
+
+       /* Can do the optimisation if right (LVAUE) is not a typeglob,
+          left (RVALUE) is a reference to something, and we're in void
+          context. */
+       if (!got_coderef && gv_type != SVt_PVGV && GIMME_V == G_VOID) {
+           /* Is the target symbol table currently empty?  */
+           GV *gv = gv_fetchsv(right, GV_NOINIT, SVt_PVGV);
+           if (SvTYPE(gv) != SVt_PVGV && !SvOK(gv)) {
+               /* Good. Create a new proxy constant subroutine in the target.
+                  The gv becomes a(nother) reference to the constant.  */
+               SV *const value = SvRV(cv);
+
+               SvUPGRADE((SV *)gv, SVt_RV);
+               SvROK_on(gv);
+               SvRV_set(gv, value);
+               SvREFCNT_inc(value);
+               SETs(right);
+               RETURN;
+           }
+       }
+
+       /* Need to fix things up.  */
+       if (gv_type != SVt_PVGV) {
+           /* Need to fix GV.  */
+           right = (SV*)gv_fetchsv(right, GV_ADD, SVt_PVGV);
+       }
+
+       if (!got_coderef) {
+           /* We've been returned a constant rather than a full subroutine,
+              but they expect a subroutine reference to apply.  */
+           ENTER;
+           SvREFCNT_inc(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
+              donated to the GV that we're about to assign to.
+           */
+           SvRV_set(left, (SV *)newCONSTSUB(GvSTASH(right), NULL,
+                                                SvRV(cv)));
+           SvREFCNT_dec(cv);
+           LEAVE;
+       }
+
+    }
     SvSetMagicSV(right, left);
     SETs(right);
     RETURN;
@@ -555,7 +608,7 @@ PP(pp_add)
 PP(pp_aelemfast)
 {
     dSP;
-    AV *av = PL_op->op_flags & OPf_SPECIAL ?
+    AV * const av = PL_op->op_flags & OPf_SPECIAL ?
                (AV*)PAD_SV(PL_op->op_targ) : GvAV(cGVOP_gv);
     const U32 lval = PL_op->op_flags & OPf_MOD;
     SV** const svp = av_fetch(av, PL_op->op_private, lval);
@@ -983,7 +1036,7 @@ PP(pp_aassign)
     I32 i;
     int magic;
     int duplicates = 0;
-    SV **firsthashrelem = 0;   /* "= 0" keeps gcc 2.95 quiet  */
+    SV **firsthashrelem = NULL;        /* "= 0" keeps gcc 2.95 quiet  */
 
 
     PL_delaymagic = DM_DELAY;          /* catch simultaneous items */
@@ -1258,7 +1311,7 @@ PP(pp_match)
     if ((global = dynpm->op_pmflags & PMf_GLOBAL)) {
        rx->startp[0] = -1;
        if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
-           MAGIC* mg = mg_find(TARG, PERL_MAGIC_regex_global);
+           MAGIC* const mg = mg_find(TARG, PERL_MAGIC_regex_global);
            if (mg && mg->mg_len >= 0) {
                if (!(rx->reganch & ROPT_GPOS_SEEN))
                    rx->endp[0] = rx->startp[0] = mg->mg_len;
@@ -1366,9 +1419,11 @@ play_it_again:
     }
     else {
        if (global) {
-           MAGIC* mg = 0;
+           MAGIC* mg;
            if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG))
                mg = mg_find(TARG, PERL_MAGIC_regex_global);
+           else
+               mg = NULL;
            if (!mg) {
                sv_magic(TARG, (SV*)0, PERL_MAGIC_regex_global, Nullch, 0);
                mg = mg_find(TARG, PERL_MAGIC_regex_global);
@@ -1632,7 +1687,7 @@ Perl_do_readline(pTHX)
                continue;
            }
        } else if (SvUTF8(sv)) { /* OP_READLINE, OP_RCATLINE */
-            const U8 *s = (const U8*)SvPVX_const(sv) + offset;
+            const U8 * const s = (const U8*)SvPVX_const(sv) + offset;
             const STRLEN len = SvCUR(sv) - offset;
             const U8 *f;
             
@@ -1686,8 +1741,8 @@ PP(pp_helem)
     dSP;
     HE* he;
     SV **svp;
-    SV *keysv = POPs;
-    HV *hv = (HV*)POPs;
+    SV * const keysv = POPs;
+    HV * const hv = (HV*)POPs;
     const U32 lval = PL_op->op_flags & OPf_MOD || LVRET;
     const U32 defer = PL_op->op_private & OPpLVAL_DEFER;
     SV *sv;
@@ -1894,7 +1949,7 @@ PP(pp_iter)
            RETPUSHNO;
 
        if (SvMAGICAL(av) || AvREIFY(av)) {
-           SV ** const svp = av_fetch(av, --cx->blk_loop.iterix, FALSE);
+           SV * const * const svp = av_fetch(av, --cx->blk_loop.iterix, FALSE);
            sv = svp ? *svp : Nullsv;
        }
        else {
@@ -1907,7 +1962,7 @@ PP(pp_iter)
            RETPUSHNO;
 
        if (SvMAGICAL(av) || AvREIFY(av)) {
-           SV ** const svp = av_fetch(av, ++cx->blk_loop.iterix, FALSE);
+           SV * const * const svp = av_fetch(av, ++cx->blk_loop.iterix, FALSE);
            sv = svp ? *svp : Nullsv;
        }
        else {
@@ -2610,7 +2665,6 @@ PP(pp_entersub)
 {
     dVAR; dSP; dPOPss;
     GV *gv;
-    HV *stash;
     register CV *cv;
     register PERL_CONTEXT *cx;
     I32 gimme;
@@ -2621,8 +2675,10 @@ PP(pp_entersub)
     switch (SvTYPE(sv)) {
        /* This is overwhelming the most common case:  */
     case SVt_PVGV:
-       if (!(cv = GvCVu((GV*)sv)))
-           cv = sv_2cv(sv, &stash, &gv, FALSE);
+       if (!(cv = GvCVu((GV*)sv))) {
+           HV *stash;
+           cv = sv_2cv(sv, &stash, &gv, 0);
+       }
        if (!cv) {
            ENTER;
            SAVETMPS;
@@ -2676,7 +2732,35 @@ PP(pp_entersub)
 
   retry:
     if (!CvROOT(cv) && !CvXSUB(cv)) {
-       goto fooey;
+       GV* autogv;
+       SV* sub_name;
+
+       /* anonymous or undef'd function leaves us no recourse */
+       if (CvANON(cv) || !(gv = CvGV(cv)))
+           DIE(aTHX_ "Undefined subroutine called");
+
+       /* autoloaded stub? */
+       if (cv != GvCV(gv)) {
+           cv = GvCV(gv);
+       }
+       /* should call AUTOLOAD now? */
+       else {
+try_autoload:
+           if ((autogv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv),
+                                  FALSE)))
+           {
+               cv = GvCV(autogv);
+           }
+           /* sorry */
+           else {
+               sub_name = sv_newmortal();
+               gv_efullname3(sub_name, gv, Nullch);
+               DIE(aTHX_ "Undefined subroutine &%"SVf" called", sub_name);
+           }
+       }
+       if (!cv)
+           DIE(aTHX_ "Not a CODE reference");
+       goto retry;
     }
 
     gimme = GIMME_V;
@@ -2821,43 +2905,6 @@ PP(pp_entersub)
        LEAVE;
        return NORMAL;
     }
-
-    /*NOTREACHED*/
-    assert (0); /* Cannot get here.  */
-    /* This is deliberately moved here as spaghetti code to keep it out of the
-       hot path.  */
-    {
-       GV* autogv;
-       SV* sub_name;
-
-      fooey:
-       /* anonymous or undef'd function leaves us no recourse */
-       if (CvANON(cv) || !(gv = CvGV(cv)))
-           DIE(aTHX_ "Undefined subroutine called");
-
-       /* autoloaded stub? */
-       if (cv != GvCV(gv)) {
-           cv = GvCV(gv);
-       }
-       /* should call AUTOLOAD now? */
-       else {
-try_autoload:
-           if ((autogv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv),
-                                  FALSE)))
-           {
-               cv = GvCV(autogv);
-           }
-           /* sorry */
-           else {
-               sub_name = sv_newmortal();
-               gv_efullname3(sub_name, gv, Nullch);
-               DIE(aTHX_ "Undefined subroutine &%"SVf" called", sub_name);
-           }
-       }
-       if (!cv)
-           DIE(aTHX_ "Not a CODE reference");
-       goto retry;
-    }
 }
 
 void