This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
s/Nullcv/NULL/g
[perl5.git] / gv.c
diff --git a/gv.c b/gv.c
index fd8367c..d06bb8d 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -1,7 +1,7 @@
 /*    gv.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.
@@ -45,7 +45,7 @@ Perl_gv_SVadd(pTHX_ GV *gv)
     if (!gv || SvTYPE((SV*)gv) != SVt_PVGV)
        Perl_croak(aTHX_ "Bad symbol for scalar");
     if (!GvSV(gv))
-       GvSV(gv) = NEWSV(72,0);
+       GvSV(gv) = newSV(0);
     return gv;
 }
 #endif
@@ -73,8 +73,22 @@ 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");
+    dVAR;
+    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)) {
@@ -89,6 +103,7 @@ Perl_gv_IOadd(pTHX_ register GV *gv)
 GV *
 Perl_gv_fetchfile(pTHX_ const char *name)
 {
+    dVAR;
     char smallbuf[256];
     char *tmpbuf;
     STRLEN tmplen;
@@ -122,6 +137,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 +163,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)) {
@@ -142,9 +194,9 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
     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);
+    GvSV(gv) = newSV(0);
 #endif
     GvLINE(gv) = CopLINE(PL_curcop);
     /* XXX Ideally this cast would be replaced with a change to const char*
@@ -152,7 +204,7 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
     GvFILE(gv) = CopFILE(PL_curcop) ? CopFILE(PL_curcop) : (char *) "";
     GvCVGEN(gv) = 0;
     GvEGV(gv) = gv;
-    sv_magic((SV*)gv, (SV*)gv, PERL_MAGIC_glob, Nullch, 0);
+    sv_magic((SV*)gv, (SV*)gv, PERL_MAGIC_glob, NULL, 0);
     GvSTASH(gv) = stash;
     if (stash)
        Perl_sv_add_backref(aTHX_ (SV*)stash, (SV*)gv);
@@ -163,9 +215,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++;
@@ -196,6 +253,7 @@ S_gv_init_sv(pTHX_ GV *gv, I32 sv_type)
     case SVt_NULL:
     case SVt_PVCV:
     case SVt_PVFM:
+    case SVt_PVGV:
        break;
     default:
        (void)GvSVn(gv);
@@ -227,6 +285,7 @@ obtained from the GV with the C<GvCV> macro.
 GV *
 Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
 {
+    dVAR;
     AV* av;
     GV* topgv;
     GV* gv;
@@ -237,7 +296,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
     /* UNIVERSAL methods should be callable without a stash */
     if (!stash) {
        level = -1;  /* probably appropriate */
-       if(!(stash = gv_stashpvn("UNIVERSAL", 9, FALSE)))
+       if(!(stash = gv_stashpvs("UNIVERSAL", FALSE)))
            return 0;
     }
 
@@ -265,15 +324,15 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
                return topgv;
            /* Stale cached entry: junk it */
            SvREFCNT_dec(cv);
-           GvCV(topgv) = cv = Nullcv;
+           GvCV(topgv) = cv = NULL;
            GvCVGEN(topgv) = 0;
        }
        else if (GvCVGEN(topgv) == PL_sub_generation)
            return 0;  /* cache indicates sub doesn't exist */
     }
 
-    gvp = (GV**)hv_fetch(stash, "ISA", 3, FALSE);
-    av = (gvp && (gv = *gvp) && gv != (GV*)&PL_sv_undef) ? GvAV(gv) : Nullav;
+    gvp = (GV**)hv_fetchs(stash, "ISA", FALSE);
+    av = (gvp && (gv = *gvp) && gv != (GV*)&PL_sv_undef) ? GvAV(gv) : NULL;
 
     /* create and re-create @.*::SUPER::ISA on demand */
     if (!av || !SvMAGIC(av)) {
@@ -284,9 +343,9 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
 
            packlen -= 7;
            basestash = gv_stashpvn(hvname, packlen, TRUE);
-           gvp = (GV**)hv_fetch(basestash, "ISA", 3, FALSE);
+           gvp = (GV**)hv_fetchs(basestash, "ISA", FALSE);
            if (gvp && (gv = *gvp) != (GV*)&PL_sv_undef && (av = GvAV(gv))) {
-               gvp = (GV**)hv_fetch(stash, "ISA", 3, TRUE);
+               gvp = (GV**)hv_fetchs(stash, "ISA", TRUE);
                if (!gvp || !(gv = *gvp))
                    Perl_croak(aTHX_ "Cannot create %s::ISA", hvname);
                if (SvTYPE(gv) != SVt_PVGV)
@@ -302,8 +361,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 +379,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_stashpvs("UNIVERSAL", FALSE);
 
-       if ((lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE))) {
+       if (lastchance) {
            if ((gv = gv_fetchmeth(lastchance, name, len,
                                  (level >= 0) ? level + 1 : level - 1)))
            {
@@ -377,40 +436,26 @@ Perl_gv_fetchmeth_autoload(pTHX_ HV *stash, const char *name, STRLEN len, I32 le
        GV **gvp;
 
        if (!stash)
-           return Nullgv;      /* UNIVERSAL::AUTOLOAD could cause trouble */
+           return NULL;        /* UNIVERSAL::AUTOLOAD could cause trouble */
        if (len == S_autolen && strnEQ(name, S_autoload, S_autolen))
-           return Nullgv;
+           return NULL;
        if (!(gv = gv_fetchmeth(stash, S_autoload, S_autolen, FALSE)))
-           return Nullgv;
+           return NULL;
        cv = GvCV(gv);
        if (!(CvROOT(cv) || CvXSUB(cv)))
-           return Nullgv;
+           return NULL;
        /* Have an autoload */
        if (level < 0)  /* Cannot do without a stub */
            gv_fetchmeth(stash, name, len, 0);
        gvp = (GV**)hv_fetch(stash, name, len, (level >= 0));
        if (!gvp)
-           return Nullgv;
+           return NULL;
        return *gvp;
     }
     return gv;
 }
 
 /*
-=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
@@ -441,13 +486,14 @@ C<call_sv> apply equally to these functions.
 GV *
 Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
 {
+    dVAR;
     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 +576,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 +593,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);
@@ -578,13 +625,13 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
     if (!isGV(vargv)) {
        gv_init(vargv, varstash, S_autoload, S_autolen, FALSE);
 #ifdef PERL_DONT_CREATE_GVSV
-       GvSV(vargv) = NEWSV(72,0);
+       GvSV(vargv) = newSV(0);
 #endif
     }
     LEAVE;
     varsv = GvSVn(vargv);
     sv_setpvn(varsv, packname, packname_len);
-    sv_catpvn(varsv, "::", 2);
+    sv_catpvs(varsv, "::");
     sv_catpvn(varsv, name, len);
     SvTAINTED_off(varsv);
     return gv;
@@ -597,7 +644,7 @@ STATIC void
 S_require_errno(pTHX_ GV *gv)
 {
     dVAR;
-    HV* stash = gv_stashpvn("Errno",5,FALSE);
+    HV* stash = gv_stashpvs("Errno", FALSE);
 
     if (!stash || !(gv_fetchmethod(stash, "TIEHASH"))) {
        dSP;
@@ -605,10 +652,10 @@ S_require_errno(pTHX_ GV *gv)
        ENTER;
        save_scalar(gv); /* keep the value of $! */
         Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT,
-                         newSVpvn("Errno",5), Nullsv);
+                         newSVpvs("Errno"), Nullsv);
        LEAVE;
        SPAGAIN;
-       stash = gv_stashpvn("Errno",5,FALSE);
+       stash = gv_stashpvs("Errno", FALSE);
        if (!stash || !(gv_fetchmethod(stash, "TIEHASH")))
            Perl_croak(aTHX_ "Can't use %%! because Errno.pm is not available");
     }
@@ -646,7 +693,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;
@@ -659,7 +706,7 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 create)
     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 +715,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;
 }
 
@@ -706,30 +753,44 @@ GV *
 Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
                       I32 sv_type)
 {
+    dVAR;
     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;
+    register const char *name_cursor;
+    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 & ~GV_NOTQUAL;
+    const char *const name_end = nambeg + full_len;
+    const char *const name_em1 = name_end - 1;
+
+    if (flags & GV_NOTQUAL) {
+       /* Caller promised that there is no stash, so we can skip the check. */
+       len = full_len;
+       goto no_stash;
+    }
 
-    if (*name == '*' && isALPHA(name[1])) /* accidental stringify on a GV? */
+    if (full_len > 2 && *name == '*' && isALPHA(name[1])) {
+       /* accidental stringify on a GV? */
        name++;
+    }
 
-    for (namend = name; *namend; namend++) {
-       if ((*namend == ':' && namend[1] == ':')
-           || (*namend == '\'' && namend[1]))
+    for (name_cursor = name; name_cursor < name_end; name_cursor++) {
+       if ((*name_cursor == ':' && name_cursor < name_em1
+            && name_cursor[1] == ':')
+           || (*name_cursor == '\'' && name_cursor[1]))
        {
            if (!stash)
                stash = PL_defstash;
            if (!stash || !SvREFCNT(stash)) /* symbol table under destruction */
                return Nullgv;
 
-           len = namend - name;
+           len = name_cursor - name;
            if (len > 0) {
-               char smallbuf[256];
+               char smallbuf[128];
                char *tmpbuf;
 
                if (len + 3 < sizeof (smallbuf))
@@ -757,47 +818,57 @@ 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, name_cursor - nambeg, 0);
            }
 
-           if (*namend == ':')
-               namend++;
-           namend++;
-           name = namend;
-           if (!*name)
-               return gv ? gv : (GV*)*hv_fetch(PL_defstash, "main::", 6, TRUE);
+           if (*name_cursor == ':')
+               name_cursor++;
+           name_cursor++;
+           name = name_cursor;
+           if (name == name_end)
+               return gv ? gv : (GV*)*hv_fetchs(PL_defstash, "main::", TRUE);
        }
     }
-    len = namend - name;
+    len = name_cursor - name;
 
     /* No stash in name, so see how we can default */
 
     if (!stash) {
-       if (isIDFIRST_lazy(name)) {
+    no_stash:
+       if (len && isIDFIRST_lazy(name)) {
            bool global = FALSE;
 
-           /* name is always \0 terminated, and initial \0 wouldn't return
-              true from isIDFIRST_lazy, so we know that name[1] is defined  */
-           switch (name[1]) {
-           case '\0':
+           switch (len) {
+           case 1:
                if (*name == '_')
                    global = TRUE;
                break;
-           case 'N':
-               if (strEQ(name, "INC") || strEQ(name, "ENV"))
+           case 3:
+               if ((name[0] == 'I' && name[1] == 'N' && name[2] == 'C')
+                   || (name[0] == 'E' && name[1] == 'N' && name[2] == 'V')
+                   || (name[0] == 'S' && name[1] == 'I' && name[2] == 'G'))
                    global = TRUE;
                break;
-           case 'I':
-               if (strEQ(name, "SIG"))
+           case 4:
+               if (name[0] == 'A' && name[1] == 'R' && name[2] == 'G'
+                   && name[3] == 'V')
                    global = TRUE;
                break;
-           case 'T':
-               if (strEQ(name, "STDIN") || strEQ(name, "STDOUT") ||
-                   strEQ(name, "STDERR"))
+           case 5:
+               if (name[0] == 'S' && name[1] == 'T' && name[2] == 'D'
+                   && name[3] == 'I' && name[4] == 'N')
                    global = TRUE;
                break;
-           case 'R':
-               if (strEQ(name, "ARGV") || strEQ(name, "ARGVOUT"))
+           case 6:
+               if ((name[0] == 'S' && name[1] == 'T' && name[2] == 'D')
+                   &&((name[3] == 'O' && name[4] == 'U' && name[5] == 'T')
+                      ||(name[3] == 'E' && name[4] == 'R' && name[5] == 'R')))
+                   global = TRUE;
+               break;
+           case 7:
+               if (name[0] == 'A' && name[1] == 'R' && name[2] == 'G'
+                   && name[3] == 'V' && name[4] == 'O' && name[5] == 'U'
+                   && name[6] == 'T')
                    global = TRUE;
                break;
            }
@@ -855,7 +926,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 +947,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;
     }
 
@@ -917,7 +990,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
                if (strEQ(name2, "SA")) {
                    AV* const av = GvAVn(gv);
                    GvMULTI_on(gv);
-                   sv_magic((SV*)av, (SV*)gv, PERL_MAGIC_isa, Nullch, 0);
+                   sv_magic((SV*)av, (SV*)gv, PERL_MAGIC_isa, NULL, 0);
                    /* NOTE: No support for tied ISA */
                    if ((add & GV_ADDMULTI) && strEQ(nambeg,"AnyDBM_File::ISA")
                        && AvFILLp(av) == -1)
@@ -956,7 +1029,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
                    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;
@@ -1060,7 +1133,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
        case '-':
        {
            AV* const av = GvAVn(gv);
-            sv_magic((SV*)av, Nullsv, PERL_MAGIC_regdata, Nullch, 0);
+            sv_magic((SV*)av, Nullsv, PERL_MAGIC_regdata, NULL, 0);
            SvREADONLY_on(av);
            goto magicalize;
        }
@@ -1077,7 +1150,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
        case '+':
        {
            AV* const av = GvAVn(gv);
-            sv_magic((SV*)av, (SV*)av, PERL_MAGIC_regdata, Nullch, 0);
+            sv_magic((SV*)av, (SV*)av, PERL_MAGIC_regdata, NULL, 0);
            SvREADONLY_on(av);
            /* FALL THROUGH */
        }
@@ -1134,7 +1207,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);
@@ -1175,61 +1248,37 @@ Perl_gv_fullname4(pTHX_ SV *sv, const GV *gv, const char *prefix, bool keepmain)
 
     if (keepmain || strNE(name, "main")) {
        sv_catpvn(sv,name,namelen);
-       sv_catpvn(sv,"::", 2);
+       sv_catpvs(sv,"::");
     }
     sv_catpvn(sv,GvNAME(gv),GvNAMELEN(gv));
 }
 
 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 *
 Perl_newIO(pTHX)
 {
+    dVAR;
     GV *iogv;
-    IO * const io = (IO*)NEWSV(0,0);
+    IO * const io = (IO*)newSV(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_fetchpvs("FileHandle::", 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_fetchpvs("IO::Handle::", GV_ADD, SVt_PVHV);
     SvSTASH_set(io, (HV*)SvREFCNT_inc(GvHV(iogv)));
     return io;
 }
@@ -1237,6 +1286,7 @@ Perl_newIO(pTHX)
 void
 Perl_gv_check(pTHX_ HV *stash)
 {
+    dVAR;
     register I32 i;
 
     if (!HvARRAY(stash))
@@ -1260,14 +1310,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;
                }
@@ -1288,6 +1338,7 @@ Perl_gv_check(pTHX_ HV *stash)
 GV *
 Perl_newGVgen(pTHX_ const char *pack)
 {
+    dVAR;
     return gv_fetchpv(Perl_form(aTHX_ "%s::_GEN_%ld", pack, (long)PL_gensym++),
                      TRUE, SVt_PVGV);
 }
@@ -1297,6 +1348,7 @@ Perl_newGVgen(pTHX_ const char *pack)
 GP*
 Perl_gp_ref(pTHX_ GP *gp)
 {
+    dVAR;
     if (!gp)
        return (GP*)NULL;
     gp->gp_refcnt++;
@@ -1304,7 +1356,7 @@ Perl_gp_ref(pTHX_ GP *gp)
        if (gp->gp_cvgen) {
            /* multi-named GPs cannot be used for method cache */
            SvREFCNT_dec(gp->gp_cv);
-           gp->gp_cv = Nullcv;
+           gp->gp_cv = NULL;
            gp->gp_cvgen = 0;
        }
        else {
@@ -1318,6 +1370,7 @@ Perl_gp_ref(pTHX_ GP *gp)
 void
 Perl_gp_free(pTHX_ GV *gv)
 {
+    dVAR;
     GP* gp;
 
     if (!gv || !(gp = GvGP(gv)))
@@ -1368,9 +1421,9 @@ Perl_magic_freeovrld(pTHX_ SV *sv, MAGIC *mg)
        int i;
        for (i = 1; i < NofAMmeth; i++) {
            CV * const cv = amtp->table[i];
-           if (cv != Nullcv) {
+           if (cv != NULL) {
                SvREFCNT_dec((SV *) cv);
-               amtp->table[i] = Nullcv;
+               amtp->table[i] = NULL;
            }
        }
     }
@@ -1382,6 +1435,7 @@ Perl_magic_freeovrld(pTHX_ SV *sv, MAGIC *mg)
 bool
 Perl_Gv_AMupdate(pTHX_ HV *stash)
 {
+  dVAR;
   MAGIC* const mg = mg_find((SV*)stash, PERL_MAGIC_overload_table);
   AMT * const amtp = (mg) ? (AMT*)mg->mg_ptr: (AMT *) NULL;
   AMT amt;
@@ -1423,11 +1477,11 @@ Perl_Gv_AMupdate(pTHX_ HV *stash)
        amt.fallback=AMGfallNEVER;
 
     for (i = 1; i < lim; i++)
-       amt.table[i] = Nullcv;
+       amt.table[i] = NULL;
     for (; i < NofAMmeth; i++) {
-       const char *cooky = PL_AMG_names[i];
+       const char * const cooky = PL_AMG_names[i];
        /* Human-readable form, for debugging: */
-       const char *cp = (i >= DESTROY_amg ? cooky : AMG_id2name(i));
+       const char * const cp = (i >= DESTROY_amg ? cooky : AMG_id2name(i));
        const STRLEN l = strlen(cooky);
 
        DEBUG_o( Perl_deb(aTHX_ "Checking overloading of \"%s\" in package \"%.256s\"\n",
@@ -1451,7 +1505,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash)
                /* This is a hack to support autoloading..., while
                   knowing *which* methods were declared as overloaded. */
                /* GvSV contains the name of the method. */
-               GV *ngv = Nullgv;
+               GV *ngv = NULL;
                SV *gvsv = GvSV(gv);
 
                DEBUG_o( Perl_deb(aTHX_ "Resolving method \"%"SVf256\
@@ -1504,11 +1558,12 @@ Perl_Gv_AMupdate(pTHX_ HV *stash)
 CV*
 Perl_gv_handler(pTHX_ HV *stash, I32 id)
 {
+    dVAR;
     MAGIC *mg;
     AMT *amtp;
 
     if (!stash || !HvNAME_get(stash))
-        return Nullcv;
+        return NULL;
     mg = mg_find((SV*)stash, PERL_MAGIC_overload_table);
     if (!mg) {
       do_update:
@@ -1526,7 +1581,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);
@@ -1534,7 +1589,7 @@ Perl_gv_handler(pTHX_ HV *stash, I32 id)
        return ret;
     }
 
-    return Nullcv;
+    return NULL;
 }
 
 
@@ -1611,13 +1666,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 +1682,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);
             }