/* gv.c
*
- * Copyright (c) 1991-2002, Larry Wall
+ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ * 2000, 2001, 2002, 2003, 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.
CvGV(GvCV(gv)) = gv;
CvFILE_set_from_cop(GvCV(gv), PL_curcop);
CvSTASH(GvCV(gv)) = PL_curstash;
-#ifdef USE_5005THREADS
- CvOWNER(GvCV(gv)) = 0;
- if (!CvMUTEXP(GvCV(gv))) {
- New(666, CvMUTEXP(GvCV(gv)), 1, perl_mutex);
- MUTEX_INIT(CvMUTEXP(GvCV(gv)));
- }
-#endif /* USE_5005THREADS */
if (proto) {
sv_setpv((SV*)GvCV(gv), proto);
Safefree(proto);
return 0;
}
+ if (!HvNAME(stash))
+ Perl_croak(aTHX_
+ "Can't use anonymous symbol table for method lookup");
+
if ((level > 100) || (level < -100))
Perl_croak(aTHX_ "Recursive inheritance detected while looking for method '%s' in package '%s'",
name, HvNAME(stash));
HV* basestash = gv_stashsv(sv, FALSE);
if (!basestash) {
if (ckWARN(WARN_MISC))
- Perl_warner(aTHX_ packWARN(WARN_MISC), "Can't locate package %s for @%s::ISA",
- SvPVX(sv), HvNAME(stash));
+ Perl_warner(aTHX_ packWARN(WARN_MISC), "Can't locate package %"SVf" for @%s::ISA",
+ sv, HvNAME(stash));
continue;
}
gv = gv_fetchmeth(basestash, name, len,
register const char *nend;
const char *nsplit = 0;
GV* gv;
+ HV* ostash = stash;
+
+ if (stash && SvTYPE(stash) < SVt_PVHV)
+ stash = Nullhv;
for (nend = name; *nend; nend++) {
if (*nend == '\'')
gv_stashpvn(origname, nsplit - origname - 7, FALSE))
stash = gv_stashpvn(origname, nsplit - origname, TRUE);
}
+ ostash = stash;
}
gv = gv_fetchmeth(stash, name, nend - name, 0);
if (strEQ(name,"import") || strEQ(name,"unimport"))
gv = (GV*)&PL_sv_yes;
else if (autoload)
- gv = gv_autoload4(stash, name, nend - name, TRUE);
+ gv = gv_autoload4(ostash, name, nend - name, TRUE);
}
else if (autoload) {
CV* cv = GvCV(gv);
HV* varstash;
GV* vargv;
SV* varsv;
+ char *packname = "";
- if (!stash)
- return Nullgv; /* UNIVERSAL::AUTOLOAD could cause trouble */
if (len == autolen && strnEQ(name, autoload, autolen))
return Nullgv;
+ if (stash) {
+ if (SvTYPE(stash) < SVt_PVHV) {
+ packname = SvPV_nolen((SV*)stash);
+ stash = Nullhv;
+ }
+ else {
+ packname = HvNAME(stash);
+ }
+ }
if (!(gv = gv_fetchmeth(stash, autoload, autolen, FALSE)))
return Nullgv;
cv = GvCV(gv);
(GvCVGEN(gv) || GvSTASH(gv) != stash))
Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
"Use of inherited AUTOLOAD for non-method %s::%.*s() is deprecated",
- HvNAME(stash), (int)len, name);
+ packname, (int)len, name);
-#ifndef USE_5005THREADS
if (CvXSUB(cv)) {
/* rather than lookup/init $AUTOLOAD here
* only to have the XSUB do another lookup for $AUTOLOAD
SvCUR(cv) = len;
return gv;
}
-#endif
/*
* Given &FOO::AUTOLOAD, set $FOO::AUTOLOAD to desired function name.
vargv = *(GV**)hv_fetch(varstash, autoload, autolen, TRUE);
ENTER;
-#ifdef USE_5005THREADS
- sv_lock((SV *)varstash);
-#endif
if (!isGV(vargv))
gv_init(vargv, varstash, autoload, autolen, FALSE);
LEAVE;
varsv = GvSV(vargv);
-#ifdef USE_5005THREADS
- sv_lock(varsv);
-#endif
- sv_setpv(varsv, HvNAME(stash));
+ sv_setpv(varsv, packname);
sv_catpvn(varsv, "::", 2);
sv_catpvn(varsv, name, len);
SvTAINTED_off(varsv);
}
}
len = namend - name;
- if (!len)
- len = 1;
/* No stash in name, so see how we can default */
if (global)
stash = PL_defstash;
- else if ((COP*)PL_curcop == &PL_compiling) {
+ else if (IN_PERL_COMPILETIME) {
stash = PL_curstash;
if (add && (PL_hints & HINT_STRICT_VARS) &&
sv_type != SVt_PVCV &&
if (!stash) {
if (add) {
- qerror(Perl_mess(aTHX_
+ register SV *err = Perl_mess(aTHX_
"Global symbol \"%s%s\" requires explicit package name",
(sv_type == SVt_PV ? "$"
: sv_type == SVt_PVAV ? "@"
: sv_type == SVt_PVHV ? "%"
- : ""), name));
- stash = PL_nullstash;
+ : ""), name);
+ if (USE_UTF8_IN_NAMES)
+ SvUTF8_on(err);
+ qerror(err);
+ stash = GvHV(gv_fetchpv("<none>::", GV_ADDMULTI, SVt_PVHV));
}
else
return Nullgv;
SvREADONLY_on(av);
}
goto magicalize;
- case '#':
case '*':
- if (ckWARN2(WARN_DEPRECATED, WARN_SYNTAX) && len == 1 && sv_type == SVt_PV)
- Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX), "Use of $%s is deprecated", name);
+ if (len == 1 && sv_type == SVt_PV && ckWARN2(WARN_DEPRECATED, WARN_SYNTAX))
+ Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
+ "$* is no longer supported");
+ break;
+ case '#':
+ if (len == 1 && sv_type == SVt_PV && ckWARN2(WARN_DEPRECATED, WARN_SYNTAX))
+ Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
+ "Use of $# is deprecated");
/* FALL THROUGH */
case '[':
case '^':
goto ro_magicalize;
else
break;
+ case '\025':
+ if (len > 1 && strNE(name, "\025NICODE"))
+ break;
+ goto ro_magicalize;
+
case '\027': /* $^W & $^WARNING_BITS */
- if (len > 1 && strNE(name, "\027ARNING_BITS")
- && strNE(name, "\027IDE_SYSTEM_CALLS"))
+ if (len > 1
+ && strNE(name, "\027ARNING_BITS")
+ )
break;
goto magicalize;
void
Perl_gv_fullname4(pTHX_ SV *sv, GV *gv, const char *prefix, bool keepmain)
{
+ char *name;
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));
+
+ if (!HvNAME(hv))
+ name = "__ANON__";
+ else
+ name = HvNAME(hv);
+ if (keepmain || strNE(name, "main")) {
+ sv_catpv(sv,name);
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) {
- (void)SvOK_off(sv);
- return;
- }
- sv_setpv(sv, prefix ? prefix : "");
- sv_catpv(sv,HvNAME(hv));
- sv_catpvn(sv,"::", 2);
- sv_catpvn(sv,GvNAME(gv),GvNAMELEN(gv));
+ gv_fullname4(sv, gv, prefix, TRUE);
}
void
void
Perl_gv_efullname3(pTHX_ SV *sv, GV *gv, const char *prefix)
{
- GV *egv = GvEGV(gv);
- if (!egv)
- egv = gv;
- gv_fullname3(sv, egv, prefix);
+ gv_efullname4(sv, gv, prefix, TRUE);
}
/* XXX compatibility with versions <= 5.003. */
sv_upgrade((SV *)io,SVt_PVIO);
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);
/* unless exists($main::{FileHandle}) and defined(%main::FileHandle::) */
if (!(iogv && GvHV(iogv) && HvARRAY(GvHV(iogv))))
for (i = 0; i <= (I32) HvMAX(stash); i++) {
for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) {
if (HeKEY(entry)[HeKLEN(entry)-1] == ':' &&
- (gv = (GV*)HeVAL(entry)) && (hv = GvHV(gv)))
+ (gv = (GV*)HeVAL(entry)) && isGV(gv) && (hv = GvHV(gv)))
{
if (hv != PL_defstash && hv != stash)
gv_check(hv); /* nested package */
return;
}
- SvREFCNT_dec(gp->gp_sv);
- SvREFCNT_dec(gp->gp_av);
- SvREFCNT_dec(gp->gp_hv);
- SvREFCNT_dec(gp->gp_io);
- SvREFCNT_dec(gp->gp_cv);
- SvREFCNT_dec(gp->gp_form);
+ if (gp->gp_sv) SvREFCNT_dec(gp->gp_sv);
+ if (gp->gp_sv) SvREFCNT_dec(gp->gp_av);
+ if (gp->gp_hv) {
+ if (PL_stashcache && HvNAME(gp->gp_hv))
+ hv_delete(PL_stashcache,
+ HvNAME(gp->gp_hv), strlen(HvNAME(gp->gp_hv)),
+ G_DISCARD);
+ SvREFCNT_dec(gp->gp_hv);
+ }
+ if (gp->gp_io) SvREFCNT_dec(gp->gp_io);
+ if (gp->gp_cv) SvREFCNT_dec(gp->gp_cv);
+ if (gp->gp_form) SvREFCNT_dec(gp->gp_form);
Safefree(gp);
GvGP(gv) = 0;
/* GvSV contains the name of the method. */
GV *ngv = Nullgv;
- DEBUG_o( Perl_deb(aTHX_ "Resolving method `%.256s' for overloaded `%s' in package `%.256s'\n",
- SvPV_nolen(GvSV(gv)), cp, HvNAME(stash)) );
+ DEBUG_o( Perl_deb(aTHX_ "Resolving method `%"SVf256\
+ "' for overloaded `%s' in package `%.256s'\n",
+ GvSV(gv), cp, HvNAME(stash)) );
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'",
- (SvPOK(GvSV(gv)) ? SvPVX(GvSV(gv)) : "???" ),
- cp, HvNAME(stash));
- } else
- Perl_croak(aTHX_ "Can't resolve method `%.256s' overloading `%s' in package `%.256s'",
- (SvPOK(GvSV(gv)) ? SvPVX(GvSV(gv)) : "???" ),
- cp, HvNAME(stash));
+ SV *gvsv = GvSV(gv);
+ const char *name = SvPOK(gvsv) ? SvPVX(gvsv) : "???";
+ Perl_croak(aTHX_ "%s method `%.256s' overloading `%s' "\
+ "in package `%.256s'",
+ (GvCVGEN(gv) ? "Stub found while resolving"
+ : "Can't resolve"),
+ name, cp, HvNAME(stash));
}
cv = GvCV(gv = ngv);
}
AMT *amtp;
CV *ret;
- if (!stash)
+ if (!stash || !HvNAME(stash))
return Nullcv;
mg = mg_find((SV*)stash, PERL_MAGIC_overload_table);
if (!mg) {
goto yes;
}
break;
+ case '\025':
+ if (len > 1 && strEQ(name, "\025NICODE"))
+ goto yes;
case '\027': /* $^W & $^WARNING_BITS */
if (len == 1
|| (len == 12 && strEQ(name, "\027ARNING_BITS"))
- || (len == 17 && strEQ(name, "\027IDE_SYSTEM_CALLS")))
+ )
{
goto yes;
}
case '!':
case '-':
case '#':
- case '*':
case '[':
case '^':
case '~':