diff options
Diffstat (limited to 'contrib/perl5/gv.c')
-rw-r--r-- | contrib/perl5/gv.c | 1741 |
1 files changed, 0 insertions, 1741 deletions
diff --git a/contrib/perl5/gv.c b/contrib/perl5/gv.c deleted file mode 100644 index 984ce51cd99c..000000000000 --- a/contrib/perl5/gv.c +++ /dev/null @@ -1,1741 +0,0 @@ -/* gv.c - * - * Copyright (c) 1991-2001, 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. - * - */ - -/* - * 'Mercy!' cried Gandalf. 'If the giving of information is to be the cure - * of your inquisitiveness, I shall spend all the rest of my days answering - * you. What more do you want to know?' - * 'The names of all the stars, and of all living things, and the whole - * history of Middle-earth and Over-heaven and of the Sundering Seas,' - * laughed Pippin. - */ - -#include "EXTERN.h" -#define PERL_IN_GV_C -#include "perl.h" - -GV * -Perl_gv_AVadd(pTHX_ register GV *gv) -{ - if (!gv || SvTYPE((SV*)gv) != SVt_PVGV) - Perl_croak(aTHX_ "Bad symbol for array"); - if (!GvAV(gv)) - GvAV(gv) = newAV(); - return gv; -} - -GV * -Perl_gv_HVadd(pTHX_ register GV *gv) -{ - if (!gv || SvTYPE((SV*)gv) != SVt_PVGV) - Perl_croak(aTHX_ "Bad symbol for hash"); - if (!GvHV(gv)) - GvHV(gv) = newHV(); - return gv; -} - -GV * -Perl_gv_IOadd(pTHX_ register GV *gv) -{ - if (!gv || SvTYPE((SV*)gv) != SVt_PVGV) - Perl_croak(aTHX_ "Bad symbol for filehandle"); - if (!GvIOp(gv)) - GvIOp(gv) = newIO(); - return gv; -} - -GV * -Perl_gv_fetchfile(pTHX_ const char *name) -{ - char smallbuf[256]; - char *tmpbuf; - STRLEN tmplen; - GV *gv; - - if (!PL_defstash) - return Nullgv; - - tmplen = strlen(name) + 2; - if (tmplen < sizeof smallbuf) - tmpbuf = smallbuf; - else - New(603, tmpbuf, tmplen + 1, char); - tmpbuf[0] = '_'; - tmpbuf[1] = '<'; - strcpy(tmpbuf + 2, name); - gv = *(GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, TRUE); - 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); - return gv; -} - -void -Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) -{ - register GP *gp; - bool doproto = SvTYPE(gv) > SVt_NULL; - char *proto = (doproto && SvPOK(gv)) ? SvPVX(gv) : NULL; - - sv_upgrade((SV*)gv, SVt_PVGV); - if (SvLEN(gv)) { - if (proto) { - SvPVX(gv) = NULL; - SvLEN(gv) = 0; - SvPOK_off(gv); - } else - Safefree(SvPVX(gv)); - } - Newz(602, gp, 1, GP); - GvGP(gv) = gp_ref(gp); - GvSV(gv) = NEWSV(72,0); - 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, '*', Nullch, 0); - GvSTASH(gv) = (HV*)SvREFCNT_inc(stash); - GvNAME(gv) = savepvn(name, len); - GvNAMELEN(gv) = len; - if (multi || doproto) /* doproto means it _was_ mentioned */ - GvMULTI_on(gv); - 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; - LEAVE; - - PL_sub_generation++; - CvGV(GvCV(gv)) = gv; - CvFILE(GvCV(gv)) = CopFILE(PL_curcop); - CvSTASH(GvCV(gv)) = PL_curstash; -#ifdef USE_THREADS - CvOWNER(GvCV(gv)) = 0; - if (!CvMUTEXP(GvCV(gv))) { - New(666, CvMUTEXP(GvCV(gv)), 1, perl_mutex); - MUTEX_INIT(CvMUTEXP(GvCV(gv))); - } -#endif /* USE_THREADS */ - if (proto) { - sv_setpv((SV*)GvCV(gv), proto); - Safefree(proto); - } - } -} - -STATIC void -S_gv_init_sv(pTHX_ GV *gv, I32 sv_type) -{ - switch (sv_type) { - case SVt_PVIO: - (void)GvIOn(gv); - break; - case SVt_PVAV: - (void)GvAVn(gv); - break; - case SVt_PVHV: - (void)GvHVn(gv); - break; - } -} - -/* -=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) -{ - AV* av; - GV* topgv; - GV* gv; - GV** gvp; - CV* cv; - - if (!stash) - return 0; - if ((level > 100) || (level < -100)) - Perl_croak(aTHX_ "Recursive inheritance detected while looking for method '%s' in package '%s'", - name, HvNAME(stash)); - - DEBUG_o( Perl_deb(aTHX_ "Looking for method %s in package %s\n",name,HvNAME(stash)) ); - - gvp = (GV**)hv_fetch(stash, name, len, (level >= 0)); - if (!gvp) - topgv = Nullgv; - else { - topgv = *gvp; - if (SvTYPE(topgv) != SVt_PVGV) - gv_init(topgv, stash, name, len, TRUE); - if ((cv = GvCV(topgv))) { - /* If genuine method or valid cache entry, use it */ - if (!GvCVGEN(topgv) || GvCVGEN(topgv) == PL_sub_generation) - return topgv; - /* Stale cached entry: junk it */ - SvREFCNT_dec(cv); - GvCV(topgv) = cv = Nullcv; - 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; - - /* create and re-create @.*::SUPER::ISA on demand */ - if (!av || !SvMAGIC(av)) { - char* packname = HvNAME(stash); - STRLEN packlen = strlen(packname); - - if (packlen >= 7 && strEQ(packname + packlen - 7, "::SUPER")) { - HV* basestash; - - packlen -= 7; - basestash = gv_stashpvn(packname, packlen, TRUE); - gvp = (GV**)hv_fetch(basestash, "ISA", 3, FALSE); - if (gvp && (gv = *gvp) != (GV*)&PL_sv_undef && (av = GvAV(gv))) { - gvp = (GV**)hv_fetch(stash, "ISA", 3, TRUE); - if (!gvp || !(gv = *gvp)) - Perl_croak(aTHX_ "Cannot create %s::ISA", HvNAME(stash)); - if (SvTYPE(gv) != SVt_PVGV) - gv_init(gv, stash, "ISA", 3, TRUE); - SvREFCNT_dec(GvAV(gv)); - GvAV(gv) = (AV*)SvREFCNT_inc(av); - } - } - } - - if (av) { - SV** svp = AvARRAY(av); - /* NOTE: No support for tied ISA */ - I32 items = AvFILLp(av) + 1; - while (items--) { - SV* sv = *svp++; - HV* basestash = gv_stashsv(sv, FALSE); - if (!basestash) { - if (ckWARN(WARN_MISC)) - Perl_warner(aTHX_ WARN_MISC, "Can't locate package %s for @%s::ISA", - SvPVX(sv), HvNAME(stash)); - continue; - } - gv = gv_fetchmeth(basestash, name, len, - (level >= 0) ? level + 1 : level - 1); - if (gv) - goto gotcha; - } - } - - /* if at top level, try UNIVERSAL */ - - 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))) - { - gotcha: - /* - * Cache method in topgv if: - * 1. topgv has no synonyms (else inheritance crosses wires) - * 2. method isn't a stub (else AUTOLOAD fails spectacularly) - */ - if (topgv && - GvREFCNT(topgv) == 1 && - (cv = GvCV(gv)) && - (CvROOT(cv) || CvXSUB(cv))) - { - if ((cv = GvCV(topgv))) - SvREFCNT_dec(cv); - GvCV(topgv) = (CV*)SvREFCNT_inc(GvCV(gv)); - GvCVGEN(topgv) = PL_sub_generation; - } - return gv; - } - else if (topgv && GvREFCNT(topgv) == 1) { - /* cache the fact that the method is not defined */ - GvCVGEN(topgv) = PL_sub_generation; - } - } - } - - 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) -{ - register const char *nend; - const char *nsplit = 0; - GV* gv; - - for (nend = name; *nend; nend++) { - if (*nend == '\'') - nsplit = nend; - else if (*nend == ':' && *(nend + 1) == ':') - nsplit = ++nend; - } - if (nsplit) { - const char *origname = name; - name = nsplit + 1; - if (*nsplit == ':') - --nsplit; - 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", - 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) ); - } - else - stash = gv_stashpvn(origname, nsplit - origname, TRUE); - } - - gv = gv_fetchmeth(stash, name, nend - name, 0); - if (!gv) { - if (strEQ(name,"import") || strEQ(name,"unimport")) - gv = (GV*)&PL_sv_yes; - else if (autoload) - gv = gv_autoload4(stash, name, nend - name, TRUE); - } - else if (autoload) { - CV* cv = GvCV(gv); - if (!CvROOT(cv) && !CvXSUB(cv)) { - GV* stubgv; - GV* autogv; - - if (CvANON(cv)) - stubgv = gv; - else { - stubgv = CvGV(cv); - if (GvCV(stubgv) != cv) /* orphaned import */ - stubgv = gv; - } - autogv = gv_autoload4(GvSTASH(stubgv), - GvNAME(stubgv), GvNAMELEN(stubgv), TRUE); - if (autogv) - gv = autogv; - } - } - - return gv; -} - -GV* -Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method) -{ - static char autoload[] = "AUTOLOAD"; - static STRLEN autolen = 8; - GV* gv; - CV* cv; - HV* varstash; - GV* vargv; - SV* varsv; - - 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)) - return Nullgv; - - /* - * Inheriting AUTOLOAD for non-methods works ... for now. - */ - 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", - HvNAME(stash), (int)len, name); - - /* - * Given &FOO::AUTOLOAD, set $FOO::AUTOLOAD to desired function name. - * The subroutine's original name may not be "AUTOLOAD", so we don't - * use that, but for lack of anything better we will use the sub's - * original package to look up $AUTOLOAD. - */ - 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); - SvTAINTED_off(varsv); - 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) -{ - return gv_stashpvn(name, strlen(name), create); -} - -HV* -Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 create) -{ - char smallbuf[256]; - char *tmpbuf; - HV *stash; - GV *tmpgv; - - if (namelen + 3 < sizeof smallbuf) - tmpbuf = smallbuf; - else - New(606, tmpbuf, namelen + 3, char); - Copy(name,tmpbuf,namelen,char); - tmpbuf[namelen++] = ':'; - tmpbuf[namelen++] = ':'; - tmpbuf[namelen] = '\0'; - tmpgv = gv_fetchpv(tmpbuf, create, SVt_PVHV); - if (tmpbuf != smallbuf) - Safefree(tmpbuf); - if (!tmpgv) - return 0; - if (!GvHV(tmpgv)) - GvHV(tmpgv) = newHV(); - stash = GvHV(tmpgv); - if (!HvNAME(stash)) - HvNAME(stash) = savepv(name); - 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) -{ - register char *ptr; - STRLEN len; - ptr = SvPV(sv,len); - return gv_stashpvn(ptr, len, create); -} - - -GV * -Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) -{ - register const char *name = nambeg; - register GV *gv = 0; - GV**gvp; - I32 len; - register const char *namend; - HV *stash = 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 (!stash) - stash = PL_defstash; - if (!stash || !SvREFCNT(stash)) /* symbol table under destruction */ - return Nullgv; - - len = namend - name; - if (len > 0) { - char smallbuf[256]; - char *tmpbuf; - - if (len + 3 < sizeof smallbuf) - tmpbuf = smallbuf; - else - New(601, tmpbuf, len+3, char); - Copy(name, tmpbuf, len, char); - tmpbuf[len++] = ':'; - tmpbuf[len++] = ':'; - tmpbuf[len] = '\0'; - gvp = (GV**)hv_fetch(stash,tmpbuf,len,add); - gv = gvp ? *gvp : Nullgv; - if (gv && gv != (GV*)&PL_sv_undef) { - if (SvTYPE(gv) != SVt_PVGV) - gv_init(gv, stash, tmpbuf, len, (add & GV_ADDMULTI)); - else - GvMULTI_on(gv); - } - if (tmpbuf != smallbuf) - Safefree(tmpbuf); - if (!gv || gv == (GV*)&PL_sv_undef) - return Nullgv; - - if (!(stash = GvHV(gv))) - stash = GvHV(gv) = newHV(); - - if (!HvNAME(stash)) - HvNAME(stash) = savepvn(nambeg, namend - nambeg); - } - - if (*namend == ':') - namend++; - namend++; - name = namend; - if (!*name) - return gv ? gv : (GV*)*hv_fetch(PL_defstash, "main::", 6, TRUE); - } - } - len = namend - name; - if (!len) - len = 1; - - /* No stash in name, so see how we can default */ - - if (!stash) { - if (isIDFIRST_lazy(name)) { - bool global = FALSE; - - if (isUPPER(*name)) { - if (*name == 'S' && ( - strEQ(name, "SIG") || - strEQ(name, "STDIN") || - strEQ(name, "STDOUT") || - strEQ(name, "STDERR"))) - global = TRUE; - else if (*name == 'I' && strEQ(name, "INC")) - global = TRUE; - else if (*name == 'E' && strEQ(name, "ENV")) - global = TRUE; - else if (*name == 'A' && ( - strEQ(name, "ARGV") || - strEQ(name, "ARGVOUT"))) - global = TRUE; - } - else if (*name == '_' && !name[1]) - global = TRUE; - - if (global) - stash = PL_defstash; - else if ((COP*)PL_curcop == &PL_compiling) { - stash = PL_curstash; - if (add && (PL_hints & HINT_STRICT_VARS) && - sv_type != SVt_PVCV && - sv_type != SVt_PVGV && - sv_type != SVt_PVFM && - sv_type != SVt_PVIO && - !(len == 1 && sv_type == SVt_PV && strchr("ab",*name)) ) - { - gvp = (GV**)hv_fetch(stash,name,len,0); - if (!gvp || - *gvp == (GV*)&PL_sv_undef || - SvTYPE(*gvp) != SVt_PVGV) - { - 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)) ) - { - Perl_warn(aTHX_ "Variable \"%c%s\" is not imported", - sv_type == SVt_PVAV ? '@' : - sv_type == SVt_PVHV ? '%' : '$', - name); - if (GvCVu(*gvp)) - Perl_warn(aTHX_ "\t(Did you mean &%s instead?)\n", name); - stash = 0; - } - } - } - else - stash = CopSTASH(PL_curcop); - } - else - stash = PL_defstash; - } - - /* By this point we should have a stash and a name */ - - if (!stash) { - if (add) { - qerror(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; - } - else - return Nullgv; - } - - if (!SvREFCNT(stash)) /* symbol table under destruction */ - return Nullgv; - - gvp = (GV**)hv_fetch(stash,name,len,add); - if (!gvp || *gvp == (GV*)&PL_sv_undef) - return Nullgv; - gv = *gvp; - if (SvTYPE(gv) == SVt_PVGV) { - if (add) { - GvMULTI_on(gv); - gv_init_sv(gv, sv_type); - } - return gv; - } else if (add & GV_NOINIT) { - return gv; - } - - /* Adding a new symbol */ - - if (add & GV_ADDWARN && ckWARN_d(WARN_INTERNAL)) - 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); - - if (isALPHA(name[0]) && ! (isLEXWARN_on ? ckWARN(WARN_ONCE) - : (PL_dowarn & G_WARN_ON ) ) ) - GvMULTI_on(gv) ; - - /* set up magic where warranted */ - switch (*name) { - case 'A': - if (strEQ(name, "ARGV")) { - IoFLAGS(GvIOn(gv)) |= IOf_ARGV|IOf_START; - } - break; - case 'E': - if (strnEQ(name, "EXPORT", 6)) - GvMULTI_on(gv); - break; - case 'I': - if (strEQ(name, "ISA")) { - AV* av = GvAVn(gv); - GvMULTI_on(gv); - sv_magic((SV*)av, (SV*)gv, 'I', Nullch, 0); - /* NOTE: No support for tied ISA */ - if ((add & GV_ADDMULTI) && strEQ(nambeg,"AnyDBM_File::ISA") - && AvFILLp(av) == -1) - { - char *pname; - av_push(av, newSVpvn(pname = "NDBM_File",9)); - gv_stashpvn(pname, 9, TRUE); - av_push(av, newSVpvn(pname = "DB_File",7)); - gv_stashpvn(pname, 7, TRUE); - av_push(av, newSVpvn(pname = "GDBM_File",9)); - gv_stashpvn(pname, 9, TRUE); - av_push(av, newSVpvn(pname = "SDBM_File",9)); - gv_stashpvn(pname, 9, TRUE); - av_push(av, newSVpvn(pname = "ODBM_File",9)); - gv_stashpvn(pname, 9, TRUE); - } - } - break; - case 'O': - if (strEQ(name, "OVERLOAD")) { - HV* hv = GvHVn(gv); - GvMULTI_on(gv); - 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, 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) - sv_setsv(*init, &PL_sv_undef); - PL_psig_ptr[i] = 0; - PL_psig_name[i] = 0; - } - } - break; - case 'V': - if (strEQ(name, "VERSION")) - GvMULTI_on(gv); - break; - - case '&': - if (len > 1) - break; - PL_sawampersand = TRUE; - goto ro_magicalize; - - case '`': - if (len > 1) - break; - PL_sawampersand = TRUE; - goto ro_magicalize; - - case '\'': - if (len > 1) - break; - PL_sawampersand = TRUE; - goto ro_magicalize; - - case ':': - if (len > 1) - break; - sv_setpv(GvSV(gv),PL_chopset); - goto magicalize; - - case '?': - if (len > 1) - break; -#ifdef COMPLEX_STATUS - (void)SvUPGRADE(GvSV(gv), SVt_PVLV); -#endif - goto magicalize; - - case '!': - if (len > 1) - break; - if (sv_type > SVt_PV && PL_curcop != &PL_compiling) { - HV* stash = gv_stashpvn("Errno",5,FALSE); - if (!stash || !(gv_fetchmethod(stash, "TIEHASH"))) { - dSP; - PUTBACK; - require_pv("Errno.pm"); - SPAGAIN; - stash = gv_stashpvn("Errno",5,FALSE); - if (!stash || !(gv_fetchmethod(stash, "TIEHASH"))) - Perl_croak(aTHX_ "Can't use %%! because Errno.pm is not available"); - } - } - goto magicalize; - case '-': - if (len > 1) - break; - else { - AV* av = GvAVn(gv); - sv_magic((SV*)av, Nullsv, 'D', Nullch, 0); - SvREADONLY_on(av); - } - 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); - /* FALL THROUGH */ - 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 '\017': /* $^O */ - case '\020': /* $^P */ - case '\024': /* $^T */ - if (len > 1) - break; - goto magicalize; - case '|': - if (len > 1) - break; - sv_setiv(GvSV(gv), (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0); - goto magicalize; - case '\023': /* $^S */ - if (len > 1) - break; - goto ro_magicalize; - case '\027': /* $^W & $^WARNING_BITS */ - if (len > 1 && strNE(name, "\027ARNING_BITS") - && strNE(name, "\027IDE_SYSTEM_CALLS")) - break; - goto magicalize; - - case '+': - if (len > 1) - break; - else { - AV* av = GvAVn(gv); - sv_magic((SV*)av, (SV*)av, 'D', Nullch, 0); - SvREADONLY_on(av); - } - /* FALL THROUGH */ - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - ro_magicalize: - SvREADONLY_on(GvSV(gv)); - magicalize: - sv_magic(GvSV(gv), (SV*)gv, 0, name, len); - break; - - case '\014': /* $^L */ - if (len > 1) - break; - sv_setpv(GvSV(gv),"\f"); - PL_formfeed = GvSV(gv); - break; - case ';': - if (len > 1) - break; - sv_setpv(GvSV(gv),"\034"); - break; - case ']': - if (len == 1) { - SV *sv = GvSV(gv); - (void)SvUPGRADE(sv, SVt_PVNV); - 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) { - (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)); -} - -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); - if (!egv) - egv = gv; - gv_fullname3(sv, egv, prefix); -} - -/* XXX compatibility with versions <= 5.003. */ -void -Perl_gv_fullname(pTHX_ SV *sv, GV *gv) -{ - gv_fullname3(sv, gv, sv == (SV*)gv ? "*" : ""); -} - -/* XXX compatibility with versions <= 5.003. */ -void -Perl_gv_efullname(pTHX_ SV *sv, GV *gv) -{ - gv_efullname3(sv, gv, sv == (SV*)gv ? "*" : ""); -} - -IO * -Perl_newIO(pTHX) -{ - IO *io; - GV *iogv; - - io = (IO*)NEWSV(0,0); - sv_upgrade((SV *)io,SVt_PVIO); - SvREFCNT(io) = 1; - SvOBJECT_on(io); - iogv = gv_fetchpv("FileHandle::", FALSE, 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); - SvSTASH(io) = (HV*)SvREFCNT_inc(GvHV(iogv)); - return io; -} - -void -Perl_gv_check(pTHX_ HV *stash) -{ - register HE *entry; - register I32 i; - register GV *gv; - HV *hv; - - if (!HvARRAY(stash)) - return; - 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)) && HvNAME(hv)) - { - if (hv != PL_defstash && 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; - 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)); - } - } - } -} - -GV * -Perl_newGVgen(pTHX_ char *pack) -{ - return gv_fetchpv(Perl_form(aTHX_ "%s::_GEN_%ld", pack, (long)PL_gensym++), - TRUE, SVt_PVGV); -} - -/* hopefully this is only called on local symbol table entries */ - -GP* -Perl_gp_ref(pTHX_ GP *gp) -{ - if (!gp) - return (GP*)NULL; - gp->gp_refcnt++; - if (gp->gp_cv) { - if (gp->gp_cvgen) { - /* multi-named GPs cannot be used for method cache */ - SvREFCNT_dec(gp->gp_cv); - gp->gp_cv = Nullcv; - gp->gp_cvgen = 0; - } - else { - /* Adding a new name to a subroutine invalidates method cache */ - PL_sub_generation++; - } - } - return gp; -} - -void -Perl_gp_free(pTHX_ GV *gv) -{ - GP* gp; - - if (!gv || !(gp = GvGP(gv))) - return; - if (gp->gp_refcnt == 0) { - if (ckWARN_d(WARN_INTERNAL)) - Perl_warner(aTHX_ WARN_INTERNAL, - "Attempt to free unreferenced glob pointers"); - return; - } - if (gp->gp_cv) { - /* Deleting the name of a subroutine invalidates method cache */ - PL_sub_generation++; - } - if (--gp->gp_refcnt > 0) { - if (gp->gp_egv == gv) - gp->gp_egv = 0; - 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); - - Safefree(gp); - GvGP(gv) = 0; -} - -#if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286)) -#define MICROPORT -#endif - -#ifdef MICROPORT /* Microport 2.4 hack */ -AV *GvAVn(gv) -register GV *gv; -{ - if (GvGP(gv)->gp_av) - return GvGP(gv)->gp_av; - else - return GvGP(gv_AVadd(gv))->gp_av; -} - -HV *GvHVn(gv) -register GV *gv; -{ - if (GvGP(gv)->gp_hv) - return GvGP(gv)->gp_hv; - else - return GvGP(gv_HVadd(gv))->gp_hv; -} -#endif /* Microport 2.4 hack */ - -/* Updates and caches the CV's */ - -bool -Perl_Gv_AMupdate(pTHX_ HV *stash) -{ - 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) - return AMT_AMAGIC(amtp); - if (amtp && AMT_AMAGIC(amtp)) { /* Have table. */ - int i; - for (i=1; i<NofAMmeth; i++) { - if (amtp->table[i]) { - SvREFCNT_dec(amtp->table[i]); - } - } - } - sv_unmagic((SV*)stash, 'c'); - - DEBUG_o( Perl_deb(aTHX_ "Recalcing overload magic in package %s\n",HvNAME(stash)) ); - - amt.was_ok_am = PL_amagic_generation; - amt.was_ok_sub = PL_sub_generation; - amt.fallback = AMGfallNO; - amt.flags = 0; - -#ifdef OVERLOAD_VIA_HASH - gvp=(GV**)hv_fetch(stash,"OVERLOAD",8,FALSE); /* A shortcut */ - if (gvp && ((gv = *gvp) != (GV*)&PL_sv_undef && (hv = GvHV(gv)))) { - int filled=0; - int i; - char *cp; - SV* sv; - SV** svp; - - /* Work with "fallback" key, which we assume to be first in PL_AMG_names */ - - if (( cp = (char *)PL_AMG_names[0] ) && - (svp = (SV**)hv_fetch(hv,cp,strlen(cp),FALSE)) && (sv = *svp)) { - if (SvTRUE(sv)) amt.fallback=AMGfallYES; - else if (SvOK(sv)) amt.fallback=AMGfallNEVER; - } - 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)) { - default: - if (!SvROK(sv)) { - if (!SvOK(sv)) break; - gv = gv_fetchmethod(stash, SvPV(sv, n_a)); - if (gv) cv = GvCV(gv); - break; - } - cv = (CV*)SvRV(sv); - if (SvTYPE(cv) == SVt_PVCV) - break; - /* FALL THROUGH */ - case SVt_PVHV: - case SVt_PVAV: - Perl_croak(aTHX_ "Not a subroutine reference in overload table"); - return FALSE; - case SVt_PVCV: - cv = (CV*)sv; - break; - case SVt_PVGV: - if (!(cv = GvCVu((GV*)sv))) - cv = sv_2cv(sv, &stash, &gv, FALSE); - break; - } - if (cv) filled=1; - else { - Perl_croak(aTHX_ "Method for operation %s not found in package %.256s during blessing\n", - cp,HvNAME(stash)); - return FALSE; - } - } -#else - { - int filled = 0; - int i; - const char *cp; - SV* sv = NULL; - - /* Work with "fallback" key, which we assume to be first in PL_AMG_names */ - - 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; - } - - for (i = 1; i < NofAMmeth; i++) { - SV *cookie = sv_2mortal(Perl_newSVpvf(aTHX_ "(%s", cp = PL_AMG_names[i])); - 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, SvPVX(cookie), SvCUR(cookie), -1); - cv = 0; - if(gv && (cv = GvCV(gv))) { - if (GvNAMELEN(CvGV(cv)) == 3 && strEQ(GvNAME(CvGV(cv)), "nil") - && strEQ(HvNAME(GvSTASH(CvGV(cv))), "overload")) { - /* GvSV contains the name of the method. */ - GV *ngv; - - 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)) - || !(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)); - } - cv = GvCV(gv = ngv); - } - DEBUG_o( Perl_deb(aTHX_ "Overloading `%s' in package `%.256s' via `%.256s::%.256s' \n", - cp, HvNAME(stash), HvNAME(GvSTASH(CvGV(cv))), - GvNAME(CvGV(cv))) ); - filled = 1; - } -#endif - amt.table[i]=(CV*)SvREFCNT_inc(cv); - } - if (filled) { - AMT_AMAGIC_on(&amt); - sv_magic((SV*)stash, 0, 'c', (char*)&amt, sizeof(AMT)); - return TRUE; - } - } - /* Here we have no table: */ - no_table: - AMT_AMAGIC_off(&amt); - sv_magic((SV*)stash, 0, 'c', (char*)&amt, sizeof(AMTS)); - return FALSE; -} - -SV* -Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) -{ - 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; - int postpr = 0, force_cpy = 0, assignshift = assign ? 1 : 0; - 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) - ? (oamtp = amtp = (AMT*)mg->mg_ptr)->table - : (CV **) NULL)) - && ((cv = cvp[off=method+assignshift]) - || (assign && amtp->fallback > AMGfallNEVER && /* fallback to - * usual method */ - (fl = 1, cv = cvp[off=method])))) { - lr = -1; /* Call method for left argument */ - } else { - if (cvp && amtp->fallback > AMGfallNEVER && flags & AMGf_unary) { - int logic; - - /* look for substituted methods */ - /* In all the covered cases we should be called with assign==0. */ - switch (method) { - case inc_amg: - force_cpy = 1; - if ((cv = cvp[off=add_ass_amg]) - || ((cv = cvp[off = add_amg]) && (force_cpy = 0, postpr = 1))) { - right = &PL_sv_yes; lr = -1; assign = 1; - } - break; - case dec_amg: - force_cpy = 1; - if ((cv = cvp[off = subtr_ass_amg]) - || ((cv = cvp[off = subtr_amg]) && (force_cpy = 0, postpr=1))) { - right = &PL_sv_yes; lr = -1; assign = 1; - } - break; - case bool__amg: - (void)((cv = cvp[off=numer_amg]) || (cv = cvp[off=string_amg])); - break; - case numer_amg: - (void)((cv = cvp[off=string_amg]) || (cv = cvp[off=bool__amg])); - break; - case string_amg: - (void)((cv = cvp[off=numer_amg]) || (cv = cvp[off=bool__amg])); - break; - case not_amg: - (void)((cv = cvp[off=bool__amg]) - || (cv = cvp[off=numer_amg]) - || (cv = cvp[off=string_amg])); - postpr = 1; - break; - case copy_amg: - { - /* - * SV* ref causes confusion with the interpreter variable of - * the same name - */ - SV* 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); - SvOBJECT_on(newref); - SvSTASH(newref) = (HV*)SvREFCNT_inc(SvSTASH(tmpRef)); - return newref; - } - } - break; - 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)); - if (off1==lt_amg) { - SV* lessp = amagic_call(left,nullsv, - lt_amg,AMGf_noright); - logic = SvTRUE(lessp); - } else { - SV* lessp = amagic_call(left,nullsv, - ncmp_amg,AMGf_noright); - logic = (SvNV(lessp) < 0); - } - if (logic) { - if (off==subtr_amg) { - right = left; - left = nullsv; - lr = 1; - } - } else { - return left; - } - } - break; - case neg_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 left; /* Delegate operation to standard mechanisms. */ - break; - default: - goto not_found; - } - 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) - ? (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)) - || (cvp && amtp->fallback > AMGfallNEVER && (lr=1))) - && !(flags & AMGf_unary)) { - /* We look for substitution for - * comparison operations and - * concatenation */ - if (method==concat_amg || method==concat_ass_amg - || method==repeat_amg || method==repeat_ass_amg) { - return NULL; /* Delegate operation to string conversion */ - } - off = -1; - switch (method) { - case lt_amg: - case le_amg: - case gt_amg: - case ge_amg: - case eq_amg: - case ne_amg: - postpr = 1; off=ncmp_amg; break; - case slt_amg: - case sle_amg: - case sgt_amg: - case sge_amg: - case seq_amg: - case sne_amg: - postpr = 1; off=scmp_amg; break; - } - if (off != -1) cv = cvp[off]; - if (!cv) { - goto not_found; - } - } 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])) { - notfound = 1; lr = 1; - } else { - SV *msg; - if (off==-1) off=method; - 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)? - "in overloaded package ": - "has no overloaded magic", - SvAMAGIC(left)? - HvNAME(SvSTASH(SvRV(left))): - "", - SvAMAGIC(right)? - ",\n\tright argument in overloaded package ": - (flags & AMGf_unary - ? "" - : ",\n\tright argument has no overloaded magic"), - SvAMAGIC(right)? - HvNAME(SvSTASH(SvRV(right))): - "")); - if (amtp && amtp->fallback >= AMGfallYES) { - DEBUG_o( Perl_deb(aTHX_ "%s", SvPVX(msg)) ); - } else { - Perl_croak(aTHX_ "%"SVf, msg); - } - return NULL; - } - force_cpy = force_cpy || assign; - } - } - if (!notfound) { - 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? "" : - " (initially `", - method+assignshift==off? "" : - PL_AMG_names[method+assignshift], - method+assignshift==off? "" : "')", - flags & AMGf_unary? "" : - lr==1 ? " for right argument": " for left argument", - flags & AMGf_unary? " for argument" : "", - HvNAME(stash), - fl? ",\n\tassignment variant used": "") ); - } - /* Since we use shallow copy during assignment, we need - * to dublicate the contents, probably calling user-supplied - * version of copy operator - */ - /* We need to copy in following cases: - * a) Assignment form was called. - * assignshift==1, assign==T, method + 1 == off - * 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, - * force_cpy == T - * d) Increment or decrement, translated to nomethod. - * assignshift==0, assign==0, - * force_cpy == T - * e) Assignment form translated to nomethod. - * assignshift==1, assign==T, method + 1 != off - * force_cpy == T - */ - /* off is method, method+assignshift, or a result of opcode substitution. - * In the latter case assignshift==0, so only notfound case is important. - */ - if (( (method + assignshift == off) - && (assign || (method == inc_amg) || (method == dec_amg))) - || force_cpy) - RvDEEPCP(left); - { - dSP; - BINOP myop; - SV* res; - bool oldcatch = CATCH_GET; - - CATCH_SET(TRUE); - Zero(&myop, 1, BINOP); - myop.op_last = (OP *) &myop; - myop.op_next = Nullop; - myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED; - - PUSHSTACKi(PERLSI_OVERLOAD); - ENTER; - SAVEOP(); - PL_op = (OP *) &myop; - if (PERLDB_SUB && PL_curstash != PL_debstash) - PL_op->op_private |= OPpENTERSUB_DB; - PUTBACK; - pp_pushmark(); - - EXTEND(SP, notfound + 5); - PUSHs(lr>0? right: left); - PUSHs(lr>0? left: right); - PUSHs( lr > 0 ? &PL_sv_yes : ( assign ? &PL_sv_undef : &PL_sv_no )); - if (notfound) { - PUSHs( sv_2mortal(newSVpv((char *)PL_AMG_names[method + assignshift],0))); - } - PUSHs((SV*)cv); - PUTBACK; - - if ((PL_op = Perl_pp_entersub(aTHX))) - CALLRUNOPS(aTHX); - LEAVE; - SPAGAIN; - - res=POPs; - PUTBACK; - POPSTACK; - CATCH_SET(oldcatch); - - if (postpr) { - int ans; - switch (method) { - case le_amg: - case sle_amg: - ans=SvIV(res)<=0; break; - case lt_amg: - case slt_amg: - ans=SvIV(res)<0; break; - case ge_amg: - case sge_amg: - ans=SvIV(res)>=0; break; - case gt_amg: - case sgt_amg: - ans=SvIV(res)>0; break; - case eq_amg: - case seq_amg: - ans=SvIV(res)==0; break; - case ne_amg: - case sne_amg: - ans=SvIV(res)!=0; break; - case inc_amg: - case dec_amg: - SvSetSV(left,res); return left; - case not_amg: - ans=!SvTRUE(res); break; - } - return boolSV(ans); - } else if (method==copy_amg) { - if (!SvROK(res)) { - Perl_croak(aTHX_ "Copy method did not return a reference"); - } - return SvREFCNT_inc(SvRV(res)); - } else { - return res; - } - } -} - -/* -=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 '\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 '\017': /* $^O */ - 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; -} |