X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/43e4250a611bbded7aab070226e8d756638cd569..14e9b8fddd27e76adaa6d1aa4f5529b74024eb74:/gv.c diff --git a/gv.c b/gv.c index e7ef9a7..eaf9d21 100644 --- a/gv.c +++ b/gv.c @@ -21,7 +21,6 @@ /* =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. @@ -102,7 +101,6 @@ GV * Perl_gv_fetchfile_flags(pTHX_ const char *const name, const STRLEN namelen, const U32 flags) { - dVAR; char smallbuf[128]; char *tmpbuf; const STRLEN tmplen = namelen + 2; @@ -153,6 +151,7 @@ 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)); @@ -217,7 +216,7 @@ Perl_newGP(pTHX_ GV *const gv) void Perl_cvgv_set(pTHX_ CV* cv, GV* gv) { - GV * const oldgv = CvGV(cv); + GV * const oldgv = CvNAMED(cv) ? NULL : SvANY(cv)->xcv_gv_u.xcv_gv; HEK *hek; PERL_ARGS_ASSERT_CVGV_SET; @@ -233,8 +232,12 @@ Perl_cvgv_set(pTHX_ CV* cv, GV* gv) sv_del_backref(MUTABLE_SV(oldgv), MUTABLE_SV(cv)); } } - else if ((hek = CvNAME_HEK(cv))) unshare_hek(hek); + 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)); @@ -249,6 +252,37 @@ Perl_cvgv_set(pTHX_ CV* cv, GV* 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 @@ -330,7 +364,6 @@ Perl_gv_init_pv(pTHX_ GV *gv, HV *stash, const char *name, U32 flags) void Perl_gv_init_pvn(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, U32 flags) { - dVAR; const U32 old_type = SvTYPE(gv); const bool doproto = old_type > SVt_NULL; char * const proto = (doproto && SvPOK(gv)) @@ -345,14 +378,14 @@ Perl_gv_init_pvn(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, U32 flag assert (!(proto && has_constant)); if (has_constant) { - /* The constant has to be a simple scalar type. */ + /* The constant has to be a scalar, array or subroutine. */ switch (SvTYPE(has_constant)) { case SVt_PVHV: - case SVt_PVCV: 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); @@ -383,7 +416,21 @@ Perl_gv_init_pvn(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, U32 flag 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 (doproto) { + 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. */ @@ -463,7 +510,7 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv, /* 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_CORE : + 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 : @@ -519,9 +566,9 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv, cv = MUTABLE_CV(newSV_type(SVt_PVCV)); GvCV_set(gv,cv); GvCVGEN(gv) = 0; - mro_method_changed_in(GvSTASH(gv)); CvISXSUB_on(cv); CvXSUB(cv) = core_xsub; + PoisonPADLIST(cv); } CvGV_set(cv, gv); /* This stops new ATTRSUB from setting CvFILE from PL_curcop. */ @@ -541,7 +588,7 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv, CvLVALUE_on(cv); /* newATTRSUB will free the CV and return NULL if we're still compiling after a syntax error */ - if ((cv = newATTRSUB_flags( + if ((cv = newATTRSUB_x( oldsavestack_ix, (OP *)gv, NULL,NULL, coresub_op( @@ -550,7 +597,7 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv, : newSVpvn(name,len), code, opnum ), - 1 + TRUE )) != NULL) { assert(GvCV(gv) == orig_cv); if (opnum != OP_VEC && opnum != OP_SUBSTR && opnum != OP_POS @@ -645,7 +692,6 @@ obtained from the GV with the C macro. GV * Perl_gv_fetchmeth_pvn(pTHX_ HV *stash, const char *name, STRLEN len, I32 level, U32 flags) { - dVAR; GV** gvp; AV* linear_av; SV** linear_svp; @@ -902,16 +948,16 @@ means yes, look for AUTOLOAD; zero means no, don't look for AUTOLOAD. Calling C is equivalent to calling C with a non-zero C parameter. -These functions grant C<"SUPER"> token as a prefix of the method name. Note +These functions grant C<"SUPER"> token +as a prefix of the method name. Note that if you want to keep the returned glob for a long time, you need to check for it being "AUTOLOAD", since at the later time the call may load a -different subroutine due to $AUTOLOAD changing its value. Use the glob -created via a side effect to do this. +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 and as C with -C. C should be writable if contains C<':'> or C<' -''>. The warning against passing the GV returned by C to -C apply equally to these functions. +These functions have the same side-effects as C with +C. The warning against passing the GV returned by +C to C applies equally to these functions. =cut */ @@ -948,7 +994,6 @@ Perl_gv_fetchmethod_pv_flags(pTHX_ HV *stash, const char *name, U32 flags) GV * Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN len, U32 flags) { - dVAR; const char *nend; const char *nsplit = NULL; GV* gv; @@ -1057,7 +1102,7 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le GV* stubgv; GV* autogv; - if (CvANON(cv)) + if (CvANON(cv) || CvLEXICAL(cv)) stubgv = gv; else { stubgv = CvGV(cv); @@ -1098,7 +1143,6 @@ Perl_gv_autoload_pv(pTHX_ HV *stash, const char *namepv, U32 flags) GV* Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags) { - dVAR; GV* gv; CV* cv; HV* varstash; @@ -1123,7 +1167,8 @@ Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags) 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))) + if (!(gv = gv_fetchmeth_pvn(stash, S_autoload, S_autolen, FALSE, + is_utf8 | (flags & GV_SUPER)))) return NULL; cv = GvCV(gv); @@ -1202,7 +1247,7 @@ Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags) * use that, but for lack of anything better we will use the sub's * original package to look up $AUTOLOAD. */ - varstash = GvSTASH(CvGV(cv)); + varstash = CvNAMED(cv) ? CvSTASH(cv) : GvSTASH(CvGV(cv)); vargv = *(GV**)hv_fetch(varstash, S_autoload, S_autolen, TRUE); ENTER; @@ -1245,7 +1290,6 @@ Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags) STATIC HV* S_require_tie_mod(pTHX_ GV *gv, const char *varpv, SV* namesv, const char *methpv,const U32 flags) { - dVAR; HV* stash = gv_stashsv(namesv, 0); PERL_ARGS_ASSERT_REQUIRE_TIE_MOD; @@ -1256,14 +1300,15 @@ S_require_tie_mod(pTHX_ GV *gv, const char *varpv, SV* namesv, const char *methp 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); - PUSHSTACKi(PERLSI_MAGIC); Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, module, NULL); - POPSTACK; + 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", @@ -1314,11 +1359,22 @@ Flags may be one of: The most important of which are probably GV_ADD and SVf_UTF8. +Note, use of C instead of C where possible is strongly +recommended for performance reasons. + =cut */ -HV* -Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags) +/* +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; @@ -1326,7 +1382,7 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags) GV *tmpgv; U32 tmplen = namelen + 2; - PERL_ARGS_ASSERT_GV_STASHPVN; + PERL_ARGS_ASSERT_GV_STASHPVN_INTERNAL; if (tmplen <= sizeof smallbuf) tmpbuf = smallbuf; @@ -1356,22 +1412,81 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags) } /* +gv_stashsvpvn_cached + +Returns a pointer to the stash for a specified package, possibly +cached. Implements both C and C. + +Requires one of either namesv or namepv to be non-null. + +See C 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. +Note this interface is strongly preferred over C for performance reasons. + =cut */ HV* Perl_gv_stashsv(pTHX_ SV *sv, I32 flags) { - STRLEN len; - const char * const ptr = SvPV_const(sv,len); - PERL_ARGS_ASSERT_GV_STASHSV; - - return gv_stashpvn(ptr, len, flags | SvUTF8(sv)); + return gv_stashsvpvn_cached(sv, NULL, 0, flags); } @@ -1451,7 +1566,7 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name, tmpbuf[(*len)++] = ':'; key = tmpbuf; } - gvp = (GV**)hv_fetch(*stash, key, is_utf8 ? -(*len) : *len, add); + 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) @@ -1582,7 +1697,7 @@ S_find_default_stash(pTHX_ HV **stash, const char *name, STRLEN len, !(len == 1 && sv_type == SVt_PV && (*name == 'a' || *name == 'b')) ) { - GV**gvp = (GV**)hv_fetch(*stash,name,is_utf8 ? -len : len,0); + 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) { @@ -1617,17 +1732,19 @@ S_find_default_stash(pTHX_ HV **stash, const char *name, STRLEN len, if (!*stash) { if (add && !PL_in_clean_all) { - SV * const err = Perl_mess(aTHX_ + GV *gv; + qerror(Perl_mess(aTHX_ "Global symbol \"%s%"UTF8f - "\" requires explicit package name", + "\" 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)); - GV *gv; - if (is_utf8) - SvUTF8_on(err); - qerror(err); + : ""), 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 @@ -1650,6 +1767,12 @@ S_find_default_stash(pTHX_ HV **stash, const char *name, STRLEN len, 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 @@ -1670,10 +1793,10 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, PERL_ARGS_ASSERT_GV_MAGICALIZE; if (stash != PL_defstash) { /* not the main stash */ - /* We only have to check for three names here: EXPORT, ISA + /* 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 > 2) { + if (len) { const char * const name2 = name + 1; switch (*name) { case 'E': @@ -1688,6 +1811,11 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, 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; } @@ -1842,7 +1970,7 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, if (!isDIGIT(*end)) return addmg; } - paren = strtoul(name, NULL, 10); + paren = grok_atou(name, NULL); goto storeparen; } } @@ -1962,7 +2090,7 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, case '\023': /* $^S */ ro_magicalize: SvREADONLY_on(GvSVn(gv)); - /* FALL THROUGH */ + /* FALLTHROUGH */ case '0': /* $0 */ case '^': /* $^ */ case '~': /* $~ */ @@ -2016,12 +2144,20 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, 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 @@ -2073,7 +2209,6 @@ GV * Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, const svtype sv_type) { - dVAR; const char *name = nambeg; GV *gv = NULL; GV**gvp; @@ -2109,7 +2244,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, } /* By this point we should have a stash and a name */ - gvp = (GV**)hv_fetch(stash,name,is_utf8 ? -len : len,add); + 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; @@ -2243,28 +2378,37 @@ Perl_gv_efullname4(pTHX_ SV *sv, const GV *gv, const char *prefix, bool keepmain 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) { - dVAR; 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; - /* SvIsCOW is unused on HVs, so we can use it to mark stashes we - are currently searching through recursively. */ - SvIsCOW_on(stash); + /* 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 && !SvIsCOW(hv)) + 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) != '_' @@ -2288,14 +2432,13 @@ Perl_gv_check(pTHX_ HV *stash) HEKfARG(GvNAME_HEK(gv))); } } - SvIsCOW_off(stash); + HvAUX(stash)->xhv_aux_flags &= ~HvAUXf_SCAN_STASH; } } GV * Perl_newGVgen_flags(pTHX_ const char *pack, U32 flags) { - dVAR; PERL_ARGS_ASSERT_NEWGVGEN_FLAGS; assert(!(flags & ~SVf_UTF8)); @@ -2310,7 +2453,6 @@ Perl_newGVgen_flags(pTHX_ const char *pack, U32 flags) GP* Perl_gp_ref(pTHX_ GP *gp) { - dVAR; if (!gp) return NULL; gp->gp_refcnt++; @@ -2330,7 +2472,6 @@ Perl_gp_ref(pTHX_ GP *gp) void Perl_gp_free(pTHX_ GV *gv) { - dVAR; GP* gp; int attempts = 100; @@ -2342,9 +2483,11 @@ Perl_gp_free(pTHX_ GV *gv) pTHX__FORMAT pTHX__VALUE); return; } - if (--gp->gp_refcnt > 0) { + if (gp->gp_refcnt > 1) { + borrowed: if (gp->gp_egv == gv) gp->gp_egv = 0; + gp->gp_refcnt--; GvGP_set(gv, NULL); return; } @@ -2377,15 +2520,28 @@ Perl_gp_free(pTHX_ GV *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); - DEBUG_o(Perl_deb(aTHX_ "gp_free clearing PL_stashcache for '%"HEKf"'\n", hvname_hek)); + DEBUG_o(Perl_deb(aTHX_ "gp_free clearing PL_stashcache for '%"HEKf"'\n", HEKfARG(hvname_hek))); if (PL_stashcache && 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 @@ -2402,6 +2558,8 @@ Perl_gp_free(pTHX_ GV *gv) } } + /* Possibly incremented by a destructor doing glob assignment */ + if (gp->gp_refcnt > 1) goto borrowed; Safefree(gp); GvGP_set(gv, NULL); } @@ -2437,7 +2595,6 @@ Perl_magic_freeovrld(pTHX_ SV *sv, MAGIC *mg) int Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing) { - dVAR; MAGIC* const mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table); AMT amt; const struct mro_meta* stash_meta = HvMROMETA(stash); @@ -2464,6 +2621,8 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing) { int filled = 0; int i; + bool deref_seen = 0; + /* Work with "fallback" key, which we assume to be first in PL_AMG_names */ @@ -2494,6 +2653,10 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing) 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: */ @@ -2511,11 +2674,14 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing) numifying instead of C's "+0". */ gv = Perl_gv_fetchmeth_pvn(aTHX_ stash, cooky, l, -1, 0); cv = 0; - if (gv && (cv = GvCV(gv))) { - if(GvNAMELEN(CvGV(cv)) == 3 && strEQ(GvNAME(CvGV(cv)), "nil")){ - const char * const hvname = HvNAME_get(GvSTASH(CvGV(cv))); - if (hvname && HEK_LEN(HvNAME_HEK(GvSTASH(CvGV(cv)))) == 8 - && strEQ(hvname, "overload")) { + 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. */ @@ -2549,7 +2715,6 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing) } } 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))), @@ -2560,7 +2725,26 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing) 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, @@ -2580,7 +2764,6 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing) CV* Perl_gv_handler(pTHX_ HV *stash, I32 id) { - dVAR; MAGIC *mg; AMT *amtp; U32 newgen; @@ -2632,7 +2815,6 @@ Perl_gv_handler(pTHX_ HV *stash, I32 id) bool Perl_try_amagic_un(pTHX_ int method, int flags) { - dVAR; dSP; SV* tmpsv; SV* const arg = TOPs; @@ -2675,7 +2857,6 @@ Perl_try_amagic_un(pTHX_ int method, int flags) { bool Perl_try_amagic_bin(pTHX_ int method, int flags) { - dVAR; dSP; SV* const left = TOPm1s; SV* const right = TOPs; @@ -2730,11 +2911,19 @@ Perl_try_amagic_bin(pTHX_ int method, int flags) { SV * Perl_amagic_deref_call(pTHX_ SV *ref, int method) { SV *tmpsv = NULL; + HV *stash; PERL_ARGS_ASSERT_AMAGIC_DEREF_CALL; - while (SvAMAGIC(ref) && - (tmpsv = amagic_call(ref, &PL_sv_undef, method, + 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"); @@ -2743,6 +2932,8 @@ Perl_amagic_deref_call(pTHX_ SV *ref, int method) { return tmpsv; } ref = tmpsv; + if (!SvAMAGIC(ref)) + break; } return tmpsv ? tmpsv : ref; } @@ -2907,7 +3098,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) case regexp_amg: /* FAIL safe */ return NULL; /* Delegate operation to standard mechanisms. */ - break; + case to_sv_amg: case to_av_amg: case to_hv_amg: @@ -2915,7 +3106,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) case to_cv_amg: /* FAIL safe */ return left; /* Delegate operation to standard mechanisms. */ - break; + default: goto not_found; } @@ -2982,7 +3173,6 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) case to_cv_amg: /* FAIL safe */ return left; /* Delegate operation to standard mechanisms. */ - break; } if (ocvp && (cv=ocvp[nomethod_amg])) { /* Call report method */ notfound = 1; lr = -1; @@ -3172,7 +3362,6 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) PL_op = (OP *) &myop; if (PERLDB_SUB && PL_curstash != PL_debstash) PL_op->op_private |= OPpENTERSUB_DB; - PUTBACK; Perl_pp_pushmark(aTHX); EXTEND(SP, notfound + 5); @@ -3336,14 +3525,13 @@ Perl_gv_try_downgrade(pTHX_ GV *gv) if (!cv) { HEK *gvnhek = GvNAME_HEK(gv); (void)hv_deletehek(stash, gvnhek, G_DISCARD); - } else if (GvMULTI(gv) && cv && + } else if (GvMULTI(gv) && cv && SvREFCNT(cv) == 1 && !SvOBJECT(cv) && !SvMAGICAL(cv) && !SvREADONLY(cv) && - CvSTASH(cv) == stash && CvGV(cv) == gv && + 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_fetch(stash, HEK_KEY(namehek), - HEK_LEN(namehek)*(HEK_UTF8(namehek) ? -1 : 1), 0)) && + (gvp = hv_fetchhek(stash, namehek, 0)) && *gvp == (SV*)gv) { SV *value = SvREFCNT_inc(CvXSUBANY(cv).any_ptr); const bool imported = !!GvIMPORTED_CV(gv); @@ -3357,6 +3545,23 @@ Perl_gv_try_downgrade(pTHX_ GV *gv) } } +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