This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Lexical use open ... support:
[perl5.git] / gv.c
diff --git a/gv.c b/gv.c
index 0688fef..86d8e79 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -1,6 +1,6 @@
 /*    gv.c
  *
- *    Copyright (c) 1991-1999, Larry Wall
+ *    Copyright (c) 1991-2000, Larry Wall
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -59,6 +59,9 @@ Perl_gv_fetchfile(pTHX_ const char *name)
     STRLEN tmplen;
     GV *gv;
 
+    if (!PL_defstash)
+       return Nullgv;
+
     tmplen = strlen(name) + 2;
     if (tmplen < sizeof smallbuf)
        tmpbuf = smallbuf;
@@ -68,15 +71,14 @@ Perl_gv_fetchfile(pTHX_ const char *name)
     tmpbuf[1] = '<';
     strcpy(tmpbuf + 2, name);
     gv = *(GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, TRUE);
-    if (!isGV(gv))
+    if (!isGV(gv)) {
        gv_init(gv, PL_defstash, tmpbuf, tmplen, FALSE);
+       sv_setpv(GvSV(gv), name);
+       if (PERLDB_LINE)
+           hv_magic(GvHVn(gv_AVadd(gv)), Nullgv, 'L');
+    }
     if (tmpbuf != smallbuf)
        Safefree(tmpbuf);
-    sv_setpv(GvSV(gv), name);
-    if (*name == '/' && (instr(name, "/lib/") || instr(name, ".pm")))
-       GvMULTI_on(gv);
-    if (PERLDB_LINE)
-       hv_magic(GvHVn(gv_AVadd(gv)), gv, 'L');
     return gv;
 }
 
@@ -100,11 +102,11 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
     Newz(602, gp, 1, GP);
     GvGP(gv) = gp_ref(gp);
     GvSV(gv) = NEWSV(72,0);
-    GvLINE(gv) = PL_curcop->cop_line;
-    GvFILEGV(gv) = PL_curcop->cop_filegv;
+    GvLINE(gv) = CopLINE(PL_curcop);
+    GvFILE(gv) = CopFILE(PL_curcop) ? CopFILE(PL_curcop) : "";
     GvCVGEN(gv) = 0;
     GvEGV(gv) = gv;
-    sv_magic((SV*)gv, (SV*)gv, '*', name, len);
+    sv_magic((SV*)gv, (SV*)gv, '*', Nullch, 0);
     GvSTASH(gv) = (HV*)SvREFCNT_inc(stash);
     GvNAME(gv) = savepvn(name, len);
     GvNAMELEN(gv) = len;
@@ -120,7 +122,7 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
 
        PL_sub_generation++;
        CvGV(GvCV(gv)) = (GV*)SvREFCNT_inc(gv);
-       CvFILEGV(GvCV(gv)) = PL_curcop->cop_filegv;
+       CvFILE(GvCV(gv)) = CopFILE(PL_curcop);
        CvSTASH(GvCV(gv)) = PL_curstash;
 #ifdef USE_THREADS
        CvOWNER(GvCV(gv)) = 0;
@@ -152,6 +154,27 @@ S_gv_init_sv(pTHX_ GV *gv, I32 sv_type)
     }
 }
 
+/*
+=for apidoc gv_fetchmeth
+
+Returns the glob with the given C<name> and a defined subroutine or
+C<NULL>.  The glob lives in the given C<stash>, or in the stashes
+accessible via @ISA and @UNIVERSAL.
+
+The argument C<level> should be either 0 or -1.  If C<level==0>, as a
+side-effect creates a glob with the given C<name> in the given C<stash>
+which in the case of success contains an alias for the subroutine, and sets
+up caching info for this glob.  Similarly for all the searched stashes.
+
+This function grants C<"SUPER"> token as a postfix of the stash name. The
+GV returned from C<gv_fetchmeth> may be a method cache entry, which is not
+visible to Perl code.  So when calling C<call_sv>, you should not use
+the GV directly; instead, you should use the method's CV, which can be
+obtained from the GV with the C<GvCV> macro.
+
+=cut
+*/
+
 GV *
 Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
 {
@@ -176,7 +199,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
        topgv = *gvp;
        if (SvTYPE(topgv) != SVt_PVGV)
            gv_init(topgv, stash, name, len, TRUE);
-       if (cv = GvCV(topgv)) {
+       if ((cv = GvCV(topgv))) {
            /* If genuine method or valid cache entry, use it */
            if (!GvCVGEN(topgv) || GvCVGEN(topgv) == PL_sub_generation)
                return topgv;
@@ -242,9 +265,10 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
     if (level == 0 || level == -1) {
        HV* lastchance;
 
-       if (lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE)) {
-           if (gv = gv_fetchmeth(lastchance, name, len,
-                                 (level >= 0) ? level + 1 : level - 1)) {
+       if ((lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE))) {
+           if ((gv = gv_fetchmeth(lastchance, name, len,
+                                 (level >= 0) ? level + 1 : level - 1)))
+           {
          gotcha:
                /*
                 * Cache method in topgv if:
@@ -256,7 +280,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
                    (cv = GvCV(gv)) &&
                    (CvROOT(cv) || CvXSUB(cv)))
                {
-                   if (cv = GvCV(topgv))
+                   if ((cv = GvCV(topgv)))
                        SvREFCNT_dec(cv);
                    GvCV(topgv) = (CV*)SvREFCNT_inc(GvCV(gv));
                    GvCVGEN(topgv) = PL_sub_generation;
@@ -273,12 +297,48 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
     return 0;
 }
 
+/*
+=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
+on the C<stash>.  In fact in the presence of autoloading this may be the
+glob for "AUTOLOAD".  In this case the corresponding variable $AUTOLOAD is
+already setup.
+
+The third parameter of C<gv_fetchmethod_autoload> determines whether
+AUTOLOAD lookup is performed if the given method is not present: non-zero
+means yes, look for AUTOLOAD; zero means no, don't look for AUTOLOAD.
+Calling C<gv_fetchmethod> is equivalent to calling C<gv_fetchmethod_autoload>
+with a non-zero C<autoload> parameter.
+
+These functions grant C<"SUPER"> token as a prefix of the method name. Note
+that if you want to keep the returned glob for a long time, you need to
+check for it being "AUTOLOAD", since at the later time the call may load a
+different subroutine due to $AUTOLOAD changing its value. Use the glob
+created via a side effect to do this.
+
+These functions have the same side-effects and as C<gv_fetchmeth> with
+C<level==0>.  C<name> should be writable if contains C<':'> or C<'
+''>. The warning against passing the GV returned by C<gv_fetchmeth> to
+C<call_sv> apply equally to these functions.
+
+=cut
+*/
+
 GV *
 Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
 {
@@ -286,7 +346,7 @@ Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
     register const char *nend;
     const char *nsplit = 0;
     GV* gv;
-    
+
     for (nend = name; *nend; nend++) {
        if (*nend == '\'')
            nsplit = nend;
@@ -301,7 +361,7 @@ Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
        if ((nsplit - origname) == 5 && strnEQ(origname, "SUPER", 5)) {
            /* ->SUPER::method should really be looked up in original stash */
            SV *tmpstr = sv_2mortal(Perl_newSVpvf(aTHX_ "%s::SUPER",
-                                            HvNAME(PL_curcop->cop_stash)));
+                                                 CopSTASHPV(PL_curcop)));
            stash = gv_stashpvn(SvPVX(tmpstr), SvCUR(tmpstr), TRUE);
            DEBUG_o( Perl_deb(aTHX_ "Treating %s as %s::%s\n",
                         origname, HvNAME(stash), name) );
@@ -312,7 +372,7 @@ Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
 
     gv = gv_fetchmeth(stash, name, nend - name, 0);
     if (!gv) {
-       if (strEQ(name,"import"))
+       if (strEQ(name,"import") || strEQ(name,"unimport"))
            gv = (GV*)&PL_sv_yes;
        else if (autoload)
            gv = gv_autoload4(stash, name, nend - name, TRUE);
@@ -358,10 +418,13 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
        return Nullgv;
     cv = GvCV(gv);
 
+    if (!CvROOT(cv))
+       return Nullgv;
+
     /*
      * Inheriting AUTOLOAD for non-methods works ... for now.
      */
-    if (ckWARN(WARN_DEPRECATED) && !method && 
+    if (ckWARN(WARN_DEPRECATED) && !method &&
        (GvCVGEN(gv) || GvSTASH(gv) != stash))
        Perl_warner(aTHX_ WARN_DEPRECATED,
          "Use of inherited AUTOLOAD for non-method %s::%.*s() is deprecated",
@@ -375,9 +438,18 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
      */
     varstash = GvSTASH(CvGV(cv));
     vargv = *(GV**)hv_fetch(varstash, autoload, autolen, TRUE);
+    ENTER;
+
+#ifdef USE_THREADS
+    sv_lock((SV *)varstash);
+#endif
     if (!isGV(vargv))
        gv_init(vargv, varstash, autoload, autolen, FALSE);
+    LEAVE;
     varsv = GvSV(vargv);
+#ifdef USE_THREADS
+    sv_lock(varsv);
+#endif
     sv_setpv(varsv, HvNAME(stash));
     sv_catpvn(varsv, "::", 2);
     sv_catpvn(varsv, name, len);
@@ -385,6 +457,17 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method)
     return gv;
 }
 
+/*
+=for apidoc gv_stashpv
+
+Returns a pointer to the stash for a specified package.  C<name> should
+be a valid UTF-8 string.  If C<create> is set then the package will be
+created if it does not already exist.  If C<create> is not set and the
+package does not exist then NULL is returned.
+
+=cut
+*/
+
 HV*
 Perl_gv_stashpv(pTHX_ const char *name, I32 create)
 {
@@ -420,6 +503,15 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 create)
     return stash;
 }
 
+/*
+=for apidoc gv_stashsv
+
+Returns a pointer to the stash for a specified package, which must be a
+valid UTF-8 string.  See C<gv_stashpv>.
+
+=cut
+*/
+
 HV*
 Perl_gv_stashsv(pTHX_ SV *sv, I32 create)
 {
@@ -440,14 +532,13 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
     I32 len;
     register const char *namend;
     HV *stash = 0;
-    U32 add_gvflags = 0;
 
     if (*name == '*' && isALPHA(name[1])) /* accidental stringify on a GV? */
        name++;
 
     for (namend = name; *namend; namend++) {
-       if ((*namend == '\'' && namend[1]) ||
-           (*namend == ':' && namend[1] == ':'))
+       if ((*namend == ':' && namend[1] == ':')
+           || (*namend == '\'' && namend[1]))
        {
            if (!stash)
                stash = PL_defstash;
@@ -502,9 +593,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
     /* No stash in name, so see how we can default */
 
     if (!stash) {
-       if (isIDFIRST(*name)
-           || (IN_UTF8 && ((*name & 0xc0) == 0xc0) && isIDFIRST_utf8((U8*)name)))
-       {
+       if (isIDFIRST_lazy(name)) {
            bool global = FALSE;
 
            if (isUPPER(*name)) {
@@ -531,7 +620,6 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
            else if ((COP*)PL_curcop == &PL_compiling) {
                stash = PL_curstash;
                if (add && (PL_hints & HINT_STRICT_VARS) &&
-                   !(add & GV_ADDOUR) &&
                    sv_type != SVt_PVCV &&
                    sv_type != SVt_PVGV &&
                    sv_type != SVt_PVFM &&
@@ -545,22 +633,22 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
                    {
                        stash = 0;
                    }
-                   else if (sv_type == SVt_PV   && !GvIMPORTED_SV(*gvp) ||
-                            sv_type == SVt_PVAV && !GvIMPORTED_AV(*gvp) ||
-                            sv_type == SVt_PVHV && !GvIMPORTED_HV(*gvp) )
+                   else if ((sv_type == SVt_PV   && !GvIMPORTED_SV(*gvp)) ||
+                            (sv_type == SVt_PVAV && !GvIMPORTED_AV(*gvp)) ||
+                            (sv_type == SVt_PVHV && !GvIMPORTED_HV(*gvp)) )
                    {
                        Perl_warn(aTHX_ "Variable \"%c%s\" is not imported",
                            sv_type == SVt_PVAV ? '@' :
                            sv_type == SVt_PVHV ? '%' : '$',
                            name);
                        if (GvCVu(*gvp))
-                           Perl_warn(aTHX_ "(Did you mean &%s instead?)\n", name);
+                           Perl_warn(aTHX_ "\t(Did you mean &%s instead?)\n", name);
                        stash = 0;
                    }
                }
            }
            else
-               stash = PL_curcop->cop_stash;
+               stash = CopSTASH(PL_curcop);
        }
        else
            stash = PL_defstash;
@@ -576,8 +664,10 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
                  : sv_type == SVt_PVAV ? "@"
                  : sv_type == SVt_PVHV ? "%"
                  : ""), name));
+           stash = PL_nullstash;
        }
-       return Nullgv;
+       else
+           return Nullgv;
     }
 
     if (!SvREFCNT(stash))      /* symbol table under destruction */
@@ -603,7 +693,6 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
        Perl_warner(aTHX_ WARN_INTERNAL, "Had to create %s unexpectedly", nambeg);
     gv_init(gv, stash, name, len, add & GV_ADDMULTI);
     gv_init_sv(gv, sv_type);
-    GvFLAGS(gv) |= add_gvflags;
 
     if (isLEXWARN_on && isALPHA(name[0]) && ! ckWARN(WARN_ONCE))
         GvMULTI_on(gv) ;
@@ -646,17 +735,22 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
         if (strEQ(name, "OVERLOAD")) {
             HV* hv = GvHVn(gv);
             GvMULTI_on(gv);
-            hv_magic(hv, gv, 'A');
+            hv_magic(hv, Nullgv, 'A');
         }
         break;
     case 'S':
        if (strEQ(name, "SIG")) {
            HV *hv;
            I32 i;
+           if (!PL_psig_ptr) {
+               int sig_num[] = { SIG_NUM };
+               New(73, PL_psig_ptr, sizeof(sig_num)/sizeof(*sig_num), SV*);
+               New(73, PL_psig_name, sizeof(sig_num)/sizeof(*sig_num), SV*);
+           }
            GvMULTI_on(gv);
            hv = GvHVn(gv);
-           hv_magic(hv, gv, 'S');
-           for(i = 1; PL_sig_name[i]; i++) {
+           hv_magic(hv, Nullgv, 'S');
+           for (i = 1; PL_sig_name[i]; i++) {
                SV ** init;
                init = hv_fetch(hv, PL_sig_name[i], strlen(PL_sig_name[i]), 1);
                if (init)
@@ -725,6 +819,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
        else {
             AV* av = GvAVn(gv);
             sv_magic((SV*)av, Nullsv, 'D', Nullch, 0);
+           SvREADONLY_on(av);
         }
        goto magicalize;
     case '#':
@@ -746,25 +841,29 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
     case '\\':
     case '/':
     case '|':
-    case '\001':
-    case '\003':
-    case '\004':
-    case '\005':
-    case '\006':
-    case '\010':
-    case '\011':       /* NOT \t in EBCDIC */
-    case '\017':
-    case '\020':
-    case '\024':
+    case '\001':       /* $^A */
+    case '\003':       /* $^C */
+    case '\004':       /* $^D */
+    case '\005':       /* $^E */
+    case '\006':       /* $^F */
+    case '\010':       /* $^H */
+    case '\011':       /* $^I, NOT \t in EBCDIC */
+    case '\020':       /* $^P */
+    case '\024':       /* $^T */
        if (len > 1)
            break;
        goto magicalize;
-    case '\023':
+    case '\017':       /* $^O & $^OPEN */
+       if (len > 1 && strNE(name, "\017PEN"))
+           break;
+       goto magicalize;
+    case '\023':       /* $^S */
        if (len > 1)
            break;
        goto ro_magicalize;
-    case '\027':       /* $^W & $^Warnings */
-       if (len > 1 && strNE(name, "\027arnings"))
+    case '\027':       /* $^W & $^WARNING_BITS */
+       if (len > 1 && strNE(name, "\027ARNING_BITS")
+           && strNE(name, "\027IDE_SYSTEM_CALLS"))
            break;
        goto magicalize;
 
@@ -774,6 +873,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
        else {
             AV* av = GvAVn(gv);
             sv_magic((SV*)av, (SV*)av, 'D', Nullch, 0);
+           SvREADONLY_on(av);
         }
        /* FALL THROUGH */
     case '1':
@@ -791,7 +891,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
        sv_magic(GvSV(gv), (SV*)gv, 0, name, len);
        break;
 
-    case '\014':
+    case '\014':       /* $^L */
        if (len > 1)
            break;
        sv_setpv(GvSV(gv),"\f");
@@ -806,21 +906,52 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
        if (len == 1) {
            SV *sv = GvSV(gv);
            (void)SvUPGRADE(sv, SVt_PVNV);
-           sv_setpv(sv, PL_patchlevel);
-           (void)sv_2nv(sv);
+           Perl_sv_setpvf(aTHX_ sv,
+#if defined(PERL_SUBVERSION) && (PERL_SUBVERSION > 0)
+                           "%8.6"
+#else
+                           "%5.3"
+#endif
+                           NVff,
+                           SvNVX(PL_patchlevel));
+           SvNVX(sv) = SvNVX(PL_patchlevel);
+           SvNOK_on(sv);
            SvREADONLY_on(sv);
        }
        break;
+    case '\026':       /* $^V */
+       if (len == 1) {
+           SV *sv = GvSV(gv);
+           GvSV(gv) = SvREFCNT_inc(PL_patchlevel);
+           SvREFCNT_dec(sv);
+       }
+       break;
     }
     return gv;
 }
 
 void
+Perl_gv_fullname4(pTHX_ SV *sv, GV *gv, const char *prefix, bool keepmain)
+{
+    HV *hv = GvSTASH(gv);
+    if (!hv) {
+       (void)SvOK_off(sv);
+       return;
+    }
+    sv_setpv(sv, prefix ? prefix : "");
+    if (keepmain || strNE(HvNAME(hv), "main")) {
+       sv_catpv(sv,HvNAME(hv));
+       sv_catpvn(sv,"::", 2);
+    }
+    sv_catpvn(sv,GvNAME(gv),GvNAMELEN(gv));
+}
+
+void
 Perl_gv_fullname3(pTHX_ SV *sv, GV *gv, const char *prefix)
 {
     HV *hv = GvSTASH(gv);
     if (!hv) {
-       SvOK_off(sv);
+       (void)SvOK_off(sv);
        return;
     }
     sv_setpv(sv, prefix ? prefix : "");
@@ -830,6 +961,15 @@ Perl_gv_fullname3(pTHX_ SV *sv, GV *gv, const char *prefix)
 }
 
 void
+Perl_gv_efullname4(pTHX_ SV *sv, GV *gv, const char *prefix, bool keepmain)
+{
+    GV *egv = GvEGV(gv);
+    if (!egv)
+       egv = gv;
+    gv_fullname4(sv, egv, prefix, keepmain);
+}
+
+void
 Perl_gv_efullname3(pTHX_ SV *sv, GV *gv, const char *prefix)
 {
     GV *egv = GvEGV(gv);
@@ -879,7 +1019,6 @@ Perl_gv_check(pTHX_ HV *stash)
     register I32 i;
     register GV *gv;
     HV *hv;
-    GV *filegv;
 
     if (!HvARRAY(stash))
        return;
@@ -892,14 +1031,25 @@ Perl_gv_check(pTHX_ HV *stash)
                     gv_check(hv);              /* nested package */
            }
            else if (isALPHA(*HeKEY(entry))) {
+               char *file;
                gv = (GV*)HeVAL(entry);
                if (SvTYPE(gv) != SVt_PVGV || GvMULTI(gv))
                    continue;
-               PL_curcop->cop_line = GvLINE(gv);
-               filegv = GvFILEGV(gv);
-               PL_curcop->cop_filegv = filegv;
-               if (filegv && GvMULTI(filegv))  /* Filename began with slash */
+               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)
+                   && (instr(file, "/lib/") || instr(file, ".pm")))
+               {
                    continue;
+               }
+               CopLINE_set(PL_curcop, GvLINE(gv));
+#ifdef USE_ITHREADS
+               CopFILE(PL_curcop) = file;      /* set for warning */
+#else
+               CopFILEGV(PL_curcop) = gv_fetchfile(file);
+#endif
                Perl_warner(aTHX_ WARN_ONCE,
                        "Name \"%s::%s\" used only once: possible typo",
                        HvNAME(stash), GvNAME(gv));
@@ -920,6 +1070,8 @@ Perl_newGVgen(pTHX_ char *pack)
 GP*
 Perl_gp_ref(pTHX_ GP *gp)
 {
+    if (!gp)
+       return (GP*)NULL;
     gp->gp_refcnt++;
     if (gp->gp_cv) {
        if (gp->gp_cvgen) {
@@ -939,9 +1091,8 @@ Perl_gp_ref(pTHX_ GP *gp)
 void
 Perl_gp_free(pTHX_ GV *gv)
 {
-    dTHR;  
+    dTHR;
     GP* gp;
-    CV* cv;
 
     if (!gv || !(gp = GvGP(gv)))
        return;
@@ -980,7 +1131,7 @@ Perl_gp_free(pTHX_ GV *gv)
 AV *GvAVn(gv)
 register GV *gv;
 {
-    if (GvGP(gv)->gp_av) 
+    if (GvGP(gv)->gp_av)
        return GvGP(gv)->gp_av;
     else
        return GvGP(gv_AVadd(gv))->gp_av;
@@ -1001,15 +1152,17 @@ register GV *gv;
 bool
 Perl_Gv_AMupdate(pTHX_ HV *stash)
 {
-  dTHR;  
-  GV** gvp;
-  HV* hv;
+  dTHR;
   GV* gv;
   CV* cv;
   MAGIC* mg=mg_find((SV*)stash,'c');
   AMT *amtp = (mg) ? (AMT*)mg->mg_ptr: (AMT *) NULL;
   AMT amt;
   STRLEN n_a;
+#ifdef OVERLOAD_VIA_HASH
+  GV** gvp;
+  HV* hv;
+#endif
 
   if (mg && amtp->was_ok_am == PL_amagic_generation
       && amtp->was_ok_sub == PL_sub_generation)
@@ -1050,7 +1203,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash)
     for (i = 1; i < NofAMmeth; i++) {
       cv = 0;
       cp = (char *)PL_AMG_names[i];
-      
+
         svp = (SV**)hv_fetch(hv, cp, strlen(cp), FALSE);
         if (svp && ((sv = *svp) != &PL_sv_undef)) {
           switch (SvTYPE(sv)) {
@@ -1090,18 +1243,21 @@ Perl_Gv_AMupdate(pTHX_ HV *stash)
     int i;
     const char *cp;
     SV* sv = NULL;
-    SV** svp;
 
     /* Work with "fallback" key, which we assume to be first in PL_AMG_names */
 
-    if ( cp = PL_AMG_names[0] ) {
+    if ((cp = PL_AMG_names[0])) {
        /* Try to find via inheritance. */
        gv = gv_fetchmeth(stash, "()", 2, -1); /* A cookie: "()". */
-       if (gv) sv = GvSV(gv);
-
-       if (!gv) goto no_table;
-       else if (SvTRUE(sv)) amt.fallback=AMGfallYES;
-       else if (SvOK(sv)) amt.fallback=AMGfallNEVER;
+       if (gv)
+           sv = GvSV(gv);
+
+       if (!gv)
+           goto no_table;
+       else if (SvTRUE(sv))
+           amt.fallback=AMGfallYES;
+       else if (SvOK(sv))
+           amt.fallback=AMGfallNEVER;
     }
 
     for (i = 1; i < NofAMmeth; i++) {
@@ -1117,19 +1273,19 @@ Perl_Gv_AMupdate(pTHX_ HV *stash)
                /* GvSV contains the name of the method. */
                GV *ngv;
                
-               DEBUG_o( Perl_deb(aTHX_ "Resolving method `%.256s' for overloaded `%s' in package `%.256s'\n", 
+               DEBUG_o( Perl_deb(aTHX_ "Resolving method `%.256s' for overloaded `%s' in package `%.256s'\n",
                             SvPV(GvSV(gv), n_a), cp, HvNAME(stash)) );
-               if (!SvPOK(GvSV(gv)) 
+               if (!SvPOK(GvSV(gv))
                    || !(ngv = gv_fetchmethod_autoload(stash, SvPVX(GvSV(gv)),
                                                       FALSE)))
                {
                    /* Can be an import stub (created by `can'). */
                    if (GvCVGEN(gv)) {
-                       Perl_croak(aTHX_ "Stub found while resolving method `%.256s' overloading `%s' in package `%.256s'", 
+                       Perl_croak(aTHX_ "Stub found while resolving method `%.256s' overloading `%s' in package `%.256s'",
                              (SvPOK(GvSV(gv)) ?  SvPVX(GvSV(gv)) : "???" ),
                              cp, HvNAME(stash));
                    } else
-                       Perl_croak(aTHX_ "Can't resolve method `%.256s' overloading `%s' in package `%.256s'", 
+                       Perl_croak(aTHX_ "Can't resolve method `%.256s' overloading `%s' in package `%.256s'",
                              (SvPOK(GvSV(gv)) ?  SvPVX(GvSV(gv)) : "???" ),
                              cp, HvNAME(stash));
                }
@@ -1140,7 +1296,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash)
                         GvNAME(CvGV(cv))) );
            filled = 1;
        }
-#endif 
+#endif
        amt.table[i]=(CV*)SvREFCNT_inc(cv);
     }
     if (filled) {
@@ -1160,8 +1316,8 @@ SV*
 Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
 {
   dTHR;
-  MAGIC *mg; 
-  CV *cv; 
+  MAGIC *mg;
+  CV *cv;
   CV **cvp=NULL, **ocvp=NULL;
   AMT *amtp, *oamtp;
   int fl=0, off, off1, lr=0, assign=AMGf_assign & flags, notfound=0;
@@ -1169,10 +1325,10 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
   HV* stash;
   if (!(AMGf_noleft & flags) && SvAMAGIC(left)
       && (mg = mg_find((SV*)(stash=SvSTASH(SvRV(left))),'c'))
-      && (ocvp = cvp = (AMT_AMAGIC((AMT*)mg->mg_ptr) 
+      && (ocvp = cvp = (AMT_AMAGIC((AMT*)mg->mg_ptr)
                        ? (oamtp = amtp = (AMT*)mg->mg_ptr)->table
                        : (CV **) NULL))
-      && ((cv = cvp[off=method+assignshift]) 
+      && ((cv = cvp[off=method+assignshift])
          || (assign && amtp->fallback > AMGfallNEVER && /* fallback to
                                                          * usual method */
                  (fl = 1, cv = cvp[off=method])))) {
@@ -1208,7 +1364,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
           (void)((cv = cvp[off=numer_amg]) || (cv = cvp[off=bool__amg]));
           break;
  case not_amg:
-   (void)((cv = cvp[off=bool__amg]) 
+   (void)((cv = cvp[off=bool__amg])
          || (cv = cvp[off=numer_amg])
          || (cv = cvp[off=string_amg]));
    postpr = 1;
@@ -1233,7 +1389,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
           }
           break;
         case abs_amg:
-          if ((cvp[off1=lt_amg] || cvp[off1=ncmp_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));
             if (off1==lt_amg) {
@@ -1257,20 +1413,23 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
           }
           break;
         case neg_amg:
-          if (cv = cvp[off=subtr_amg]) {
+          if ((cv = cvp[off=subtr_amg])) {
             right = left;
             left = sv_2mortal(newSViv(0));
             lr = 1;
           }
           break;
         case iter_amg:                 /* XXXX Eventually should do to_gv. */
+            /* FAIL safe */
+            return NULL;       /* Delegate operation to standard mechanisms. */
+            break;
         case to_sv_amg:
         case to_av_amg:
         case to_hv_amg:
         case to_gv_amg:
         case to_cv_amg:
             /* FAIL safe */
-            return NULL;       /* Delegate operation to standard mechanisms. */
+            return left;       /* Delegate operation to standard mechanisms. */
             break;
         default:
           goto not_found;
@@ -1278,14 +1437,14 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
         if (!cv) goto not_found;
     } else if (!(AMGf_noright & flags) && SvAMAGIC(right)
               && (mg = mg_find((SV*)(stash=SvSTASH(SvRV(right))),'c'))
-              && (cvp = (AMT_AMAGIC((AMT*)mg->mg_ptr) 
+              && (cvp = (AMT_AMAGIC((AMT*)mg->mg_ptr)
                          ? (amtp = (AMT*)mg->mg_ptr)->table
                          : (CV **) NULL))
               && (cv = cvp[off=method])) { /* Method for right
                                             * argument found */
       lr=1;
-    } else if (((ocvp && oamtp->fallback > AMGfallNEVER 
-                && (cvp=ocvp) && (lr = -1)) 
+    } else if (((ocvp && oamtp->fallback > AMGfallNEVER
+                && (cvp=ocvp) && (lr = -1))
                || (cvp && amtp->fallback > AMGfallNEVER && (lr=1)))
               && !(flags & AMGf_unary)) {
                                /* We look for substitution for
@@ -1318,6 +1477,16 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
       }
     } else {
     not_found:                 /* No method found, either report or croak */
+      switch (method) {
+        case to_sv_amg:
+        case to_av_amg:
+        case to_hv_amg:
+        case to_gv_amg:
+        case to_cv_amg:
+            /* FAIL safe */
+            return left;       /* Delegate operation to standard mechanisms. */
+            break;
+      }
       if (ocvp && (cv=ocvp[nomethod_amg])) { /* Call report method */
        notfound = 1; lr = -1;
       } else if (cvp && (cv=cvp[nomethod_amg])) {
@@ -1325,28 +1494,28 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
       } else {
        SV *msg;
        if (off==-1) off=method;
-       msg = sv_2mortal(Perl_newSVpvf(aTHX_ 
+       msg = sv_2mortal(Perl_newSVpvf(aTHX_
                      "Operation `%s': no method found,%sargument %s%s%s%s",
                      PL_AMG_names[method + assignshift],
                      (flags & AMGf_unary ? " " : "\n\tleft "),
-                     SvAMAGIC(left)? 
+                     SvAMAGIC(left)?
                        "in overloaded package ":
                        "has no overloaded magic",
-                     SvAMAGIC(left)? 
+                     SvAMAGIC(left)?
                        HvNAME(SvSTASH(SvRV(left))):
                        "",
-                     SvAMAGIC(right)? 
+                     SvAMAGIC(right)?
                        ",\n\tright argument in overloaded package ":
-                       (flags & AMGf_unary 
+                       (flags & AMGf_unary
                         ? ""
                         : ",\n\tright argument has no overloaded magic"),
-                     SvAMAGIC(right)? 
+                     SvAMAGIC(right)?
                        HvNAME(SvSTASH(SvRV(right))):
                        ""));
        if (amtp && amtp->fallback >= AMGfallYES) {
          DEBUG_o( Perl_deb(aTHX_ "%s", SvPVX(msg)) );
        } else {
-         Perl_croak(aTHX_ "%_", msg);
+         Perl_croak(aTHX_ "%"SVf, msg);
        }
        return NULL;
       }
@@ -1354,7 +1523,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
     }
   }
   if (!notfound) {
-    DEBUG_o( Perl_deb(aTHX_ 
+    DEBUG_o( Perl_deb(aTHX_
   "Overloaded operator `%s'%s%s%s:\n\tmethod%s found%s in package %s%s\n",
                 PL_AMG_names[off],
                 method+assignshift==off? "" :
@@ -1365,7 +1534,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
                 flags & AMGf_unary? "" :
                   lr==1 ? " for right argument": " for left argument",
                 flags & AMGf_unary? " for argument" : "",
-                HvNAME(stash), 
+                HvNAME(stash),
                 fl? ",\n\tassignment variant used": "") );
   }
     /* Since we use shallow copy during assignment, we need
@@ -1378,10 +1547,10 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
      * b) Increment or decrement, called directly.
      *                 assignshift==0,  assign==0, method + 0 == off
      * c) Increment or decrement, translated to assignment add/subtr.
-     *                 assignshift==0,  assign==T, 
+     *                 assignshift==0,  assign==T,
      *         force_cpy == T
      * d) Increment or decrement, translated to nomethod.
-     *                 assignshift==0,  assign==0, 
+     *                 assignshift==0,  assign==0,
      *         force_cpy == T
      * e) Assignment form translated to nomethod.
      *                 assignshift==1,  assign==T, method + 1 != off
@@ -1425,7 +1594,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
     PUSHs((SV*)cv);
     PUTBACK;
 
-    if (PL_op = Perl_pp_entersub(aTHX))
+    if ((PL_op = Perl_pp_entersub(aTHX)))
       CALLRUNOPS(aTHX);
     LEAVE;
     SPAGAIN;
@@ -1473,3 +1642,116 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
     }
   }
 }
+
+/*
+=for apidoc is_gv_magical
+
+Returns C<TRUE> if given the name of a magical GV.
+
+Currently only useful internally when determining if a GV should be
+created even in rvalue contexts.
+
+C<flags> is not used at present but available for future extension to
+allow selecting particular classes of magical variable.
+
+=cut
+*/
+bool
+Perl_is_gv_magical(pTHX_ char *name, STRLEN len, U32 flags)
+{
+    if (!len)
+       return FALSE;
+
+    switch (*name) {
+    case 'I':
+       if (len == 3 && strEQ(name, "ISA"))
+           goto yes;
+       break;
+    case 'O':
+       if (len == 8 && strEQ(name, "OVERLOAD"))
+           goto yes;
+       break;
+    case 'S':
+       if (len == 3 && strEQ(name, "SIG"))
+           goto yes;
+       break;
+    case '\017':   /* $^O & $^OPEN */
+       if (len == 1
+           || (len == 4 && strEQ(name, "\027PEN")))
+       {
+           goto yes;
+       }
+       break;
+    case '\027':   /* $^W & $^WARNING_BITS */
+       if (len == 1
+           || (len == 12 && strEQ(name, "\027ARNING_BITS"))
+           || (len == 17 && strEQ(name, "\027IDE_SYSTEM_CALLS")))
+       {
+           goto yes;
+       }
+       break;
+
+    case '&':
+    case '`':
+    case '\'':
+    case ':':
+    case '?':
+    case '!':
+    case '-':
+    case '#':
+    case '*':
+    case '[':
+    case '^':
+    case '~':
+    case '=':
+    case '%':
+    case '.':
+    case '(':
+    case ')':
+    case '<':
+    case '>':
+    case ',':
+    case '\\':
+    case '/':
+    case '|':
+    case '+':
+    case ';':
+    case ']':
+    case '\001':   /* $^A */
+    case '\003':   /* $^C */
+    case '\004':   /* $^D */
+    case '\005':   /* $^E */
+    case '\006':   /* $^F */
+    case '\010':   /* $^H */
+    case '\011':   /* $^I, NOT \t in EBCDIC */
+    case '\014':   /* $^L */
+    case '\020':   /* $^P */
+    case '\023':   /* $^S */
+    case '\024':   /* $^T */
+    case '\026':   /* $^V */
+       if (len == 1)
+           goto yes;
+       break;
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+       if (len > 1) {
+           char *end = name + len;
+           while (--end > name) {
+               if (!isDIGIT(*end))
+                   return FALSE;
+           }
+       }
+    yes:
+       return TRUE;
+    default:
+       break;
+    }
+    return FALSE;
+}