Bad symbols that are pretending to be dirhandles, should say they
[p5sagit/p5-mst-13.2.git] / gv.c
diff --git a/gv.c b/gv.c
index 39f4b6a..06982bd 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -73,8 +73,21 @@ Perl_gv_HVadd(pTHX_ register GV *gv)
 GV *
 Perl_gv_IOadd(pTHX_ register GV *gv)
 {
-    if (!gv || SvTYPE((SV*)gv) != SVt_PVGV)
-       Perl_croak(aTHX_ "Bad symbol for filehandle");
+    if (!gv || SvTYPE((SV*)gv) != SVt_PVGV) {
+
+        /*
+         * if it walks like a dirhandle, then let's assume that
+         * this is a dirhandle.
+         */
+        const char *fh = PL_op->op_type == OP_READDIR ||
+                         PL_op->op_type ==  OP_TELLDIR ||
+                         PL_op->op_type ==  OP_SEEKDIR ||
+                         PL_op->op_type ==  OP_REWINDDIR ||
+                         PL_op->op_type ==  OP_CLOSEDIR ?
+                         "dirhandle" : "filehandle";
+        Perl_croak(aTHX_ "Bad symbol for %s", fh);
+    }
+
     if (!GvIOp(gv)) {
 #ifdef GV_UNIQUE_CHECK
         if (GvUNIQUE(gv)) {
@@ -101,7 +114,7 @@ Perl_gv_fetchfile(pTHX_ const char *name)
     if (tmplen < sizeof smallbuf)
        tmpbuf = smallbuf;
     else
-       New(603, tmpbuf, tmplen + 1, char);
+       Newx(tmpbuf, tmplen + 1, char);
     /* This is where the debugger's %{"::_<$filename"} hash is created */
     tmpbuf[0] = '_';
     tmpbuf[1] = '<';
@@ -122,6 +135,25 @@ Perl_gv_fetchfile(pTHX_ const char *name)
     return gv;
 }
 
+/*
+=for apidoc gv_const_sv
+
+If C<gv> is a typeglob whose subroutine entry is a constant sub eligible for
+inlining, or C<gv> is a placeholder reference that would be promoted to such
+a typeglob, then returns the value returned by the sub.  Otherwise, returns
+NULL.
+
+=cut
+*/
+
+SV *
+Perl_gv_const_sv(pTHX_ GV *gv)
+{
+    if (SvTYPE(gv) == SVt_PVGV)
+       return cv_const_sv(GvCVu(gv));
+    return SvROK(gv) ? SvRV(gv) : NULL;
+}
+
 void
 Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
 {
@@ -129,6 +161,24 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
     register GP *gp;
     const bool doproto = SvTYPE(gv) > SVt_NULL;
     const char * const proto = (doproto && SvPOK(gv)) ? SvPVX_const(gv) : NULL;
+    SV *const has_constant = doproto && SvROK(gv) ? SvRV(gv) : NULL;
+
+    assert (!(proto && has_constant));
+
+    if (has_constant) {
+       /* The constant has to be a simple scalar type.  */
+       switch (SvTYPE(has_constant)) {
+       case SVt_PVAV:
+       case SVt_PVHV:
+       case SVt_PVCV:
+       case SVt_PVFM:
+       case SVt_PVIO:
+            Perl_croak(aTHX_ "Cannot convert a reference to %s to typeglob",
+                      sv_reftype(has_constant, 0));
+       }
+       SvRV_set(gv, NULL);
+       SvROK_off(gv);
+    }
 
     sv_upgrade((SV*)gv, SVt_PVGV);
     if (SvLEN(gv)) {
@@ -139,10 +189,10 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
        } else
            Safefree(SvPVX_mutable(gv));
     }
-    Newz(602, gp, 1, GP);
+    Newxz(gp, 1, GP);
     GvGP(gv) = gp_ref(gp);
 #ifdef PERL_DONT_CREATE_GVSV
-    GvSV(gv) = 0;
+    GvSV(gv) = NULL;
 #else
     GvSV(gv) = NEWSV(72,0);
 #endif
@@ -163,9 +213,14 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
     if (doproto) {                     /* Replicate part of newSUB here. */
        SvIOK_off(gv);
        ENTER;
-       /* XXX unsafe for threads if eval_owner isn't held */
-       start_subparse(0,0);            /* Create CV in compcv. */
-       GvCV(gv) = PL_compcv;
+       if (has_constant) {
+           /* newCONSTSUB takes ownership of the reference from us.  */
+           GvCV(gv) = newCONSTSUB(stash, name, has_constant);
+       } else {
+           /* XXX unsafe for threads if eval_owner isn't held */
+           (void) start_subparse(0,0); /* Create empty CV in compcv. */
+           GvCV(gv) = PL_compcv;
+       }
        LEAVE;
 
        PL_sub_generation++;
@@ -273,7 +328,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
     }
 
     gvp = (GV**)hv_fetch(stash, "ISA", 3, FALSE);
-    av = (gvp && (gv = *gvp) && gv != (GV*)&PL_sv_undef) ? GvAV(gv) : Nullav;
+    av = (gvp && (gv = *gvp) && gv != (GV*)&PL_sv_undef) ? GvAV(gv) : NULL;
 
     /* create and re-create @.*::SUPER::ISA on demand */
     if (!av || !SvMAGIC(av)) {
@@ -302,8 +357,8 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
        /* NOTE: No support for tied ISA */
        I32 items = AvFILLp(av) + 1;
        while (items--) {
-           SV* sv = *svp++;
-           HV* basestash = gv_stashsv(sv, FALSE);
+           SV* const sv = *svp++;
+           HV* const basestash = gv_stashsv(sv, FALSE);
            if (!basestash) {
                if (ckWARN(WARN_MISC))
                    Perl_warner(aTHX_ packWARN(WARN_MISC), "Can't locate package %"SVf" for @%s::ISA",
@@ -320,9 +375,9 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
     /* if at top level, try UNIVERSAL */
 
     if (level == 0 || level == -1) {
-       HV* lastchance;
+       HV* const lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE);
 
-       if ((lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE))) {
+       if (lastchance) {
            if ((gv = gv_fetchmeth(lastchance, name, len,
                                  (level >= 0) ? level + 1 : level - 1)))
            {
@@ -397,20 +452,6 @@ Perl_gv_fetchmeth_autoload(pTHX_ HV *stash, const char *name, STRLEN len, I32 le
 }
 
 /*
-=for apidoc gv_fetchmethod
-
-See L<gv_fetchmethod_autoload>.
-
-=cut
-*/
-
-GV *
-Perl_gv_fetchmethod(pTHX_ HV *stash, const char *name)
-{
-    return gv_fetchmethod_autoload(stash, name, TRUE);
-}
-
-/*
 =for apidoc gv_fetchmethod_autoload
 
 Returns the glob which contains the subroutine to call to invoke the method
@@ -442,12 +483,12 @@ GV *
 Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
 {
     register const char *nend;
-    const char *nsplit = 0;
+    const char *nsplit = NULL;
     GV* gv;
     HV* ostash = stash;
 
     if (stash && SvTYPE(stash) < SVt_PVHV)
-       stash = Nullhv;
+       stash = NULL;
 
     for (nend = name; *nend; nend++) {
        if (*nend == '\'')
@@ -530,7 +571,7 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
     if (stash) {
        if (SvTYPE(stash) < SVt_PVHV) {
            packname = SvPV_const((SV*)stash, packname_len);
-           stash = Nullhv;
+           stash = NULL;
        }
        else {
            packname = HvNAME_get(stash);
@@ -547,8 +588,9 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
     /*
      * Inheriting AUTOLOAD for non-methods works ... for now.
      */
-    if (ckWARN2(WARN_DEPRECATED, WARN_SYNTAX) && !method &&
-       (GvCVGEN(gv) || GvSTASH(gv) != stash))
+    if (!method && (GvCVGEN(gv) || GvSTASH(gv) != stash)
+       && ckWARN2(WARN_DEPRECATED, WARN_SYNTAX)
+    )
        Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
          "Use of inherited AUTOLOAD for non-method %s::%.*s() is deprecated",
             packname, (int)len, name);
@@ -646,7 +688,7 @@ package does not exist then NULL is returned.
 HV*
 Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 create)
 {
-    char smallbuf[256];
+    char smallbuf[128];
     char *tmpbuf;
     HV *stash;
     GV *tmpgv;
@@ -654,12 +696,12 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 create)
     if (namelen + 3 < sizeof smallbuf)
        tmpbuf = smallbuf;
     else
-       New(606, tmpbuf, namelen + 3, char);
+       Newx(tmpbuf, namelen + 3, char);
     Copy(name,tmpbuf,namelen,char);
     tmpbuf[namelen++] = ':';
     tmpbuf[namelen++] = ':';
     tmpbuf[namelen] = '\0';
-    tmpgv = gv_fetchpv(tmpbuf, create, SVt_PVHV);
+    tmpgv = gv_fetchpvn_flags(tmpbuf, namelen, create, SVt_PVHV);
     if (tmpbuf != smallbuf)
        Safefree(tmpbuf);
     if (!tmpgv)
@@ -668,7 +710,7 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 create)
        GvHV(tmpgv) = newHV();
     stash = GvHV(tmpgv);
     if (!HvNAME_get(stash))
-       Perl_hv_name_set(aTHX_ stash, name, namelen, 0);
+       hv_name_set(stash, name, namelen, 0);
     return stash;
 }
 
@@ -707,13 +749,16 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
                       I32 sv_type)
 {
     register const char *name = nambeg;
-    register GV *gv = 0;
+    register GV *gv = NULL;
     GV**gvp;
     I32 len;
     register const char *namend;
-    HV *stash = 0;
-    const I32 add = flags & ~SVf_UTF8;
-    (void)full_len;
+    HV *stash = NULL;
+    const I32 no_init = flags & (GV_NOADD_NOINIT | GV_NOINIT);
+    const I32 no_expand = flags & GV_NOEXPAND;
+    const I32 add = flags & ~SVf_UTF8 & ~GV_NOADD_NOINIT & ~GV_NOEXPAND;
+
+    PERL_UNUSED_ARG(full_len);
 
     if (*name == '*' && isALPHA(name[1])) /* accidental stringify on a GV? */
        name++;
@@ -729,13 +774,13 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
 
            len = namend - name;
            if (len > 0) {
-               char smallbuf[256];
+               char smallbuf[128];
                char *tmpbuf;
 
                if (len + 3 < sizeof (smallbuf))
                    tmpbuf = smallbuf;
                else
-                   New(601, tmpbuf, len+3, char);
+                   Newx(tmpbuf, len+3, char);
                Copy(name, tmpbuf, len, char);
                tmpbuf[len++] = ':';
                tmpbuf[len++] = ':';
@@ -757,7 +802,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
                    stash = GvHV(gv) = newHV();
 
                if (!HvNAME_get(stash))
-                   Perl_hv_name_set(aTHX_ stash, nambeg, namend - nambeg, 0);
+                   hv_name_set(stash, nambeg, namend - nambeg, 0);
            }
 
            if (*namend == ':')
@@ -855,7 +900,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
            if (USE_UTF8_IN_NAMES)
                SvUTF8_on(err);
            qerror(err);
-           stash = GvHV(gv_fetchpv("<none>::", GV_ADDMULTI, SVt_PVHV));
+           stash = GvHV(gv_fetchpvn_flags("<none>::", 8, GV_ADDMULTI, SVt_PVHV));
        }
        else
            return Nullgv;
@@ -876,7 +921,9 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
                require_errno(gv);
        }
        return gv;
-    } else if (add & GV_NOINIT) {
+    } else if (no_init) {
+       return gv;
+    } else if (no_expand && SvROK(gv)) {
        return gv;
     }
 
@@ -948,15 +995,15 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
                    HV *hv;
                    I32 i;
                    if (!PL_psig_ptr) {
-                       Newz(73, PL_psig_ptr,  SIG_SIZE, SV*);
-                       Newz(73, PL_psig_name, SIG_SIZE, SV*);
-                       Newz(73, PL_psig_pend, SIG_SIZE, int);
+                       Newxz(PL_psig_ptr,  SIG_SIZE, SV*);
+                       Newxz(PL_psig_name, SIG_SIZE, SV*);
+                       Newxz(PL_psig_pend, SIG_SIZE, int);
                    }
                    GvMULTI_on(gv);
                    hv = GvHVn(gv);
                    hv_magic(hv, Nullgv, PERL_MAGIC_sig);
                    for (i = 1; i < SIG_SIZE; i++) {
-                       SV ** const init = hv_fetch(hv, PL_sig_name[i], strlen(PL_sig_name[i]), 1);
+                       SV * const * const init = hv_fetch(hv, PL_sig_name[i], strlen(PL_sig_name[i]), 1);
                        if (init)
                            sv_setsv(*init, &PL_sv_undef);
                        PL_psig_ptr[i] = 0;
@@ -1134,7 +1181,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
        {
            SV * const sv = GvSVn(gv);
            if (!sv_derived_from(PL_patchlevel, "version"))
-               (void *)upg_version(PL_patchlevel);
+               upg_version(PL_patchlevel);
            GvSV(gv) = vnumify(PL_patchlevel);
            SvREADONLY_on(GvSV(gv));
            SvREFCNT_dec(sv);
@@ -1181,38 +1228,10 @@ Perl_gv_fullname4(pTHX_ SV *sv, const GV *gv, const char *prefix, bool keepmain)
 }
 
 void
-Perl_gv_fullname3(pTHX_ SV *sv, const GV *gv, const char *prefix)
-{
-    gv_fullname4(sv, gv, prefix, TRUE);
-}
-
-void
 Perl_gv_efullname4(pTHX_ SV *sv, const GV *gv, const char *prefix, bool keepmain)
 {
-    const GV *egv = GvEGV(gv);
-    if (!egv)
-       egv = gv;
-    gv_fullname4(sv, egv, prefix, keepmain);
-}
-
-void
-Perl_gv_efullname3(pTHX_ SV *sv, const GV *gv, const char *prefix)
-{
-    gv_efullname4(sv, gv, prefix, TRUE);
-}
-
-/* compatibility with versions <= 5.003. */
-void
-Perl_gv_fullname(pTHX_ SV *sv, const GV *gv)
-{
-    gv_fullname3(sv, gv, sv == (const SV*)gv ? "*" : "");
-}
-
-/* compatibility with versions <= 5.003. */
-void
-Perl_gv_efullname(pTHX_ SV *sv, const GV *gv)
-{
-    gv_efullname3(sv, gv, sv == (const SV*)gv ? "*" : "");
+    const GV * const egv = GvEGV(gv);
+    gv_fullname4(sv, egv ? egv : gv, prefix, keepmain);
 }
 
 IO *
@@ -1222,14 +1241,17 @@ Perl_newIO(pTHX)
     IO * const io = (IO*)NEWSV(0,0);
 
     sv_upgrade((SV *)io,SVt_PVIO);
-    SvREFCNT(io) = 1;
+    /* This used to read SvREFCNT(io) = 1;
+       It's not clear why the reference count needed an explicit reset. NWC
+    */
+    assert (SvREFCNT(io) == 1);
     SvOBJECT_on(io);
     /* Clear the stashcache because a new IO could overrule a package name */
     hv_clear(PL_stashcache);
-    iogv = gv_fetchpv("FileHandle::", FALSE, SVt_PVHV);
+    iogv = gv_fetchpvn_flags("FileHandle::", 12, 0, SVt_PVHV);
     /* unless exists($main::{FileHandle}) and defined(%main::FileHandle::) */
     if (!(iogv && GvHV(iogv) && HvARRAY(GvHV(iogv))))
-      iogv = gv_fetchpv("IO::Handle::", TRUE, SVt_PVHV);
+      iogv = gv_fetchpvn_flags("IO::Handle::", 12, TRUE, SVt_PVHV);
     SvSTASH_set(io, (HV*)SvREFCNT_inc(GvHV(iogv)));
     return io;
 }
@@ -1260,14 +1282,14 @@ Perl_gv_check(pTHX_ HV *stash)
                file = GvFILE(gv);
                /* performance hack: if filename is absolute and it's a standard
                 * module, don't bother warning */
-               if (file
-                   && PERL_FILE_IS_ABSOLUTE(file)
 #ifdef MACOS_TRADITIONAL
-                   && (instr(file, ":lib:")
+#   define LIB_COMPONENT ":lib:"
 #else
-                   && (instr(file, "/lib/")
+#   define LIB_COMPONENT "/lib/"
 #endif
-                   || instr(file, ".pm")))
+               if (file
+                   && PERL_FILE_IS_ABSOLUTE(file)
+                   && (instr(file, LIB_COMPONENT) || instr(file, ".pm")))
                {
                    continue;
                }
@@ -1526,7 +1548,7 @@ Perl_gv_handler(pTHX_ HV *stash, I32 id)
               "Inherited AUTOLOAD for a non-method deprecated", since
               our caller is going through a function call, not a method call.
               So return the CV for AUTOLOAD, setting $AUTOLOAD. */
-           GV *gv = gv_fetchmethod(stash, PL_AMG_names[id]);
+           GV * const gv = gv_fetchmethod(stash, PL_AMG_names[id]);
 
            if (gv && GvCV(gv))
                return GvCV(gv);
@@ -1611,13 +1633,13 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
                  * SV* ref causes confusion with the interpreter variable of
                  * the same name
                  */
-            SV* tmpRef=SvRV(left);
+            SV* const tmpRef=SvRV(left);
             if (!SvROK(tmpRef) && SvTYPE(tmpRef) <= SVt_PVMG) {
                /*
                 * Just to be extra cautious.  Maybe in some
                 * additional cases sv_setsv is safe, too.
                 */
-               SV* newref = newSVsv(tmpRef);
+               SV* const newref = newSVsv(tmpRef);
                SvOBJECT_on(newref);
                SvSTASH_set(newref, (HV*)SvREFCNT_inc(SvSTASH(tmpRef)));
                return newref;
@@ -1627,13 +1649,13 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
         case abs_amg:
           if ((cvp[off1=lt_amg] || cvp[off1=ncmp_amg])
               && ((cv = cvp[off=neg_amg]) || (cv = cvp[off=subtr_amg]))) {
-            SV* nullsv=sv_2mortal(newSViv(0));
+            SV* const nullsv=sv_2mortal(newSViv(0));
             if (off1==lt_amg) {
-              SV* lessp = amagic_call(left,nullsv,
+              SV* const lessp = amagic_call(left,nullsv,
                                       lt_amg,AMGf_noright);
               logic = SvTRUE(lessp);
             } else {
-              SV* lessp = amagic_call(left,nullsv,
+              SV* const lessp = amagic_call(left,nullsv,
                                       ncmp_amg,AMGf_noright);
               logic = (SvNV(lessp) < 0);
             }
@@ -1897,7 +1919,7 @@ bool
 Perl_is_gv_magical_sv(pTHX_ SV *name, U32 flags)
 {
     STRLEN len;
-    const char *temp = SvPV_const(name, len);
+    const char * const temp = SvPV_const(name, len);
     return is_gv_magical(temp, len, flags);
 }