Mercurial > repo
diff perl-5.22.2/gv.c @ 8045:a16537d2fe07
<xfix> tar xf perl-5.22.2.tar.gz # Ah, whatever, I\'m doing it anyway
author | HackBot |
---|---|
date | Sat, 14 May 2016 14:54:38 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/perl-5.22.2/gv.c Sat May 14 14:54:38 2016 +0000 @@ -0,0 +1,3610 @@ +/* gv.c + * + * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + * 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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. + * + */ + +/* + * '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 in 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. + * + * [p.599 of _The Lord of the Rings_, III/xi: "The PalantÃr"] + */ + +/* +=head1 GV Functions +A GV is a structure which corresponds to to a Perl typeglob, ie *foo. +It is a structure that holds a pointer to a scalar, an array, a hash etc, +corresponding to $foo, @foo, %foo. + +GVs are usually found as values in stashes (symbol table hashes) where +Perl stores its global variables. + +=cut +*/ + +#include "EXTERN.h" +#define PERL_IN_GV_C +#include "perl.h" +#include "overload.c" +#include "keywords.h" +#include "feature.h" + +static const char S_autoload[] = "AUTOLOAD"; +#define S_autolen (sizeof("AUTOLOAD")-1) + +GV * +Perl_gv_add_by_type(pTHX_ GV *gv, svtype type) +{ + SV **where; + + if ( + !gv + || ( + SvTYPE((const SV *)gv) != SVt_PVGV + && SvTYPE((const SV *)gv) != SVt_PVLV + ) + ) { + const char *what; + if (type == SVt_PVIO) { + /* + * if it walks like a dirhandle, then let's assume that + * this is a dirhandle. + */ + what = OP_IS_DIRHOP(PL_op->op_type) ? + "dirhandle" : "filehandle"; + } else if (type == SVt_PVHV) { + what = "hash"; + } else { + what = type == SVt_PVAV ? "array" : "scalar"; + } + /* diag_listed_as: Bad symbol for filehandle */ + Perl_croak(aTHX_ "Bad symbol for %s", what); + } + + if (type == SVt_PVHV) { + where = (SV **)&GvHV(gv); + } else if (type == SVt_PVAV) { + where = (SV **)&GvAV(gv); + } else if (type == SVt_PVIO) { + where = (SV **)&GvIOp(gv); + } else { + where = &GvSV(gv); + } + + if (!*where) + { + *where = newSV_type(type); + if (type == SVt_PVAV && GvNAMELEN(gv) == 3 + && strnEQ(GvNAME(gv), "ISA", 3)) + sv_magic(*where, (SV *)gv, PERL_MAGIC_isa, NULL, 0); + } + return gv; +} + +GV * +Perl_gv_fetchfile(pTHX_ const char *name) +{ + PERL_ARGS_ASSERT_GV_FETCHFILE; + return gv_fetchfile_flags(name, strlen(name), 0); +} + +GV * +Perl_gv_fetchfile_flags(pTHX_ const char *const name, const STRLEN namelen, + const U32 flags) +{ + char smallbuf[128]; + char *tmpbuf; + const STRLEN tmplen = namelen + 2; + GV *gv; + + PERL_ARGS_ASSERT_GV_FETCHFILE_FLAGS; + PERL_UNUSED_ARG(flags); + + if (!PL_defstash) + return NULL; + + if (tmplen <= sizeof smallbuf) + tmpbuf = smallbuf; + else + Newx(tmpbuf, tmplen, char); + /* This is where the debugger's %{"::_<$filename"} hash is created */ + tmpbuf[0] = '_'; + tmpbuf[1] = '<'; + memcpy(tmpbuf + 2, name, namelen); + gv = *(GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, TRUE); + if (!isGV(gv)) { + gv_init(gv, PL_defstash, tmpbuf, tmplen, FALSE); +#ifdef PERL_DONT_CREATE_GVSV + GvSV(gv) = newSVpvn(name, namelen); +#else + sv_setpvn(GvSV(gv), name, namelen); +#endif + } + if ((PERLDB_LINE || PERLDB_SAVESRC) && !GvAV(gv)) + hv_magic(GvHVn(gv), GvAVn(gv), PERL_MAGIC_dbfile); + if (tmpbuf != smallbuf) + Safefree(tmpbuf); + 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) +{ + PERL_ARGS_ASSERT_GV_CONST_SV; + PERL_UNUSED_CONTEXT; + + if (SvTYPE(gv) == SVt_PVGV) + return cv_const_sv(GvCVu(gv)); + return SvROK(gv) && SvTYPE(SvRV(gv)) != SVt_PVAV && SvTYPE(SvRV(gv)) != SVt_PVCV ? SvRV(gv) : NULL; +} + +GP * +Perl_newGP(pTHX_ GV *const gv) +{ + GP *gp; + U32 hash; + const char *file; + STRLEN len; +#ifndef USE_ITHREADS + GV *filegv; +#endif + dVAR; + + PERL_ARGS_ASSERT_NEWGP; + Newxz(gp, 1, GP); + gp->gp_egv = gv; /* allow compiler to reuse gv after this */ +#ifndef PERL_DONT_CREATE_GVSV + gp->gp_sv = newSV(0); +#endif + + /* PL_curcop may be null here. E.g., + INIT { bless {} and exit } + frees INIT before looking up DESTROY (and creating *DESTROY) + */ + if (PL_curcop) { + gp->gp_line = CopLINE(PL_curcop); /* 0 otherwise Newxz */ +#ifdef USE_ITHREADS + if (CopFILE(PL_curcop)) { + file = CopFILE(PL_curcop); + len = strlen(file); + } +#else + filegv = CopFILEGV(PL_curcop); + if (filegv) { + file = GvNAME(filegv)+2; + len = GvNAMELEN(filegv)-2; + } +#endif + else goto no_file; + } + else { + no_file: + file = ""; + len = 0; + } + + PERL_HASH(hash, file, len); + gp->gp_file_hek = share_hek(file, len, hash); + gp->gp_refcnt = 1; + + return gp; +} + +/* Assign CvGV(cv) = gv, handling weak references. + * See also S_anonymise_cv_maybe */ + +void +Perl_cvgv_set(pTHX_ CV* cv, GV* gv) +{ + GV * const oldgv = CvNAMED(cv) ? NULL : SvANY(cv)->xcv_gv_u.xcv_gv; + HEK *hek; + PERL_ARGS_ASSERT_CVGV_SET; + + if (oldgv == gv) + return; + + if (oldgv) { + if (CvCVGV_RC(cv)) { + SvREFCNT_dec_NN(oldgv); + CvCVGV_RC_off(cv); + } + else { + sv_del_backref(MUTABLE_SV(oldgv), MUTABLE_SV(cv)); + } + } + else if ((hek = CvNAME_HEK(cv))) { + unshare_hek(hek); + CvLEXICAL_off(cv); + } + + CvNAMED_off(cv); + SvANY(cv)->xcv_gv_u.xcv_gv = gv; + assert(!CvCVGV_RC(cv)); + + if (!gv) + return; + + if (isGV_with_GP(gv) && GvGP(gv) && (GvCV(gv) == cv || GvFORM(gv) == cv)) + Perl_sv_add_backref(aTHX_ MUTABLE_SV(gv), MUTABLE_SV(cv)); + else { + CvCVGV_RC_on(cv); + SvREFCNT_inc_simple_void_NN(gv); + } +} + +/* Convert CvSTASH + CvNAME_HEK into a GV. Conceptually, all subs have a + GV, but for efficiency that GV may not in fact exist. This function, + called by CvGV, reifies it. */ + +GV * +Perl_cvgv_from_hek(pTHX_ CV *cv) +{ + GV *gv; + SV **svp; + PERL_ARGS_ASSERT_CVGV_FROM_HEK; + assert(SvTYPE(cv) == SVt_PVCV); + if (!CvSTASH(cv)) return NULL; + ASSUME(CvNAME_HEK(cv)); + svp = hv_fetchhek(CvSTASH(cv), CvNAME_HEK(cv), 0); + gv = MUTABLE_GV(svp && *svp ? *svp : newSV(0)); + if (!isGV(gv)) + gv_init_pvn(gv, CvSTASH(cv), HEK_KEY(CvNAME_HEK(cv)), + HEK_LEN(CvNAME_HEK(cv)), + SVf_UTF8 * !!HEK_UTF8(CvNAME_HEK(cv))); + if (!CvNAMED(cv)) { /* gv_init took care of it */ + assert (SvANY(cv)->xcv_gv_u.xcv_gv == gv); + return gv; + } + unshare_hek(CvNAME_HEK(cv)); + CvNAMED_off(cv); + SvANY(cv)->xcv_gv_u.xcv_gv = gv; + if (svp && *svp) SvREFCNT_inc_simple_void_NN(gv); + CvCVGV_RC_on(cv); + return gv; +} + +/* Assign CvSTASH(cv) = st, handling weak references. */ + +void +Perl_cvstash_set(pTHX_ CV *cv, HV *st) +{ + HV *oldst = CvSTASH(cv); + PERL_ARGS_ASSERT_CVSTASH_SET; + if (oldst == st) + return; + if (oldst) + sv_del_backref(MUTABLE_SV(oldst), MUTABLE_SV(cv)); + SvANY(cv)->xcv_stash = st; + if (st) + Perl_sv_add_backref(aTHX_ MUTABLE_SV(st), MUTABLE_SV(cv)); +} + +/* +=for apidoc gv_init_pvn + +Converts a scalar into a typeglob. This is an incoercible typeglob; +assigning a reference to it will assign to one of its slots, instead of +overwriting it as happens with typeglobs created by SvSetSV. Converting +any scalar that is SvOK() may produce unpredictable results and is reserved +for perl's internal use. + +C<gv> is the scalar to be converted. + +C<stash> is the parent stash/package, if any. + +C<name> and C<len> give the name. The name must be unqualified; +that is, it must not include the package name. If C<gv> is a +stash element, it is the caller's responsibility to ensure that the name +passed to this function matches the name of the element. If it does not +match, perl's internal bookkeeping will get out of sync. + +C<flags> can be set to SVf_UTF8 if C<name> is a UTF8 string, or +the return value of SvUTF8(sv). It can also take the +GV_ADDMULTI flag, which means to pretend that the GV has been +seen before (i.e., suppress "Used once" warnings). + +=for apidoc gv_init + +The old form of gv_init_pvn(). It does not work with UTF8 strings, as it +has no flags parameter. If the C<multi> parameter is set, the +GV_ADDMULTI flag will be passed to gv_init_pvn(). + +=for apidoc gv_init_pv + +Same as gv_init_pvn(), but takes a nul-terminated string for the name +instead of separate char * and length parameters. + +=for apidoc gv_init_sv + +Same as gv_init_pvn(), but takes an SV * for the name instead of separate +char * and length parameters. C<flags> is currently unused. + +=cut +*/ + +void +Perl_gv_init_sv(pTHX_ GV *gv, HV *stash, SV* namesv, U32 flags) +{ + char *namepv; + STRLEN namelen; + PERL_ARGS_ASSERT_GV_INIT_SV; + namepv = SvPV(namesv, namelen); + if (SvUTF8(namesv)) + flags |= SVf_UTF8; + gv_init_pvn(gv, stash, namepv, namelen, flags); +} + +void +Perl_gv_init_pv(pTHX_ GV *gv, HV *stash, const char *name, U32 flags) +{ + PERL_ARGS_ASSERT_GV_INIT_PV; + gv_init_pvn(gv, stash, name, strlen(name), flags); +} + +void +Perl_gv_init_pvn(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, U32 flags) +{ + const U32 old_type = SvTYPE(gv); + const bool doproto = old_type > SVt_NULL; + char * const proto = (doproto && SvPOK(gv)) + ? ((void)(SvIsCOW(gv) && (sv_force_normal((SV *)gv), 0)), SvPVX(gv)) + : NULL; + const STRLEN protolen = proto ? SvCUR(gv) : 0; + const U32 proto_utf8 = proto ? SvUTF8(gv) : 0; + SV *const has_constant = doproto && SvROK(gv) ? SvRV(gv) : NULL; + const U32 exported_constant = has_constant ? SvPCS_IMPORTED(gv) : 0; + + PERL_ARGS_ASSERT_GV_INIT_PVN; + assert (!(proto && has_constant)); + + if (has_constant) { + /* The constant has to be a scalar, array or subroutine. */ + switch (SvTYPE(has_constant)) { + case SVt_PVHV: + case SVt_PVFM: + case SVt_PVIO: + Perl_croak(aTHX_ "Cannot convert a reference to %s to typeglob", + sv_reftype(has_constant, 0)); + + default: NOOP; + } + SvRV_set(gv, NULL); + SvROK_off(gv); + } + + + if (old_type < SVt_PVGV) { + if (old_type >= SVt_PV) + SvCUR_set(gv, 0); + sv_upgrade(MUTABLE_SV(gv), SVt_PVGV); + } + if (SvLEN(gv)) { + if (proto) { + SvPV_set(gv, NULL); + SvLEN_set(gv, 0); + SvPOK_off(gv); + } else + Safefree(SvPVX_mutable(gv)); + } + SvIOK_off(gv); + isGV_with_GP_on(gv); + + GvGP_set(gv, Perl_newGP(aTHX_ gv)); + GvSTASH(gv) = stash; + if (stash) + Perl_sv_add_backref(aTHX_ MUTABLE_SV(stash), MUTABLE_SV(gv)); + gv_name_set(gv, name, len, GV_ADD | ( flags & SVf_UTF8 ? SVf_UTF8 : 0 )); + if (flags & GV_ADDMULTI || doproto) /* doproto means it */ + GvMULTI_on(gv); /* _was_ mentioned */ + if (has_constant && SvTYPE(has_constant) == SVt_PVCV) { + /* Not actually a constant. Just a regular sub. */ + CV * const cv = (CV *)has_constant; + GvCV_set(gv,cv); + if (CvSTASH(cv) == stash && ( + CvNAME_HEK(cv) == GvNAME_HEK(gv) + || ( HEK_LEN(CvNAME_HEK(cv)) == HEK_LEN(GvNAME_HEK(gv)) + && HEK_FLAGS(CvNAME_HEK(cv)) != HEK_FLAGS(GvNAME_HEK(gv)) + && HEK_UTF8(CvNAME_HEK(cv)) == HEK_UTF8(GvNAME_HEK(gv)) + && memEQ(HEK_KEY(CvNAME_HEK(cv)), GvNAME(gv), GvNAMELEN(gv)) + ) + )) + CvGV_set(cv,gv); + } + else if (doproto) { + CV *cv; + if (has_constant) { + /* newCONSTSUB takes ownership of the reference from us. */ + cv = newCONSTSUB_flags(stash, name, len, flags, has_constant); + /* In case op.c:S_process_special_blocks stole it: */ + if (!GvCV(gv)) + GvCV_set(gv, (CV *)SvREFCNT_inc_simple_NN(cv)); + assert(GvCV(gv) == cv); /* newCONSTSUB should have set this */ + /* If this reference was a copy of another, then the subroutine + must have been "imported", by a Perl space assignment to a GV + from a reference to CV. */ + if (exported_constant) + GvIMPORTED_CV_on(gv); + CvSTASH_set(cv, PL_curstash); /* XXX Why is this needed? */ + } else { + cv = newSTUB(gv,1); + } + if (proto) { + sv_usepvn_flags(MUTABLE_SV(cv), proto, protolen, + SV_HAS_TRAILING_NUL); + if ( proto_utf8 ) SvUTF8_on(MUTABLE_SV(cv)); + } + } +} + +STATIC void +S_gv_init_svtype(pTHX_ GV *gv, const svtype sv_type) +{ + PERL_ARGS_ASSERT_GV_INIT_SVTYPE; + + switch (sv_type) { + case SVt_PVIO: + (void)GvIOn(gv); + break; + case SVt_PVAV: + (void)GvAVn(gv); + break; + case SVt_PVHV: + (void)GvHVn(gv); + break; +#ifdef PERL_DONT_CREATE_GVSV + case SVt_NULL: + case SVt_PVCV: + case SVt_PVFM: + case SVt_PVGV: + break; + default: + if(GvSVn(gv)) { + /* Work round what appears to be a bug in Sun C++ 5.8 2005/10/13 + If we just cast GvSVn(gv) to void, it ignores evaluating it for + its side effect */ + } +#endif + } +} + +static void core_xsub(pTHX_ CV* cv); + +static GV * +S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv, + const char * const name, const STRLEN len) +{ + const int code = keyword(name, len, 1); + static const char file[] = __FILE__; + CV *cv, *oldcompcv = NULL; + int opnum = 0; + bool ampable = TRUE; /* &{}-able */ + COP *oldcurcop = NULL; + yy_parser *oldparser = NULL; + I32 oldsavestack_ix = 0; + + assert(gv || stash); + assert(name); + + if (!code) return NULL; /* Not a keyword */ + switch (code < 0 ? -code : code) { + /* no support for \&CORE::infix; + no support for funcs that do not parse like funcs */ + case KEY___DATA__: case KEY___END__: case KEY_and: case KEY_AUTOLOAD: + case KEY_BEGIN : case KEY_CHECK : case KEY_cmp: + case KEY_default : case KEY_DESTROY: + case KEY_do : case KEY_dump : case KEY_else : case KEY_elsif : + case KEY_END : case KEY_eq : case KEY_eval : + case KEY_for : case KEY_foreach: case KEY_format: case KEY_ge : + case KEY_given : case KEY_goto : case KEY_grep : + case KEY_gt : case KEY_if: case KEY_INIT: case KEY_last: case KEY_le: + case KEY_local: case KEY_lt: case KEY_m : case KEY_map : case KEY_my: + case KEY_ne : case KEY_next : case KEY_no: case KEY_or: case KEY_our: + case KEY_package: case KEY_print: case KEY_printf: + case KEY_q : case KEY_qq : case KEY_qr : case KEY_qw : + case KEY_qx : case KEY_redo : case KEY_require: case KEY_return: + case KEY_s : case KEY_say : case KEY_sort : + case KEY_state: case KEY_sub : + case KEY_tr : case KEY_UNITCHECK: case KEY_unless: + case KEY_until: case KEY_use : case KEY_when : case KEY_while : + case KEY_x : case KEY_xor : case KEY_y : + return NULL; + case KEY_chdir: + case KEY_chomp: case KEY_chop: case KEY_defined: case KEY_delete: + case KEY_each : case KEY_eof : case KEY_exec : case KEY_exists: + case KEY_keys: + case KEY_lstat: + case KEY_pop: + case KEY_push: + case KEY_shift: + case KEY_splice: case KEY_split: + case KEY_stat: + case KEY_system: + case KEY_truncate: case KEY_unlink: + case KEY_unshift: + case KEY_values: + ampable = FALSE; + } + if (!gv) { + gv = (GV *)newSV(0); + gv_init(gv, stash, name, len, TRUE); + } + GvMULTI_on(gv); + if (ampable) { + ENTER; + oldcurcop = PL_curcop; + oldparser = PL_parser; + lex_start(NULL, NULL, 0); + oldcompcv = PL_compcv; + PL_compcv = NULL; /* Prevent start_subparse from setting + CvOUTSIDE. */ + oldsavestack_ix = start_subparse(FALSE,0); + cv = PL_compcv; + } + else { + /* Avoid calling newXS, as it calls us, and things start to + get hairy. */ + cv = MUTABLE_CV(newSV_type(SVt_PVCV)); + GvCV_set(gv,cv); + GvCVGEN(gv) = 0; + CvISXSUB_on(cv); + CvXSUB(cv) = core_xsub; + PoisonPADLIST(cv); + } + CvGV_set(cv, gv); /* This stops new ATTRSUB from setting CvFILE + from PL_curcop. */ + (void)gv_fetchfile(file); + CvFILE(cv) = (char *)file; + /* XXX This is inefficient, as doing things this order causes + a prototype check in newATTRSUB. But we have to do + it this order as we need an op number before calling + new ATTRSUB. */ + (void)core_prototype((SV *)cv, name, code, &opnum); + if (stash) + (void)hv_store(stash,name,len,(SV *)gv,0); + if (ampable) { +#ifdef DEBUGGING + CV *orig_cv = cv; +#endif + CvLVALUE_on(cv); + /* newATTRSUB will free the CV and return NULL if we're still + compiling after a syntax error */ + if ((cv = newATTRSUB_x( + oldsavestack_ix, (OP *)gv, + NULL,NULL, + coresub_op( + opnum + ? newSVuv((UV)opnum) + : newSVpvn(name,len), + code, opnum + ), + TRUE + )) != NULL) { + assert(GvCV(gv) == orig_cv); + if (opnum != OP_VEC && opnum != OP_SUBSTR && opnum != OP_POS + && opnum != OP_UNDEF) + CvLVALUE_off(cv); /* Now *that* was a neat trick. */ + } + LEAVE; + PL_parser = oldparser; + PL_curcop = oldcurcop; + PL_compcv = oldcompcv; + } + if (cv) { + SV *opnumsv = opnum ? newSVuv((UV)opnum) : (SV *)NULL; + cv_set_call_checker( + cv, Perl_ck_entersub_args_core, opnumsv ? opnumsv : (SV *)cv + ); + SvREFCNT_dec(opnumsv); + } + + return gv; +} + +/* +=for apidoc gv_fetchmeth + +Like L</gv_fetchmeth_pvn>, but lacks a flags parameter. + +=for apidoc gv_fetchmeth_sv + +Exactly like L</gv_fetchmeth_pvn>, but takes the name string in the form +of an SV instead of a string/length pair. + +=cut +*/ + +GV * +Perl_gv_fetchmeth_sv(pTHX_ HV *stash, SV *namesv, I32 level, U32 flags) +{ + char *namepv; + STRLEN namelen; + PERL_ARGS_ASSERT_GV_FETCHMETH_SV; + if (LIKELY(SvPOK_nog(namesv))) /* common case */ + return gv_fetchmeth_internal(stash, namesv, NULL, 0, level, flags); + namepv = SvPV(namesv, namelen); + if (SvUTF8(namesv)) flags |= SVf_UTF8; + return gv_fetchmeth_pvn(stash, namepv, namelen, level, flags); +} + +/* +=for apidoc gv_fetchmeth_pv + +Exactly like L</gv_fetchmeth_pvn>, but takes a nul-terminated string +instead of a string/length pair. + +=cut +*/ + +GV * +Perl_gv_fetchmeth_pv(pTHX_ HV *stash, const char *name, I32 level, U32 flags) +{ + PERL_ARGS_ASSERT_GV_FETCHMETH_PV; + return gv_fetchmeth_internal(stash, NULL, name, strlen(name), level, flags); +} + +/* +=for apidoc gv_fetchmeth_pvn + +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. + +The only significant values for C<flags> are GV_SUPER and SVf_UTF8. + +GV_SUPER indicates that we want to look up the method in the superclasses +of the C<stash>. + +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 +*/ + +/* NOTE: No support for tied ISA */ + +PERL_STATIC_INLINE GV* +S_gv_fetchmeth_internal(pTHX_ HV* stash, SV* meth, const char* name, STRLEN len, I32 level, U32 flags) +{ + GV** gvp; + HE* he; + AV* linear_av; + SV** linear_svp; + SV* linear_sv; + HV* cstash, *cachestash; + GV* candidate = NULL; + CV* cand_cv = NULL; + GV* topgv = NULL; + const char *hvname; + I32 create = (level >= 0) ? HV_FETCH_LVALUE : 0; + I32 items; + U32 topgen_cmp; + U32 is_utf8 = flags & SVf_UTF8; + + /* UNIVERSAL methods should be callable without a stash */ + if (!stash) { + create = 0; /* probably appropriate */ + if(!(stash = gv_stashpvs("UNIVERSAL", 0))) + return 0; + } + + assert(stash); + + hvname = HvNAME_get(stash); + if (!hvname) + Perl_croak(aTHX_ "Can't use anonymous symbol table for method lookup"); + + assert(hvname); + assert(name || meth); + + DEBUG_o( Perl_deb(aTHX_ "Looking for %smethod %s in package %s\n", + flags & GV_SUPER ? "SUPER " : "", + name ? name : SvPV_nolen(meth), hvname) ); + + topgen_cmp = HvMROMETA(stash)->cache_gen + PL_sub_generation; + + if (flags & GV_SUPER) { + if (!HvAUX(stash)->xhv_mro_meta->super) + HvAUX(stash)->xhv_mro_meta->super = newHV(); + cachestash = HvAUX(stash)->xhv_mro_meta->super; + } + else cachestash = stash; + + /* check locally for a real method or a cache entry */ + he = (HE*)hv_common( + cachestash, meth, name, len, (flags & SVf_UTF8) ? HVhek_UTF8 : 0, create, NULL, 0 + ); + if (he) gvp = (GV**)&HeVAL(he); + else gvp = NULL; + + if(gvp) { + topgv = *gvp; + have_gv: + assert(topgv); + if (SvTYPE(topgv) != SVt_PVGV) + { + if (!name) + name = SvPV_nomg(meth, len); + gv_init_pvn(topgv, stash, name, len, GV_ADDMULTI|is_utf8); + } + if ((cand_cv = GvCV(topgv))) { + /* If genuine method or valid cache entry, use it */ + if (!GvCVGEN(topgv) || GvCVGEN(topgv) == topgen_cmp) { + return topgv; + } + else { + /* stale cache entry, junk it and move on */ + SvREFCNT_dec_NN(cand_cv); + GvCV_set(topgv, NULL); + cand_cv = NULL; + GvCVGEN(topgv) = 0; + } + } + else if (GvCVGEN(topgv) == topgen_cmp) { + /* cache indicates no such method definitively */ + return 0; + } + else if (stash == cachestash + && len > 1 /* shortest is uc */ && HvNAMELEN_get(stash) == 4 + && strnEQ(hvname, "CORE", 4) + && S_maybe_add_coresub(aTHX_ NULL,topgv,name,len)) + goto have_gv; + } + + linear_av = mro_get_linear_isa(stash); /* has ourselves at the top of the list */ + linear_svp = AvARRAY(linear_av) + 1; /* skip over self */ + items = AvFILLp(linear_av); /* no +1, to skip over self */ + while (items--) { + linear_sv = *linear_svp++; + assert(linear_sv); + cstash = gv_stashsv(linear_sv, 0); + + if (!cstash) { + Perl_ck_warner(aTHX_ packWARN(WARN_SYNTAX), + "Can't locate package %"SVf" for @%"HEKf"::ISA", + SVfARG(linear_sv), + HEKfARG(HvNAME_HEK(stash))); + continue; + } + + assert(cstash); + + gvp = (GV**)hv_fetch(cstash, name, is_utf8 ? -(I32)len : (I32)len, 0); + if (!gvp) { + if (len > 1 && HvNAMELEN_get(cstash) == 4) { + const char *hvname = HvNAME(cstash); assert(hvname); + if (strnEQ(hvname, "CORE", 4) + && (candidate = + S_maybe_add_coresub(aTHX_ cstash,NULL,name,len) + )) + goto have_candidate; + } + continue; + } + else candidate = *gvp; + have_candidate: + assert(candidate); + if (SvTYPE(candidate) != SVt_PVGV) + gv_init_pvn(candidate, cstash, name, len, GV_ADDMULTI|is_utf8); + if (SvTYPE(candidate) == SVt_PVGV && (cand_cv = GvCV(candidate)) && !GvCVGEN(candidate)) { + /* + * Found real method, 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) && (CvROOT(cand_cv) || CvXSUB(cand_cv))) { + CV *old_cv = GvCV(topgv); + SvREFCNT_dec(old_cv); + SvREFCNT_inc_simple_void_NN(cand_cv); + GvCV_set(topgv, cand_cv); + GvCVGEN(topgv) = topgen_cmp; + } + return candidate; + } + } + + /* Check UNIVERSAL without caching */ + if(level == 0 || level == -1) { + candidate = gv_fetchmeth_internal(NULL, meth, name, len, 1, + flags &~GV_SUPER); + if(candidate) { + cand_cv = GvCV(candidate); + if (topgv && (GvREFCNT(topgv) == 1) && (CvROOT(cand_cv) || CvXSUB(cand_cv))) { + CV *old_cv = GvCV(topgv); + SvREFCNT_dec(old_cv); + SvREFCNT_inc_simple_void_NN(cand_cv); + GvCV_set(topgv, cand_cv); + GvCVGEN(topgv) = topgen_cmp; + } + return candidate; + } + } + + if (topgv && GvREFCNT(topgv) == 1) { + /* cache the fact that the method is not defined */ + GvCVGEN(topgv) = topgen_cmp; + } + + return 0; +} + +GV * +Perl_gv_fetchmeth_pvn(pTHX_ HV *stash, const char *name, STRLEN len, I32 level, U32 flags) +{ + PERL_ARGS_ASSERT_GV_FETCHMETH_PVN; + return gv_fetchmeth_internal(stash, NULL, name, len, level, flags); +} + +/* +=for apidoc gv_fetchmeth_autoload + +This is the old form of L</gv_fetchmeth_pvn_autoload>, which has no flags +parameter. + +=for apidoc gv_fetchmeth_sv_autoload + +Exactly like L</gv_fetchmeth_pvn_autoload>, but takes the name string in the form +of an SV instead of a string/length pair. + +=cut +*/ + +GV * +Perl_gv_fetchmeth_sv_autoload(pTHX_ HV *stash, SV *namesv, I32 level, U32 flags) +{ + char *namepv; + STRLEN namelen; + PERL_ARGS_ASSERT_GV_FETCHMETH_SV_AUTOLOAD; + namepv = SvPV(namesv, namelen); + if (SvUTF8(namesv)) + flags |= SVf_UTF8; + return gv_fetchmeth_pvn_autoload(stash, namepv, namelen, level, flags); +} + +/* +=for apidoc gv_fetchmeth_pv_autoload + +Exactly like L</gv_fetchmeth_pvn_autoload>, but takes a nul-terminated string +instead of a string/length pair. + +=cut +*/ + +GV * +Perl_gv_fetchmeth_pv_autoload(pTHX_ HV *stash, const char *name, I32 level, U32 flags) +{ + PERL_ARGS_ASSERT_GV_FETCHMETH_PV_AUTOLOAD; + return gv_fetchmeth_pvn_autoload(stash, name, strlen(name), level, flags); +} + +/* +=for apidoc gv_fetchmeth_pvn_autoload + +Same as gv_fetchmeth_pvn(), 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<level < 0>. For an autoloaded subroutine without a stub, GvCV() +of the result may be zero. + +Currently, the only significant value for C<flags> is SVf_UTF8. + +=cut +*/ + +GV * +Perl_gv_fetchmeth_pvn_autoload(pTHX_ HV *stash, const char *name, STRLEN len, I32 level, U32 flags) +{ + GV *gv = gv_fetchmeth_pvn(stash, name, len, level, flags); + + PERL_ARGS_ASSERT_GV_FETCHMETH_PVN_AUTOLOAD; + + if (!gv) { + CV *cv; + GV **gvp; + + if (!stash) + return NULL; /* UNIVERSAL::AUTOLOAD could cause trouble */ + if (len == S_autolen && memEQ(name, S_autoload, S_autolen)) + return NULL; + if (!(gv = gv_fetchmeth_pvn(stash, S_autoload, S_autolen, FALSE, flags))) + return NULL; + cv = GvCV(gv); + if (!(CvROOT(cv) || CvXSUB(cv))) + return NULL; + /* Have an autoload */ + if (level < 0) /* Cannot do without a stub */ + gv_fetchmeth_pvn(stash, name, len, 0, flags); + gvp = (GV**)hv_fetch(stash, name, + (flags & SVf_UTF8) ? -(I32)len : (I32)len, (level >= 0)); + if (!gvp) + return NULL; + return *gvp; + } + return gv; +} + +/* +=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 as a side effect to do this. + +These functions have the same side-effects as C<gv_fetchmeth> with +C<level==0>. The warning against passing the GV returned by +C<gv_fetchmeth> to C<call_sv> applies equally to these functions. + +=cut +*/ + +GV * +Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload) +{ + PERL_ARGS_ASSERT_GV_FETCHMETHOD_AUTOLOAD; + + return gv_fetchmethod_flags(stash, name, autoload ? GV_AUTOLOAD : 0); +} + +GV * +Perl_gv_fetchmethod_sv_flags(pTHX_ HV *stash, SV *namesv, U32 flags) +{ + char *namepv; + STRLEN namelen; + PERL_ARGS_ASSERT_GV_FETCHMETHOD_SV_FLAGS; + namepv = SvPV(namesv, namelen); + if (SvUTF8(namesv)) + flags |= SVf_UTF8; + return gv_fetchmethod_pvn_flags(stash, namepv, namelen, flags); +} + +GV * +Perl_gv_fetchmethod_pv_flags(pTHX_ HV *stash, const char *name, U32 flags) +{ + PERL_ARGS_ASSERT_GV_FETCHMETHOD_PV_FLAGS; + return gv_fetchmethod_pvn_flags(stash, name, strlen(name), flags); +} + +/* Don't merge this yet, as it's likely to get a len parameter, and possibly + even a U32 hash */ +GV * +Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN len, U32 flags) +{ + const char *nend; + const char *nsplit = NULL; + GV* gv; + HV* ostash = stash; + const char * const origname = name; + SV *const error_report = MUTABLE_SV(stash); + const U32 autoload = flags & GV_AUTOLOAD; + const U32 do_croak = flags & GV_CROAK; + const U32 is_utf8 = flags & SVf_UTF8; + + PERL_ARGS_ASSERT_GV_FETCHMETHOD_PVN_FLAGS; + + if (SvTYPE(stash) < SVt_PVHV) + stash = NULL; + else { + /* The only way stash can become NULL later on is if nsplit is set, + which in turn means that there is no need for a SVt_PVHV case + the error reporting code. */ + } + + for (nend = name; *nend || nend != (origname + len); nend++) { + if (*nend == '\'') { + nsplit = nend; + name = nend + 1; + } + else if (*nend == ':' && *(nend + 1) == ':') { + nsplit = nend++; + name = nend + 1; + } + } + if (nsplit) { + if ((nsplit - origname) == 5 && memEQ(origname, "SUPER", 5)) { + /* ->SUPER::method should really be looked up in original stash */ + stash = CopSTASH(PL_curcop); + flags |= GV_SUPER; + DEBUG_o( Perl_deb(aTHX_ "Treating %s as %s::%s\n", + origname, HvENAME_get(stash), name) ); + } + else if ((nsplit - origname) >= 7 && + strnEQ(nsplit - 7, "::SUPER", 7)) { + /* don't autovifify if ->NoSuchStash::SUPER::method */ + stash = gv_stashpvn(origname, nsplit - origname - 7, is_utf8); + if (stash) flags |= GV_SUPER; + } + else { + /* don't autovifify if ->NoSuchStash::method */ + stash = gv_stashpvn(origname, nsplit - origname, is_utf8); + } + ostash = stash; + } + + gv = gv_fetchmeth_pvn(stash, name, nend - name, 0, flags); + if (!gv) { + if (strEQ(name,"import") || strEQ(name,"unimport")) + gv = MUTABLE_GV(&PL_sv_yes); + else if (autoload) + gv = gv_autoload_pvn( + ostash, name, nend - name, GV_AUTOLOAD_ISMETHOD|flags + ); + if (!gv && do_croak) { + /* Right now this is exclusively for the benefit of S_method_common + in pp_hot.c */ + if (stash) { + /* If we can't find an IO::File method, it might be a call on + * a filehandle. If IO:File has not been loaded, try to + * require it first instead of croaking */ + const char *stash_name = HvNAME_get(stash); + if (stash_name && memEQs(stash_name, HvNAMELEN_get(stash), "IO::File") + && !Perl_hv_common(aTHX_ GvHVn(PL_incgv), NULL, + STR_WITH_LEN("IO/File.pm"), 0, + HV_FETCH_ISEXISTS, NULL, 0) + ) { + require_pv("IO/File.pm"); + gv = gv_fetchmeth_pvn(stash, name, nend - name, 0, flags); + if (gv) + return gv; + } + Perl_croak(aTHX_ + "Can't locate object method \"%"UTF8f + "\" via package \"%"HEKf"\"", + UTF8fARG(is_utf8, nend - name, name), + HEKfARG(HvNAME_HEK(stash))); + } + else { + SV* packnamesv; + + if (nsplit) { + packnamesv = newSVpvn_flags(origname, nsplit - origname, + SVs_TEMP | is_utf8); + } else { + packnamesv = error_report; + } + + Perl_croak(aTHX_ + "Can't locate object method \"%"UTF8f + "\" via package \"%"SVf"\"" + " (perhaps you forgot to load \"%"SVf"\"?)", + UTF8fARG(is_utf8, nend - name, name), + SVfARG(packnamesv), SVfARG(packnamesv)); + } + } + } + else if (autoload) { + CV* const cv = GvCV(gv); + if (!CvROOT(cv) && !CvXSUB(cv)) { + GV* stubgv; + GV* autogv; + + if (CvANON(cv) || CvLEXICAL(cv)) + stubgv = gv; + else { + stubgv = CvGV(cv); + if (GvCV(stubgv) != cv) /* orphaned import */ + stubgv = gv; + } + autogv = gv_autoload_pvn(GvSTASH(stubgv), + GvNAME(stubgv), GvNAMELEN(stubgv), + GV_AUTOLOAD_ISMETHOD + | (GvNAMEUTF8(stubgv) ? SVf_UTF8 : 0)); + if (autogv) + gv = autogv; + } + } + + return gv; +} + +GV* +Perl_gv_autoload_sv(pTHX_ HV *stash, SV* namesv, U32 flags) +{ + char *namepv; + STRLEN namelen; + PERL_ARGS_ASSERT_GV_AUTOLOAD_SV; + namepv = SvPV(namesv, namelen); + if (SvUTF8(namesv)) + flags |= SVf_UTF8; + return gv_autoload_pvn(stash, namepv, namelen, flags); +} + +GV* +Perl_gv_autoload_pv(pTHX_ HV *stash, const char *namepv, U32 flags) +{ + PERL_ARGS_ASSERT_GV_AUTOLOAD_PV; + return gv_autoload_pvn(stash, namepv, strlen(namepv), flags); +} + +GV* +Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags) +{ + GV* gv; + CV* cv; + HV* varstash; + GV* vargv; + SV* varsv; + SV *packname = NULL; + U32 is_utf8 = flags & SVf_UTF8 ? SVf_UTF8 : 0; + + PERL_ARGS_ASSERT_GV_AUTOLOAD_PVN; + + if (len == S_autolen && memEQ(name, S_autoload, S_autolen)) + return NULL; + if (stash) { + if (SvTYPE(stash) < SVt_PVHV) { + STRLEN packname_len = 0; + const char * const packname_ptr = SvPV_const(MUTABLE_SV(stash), packname_len); + packname = newSVpvn_flags(packname_ptr, packname_len, + SVs_TEMP | SvUTF8(stash)); + stash = NULL; + } + else + packname = sv_2mortal(newSVhek(HvNAME_HEK(stash))); + if (flags & GV_SUPER) sv_catpvs(packname, "::SUPER"); + } + if (!(gv = gv_fetchmeth_pvn(stash, S_autoload, S_autolen, FALSE, + is_utf8 | (flags & GV_SUPER)))) + return NULL; + cv = GvCV(gv); + + if (!(CvROOT(cv) || CvXSUB(cv))) + return NULL; + + /* + * Inheriting AUTOLOAD for non-methods works ... for now. + */ + if ( + !(flags & GV_AUTOLOAD_ISMETHOD) + && (GvCVGEN(gv) || GvSTASH(gv) != stash) + ) + Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED), + "Use of inherited AUTOLOAD for non-method %"SVf + "::%"UTF8f"() is deprecated", + SVfARG(packname), + UTF8fARG(is_utf8, len, name)); + + if (CvISXSUB(cv)) { + /* Instead of forcing the XSUB do another lookup for $AUTOLOAD + * and split that value on the last '::', pass along the same data + * via the SvPVX field in the CV, and the stash in CvSTASH. + * + * Due to an unfortunate accident of history, the SvPVX field + * serves two purposes. It is also used for the subroutine's pro- + * type. Since SvPVX has been documented as returning the sub name + * for a long time, but not as returning the prototype, we have + * to preserve the SvPVX AUTOLOAD behaviour and put the prototype + * elsewhere. + * + * We put the prototype in the same allocated buffer, but after + * the sub name. The SvPOK flag indicates the presence of a proto- + * type. The CvAUTOLOAD flag indicates the presence of a sub name. + * If both flags are on, then SvLEN is used to indicate the end of + * the prototype (artificially lower than what is actually allo- + * cated), at the risk of having to reallocate a few bytes unneces- + * sarily--but that should happen very rarely, if ever. + * + * We use SvUTF8 for both prototypes and sub names, so if one is + * UTF8, the other must be upgraded. + */ + CvSTASH_set(cv, stash); + if (SvPOK(cv)) { /* Ouch! */ + SV * const tmpsv = newSVpvn_flags(name, len, is_utf8); + STRLEN ulen; + const char *proto = CvPROTO(cv); + assert(proto); + if (SvUTF8(cv)) + sv_utf8_upgrade_flags_grow(tmpsv, 0, CvPROTOLEN(cv) + 2); + ulen = SvCUR(tmpsv); + SvCUR(tmpsv)++; /* include null in string */ + sv_catpvn_flags( + tmpsv, proto, CvPROTOLEN(cv), SV_CATBYTES*!SvUTF8(cv) + ); + SvTEMP_on(tmpsv); /* Allow theft */ + sv_setsv_nomg((SV *)cv, tmpsv); + SvTEMP_off(tmpsv); + SvREFCNT_dec_NN(tmpsv); + SvLEN(cv) = SvCUR(cv) + 1; + SvCUR(cv) = ulen; + } + else { + sv_setpvn((SV *)cv, name, len); + SvPOK_off(cv); + if (is_utf8) + SvUTF8_on(cv); + else SvUTF8_off(cv); + } + CvAUTOLOAD_on(cv); + } + + /* + * 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 = CvNAMED(cv) ? CvSTASH(cv) : GvSTASH(CvGV(cv)); + vargv = *(GV**)hv_fetch(varstash, S_autoload, S_autolen, TRUE); + ENTER; + + if (!isGV(vargv)) { + gv_init_pvn(vargv, varstash, S_autoload, S_autolen, 0); +#ifdef PERL_DONT_CREATE_GVSV + GvSV(vargv) = newSV(0); +#endif + } + LEAVE; + varsv = GvSVn(vargv); + SvTAINTED_off(varsv); /* previous $AUTOLOAD taint is obsolete */ + /* XXX: this process is not careful to avoid extra magic gets and sets; tied $AUTOLOAD will get noise */ + sv_setsv(varsv, packname); + sv_catpvs(varsv, "::"); + /* Ensure SvSETMAGIC() is called if necessary. In particular, to clear + tainting if $FOO::AUTOLOAD was previously tainted, but is not now. */ + sv_catpvn_flags( + varsv, name, len, + SV_SMAGIC|(is_utf8 ? SV_CATUTF8 : SV_CATBYTES) + ); + if (is_utf8) + SvUTF8_on(varsv); + return gv; +} + + +/* require_tie_mod() internal routine for requiring a module + * that implements the logic of automatic ties like %! and %- + * + * The "gv" parameter should be the glob. + * "varpv" holds the name of the var, used for error messages. + * "namesv" holds the module name. Its refcount will be decremented. + * "methpv" holds the method name to test for to check that things + * are working reasonably close to as expected. + * "flags": if flag & 1 then save the scalar before loading. + * For the protection of $! to work (it is set by this routine) + * the sv slot must already be magicalized. + */ +STATIC HV* +S_require_tie_mod(pTHX_ GV *gv, const char *varpv, SV* namesv, const char *methpv,const U32 flags) +{ + HV* stash = gv_stashsv(namesv, 0); + + PERL_ARGS_ASSERT_REQUIRE_TIE_MOD; + + if (!stash || !(gv_fetchmethod_autoload(stash, methpv, FALSE))) { + SV *module = newSVsv(namesv); + char varname = *varpv; /* varpv might be clobbered by load_module, + so save it. For the moment it's always + a single char. */ + const char type = varname == '[' ? '$' : '%'; +#ifdef DEBUGGING + dSP; +#endif + ENTER; + SAVEFREESV(namesv); + if ( flags & 1 ) + save_scalar(gv); + Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, module, NULL); + assert(sp == PL_stack_sp); + stash = gv_stashsv(namesv, 0); + if (!stash) + Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" is not available", + type, varname, SVfARG(namesv)); + else if (!gv_fetchmethod(stash, methpv)) + Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" does not support method %s", + type, varname, SVfARG(namesv), methpv); + LEAVE; + } + else SvREFCNT_dec_NN(namesv); + return stash; +} + +/* +=for apidoc gv_stashpv + +Returns a pointer to the stash for a specified package. Uses C<strlen> to +determine the length of C<name>, then calls C<gv_stashpvn()>. + +=cut +*/ + +HV* +Perl_gv_stashpv(pTHX_ const char *name, I32 create) +{ + PERL_ARGS_ASSERT_GV_STASHPV; + return gv_stashpvn(name, strlen(name), create); +} + +/* +=for apidoc gv_stashpvn + +Returns a pointer to the stash for a specified package. The C<namelen> +parameter indicates the length of the C<name>, in bytes. C<flags> is passed +to C<gv_fetchpvn_flags()>, so if set to C<GV_ADD> then the package will be +created if it does not already exist. If the package does not exist and +C<flags> is 0 (or any other setting that does not create packages) then NULL +is returned. + +Flags may be one of: + + GV_ADD + SVf_UTF8 + GV_NOADD_NOINIT + GV_NOINIT + GV_NOEXPAND + GV_ADDMG + +The most important of which are probably GV_ADD and SVf_UTF8. + +Note, use of C<gv_stashsv> instead of C<gv_stashpvn> where possible is strongly +recommended for performance reasons. + +=cut +*/ + +/* +gv_stashpvn_internal + +Perform the internal bits of gv_stashsvpvn_cached. You could think of this +as being one half of the logic. Not to be called except from gv_stashsvpvn_cached(). + +*/ + +PERL_STATIC_INLINE HV* +S_gv_stashpvn_internal(pTHX_ const char *name, U32 namelen, I32 flags) +{ + char smallbuf[128]; + char *tmpbuf; + HV *stash; + GV *tmpgv; + U32 tmplen = namelen + 2; + + PERL_ARGS_ASSERT_GV_STASHPVN_INTERNAL; + + if (tmplen <= sizeof smallbuf) + tmpbuf = smallbuf; + else + Newx(tmpbuf, tmplen, char); + Copy(name, tmpbuf, namelen, char); + tmpbuf[namelen] = ':'; + tmpbuf[namelen+1] = ':'; + tmpgv = gv_fetchpvn_flags(tmpbuf, tmplen, flags, SVt_PVHV); + if (tmpbuf != smallbuf) + Safefree(tmpbuf); + if (!tmpgv || !isGV_with_GP(tmpgv)) + return NULL; + stash = GvHV(tmpgv); + if (!(flags & ~GV_NOADD_MASK) && !stash) return NULL; + assert(stash); + if (!HvNAME_get(stash)) { + hv_name_set(stash, name, namelen, flags & SVf_UTF8 ? SVf_UTF8 : 0 ); + + /* FIXME: This is a repeat of logic in gv_fetchpvn_flags */ + /* If the containing stash has multiple effective + names, see that this one gets them, too. */ + if (HvAUX(GvSTASH(tmpgv))->xhv_name_count) + mro_package_moved(stash, NULL, tmpgv, 1); + } + return stash; +} + +/* +gv_stashsvpvn_cached + +Returns a pointer to the stash for a specified package, possibly +cached. Implements both C<gv_stashpvn> and C<gc_stashsv>. + +Requires one of either namesv or namepv to be non-null. + +See C<gv_stashpvn> for details on "flags". + +Note the sv interface is strongly preferred for performance reasons. + +*/ + +#define PERL_ARGS_ASSERT_GV_STASHSVPVN_CACHED \ + assert(namesv || name) + +PERL_STATIC_INLINE HV* +S_gv_stashsvpvn_cached(pTHX_ SV *namesv, const char *name, U32 namelen, I32 flags) +{ + HV* stash; + HE* he; + + PERL_ARGS_ASSERT_GV_STASHSVPVN_CACHED; + + he = (HE *)hv_common( + PL_stashcache, namesv, name, namelen, + (flags & SVf_UTF8) ? HVhek_UTF8 : 0, 0, NULL, 0 + ); + + if (he) return INT2PTR(HV*,SvIVX(HeVAL(he))); + else if (flags & GV_CACHE_ONLY) return NULL; + + if (namesv) { + if (SvOK(namesv)) { /* prevent double uninit warning */ + STRLEN len; + name = SvPV_const(namesv, len); + namelen = len; + flags |= SvUTF8(namesv); + } else { + name = ""; namelen = 0; + } + } + stash = gv_stashpvn_internal(name, namelen, flags); + + if (stash && namelen) { + SV* const ref = newSViv(PTR2IV(stash)); + (void)hv_store(PL_stashcache, name, + (flags & SVf_UTF8) ? -(I32)namelen : (I32)namelen, ref, 0); + } + + return stash; +} + +HV* +Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags) +{ + PERL_ARGS_ASSERT_GV_STASHPVN; + return gv_stashsvpvn_cached(NULL, name, namelen, flags); +} + +/* +=for apidoc gv_stashsv + +Returns a pointer to the stash for a specified package. See C<gv_stashpvn>. + +Note this interface is strongly preferred over C<gv_stashpvn> for performance reasons. + +=cut +*/ + +HV* +Perl_gv_stashsv(pTHX_ SV *sv, I32 flags) +{ + PERL_ARGS_ASSERT_GV_STASHSV; + return gv_stashsvpvn_cached(sv, NULL, 0, flags); +} + + +GV * +Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, const svtype sv_type) { + PERL_ARGS_ASSERT_GV_FETCHPV; + return gv_fetchpvn_flags(nambeg, strlen(nambeg), add, sv_type); +} + +GV * +Perl_gv_fetchsv(pTHX_ SV *name, I32 flags, const svtype sv_type) { + STRLEN len; + const char * const nambeg = + SvPV_flags_const(name, len, flags & GV_NO_SVGMAGIC ? 0 : SV_GMAGIC); + PERL_ARGS_ASSERT_GV_FETCHSV; + return gv_fetchpvn_flags(nambeg, len, flags | SvUTF8(name), sv_type); +} + +PERL_STATIC_INLINE void +S_gv_magicalize_isa(pTHX_ GV *gv) +{ + AV* av; + + PERL_ARGS_ASSERT_GV_MAGICALIZE_ISA; + + av = GvAVn(gv); + GvMULTI_on(gv); + sv_magic(MUTABLE_SV(av), MUTABLE_SV(gv), PERL_MAGIC_isa, + NULL, 0); +} + +/* This function grabs name and tries to split a stash and glob + * from its contents. TODO better description, comments + * + * If the function returns TRUE and 'name == name_end', then + * 'gv' can be directly returned to the caller of gv_fetchpvn_flags + */ +PERL_STATIC_INLINE bool +S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name, + STRLEN *len, const char *nambeg, STRLEN full_len, + const U32 is_utf8, const I32 add) +{ + const char *name_cursor; + const char *const name_end = nambeg + full_len; + const char *const name_em1 = name_end - 1; + + PERL_ARGS_ASSERT_PARSE_GV_STASH_NAME; + + if (full_len > 2 && **name == '*' && isIDFIRST_lazy_if(*name + 1, is_utf8)) { + /* accidental stringify on a GV? */ + (*name)++; + } + + for (name_cursor = *name; name_cursor < name_end; name_cursor++) { + if (name_cursor < name_em1 && + ((*name_cursor == ':' && name_cursor[1] == ':') + || *name_cursor == '\'')) + { + if (!*stash) + *stash = PL_defstash; + if (!*stash || !SvREFCNT(*stash)) /* symbol table under destruction */ + return FALSE; + + *len = name_cursor - *name; + if (name_cursor > nambeg) { /* Skip for initial :: or ' */ + const char *key; + GV**gvp; + if (*name_cursor == ':') { + key = *name; + *len += 2; + } + else { + char *tmpbuf; + Newx(tmpbuf, *len+2, char); + Copy(*name, tmpbuf, *len, char); + tmpbuf[(*len)++] = ':'; + tmpbuf[(*len)++] = ':'; + key = tmpbuf; + } + gvp = (GV**)hv_fetch(*stash, key, is_utf8 ? -((I32)*len) : (I32)*len, add); + *gv = gvp ? *gvp : NULL; + if (*gv && *gv != (const GV *)&PL_sv_undef) { + if (SvTYPE(*gv) != SVt_PVGV) + gv_init_pvn(*gv, *stash, key, *len, (add & GV_ADDMULTI)|is_utf8); + else + GvMULTI_on(*gv); + } + if (key != *name) + Safefree(key); + if (!*gv || *gv == (const GV *)&PL_sv_undef) + return FALSE; + + if (!(*stash = GvHV(*gv))) { + *stash = GvHV(*gv) = newHV(); + if (!HvNAME_get(*stash)) { + if (GvSTASH(*gv) == PL_defstash && *len == 6 + && strnEQ(*name, "CORE", 4)) + hv_name_set(*stash, "CORE", 4, 0); + else + hv_name_set( + *stash, nambeg, name_cursor-nambeg, is_utf8 + ); + /* If the containing stash has multiple effective + names, see that this one gets them, too. */ + if (HvAUX(GvSTASH(*gv))->xhv_name_count) + mro_package_moved(*stash, NULL, *gv, 1); + } + } + else if (!HvNAME_get(*stash)) + hv_name_set(*stash, nambeg, name_cursor - nambeg, is_utf8); + } + + if (*name_cursor == ':') + name_cursor++; + *name = name_cursor+1; + if (*name == name_end) { + if (!*gv) + *gv = MUTABLE_GV(*hv_fetchs(PL_defstash, "main::", TRUE)); + return TRUE; + } + } + } + *len = name_cursor - *name; + return TRUE; +} + +/* Checks if an unqualified name is in the main stash */ +PERL_STATIC_INLINE bool +S_gv_is_in_main(pTHX_ const char *name, STRLEN len, const U32 is_utf8) +{ + PERL_ARGS_ASSERT_GV_IS_IN_MAIN; + + /* If it's an alphanumeric variable */ + if ( len && isIDFIRST_lazy_if(name, is_utf8) ) { + /* Some "normal" variables are always in main::, + * like INC or STDOUT. + */ + switch (len) { + case 1: + if (*name == '_') + return TRUE; + break; + 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')) + return TRUE; + break; + case 4: + if (name[0] == 'A' && name[1] == 'R' && name[2] == 'G' + && name[3] == 'V') + return TRUE; + break; + case 5: + if (name[0] == 'S' && name[1] == 'T' && name[2] == 'D' + && name[3] == 'I' && name[4] == 'N') + return TRUE; + break; + 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'))) + return 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') + return TRUE; + break; + } + } + /* *{""}, or a special variable like $@ */ + else + return TRUE; + + return FALSE; +} + + +/* This function is called if parse_gv_stash_name() failed to + * find a stash, or if GV_NOTQUAL or an empty name was passed + * to gv_fetchpvn_flags. + * + * It returns FALSE if the default stash can't be found nor created, + * which might happen during global destruction. + */ +PERL_STATIC_INLINE bool +S_find_default_stash(pTHX_ HV **stash, const char *name, STRLEN len, + const U32 is_utf8, const I32 add, + const svtype sv_type) +{ + PERL_ARGS_ASSERT_FIND_DEFAULT_STASH; + + /* No stash in name, so see how we can default */ + + if ( gv_is_in_main(name, len, is_utf8) ) { + *stash = PL_defstash; + } + else { + if (IN_PERL_COMPILETIME) { + *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 && + (*name == 'a' || *name == 'b')) ) + { + GV**gvp = (GV**)hv_fetch(*stash,name,is_utf8 ? -(I32)len : (I32)len,0); + if (!gvp || *gvp == (const GV *)&PL_sv_undef || + SvTYPE(*gvp) != SVt_PVGV) + { + *stash = NULL; + } + else if ((sv_type == SVt_PV && !GvIMPORTED_SV(*gvp)) || + (sv_type == SVt_PVAV && !GvIMPORTED_AV(*gvp)) || + (sv_type == SVt_PVHV && !GvIMPORTED_HV(*gvp)) ) + { + /* diag_listed_as: Variable "%s" is not imported%s */ + Perl_ck_warner_d( + aTHX_ packWARN(WARN_MISC), + "Variable \"%c%"UTF8f"\" is not imported", + sv_type == SVt_PVAV ? '@' : + sv_type == SVt_PVHV ? '%' : '$', + UTF8fARG(is_utf8, len, name)); + if (GvCVu(*gvp)) + Perl_ck_warner_d( + aTHX_ packWARN(WARN_MISC), + "\t(Did you mean &%"UTF8f" instead?)\n", + UTF8fARG(is_utf8, len, name) + ); + *stash = NULL; + } + } + } + else { + /* Use the current op's stash */ + *stash = CopSTASH(PL_curcop); + } + } + + if (!*stash) { + if (add && !PL_in_clean_all) { + GV *gv; + qerror(Perl_mess(aTHX_ + "Global symbol \"%s%"UTF8f + "\" requires explicit package name (did you forget to " + "declare \"my %s%"UTF8f"\"?)", + (sv_type == SVt_PV ? "$" + : sv_type == SVt_PVAV ? "@" + : sv_type == SVt_PVHV ? "%" + : ""), UTF8fARG(is_utf8, len, name), + (sv_type == SVt_PV ? "$" + : sv_type == SVt_PVAV ? "@" + : sv_type == SVt_PVHV ? "%" + : ""), UTF8fARG(is_utf8, len, name))); + /* To maintain the output of errors after the strict exception + * above, and to keep compat with older releases, rather than + * placing the variables in the pad, we place + * them in the <none>:: stash. + */ + gv = gv_fetchpvs("<none>::", GV_ADDMULTI, SVt_PVHV); + if (!gv) { + /* symbol table under destruction */ + return FALSE; + } + *stash = GvHV(gv); + } + else + return FALSE; + } + + if (!SvREFCNT(*stash)) /* symbol table under destruction */ + return FALSE; + + return TRUE; +} + +/* gv_magicalize only turns on the SVf_READONLY flag, not SVf_PROTECT. So + redefine SvREADONLY_on for that purpose. We don’t use it later on in + this file. */ +#undef SvREADONLY_on +#define SvREADONLY_on(sv) (SvFLAGS(sv) |= SVf_READONLY) + +/* gv_magicalize() is called by gv_fetchpvn_flags when creating + * a new GV. + * Note that it does not insert the GV into the stash prior to + * magicalization, which some variables require need in order + * to work (like $[, %+, %-, %!), so callers must take care of + * that beforehand. + * + * The return value has a specific meaning for gv_fetchpvn_flags: + * If it returns true, and the gv is empty, it indicates that its + * refcount should be decreased. + */ +PERL_STATIC_INLINE bool +S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, + bool addmg, const svtype sv_type) +{ + SSize_t paren; + + PERL_ARGS_ASSERT_GV_MAGICALIZE; + + if (stash != PL_defstash) { /* not the main stash */ + /* We only have to check for a few names here: a, b, EXPORT, ISA + and VERSION. All the others apply only to the main stash or to + CORE (which is checked right after this). */ + if (len) { + const char * const name2 = name + 1; + switch (*name) { + case 'E': + if (strnEQ(name2, "XPORT", 5)) + GvMULTI_on(gv); + break; + case 'I': + if (strEQ(name2, "SA")) + gv_magicalize_isa(gv); + break; + case 'V': + if (strEQ(name2, "ERSION")) + GvMULTI_on(gv); + break; + case 'a': + case 'b': + if (len == 1 && sv_type == SVt_PV) + GvMULTI_on(gv); + /* FALLTHROUGH */ + default: + goto try_core; + } + return addmg; + } + try_core: + if (len > 1 /* shortest is uc */ && HvNAMELEN_get(stash) == 4) { + /* Avoid null warning: */ + const char * const stashname = HvNAME(stash); assert(stashname); + if (strnEQ(stashname, "CORE", 4)) + S_maybe_add_coresub(aTHX_ 0, gv, name, len); + } + } + else if (len > 1) { +#ifndef EBCDIC + if (*name > 'V' ) { + NOOP; + /* Nothing else to do. + The compiler will probably turn the switch statement into a + branch table. Make sure we avoid even that small overhead for + the common case of lower case variable names. (On EBCDIC + platforms, we can't just do: + if (NATIVE_TO_ASCII(*name) > NATIVE_TO_ASCII('V') ) { + because cases like '\027' in the switch statement below are + C1 (non-ASCII) controls on those platforms, so the remapping + would make them larger than 'V') + */ + } else +#endif + { + const char * name2 = name + 1; + switch (*name) { + case 'A': + if (strEQ(name2, "RGV")) { + IoFLAGS(GvIOn(gv)) |= IOf_ARGV|IOf_START; + } + else if (strEQ(name2, "RGVOUT")) { + GvMULTI_on(gv); + } + break; + case 'E': + if (strnEQ(name2, "XPORT", 5)) + GvMULTI_on(gv); + break; + case 'I': + if (strEQ(name2, "SA")) { + gv_magicalize_isa(gv); + } + break; + case 'S': + if (strEQ(name2, "IG")) { + HV *hv; + I32 i; + if (!PL_psig_name) { + Newxz(PL_psig_name, 2 * SIG_SIZE, SV*); + Newxz(PL_psig_pend, SIG_SIZE, int); + PL_psig_ptr = PL_psig_name + SIG_SIZE; + } else { + /* I think that the only way to get here is to re-use an + embedded perl interpreter, where the previous + use didn't clean up fully because + PL_perl_destruct_level was 0. I'm not sure that we + "support" that, in that I suspect in that scenario + there are sufficient other garbage values left in the + interpreter structure that something else will crash + before we get here. I suspect that this is one of + those "doctor, it hurts when I do this" bugs. */ + Zero(PL_psig_name, 2 * SIG_SIZE, SV*); + Zero(PL_psig_pend, SIG_SIZE, int); + } + GvMULTI_on(gv); + hv = GvHVn(gv); + hv_magic(hv, NULL, PERL_MAGIC_sig); + for (i = 1; i < SIG_SIZE; i++) { + 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); + } + } + break; + case 'V': + if (strEQ(name2, "ERSION")) + GvMULTI_on(gv); + break; + case '\003': /* $^CHILD_ERROR_NATIVE */ + if (strEQ(name2, "HILD_ERROR_NATIVE")) + goto magicalize; + break; + case '\005': /* $^ENCODING */ + if (*name2 == '_') { + name2++; + } + if (strEQ(name2, "NCODING")) + goto magicalize; + break; + case '\007': /* $^GLOBAL_PHASE */ + if (strEQ(name2, "LOBAL_PHASE")) + goto ro_magicalize; + break; + case '\014': /* $^LAST_FH */ + if (strEQ(name2, "AST_FH")) + goto ro_magicalize; + break; + case '\015': /* $^MATCH */ + if (strEQ(name2, "ATCH")) { + paren = RX_BUFF_IDX_CARET_FULLMATCH; + goto storeparen; + } + break; + case '\017': /* $^OPEN */ + if (strEQ(name2, "PEN")) + goto magicalize; + break; + case '\020': /* $^PREMATCH $^POSTMATCH */ + if (strEQ(name2, "REMATCH")) { + paren = RX_BUFF_IDX_CARET_PREMATCH; + goto storeparen; + } + if (strEQ(name2, "OSTMATCH")) { + paren = RX_BUFF_IDX_CARET_POSTMATCH; + goto storeparen; + } + break; + case '\024': /* ${^TAINT} */ + if (strEQ(name2, "AINT")) + goto ro_magicalize; + break; + case '\025': /* ${^UNICODE}, ${^UTF8LOCALE} */ + if (strEQ(name2, "NICODE")) + goto ro_magicalize; + if (strEQ(name2, "TF8LOCALE")) + goto ro_magicalize; + if (strEQ(name2, "TF8CACHE")) + goto magicalize; + break; + case '\027': /* $^WARNING_BITS */ + if (strEQ(name2, "ARNING_BITS")) + goto magicalize; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + /* Ensures that we have an all-digit variable, ${"1foo"} fails + this test */ + UV uv; + if (!grok_atoUV(name, &uv, NULL) || uv > I32_MAX) + return addmg; + /* XXX why are we using a SSize_t? */ + paren = (SSize_t)(I32)uv; + goto storeparen; + } + } + } + } else { + /* Names of length 1. (Or 0. But name is NUL terminated, so that will + be case '\0' in this switch statement (ie a default case) */ + switch (*name) { + case '&': /* $& */ + paren = RX_BUFF_IDX_FULLMATCH; + goto sawampersand; + case '`': /* $` */ + paren = RX_BUFF_IDX_PREMATCH; + goto sawampersand; + case '\'': /* $' */ + paren = RX_BUFF_IDX_POSTMATCH; + sawampersand: +#ifdef PERL_SAWAMPERSAND + if (!( + sv_type == SVt_PVAV || + sv_type == SVt_PVHV || + sv_type == SVt_PVCV || + sv_type == SVt_PVFM || + sv_type == SVt_PVIO + )) { PL_sawampersand |= + (*name == '`') + ? SAWAMPERSAND_LEFT + : (*name == '&') + ? SAWAMPERSAND_MIDDLE + : SAWAMPERSAND_RIGHT; + } +#endif + goto storeparen; + case '1': /* $1 */ + case '2': /* $2 */ + case '3': /* $3 */ + case '4': /* $4 */ + case '5': /* $5 */ + case '6': /* $6 */ + case '7': /* $7 */ + case '8': /* $8 */ + case '9': /* $9 */ + paren = *name - '0'; + + storeparen: + /* Flag the capture variables with a NULL mg_ptr + Use mg_len for the array index to lookup. */ + sv_magic(GvSVn(gv), MUTABLE_SV(gv), PERL_MAGIC_sv, NULL, paren); + break; + + case ':': /* $: */ + sv_setpv(GvSVn(gv),PL_chopset); + goto magicalize; + + case '?': /* $? */ +#ifdef COMPLEX_STATUS + SvUPGRADE(GvSVn(gv), SVt_PVLV); +#endif + goto magicalize; + + case '!': /* $! */ + GvMULTI_on(gv); + /* If %! has been used, automatically load Errno.pm. */ + + sv_magic(GvSVn(gv), MUTABLE_SV(gv), PERL_MAGIC_sv, name, len); + + /* magicalization must be done before require_tie_mod is called */ + if (sv_type == SVt_PVHV || sv_type == SVt_PVGV) + { + require_tie_mod(gv, "!", newSVpvs("Errno"), "TIEHASH", 1); + addmg = FALSE; + } + + break; + case '-': /* $- */ + case '+': /* $+ */ + GvMULTI_on(gv); /* no used once warnings here */ + { + AV* const av = GvAVn(gv); + SV* const avc = (*name == '+') ? MUTABLE_SV(av) : NULL; + + sv_magic(MUTABLE_SV(av), avc, PERL_MAGIC_regdata, NULL, 0); + sv_magic(GvSVn(gv), MUTABLE_SV(gv), PERL_MAGIC_sv, name, len); + if (avc) + SvREADONLY_on(GvSVn(gv)); + SvREADONLY_on(av); + + if (sv_type == SVt_PVHV || sv_type == SVt_PVGV) + { + require_tie_mod(gv, name, newSVpvs("Tie::Hash::NamedCapture"), "TIEHASH", 0); + addmg = FALSE; + } + + break; + } + case '*': /* $* */ + case '#': /* $# */ + if (sv_type == SVt_PV) + /* diag_listed_as: $* is no longer supported */ + Perl_ck_warner_d(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX), + "$%c is no longer supported", *name); + break; + case '\010': /* $^H */ + { + HV *const hv = GvHVn(gv); + hv_magic(hv, NULL, PERL_MAGIC_hints); + } + goto magicalize; + case '[': /* $[ */ + if ((sv_type == SVt_PV || sv_type == SVt_PVGV) + && FEATURE_ARYBASE_IS_ENABLED) { + require_tie_mod(gv,name,newSVpvs("arybase"),"FETCH",0); + addmg = FALSE; + } + else goto magicalize; + break; + case '\023': /* $^S */ + ro_magicalize: + SvREADONLY_on(GvSVn(gv)); + /* FALLTHROUGH */ + case '0': /* $0 */ + 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 '\011': /* $^I, NOT \t in EBCDIC */ + case '\016': /* $^N */ + case '\017': /* $^O */ + case '\020': /* $^P */ + case '\024': /* $^T */ + case '\027': /* $^W */ + magicalize: + sv_magic(GvSVn(gv), MUTABLE_SV(gv), PERL_MAGIC_sv, name, len); + break; + + case '\014': /* $^L */ + sv_setpvs(GvSVn(gv),"\f"); + break; + case ';': /* $; */ + sv_setpvs(GvSVn(gv),"\034"); + break; + case ']': /* $] */ + { + SV * const sv = GvSV(gv); + if (!sv_derived_from(PL_patchlevel, "version")) + upg_version(PL_patchlevel, TRUE); + GvSV(gv) = vnumify(PL_patchlevel); + SvREADONLY_on(GvSV(gv)); + SvREFCNT_dec(sv); + } + break; + case '\026': /* $^V */ + { + SV * const sv = GvSV(gv); + GvSV(gv) = new_version(PL_patchlevel); + SvREADONLY_on(GvSV(gv)); + SvREFCNT_dec(sv); + } + break; + case 'a': + case 'b': + if (sv_type == SVt_PV) + GvMULTI_on(gv); + } + } + + return addmg; +} + +/* If we do ever start using this later on in the file, we need to make + sure we don’t accidentally use the wrong definition. */ +#undef SvREADONLY_on + +/* This function is called when the stash already holds the GV of the magic + * variable we're looking for, but we need to check that it has the correct + * kind of magic. For example, if someone first uses $! and then %!, the + * latter would end up here, and we add the Errno tie to the HASH slot of + * the *! glob. + */ +PERL_STATIC_INLINE void +S_maybe_multimagic_gv(pTHX_ GV *gv, const char *name, const svtype sv_type) +{ + PERL_ARGS_ASSERT_MAYBE_MULTIMAGIC_GV; + + if (sv_type == SVt_PVHV || sv_type == SVt_PVGV) { + if (*name == '!') + require_tie_mod(gv, "!", newSVpvs("Errno"), "TIEHASH", 1); + else if (*name == '-' || *name == '+') + require_tie_mod(gv, name, newSVpvs("Tie::Hash::NamedCapture"), "TIEHASH", 0); + } else if (sv_type == SVt_PV) { + if (*name == '*' || *name == '#') { + /* diag_listed_as: $* is no longer supported */ + Perl_ck_warner_d(aTHX_ packWARN2(WARN_DEPRECATED, + WARN_SYNTAX), + "$%c is no longer supported", *name); + } + } + if (sv_type==SVt_PV || sv_type==SVt_PVGV) { + switch (*name) { + case '[': + require_tie_mod(gv,name,newSVpvs("arybase"),"FETCH",0); + break; +#ifdef PERL_SAWAMPERSAND + case '`': + PL_sawampersand |= SAWAMPERSAND_LEFT; + (void)GvSVn(gv); + break; + case '&': + PL_sawampersand |= SAWAMPERSAND_MIDDLE; + (void)GvSVn(gv); + break; + case '\'': + PL_sawampersand |= SAWAMPERSAND_RIGHT; + (void)GvSVn(gv); + break; +#endif + } + } +} + +GV * +Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, + const svtype sv_type) +{ + const char *name = nambeg; + GV *gv = NULL; + GV**gvp; + STRLEN len; + HV *stash = NULL; + const I32 no_init = flags & (GV_NOADD_NOINIT | GV_NOINIT); + const I32 no_expand = flags & GV_NOEXPAND; + const I32 add = flags & ~GV_NOADD_MASK; + const U32 is_utf8 = flags & SVf_UTF8; + bool addmg = cBOOL(flags & GV_ADDMG); + const char *const name_end = nambeg + full_len; + U32 faking_it; + + PERL_ARGS_ASSERT_GV_FETCHPVN_FLAGS; + + /* If we have GV_NOTQUAL, the caller promised that + * there is no stash, so we can skip the check. + * Similarly if full_len is 0, since then we're + * dealing with something like *{""} or ""->foo() + */ + if ((flags & GV_NOTQUAL) || !full_len) { + len = full_len; + } + else if (parse_gv_stash_name(&stash, &gv, &name, &len, nambeg, full_len, is_utf8, add)) { + if (name == name_end) return gv; + } + else { + return NULL; + } + + if (!stash && !find_default_stash(&stash, name, len, is_utf8, add, sv_type)) { + return NULL; + } + + /* By this point we should have a stash and a name */ + gvp = (GV**)hv_fetch(stash,name,is_utf8 ? -(I32)len : (I32)len,add); + if (!gvp || *gvp == (const GV *)&PL_sv_undef) { + if (addmg) gv = (GV *)newSV(0); + else return NULL; + } + else gv = *gvp, addmg = 0; + /* From this point on, addmg means gv has not been inserted in the + symtab yet. */ + + if (SvTYPE(gv) == SVt_PVGV) { + /* The GV already exists, so return it, but check if we need to do + * anything else with it before that. + */ + if (add) { + /* This is the heuristic that handles if a variable triggers the + * 'used only once' warning. If there's already a GV in the stash + * with this name, then we assume that the variable has been used + * before and turn its MULTI flag on. + * It's a heuristic because it can easily be "tricked", like with + * BEGIN { $a = 1; $::{foo} = *a }; () = $foo + * not warning about $main::foo being used just once + */ + GvMULTI_on(gv); + gv_init_svtype(gv, sv_type); + /* You reach this path once the typeglob has already been created, + either by the same or a different sigil. If this path didn't + exist, then (say) referencing $! first, and %! second would + mean that %! was not handled correctly. */ + if (len == 1 && stash == PL_defstash) { + maybe_multimagic_gv(gv, name, sv_type); + } + else if (len == 3 && sv_type == SVt_PVAV + && strnEQ(name, "ISA", 3) + && (!GvAV(gv) || !SvSMAGICAL(GvAV(gv)))) + gv_magicalize_isa(gv); + } + return gv; + } else if (no_init) { + assert(!addmg); + return gv; + } + /* If GV_NOEXPAND is true and what we got off the stash is a ref, + * don't expand it to a glob. This is an optimization so that things + * copying constants over, like Exporter, don't have to be rewritten + * to take into account that you can store more than just globs in + * stashes. + */ + else if (no_expand && SvROK(gv)) { + assert(!addmg); + return gv; + } + + /* Adding a new symbol. + Unless of course there was already something non-GV here, in which case + we want to behave as if there was always a GV here, containing some sort + of subroutine. + Otherwise we run the risk of creating things like GvIO, which can cause + subtle bugs. eg the one that tripped up SQL::Translator */ + + faking_it = SvOK(gv); + + if (add & GV_ADDWARN) + Perl_ck_warner_d(aTHX_ packWARN(WARN_INTERNAL), + "Had to create %"UTF8f" unexpectedly", + UTF8fARG(is_utf8, name_end-nambeg, nambeg)); + gv_init_pvn(gv, stash, name, len, (add & GV_ADDMULTI)|is_utf8); + + if ( isIDFIRST_lazy_if(name, is_utf8) && !ckWARN(WARN_ONCE) ) + GvMULTI_on(gv) ; + + /* First, store the gv in the symtab if we're adding magic, + * but only for non-empty GVs + */ +#define GvEMPTY(gv) !(GvAV(gv) || GvHV(gv) || GvIO(gv) \ + || GvCV(gv) || (GvSV(gv) && SvOK(GvSV(gv)))) + + if ( addmg && !GvEMPTY(gv) ) { + (void)hv_store(stash,name,len,(SV *)gv,0); + } + + /* set up magic where warranted */ + if ( gv_magicalize(gv, stash, name, len, addmg, sv_type) ) { + /* See 23496c6 */ + if (GvEMPTY(gv)) { + if ( GvSV(gv) && SvMAGICAL(GvSV(gv)) ) { + /* The GV was and still is "empty", except that now + * it has the magic flags turned on, so we want it + * stored in the symtab. + */ + (void)hv_store(stash,name,len,(SV *)gv,0); + } + else { + /* Most likely the temporary GV created above */ + SvREFCNT_dec_NN(gv); + gv = NULL; + } + } + } + + if (gv) gv_init_svtype(gv, faking_it ? SVt_PVCV : sv_type); + return gv; +} + +void +Perl_gv_fullname4(pTHX_ SV *sv, const GV *gv, const char *prefix, bool keepmain) +{ + const char *name; + const HV * const hv = GvSTASH(gv); + + PERL_ARGS_ASSERT_GV_FULLNAME4; + + sv_setpv(sv, prefix ? prefix : ""); + + if (hv && (name = HvNAME(hv))) { + const STRLEN len = HvNAMELEN(hv); + if (keepmain || strnNE(name, "main", len)) { + sv_catpvn_flags(sv,name,len,HvNAMEUTF8(hv)?SV_CATUTF8:SV_CATBYTES); + sv_catpvs(sv,"::"); + } + } + else sv_catpvs(sv,"__ANON__::"); + sv_catsv(sv,sv_2mortal(newSVhek(GvNAME_HEK(gv)))); +} + +void +Perl_gv_efullname4(pTHX_ SV *sv, const GV *gv, const char *prefix, bool keepmain) +{ + const GV * const egv = GvEGVx(gv); + + PERL_ARGS_ASSERT_GV_EFULLNAME4; + + gv_fullname4(sv, egv ? egv : gv, prefix, keepmain); +} + + +/* recursively scan a stash and any nested stashes looking for entries + * that need the "only used once" warning raised + */ + +void +Perl_gv_check(pTHX_ HV *stash) +{ + I32 i; + + PERL_ARGS_ASSERT_GV_CHECK; + + if (!HvARRAY(stash)) + return; + + assert(SvOOK(stash)); + + for (i = 0; i <= (I32) HvMAX(stash); i++) { + const HE *entry; + /* mark stash is being scanned, to avoid recursing */ + HvAUX(stash)->xhv_aux_flags |= HvAUXf_SCAN_STASH; + for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) { + GV *gv; + HV *hv; + if (HeKEY(entry)[HeKLEN(entry)-1] == ':' && + (gv = MUTABLE_GV(HeVAL(entry))) && isGV(gv) && (hv = GvHV(gv))) + { + if (hv != PL_defstash && hv != stash + && !(SvOOK(hv) + && (HvAUX(hv)->xhv_aux_flags & HvAUXf_SCAN_STASH)) + ) + gv_check(hv); /* nested package */ + } + else if ( *HeKEY(entry) != '_' + && isIDFIRST_lazy_if(HeKEY(entry), HeUTF8(entry)) ) { + const char *file; + gv = MUTABLE_GV(HeVAL(entry)); + if (SvTYPE(gv) != SVt_PVGV || GvMULTI(gv)) + continue; + file = GvFILE(gv); + CopLINE_set(PL_curcop, GvLINE(gv)); +#ifdef USE_ITHREADS + CopFILE(PL_curcop) = (char *)file; /* set for warning */ +#else + CopFILEGV(PL_curcop) + = gv_fetchfile_flags(file, HEK_LEN(GvFILE_HEK(gv)), 0); +#endif + Perl_warner(aTHX_ packWARN(WARN_ONCE), + "Name \"%"HEKf"::%"HEKf + "\" used only once: possible typo", + HEKfARG(HvNAME_HEK(stash)), + HEKfARG(GvNAME_HEK(gv))); + } + } + HvAUX(stash)->xhv_aux_flags &= ~HvAUXf_SCAN_STASH; + } +} + +GV * +Perl_newGVgen_flags(pTHX_ const char *pack, U32 flags) +{ + PERL_ARGS_ASSERT_NEWGVGEN_FLAGS; + assert(!(flags & ~SVf_UTF8)); + + return gv_fetchpv(Perl_form(aTHX_ "%"UTF8f"::_GEN_%ld", + UTF8fARG(flags, strlen(pack), pack), + (long)PL_gensym++), + GV_ADD, SVt_PVGV); +} + +/* hopefully this is only called on local symbol table entries */ + +GP* +Perl_gp_ref(pTHX_ GP *gp) +{ + if (!gp) + return NULL; + gp->gp_refcnt++; + if (gp->gp_cv) { + if (gp->gp_cvgen) { + /* If the GP they asked for a reference to contains + a method cache entry, clear it first, so that we + don't infect them with our cached entry */ + SvREFCNT_dec_NN(gp->gp_cv); + gp->gp_cv = NULL; + gp->gp_cvgen = 0; + } + } + return gp; +} + +void +Perl_gp_free(pTHX_ GV *gv) +{ + GP* gp; + int attempts = 100; + + if (!gv || !isGV_with_GP(gv) || !(gp = GvGP(gv))) + return; + if (gp->gp_refcnt == 0) { + Perl_ck_warner_d(aTHX_ packWARN(WARN_INTERNAL), + "Attempt to free unreferenced glob pointers" + pTHX__FORMAT pTHX__VALUE); + return; + } + if (gp->gp_refcnt > 1) { + borrowed: + if (gp->gp_egv == gv) + gp->gp_egv = 0; + gp->gp_refcnt--; + GvGP_set(gv, NULL); + return; + } + + while (1) { + /* Copy and null out all the glob slots, so destructors do not see + freed SVs. */ + HEK * const file_hek = gp->gp_file_hek; + SV * const sv = gp->gp_sv; + AV * const av = gp->gp_av; + HV * const hv = gp->gp_hv; + IO * const io = gp->gp_io; + CV * const cv = gp->gp_cv; + CV * const form = gp->gp_form; + + gp->gp_file_hek = NULL; + gp->gp_sv = NULL; + gp->gp_av = NULL; + gp->gp_hv = NULL; + gp->gp_io = NULL; + gp->gp_cv = NULL; + gp->gp_form = NULL; + + if (file_hek) + unshare_hek(file_hek); + + SvREFCNT_dec(sv); + SvREFCNT_dec(av); + /* FIXME - another reference loop GV -> symtab -> GV ? + Somehow gp->gp_hv can end up pointing at freed garbage. */ + if (hv && SvTYPE(hv) == SVt_PVHV) { + const HEK *hvname_hek = HvNAME_HEK(hv); + if (PL_stashcache && hvname_hek) { + DEBUG_o(Perl_deb(aTHX_ + "gp_free clearing PL_stashcache for '%"HEKf"'\n", + HEKfARG(hvname_hek))); + (void)hv_deletehek(PL_stashcache, hvname_hek, G_DISCARD); + } + SvREFCNT_dec(hv); + } + if (io && SvREFCNT(io) == 1 && IoIFP(io) + && (IoTYPE(io) == IoTYPE_WRONLY || + IoTYPE(io) == IoTYPE_RDWR || + IoTYPE(io) == IoTYPE_APPEND) + && ckWARN_d(WARN_IO) + && IoIFP(io) != PerlIO_stdin() + && IoIFP(io) != PerlIO_stdout() + && IoIFP(io) != PerlIO_stderr() + && !(IoFLAGS(io) & IOf_FAKE_DIRP)) + io_close(io, gv, FALSE, TRUE); + SvREFCNT_dec(io); + SvREFCNT_dec(cv); + SvREFCNT_dec(form); + + /* Possibly reallocated by a destructor */ + gp = GvGP(gv); + + if (!gp->gp_file_hek + && !gp->gp_sv + && !gp->gp_av + && !gp->gp_hv + && !gp->gp_io + && !gp->gp_cv + && !gp->gp_form) break; + + if (--attempts == 0) { + Perl_die(aTHX_ + "panic: gp_free failed to free glob pointer - " + "something is repeatedly re-creating entries" + ); + } + } + + /* Possibly incremented by a destructor doing glob assignment */ + if (gp->gp_refcnt > 1) goto borrowed; + Safefree(gp); + GvGP_set(gv, NULL); +} + +int +Perl_magic_freeovrld(pTHX_ SV *sv, MAGIC *mg) +{ + AMT * const amtp = (AMT*)mg->mg_ptr; + PERL_UNUSED_ARG(sv); + + PERL_ARGS_ASSERT_MAGIC_FREEOVRLD; + + if (amtp && AMT_AMAGIC(amtp)) { + int i; + for (i = 1; i < NofAMmeth; i++) { + CV * const cv = amtp->table[i]; + if (cv) { + SvREFCNT_dec_NN(MUTABLE_SV(cv)); + amtp->table[i] = NULL; + } + } + } + return 0; +} + +/* Updates and caches the CV's */ +/* Returns: + * 1 on success and there is some overload + * 0 if there is no overload + * -1 if some error occurred and it couldn't croak + */ + +int +Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing) +{ + MAGIC* const mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table); + AMT amt; + const struct mro_meta* stash_meta = HvMROMETA(stash); + U32 newgen; + + PERL_ARGS_ASSERT_GV_AMUPDATE; + + newgen = PL_sub_generation + stash_meta->pkg_gen + stash_meta->cache_gen; + if (mg) { + const AMT * const amtp = (AMT*)mg->mg_ptr; + if (amtp->was_ok_sub == newgen) { + return AMT_AMAGIC(amtp) ? 1 : 0; + } + sv_unmagic(MUTABLE_SV(stash), PERL_MAGIC_overload_table); + } + + DEBUG_o( Perl_deb(aTHX_ "Recalcing overload magic in package %s\n",HvNAME_get(stash)) ); + + Zero(&amt,1,AMT); + amt.was_ok_sub = newgen; + amt.fallback = AMGfallNO; + amt.flags = 0; + + { + int filled = 0; + int i; + bool deref_seen = 0; + + + /* Work with "fallback" key, which we assume to be first in PL_AMG_names */ + + /* Try to find via inheritance. */ + GV *gv = gv_fetchmeth_pvn(stash, PL_AMG_names[0], 2, -1, 0); + SV * const sv = gv ? GvSV(gv) : NULL; + CV* cv; + + if (!gv) + { + if (!gv_fetchmeth_pvn(stash, "((", 2, -1, 0)) + goto no_table; + } +#ifdef PERL_DONT_CREATE_GVSV + else if (!sv) { + NOOP; /* Equivalent to !SvTRUE and !SvOK */ + } +#endif + else if (SvTRUE(sv)) + /* don't need to set overloading here because fallback => 1 + * is the default setting for classes without overloading */ + amt.fallback=AMGfallYES; + else if (SvOK(sv)) { + amt.fallback=AMGfallNEVER; + filled = 1; + } + else { + filled = 1; + } + + assert(SvOOK(stash)); + /* initially assume the worst */ + HvAUX(stash)->xhv_aux_flags &= ~HvAUXf_NO_DEREF; + + for (i = 1; i < NofAMmeth; i++) { + const char * const cooky = PL_AMG_names[i]; + /* Human-readable form, for debugging: */ + const char * const cp = AMG_id2name(i); + const STRLEN l = PL_AMG_namelens[i]; + + DEBUG_o( Perl_deb(aTHX_ "Checking overloading of \"%s\" in package \"%.256s\"\n", + cp, HvNAME_get(stash)) ); + /* 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". */ + gv = Perl_gv_fetchmeth_pvn(aTHX_ stash, cooky, l, -1, 0); + cv = 0; + if (gv && (cv = GvCV(gv)) && CvHASGV(cv)) { + const HEK * const gvhek = + CvNAMED(cv) ? CvNAME_HEK(cv) : GvNAME_HEK(CvGV(cv)); + const HEK * const stashek = + HvNAME_HEK(CvNAMED(cv) ? CvSTASH(cv) : GvSTASH(CvGV(cv))); + if (HEK_LEN(gvhek) == 3 && strEQ(HEK_KEY(gvhek), "nil") + && stashek && HEK_LEN(stashek) == 8 + && strEQ(HEK_KEY(stashek), "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 = NULL; + SV *gvsv = GvSV(gv); + + DEBUG_o( Perl_deb(aTHX_ "Resolving method \"%"SVf256\ + "\" for overloaded \"%s\" in package \"%.256s\"\n", + (void*)GvSV(gv), cp, HvNAME(stash)) ); + if (!gvsv || !SvPOK(gvsv) + || !(ngv = gv_fetchmethod_sv_flags(stash, gvsv, 0))) + { + /* Can be an import stub (created by "can"). */ + if (destructing) { + return -1; + } + else { + const SV * const name = (gvsv && SvPOK(gvsv)) + ? gvsv + : newSVpvs_flags("???", SVs_TEMP); + /* diag_listed_as: Can't resolve method "%s" overloading "%s" in package "%s" */ + Perl_croak(aTHX_ "%s method \"%"SVf256 + "\" overloading \"%s\" "\ + "in package \"%"HEKf256"\"", + (GvCVGEN(gv) ? "Stub found while resolving" + : "Can't resolve"), + SVfARG(name), cp, + HEKfARG( + HvNAME_HEK(stash) + )); + } + } + cv = GvCV(gv = ngv); + } + DEBUG_o( Perl_deb(aTHX_ "Overloading \"%s\" in package \"%.256s\" via \"%.256s::%.256s\"\n", + cp, HvNAME_get(stash), HvNAME_get(GvSTASH(CvGV(cv))), + GvNAME(CvGV(cv))) ); + filled = 1; + } else if (gv) { /* Autoloaded... */ + cv = MUTABLE_CV(gv); + filled = 1; + } + amt.table[i]=MUTABLE_CV(SvREFCNT_inc_simple(cv)); + + if (gv) { + switch (i) { + case to_sv_amg: + case to_av_amg: + case to_hv_amg: + case to_gv_amg: + case to_cv_amg: + case nomethod_amg: + deref_seen = 1; + break; + } + } + } + if (!deref_seen) + /* none of @{} etc overloaded; we can do $obj->[N] quicker. + * NB - aux var invalid here, HvARRAY() could have been + * reallocated since it was assigned to */ + HvAUX(stash)->xhv_aux_flags |= HvAUXf_NO_DEREF; + + if (filled) { + AMT_AMAGIC_on(&amt); + sv_magic(MUTABLE_SV(stash), 0, PERL_MAGIC_overload_table, + (char*)&amt, sizeof(AMT)); + return TRUE; + } + } + /* Here we have no table: */ + no_table: + AMT_AMAGIC_off(&amt); + sv_magic(MUTABLE_SV(stash), 0, PERL_MAGIC_overload_table, + (char*)&amt, sizeof(AMTS)); + return 0; +} + + +CV* +Perl_gv_handler(pTHX_ HV *stash, I32 id) +{ + MAGIC *mg; + AMT *amtp; + U32 newgen; + struct mro_meta* stash_meta; + + if (!stash || !HvNAME_get(stash)) + return NULL; + + stash_meta = HvMROMETA(stash); + newgen = PL_sub_generation + stash_meta->pkg_gen + stash_meta->cache_gen; + + mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table); + if (!mg) { + do_update: + if (Gv_AMupdate(stash, 0) == -1) + return NULL; + mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table); + } + assert(mg); + amtp = (AMT*)mg->mg_ptr; + if ( amtp->was_ok_sub != newgen ) + goto do_update; + if (AMT_AMAGIC(amtp)) { + CV * const ret = amtp->table[id]; + if (ret && isGV(ret)) { /* Autoloading stab */ + /* Passing it through may have resulted in a warning + "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 * const gv = gv_fetchmethod(stash, PL_AMG_names[id]); + + if (gv && GvCV(gv)) + return GvCV(gv); + } + return ret; + } + + return NULL; +} + + +/* Implement tryAMAGICun_MG macro. + Do get magic, then see if the stack arg is overloaded and if so call it. + Flags: + AMGf_set return the arg using SETs rather than assigning to + the targ + AMGf_numeric apply sv_2num to the stack arg. +*/ + +bool +Perl_try_amagic_un(pTHX_ int method, int flags) { + dSP; + SV* tmpsv; + SV* const arg = TOPs; + + SvGETMAGIC(arg); + + if (SvAMAGIC(arg) && (tmpsv = amagic_call(arg, &PL_sv_undef, method, + AMGf_noright | AMGf_unary + | (flags & AMGf_numarg)))) + { + if (flags & AMGf_set) { + SETs(tmpsv); + } + else { + dTARGET; + if (SvPADMY(TARG)) { + sv_setsv(TARG, tmpsv); + SETTARG; + } + else + SETs(tmpsv); + } + PUTBACK; + return TRUE; + } + + if ((flags & AMGf_numeric) && SvROK(arg)) + *sp = sv_2num(arg); + return FALSE; +} + + +/* Implement tryAMAGICbin_MG macro. + Do get magic, then see if the two stack args are overloaded and if so + call it. + Flags: + AMGf_set return the arg using SETs rather than assigning to + the targ + AMGf_assign op may be called as mutator (eg +=) + AMGf_numeric apply sv_2num to the stack arg. +*/ + +bool +Perl_try_amagic_bin(pTHX_ int method, int flags) { + dSP; + SV* const left = TOPm1s; + SV* const right = TOPs; + + SvGETMAGIC(left); + if (left != right) + SvGETMAGIC(right); + + if (SvAMAGIC(left) || SvAMAGIC(right)) { + SV * const tmpsv = amagic_call(left, right, method, + ((flags & AMGf_assign) && opASSIGN ? AMGf_assign: 0) + | (flags & AMGf_numarg)); + if (tmpsv) { + if (flags & AMGf_set) { + (void)POPs; + SETs(tmpsv); + } + else { + dATARGET; + (void)POPs; + if (opASSIGN || SvPADMY(TARG)) { + sv_setsv(TARG, tmpsv); + SETTARG; + } + else + SETs(tmpsv); + } + PUTBACK; + return TRUE; + } + } + if(left==right && SvGMAGICAL(left)) { + SV * const left = sv_newmortal(); + *(sp-1) = left; + /* Print the uninitialized warning now, so it includes the vari- + able name. */ + if (!SvOK(right)) { + if (ckWARN(WARN_UNINITIALIZED)) report_uninit(right); + sv_setsv_flags(left, &PL_sv_no, 0); + } + else sv_setsv_flags(left, right, 0); + SvGETMAGIC(right); + } + if (flags & AMGf_numeric) { + if (SvROK(TOPm1s)) + *(sp-1) = sv_2num(TOPm1s); + if (SvROK(right)) + *sp = sv_2num(right); + } + return FALSE; +} + +SV * +Perl_amagic_deref_call(pTHX_ SV *ref, int method) { + SV *tmpsv = NULL; + HV *stash; + + PERL_ARGS_ASSERT_AMAGIC_DEREF_CALL; + + if (!SvAMAGIC(ref)) + return ref; + /* return quickly if none of the deref ops are overloaded */ + stash = SvSTASH(SvRV(ref)); + assert(SvOOK(stash)); + if (HvAUX(stash)->xhv_aux_flags & HvAUXf_NO_DEREF) + return ref; + + while ((tmpsv = amagic_call(ref, &PL_sv_undef, method, + AMGf_noright | AMGf_unary))) { + if (!SvROK(tmpsv)) + Perl_croak(aTHX_ "Overloaded dereference did not return a reference"); + if (tmpsv == ref || SvRV(tmpsv) == SvRV(ref)) { + /* Bail out if it returns us the same reference. */ + return tmpsv; + } + ref = tmpsv; + if (!SvAMAGIC(ref)) + break; + } + return tmpsv ? tmpsv : ref; +} + +bool +Perl_amagic_is_enabled(pTHX_ int method) +{ + SV *lex_mask = cop_hints_fetch_pvs(PL_curcop, "overloading", 0); + + assert(PL_curcop->cop_hints & HINT_NO_AMAGIC); + + if ( !lex_mask || !SvOK(lex_mask) ) + /* overloading lexically disabled */ + return FALSE; + else if ( lex_mask && SvPOK(lex_mask) ) { + /* we have an entry in the hints hash, check if method has been + * masked by overloading.pm */ + STRLEN len; + const int offset = method / 8; + const int bit = method % 8; + char *pv = SvPV(lex_mask, len); + + /* Bit set, so this overloading operator is disabled */ + if ( (STRLEN)offset < len && pv[offset] & ( 1 << bit ) ) + return FALSE; + } + return TRUE; +} + +SV* +Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) +{ + dVAR; + MAGIC *mg; + CV *cv=NULL; + CV **cvp=NULL, **ocvp=NULL; + AMT *amtp=NULL, *oamtp=NULL; + int off = 0, off1, lr = 0, notfound = 0; + int postpr = 0, force_cpy = 0; + int assign = AMGf_assign & flags; + const int assignshift = assign ? 1 : 0; + int use_default_op = 0; + int force_scalar = 0; +#ifdef DEBUGGING + int fl=0; +#endif + HV* stash=NULL; + + PERL_ARGS_ASSERT_AMAGIC_CALL; + + if ( PL_curcop->cop_hints & HINT_NO_AMAGIC ) { + if (!amagic_is_enabled(method)) return NULL; + } + + if (!(AMGf_noleft & flags) && SvAMAGIC(left) + && (stash = SvSTASH(SvRV(left))) && Gv_AMG(stash) + && (mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table)) + && (ocvp = cvp = (AMT_AMAGIC((AMT*)mg->mg_ptr) + ? (oamtp = amtp = (AMT*)mg->mg_ptr)->table + : NULL)) + && ((cv = cvp[off=method+assignshift]) + || (assign && amtp->fallback > AMGfallNEVER && /* fallback to + * usual method */ + ( +#ifdef DEBUGGING + fl = 1, +#endif + 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])); + if (cv) + postpr = 1; + break; + case copy_amg: + { + /* + * SV* ref causes confusion with the interpreter variable of + * the same name + */ + 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* const newref = newSVsv(tmpRef); + SvOBJECT_on(newref); + /* No need to do SvAMAGIC_on here, as SvAMAGIC macros + delegate to the stash. */ + SvSTASH_set(newref, MUTABLE_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* const nullsv=sv_2mortal(newSViv(0)); + if (off1==lt_amg) { + SV* const lessp = amagic_call(left,nullsv, + lt_amg,AMGf_noright); + logic = SvTRUE(lessp); + } else { + SV* const 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 int_amg: + case iter_amg: /* XXXX Eventually should do to_gv. */ + case ftest_amg: /* XXXX Eventually should do to_gv. */ + case regexp_amg: + /* FAIL safe */ + return NULL; /* Delegate operation to standard mechanisms. */ + + 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. */ + + default: + goto not_found; + } + if (!cv) goto not_found; + } else if (!(AMGf_noright & flags) && SvAMAGIC(right) + && (stash = SvSTASH(SvRV(right))) && Gv_AMG(stash) + && (mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table)) + && (cvp = (AMT_AMAGIC((AMT*)mg->mg_ptr) + ? (amtp = (AMT*)mg->mg_ptr)->table + : NULL)) + && (cv = cvp[off=method])) { /* Method for right + * argument found */ + lr=1; + } else if (((cvp && amtp->fallback > AMGfallNEVER) + || (ocvp && oamtp->fallback > AMGfallNEVER)) + && !(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: + off = ncmp_amg; + break; + case slt_amg: + case sle_amg: + case sgt_amg: + case sge_amg: + case seq_amg: + case sne_amg: + off = scmp_amg; + break; + } + if (off != -1) { + if (ocvp && (oamtp->fallback > AMGfallNEVER)) { + cv = ocvp[off]; + lr = -1; + } + if (!cv && (cvp && amtp->fallback > AMGfallNEVER)) { + cv = cvp[off]; + lr = 1; + } + } + if (cv) + postpr = 1; + else + 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. */ + } + 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 if ((use_default_op = + (!ocvp || oamtp->fallback >= AMGfallYES) + && (!cvp || amtp->fallback >= AMGfallYES)) + && !DEBUG_o_TEST) { + /* Skip generating the "no method found" message. */ + return NULL; + } else { + SV *msg; + if (off==-1) off=method; + msg = sv_2mortal(Perl_newSVpvf(aTHX_ + "Operation \"%s\": no method found,%sargument %s%"SVf"%s%"SVf, + AMG_id2name(method + assignshift), + (flags & AMGf_unary ? " " : "\n\tleft "), + SvAMAGIC(left)? + "in overloaded package ": + "has no overloaded magic", + SvAMAGIC(left)? + SVfARG(sv_2mortal(newSVhek(HvNAME_HEK(SvSTASH(SvRV(left)))))): + SVfARG(&PL_sv_no), + SvAMAGIC(right)? + ",\n\tright argument in overloaded package ": + (flags & AMGf_unary + ? "" + : ",\n\tright argument has no overloaded magic"), + SvAMAGIC(right)? + SVfARG(sv_2mortal(newSVhek(HvNAME_HEK(SvSTASH(SvRV(right)))))): + SVfARG(&PL_sv_no))); + if (use_default_op) { + DEBUG_o( Perl_deb(aTHX_ "%"SVf, SVfARG(msg)) ); + } else { + Perl_croak(aTHX_ "%"SVf, SVfARG(msg)); + } + return NULL; + } + force_cpy = force_cpy || assign; + } + } + + switch (method) { + /* in these cases, we're calling '+' or '-' as a fallback for a ++ or -- + * operation. we need this to return a value, so that it can be assigned + * later on, in the postpr block (case inc_amg/dec_amg), even if the + * increment or decrement was itself called in void context */ + case inc_amg: + if (off == add_amg) + force_scalar = 1; + break; + case dec_amg: + if (off == subtr_amg) + force_scalar = 1; + break; + /* in these cases, we're calling an assignment variant of an operator + * (+= rather than +, for instance). regardless of whether it's a + * fallback or not, it always has to return a value, which will be + * assigned to the proper variable later */ + case add_amg: + case subtr_amg: + case mult_amg: + case div_amg: + case modulo_amg: + case pow_amg: + case lshift_amg: + case rshift_amg: + case repeat_amg: + case concat_amg: + case band_amg: + case bor_amg: + case bxor_amg: + case sband_amg: + case sbor_amg: + case sbxor_amg: + if (assign) + force_scalar = 1; + break; + /* the copy constructor always needs to return a value */ + case copy_amg: + force_scalar = 1; + break; + /* because of the way these are implemented (they don't perform the + * dereferencing themselves, they return a reference that perl then + * dereferences later), they always have to be in scalar context */ + case to_sv_amg: + case to_av_amg: + case to_hv_amg: + case to_gv_amg: + case to_cv_amg: + force_scalar = 1; + break; + /* these don't have an op of their own; they're triggered by their parent + * op, so the context there isn't meaningful ('$a and foo()' in void + * context still needs to pass scalar context on to $a's bool overload) */ + case bool__amg: + case numer_amg: + case string_amg: + force_scalar = 1; + break; + } + +#ifdef DEBUGGING + if (!notfound) { + DEBUG_o(Perl_deb(aTHX_ + "Overloaded operator \"%s\"%s%s%s:\n\tmethod%s found%s in package %"SVf"%s\n", + AMG_id2name(off), + method+assignshift==off? "" : + " (initially \"", + method+assignshift==off? "" : + AMG_id2name(method+assignshift), + method+assignshift==off? "" : "\")", + flags & AMGf_unary? "" : + lr==1 ? " for right argument": " for left argument", + flags & AMGf_unary? " for argument" : "", + stash ? SVfARG(sv_2mortal(newSVhek(HvNAME_HEK(stash)))) : SVfARG(newSVpvs_flags("null", SVs_TEMP)), + fl? ",\n\tassignment variant used": "") ); + } +#endif + /* 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 ( (lr == -1) && ( ( (method + assignshift == off) + && (assign || (method == inc_amg) || (method == dec_amg))) + || force_cpy) ) + { + /* newSVsv does not behave as advertised, so we copy missing + * information by hand */ + SV *tmpRef = SvRV(left); + SV *rv_copy; + if (SvREFCNT(tmpRef) > 1 && (rv_copy = AMG_CALLunary(left,copy_amg))) { + SvRV_set(left, rv_copy); + SvSETMAGIC(left); + SvREFCNT_dec_NN(tmpRef); + } + } + + { + dSP; + BINOP myop; + SV* res; + const bool oldcatch = CATCH_GET; + I32 oldmark, nret; + int gimme = force_scalar ? G_SCALAR : GIMME_V; + + CATCH_SET(TRUE); + Zero(&myop, 1, BINOP); + myop.op_last = (OP *) &myop; + myop.op_next = NULL; + myop.op_flags = OPf_STACKED; + + switch (gimme) { + case G_VOID: + myop.op_flags |= OPf_WANT_VOID; + break; + case G_ARRAY: + if (flags & AMGf_want_list) { + myop.op_flags |= OPf_WANT_LIST; + break; + } + /* FALLTHROUGH */ + default: + myop.op_flags |= OPf_WANT_SCALAR; + break; + } + + PUSHSTACKi(PERLSI_OVERLOAD); + ENTER; + SAVEOP(); + PL_op = (OP *) &myop; + if (PERLDB_SUB && PL_curstash != PL_debstash) + PL_op->op_private |= OPpENTERSUB_DB; + Perl_pp_pushmark(aTHX); + + 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(newSVpvn_flags(AMG_id2name(method + assignshift), + AMG_id2namelen(method + assignshift), SVs_TEMP)); + } + else if (flags & AMGf_numarg) + PUSHs(&PL_sv_undef); + if (flags & AMGf_numarg) + PUSHs(&PL_sv_yes); + PUSHs(MUTABLE_SV(cv)); + PUTBACK; + oldmark = TOPMARK; + + if ((PL_op = PL_ppaddr[OP_ENTERSUB](aTHX))) + CALLRUNOPS(aTHX); + LEAVE; + SPAGAIN; + nret = SP - (PL_stack_base + oldmark); + + switch (gimme) { + case G_VOID: + /* returning NULL has another meaning, and we check the context + * at the call site too, so this can be differentiated from the + * scalar case */ + res = &PL_sv_undef; + SP = PL_stack_base + oldmark; + break; + case G_ARRAY: { + if (flags & AMGf_want_list) { + res = sv_2mortal((SV *)newAV()); + av_extend((AV *)res, nret); + while (nret--) + av_store((AV *)res, nret, POPs); + break; + } + /* FALLTHROUGH */ + } + default: + res = POPs; + break; + } + + 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; + default: + ans=0; 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; + } + } +} + +void +Perl_gv_name_set(pTHX_ GV *gv, const char *name, U32 len, U32 flags) +{ + dVAR; + U32 hash; + + PERL_ARGS_ASSERT_GV_NAME_SET; + + if (len > I32_MAX) + Perl_croak(aTHX_ "panic: gv name too long (%"UVuf")", (UV) len); + + if (!(flags & GV_ADD) && GvNAME_HEK(gv)) { + unshare_hek(GvNAME_HEK(gv)); + } + + PERL_HASH(hash, name, len); + GvNAME_HEK(gv) = share_hek(name, (flags & SVf_UTF8 ? -(I32)len : (I32)len), hash); +} + +/* +=for apidoc gv_try_downgrade + +If the typeglob C<gv> can be expressed more succinctly, by having +something other than a real GV in its place in the stash, replace it +with the optimised form. Basic requirements for this are that C<gv> +is a real typeglob, is sufficiently ordinary, and is only referenced +from its package. This function is meant to be used when a GV has been +looked up in part to see what was there, causing upgrading, but based +on what was found it turns out that the real GV isn't required after all. + +If C<gv> is a completely empty typeglob, it is deleted from the stash. + +If C<gv> is a typeglob containing only a sufficiently-ordinary constant +sub, the typeglob is replaced with a scalar-reference placeholder that +more compactly represents the same thing. + +=cut +*/ + +void +Perl_gv_try_downgrade(pTHX_ GV *gv) +{ + HV *stash; + CV *cv; + HEK *namehek; + SV **gvp; + PERL_ARGS_ASSERT_GV_TRY_DOWNGRADE; + + /* XXX Why and where does this leave dangling pointers during global + destruction? */ + if (PL_phase == PERL_PHASE_DESTRUCT) return; + + if (!(SvREFCNT(gv) == 1 && SvTYPE(gv) == SVt_PVGV && !SvFAKE(gv) && + !SvOBJECT(gv) && !SvREADONLY(gv) && + isGV_with_GP(gv) && GvGP(gv) && + !GvINTRO(gv) && GvREFCNT(gv) == 1 && + !GvSV(gv) && !GvAV(gv) && !GvHV(gv) && !GvIOp(gv) && !GvFORM(gv) && + GvEGVx(gv) == gv && (stash = GvSTASH(gv)))) + return; + if (gv == PL_statgv || gv == PL_last_in_gv || gv == PL_stderrgv) + return; + if (SvMAGICAL(gv)) { + MAGIC *mg; + /* only backref magic is allowed */ + if (SvGMAGICAL(gv) || SvSMAGICAL(gv)) + return; + for (mg = SvMAGIC(gv); mg; mg = mg->mg_moremagic) { + if (mg->mg_type != PERL_MAGIC_backref) + return; + } + } + cv = GvCV(gv); + if (!cv) { + HEK *gvnhek = GvNAME_HEK(gv); + (void)hv_deletehek(stash, gvnhek, G_DISCARD); + } else if (GvMULTI(gv) && cv && SvREFCNT(cv) == 1 && + !SvOBJECT(cv) && !SvMAGICAL(cv) && !SvREADONLY(cv) && + CvSTASH(cv) == stash && !CvNAMED(cv) && CvGV(cv) == gv && + CvCONST(cv) && !CvMETHOD(cv) && !CvLVALUE(cv) && !CvUNIQUE(cv) && + !CvNODEBUG(cv) && !CvCLONE(cv) && !CvCLONED(cv) && !CvANON(cv) && + (namehek = GvNAME_HEK(gv)) && + (gvp = hv_fetchhek(stash, namehek, 0)) && + *gvp == (SV*)gv) { + SV *value = SvREFCNT_inc(CvXSUBANY(cv).any_ptr); + const bool imported = !!GvIMPORTED_CV(gv); + SvREFCNT(gv) = 0; + sv_clear((SV*)gv); + SvREFCNT(gv) = 1; + SvFLAGS(gv) = SVt_IV|SVf_ROK|SVprv_PCS_IMPORTED * imported; + + /* See also: 'SET_SVANY_FOR_BODYLESS_IV' in sv.c */ + SvANY(gv) = (XPVGV*)((char*)&(gv->sv_u.svu_iv) - + STRUCT_OFFSET(XPVIV, xiv_iv)); + SvRV_set(gv, value); + } +} + +GV * +Perl_gv_override(pTHX_ const char * const name, const STRLEN len) +{ + GV *gv = gv_fetchpvn(name, len, GV_NOTQUAL, SVt_PVCV); + GV * const *gvp; + PERL_ARGS_ASSERT_GV_OVERRIDE; + if (gv && GvCVu(gv) && GvIMPORTED_CV(gv)) return gv; + gvp = (GV**)hv_fetch(PL_globalstash, name, len, FALSE); + gv = gvp ? *gvp : NULL; + if (gv && !isGV(gv)) { + if (!SvPCS_IMPORTED(gv)) return NULL; + gv_init(gv, PL_globalstash, name, len, 0); + return gv; + } + return gv && GvCVu(gv) && GvIMPORTED_CV(gv) ? gv : NULL; +} + +#include "XSUB.h" + +static void +core_xsub(pTHX_ CV* cv) +{ + Perl_croak(aTHX_ + "&CORE::%s cannot be called directly", GvNAME(CvGV(cv)) + ); +} + +/* + * ex: set ts=8 sts=4 sw=4 et: + */