X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=gv.c;h=70a9a12271e4fb8905e150407497603f29755728;hb=b0a2b4f5d11a46676e755e10a5905ed77204b20d;hp=90d415276c1aa377fab64344178d82e1d19c660f;hpb=eb1102fcca2230364ceadea29bd8e87ee51b15fa;p=p5sagit%2Fp5-mst-13.2.git diff --git a/gv.c b/gv.c index 90d4152..70a9a12 100644 --- a/gv.c +++ b/gv.c @@ -310,6 +310,50 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) } /* +=for apidoc gv_fetchmeth_autoload + +Same as gv_fetchmeth(), but looks for autoloaded subroutines too. +Returns a glob for the subroutine. + +For an autoloaded subroutine without a GV, will create a GV even +if C. For an autoloaded subroutine without a stub, GvCV() +of the result may be zero. + +=cut +*/ + +GV * +Perl_gv_fetchmeth_autoload(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) +{ + GV *gv = gv_fetchmeth(stash, name, len, level); + + if (!gv) { + char autoload[] = "AUTOLOAD"; + STRLEN autolen = sizeof(autoload)-1; + CV *cv; + GV **gvp; + + if (!stash) + return Nullgv; /* UNIVERSAL::AUTOLOAD could cause trouble */ + if (len == autolen && strnEQ(name, autoload, autolen)) + return Nullgv; + if (!(gv = gv_fetchmeth(stash, autoload, autolen, FALSE))) + return Nullgv; + cv = GvCV(gv); + if (!(CvROOT(cv) || CvXSUB(cv))) + return Nullgv; + /* 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 *gvp; + } + return gv; +} + +/* =for apidoc gv_fetchmethod See L. @@ -438,9 +482,9 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method) /* * Inheriting AUTOLOAD for non-methods works ... for now. */ - if (ckWARN(WARN_DEPRECATED) && !method && + if (ckWARN2(WARN_DEPRECATED, WARN_SYNTAX) && !method && (GvCVGEN(gv) || GvSTASH(gv) != stash)) - Perl_warner(aTHX_ WARN_DEPRECATED, + Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX), "Use of inherited AUTOLOAD for non-method %s::%.*s() is deprecated", HvNAME(stash), (int)len, name); @@ -498,7 +542,8 @@ S_require_errno(pTHX_ GV *gv) PUTBACK; ENTER; save_scalar(gv); /* keep the value of $! */ - require_pv("Errno.pm"); + Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, + newSVpvn("Errno",5), Nullsv); LEAVE; SPAGAIN; stash = gv_stashpvn("Errno",5,FALSE); @@ -661,7 +706,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) strEQ(name, "ARGVOUT"))) global = TRUE; } - else if (*name == '_' && (!name[1] || strEQ(name,"__ANON__"))) + else if (*name == '_' && !name[1]) global = TRUE; if (global) @@ -873,8 +918,8 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) goto magicalize; case '#': case '*': - if (ckWARN(WARN_DEPRECATED) && len == 1 && sv_type == SVt_PV) - Perl_warner(aTHX_ WARN_DEPRECATED, "Use of $%s is deprecated", name); + 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); /* FALL THROUGH */ case '[': case '^': @@ -1294,12 +1339,23 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) DEBUG_o( Perl_deb(aTHX_ "Checking overloading of `%s' in package `%.256s'\n", cp, HvNAME(stash)) ); - /* don't fill the cache while looking up! */ - gv = gv_fetchmeth(stash, cooky, l, -1); + /* don't fill the cache while looking up! + Creation of inheritance stubs in intermediate packages may + conflict with the logic of runtime method substitution. + Indeed, for inheritance A -> B -> C, if C overloads "+0", + then we could have created stubs for "(+0" in A and C too. + But if B overloads "bool", we may want to use it for + numifying instead of C's "+0". */ + if (i >= DESTROY_amg) + gv = Perl_gv_fetchmeth_autoload(aTHX_ stash, cooky, l, 0); + else /* Autoload taken care of below */ + gv = Perl_gv_fetchmeth(aTHX_ stash, cooky, l, -1); cv = 0; if (gv && (cv = GvCV(gv))) { if (GvNAMELEN(CvGV(cv)) == 3 && strEQ(GvNAME(CvGV(cv)), "nil") && strEQ(HvNAME(GvSTASH(CvGV(cv))), "overload")) { + /* 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; @@ -1327,6 +1383,9 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) filled = 1; if (i < DESTROY_amg) have_ovl = 1; + } else if (gv) { /* Autoloaded... */ + cv = (CV*)gv; + filled = 1; } amt.table[i]=(CV*)SvREFCNT_inc(cv); }