X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/e17aed30f88453e866224b8226836acc4cbc3824..999448781bc711c8732271b98a45a724f7357c46:/gv.c diff --git a/gv.c b/gv.c index 476afc5..8b43d91 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; @@ -132,7 +130,7 @@ Perl_gv_fetchfile_flags(pTHX_ const char *const name, const STRLEN namelen, #endif } if ((PERLDB_LINE || PERLDB_SAVESRC) && !GvAV(gv)) - hv_magic(GvHVn(gv_AVadd(gv)), NULL, PERL_MAGIC_dbfile); + hv_magic(GvHVn(gv), GvAVn(gv), PERL_MAGIC_dbfile); if (tmpbuf != smallbuf) Safefree(tmpbuf); return gv; @@ -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)); @@ -330,7 +329,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)) @@ -353,6 +351,7 @@ Perl_gv_init_pvn(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, U32 flag 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); @@ -463,7 +462,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,7 +518,6 @@ 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; } @@ -541,7 +539,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 +548,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 +643,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 +899,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 +945,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 +1053,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) || !CvGV(cv)) stubgv = gv; else { stubgv = CvGV(cv); @@ -1098,7 +1094,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 +1118,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); @@ -1245,7 +1241,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 +1251,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", @@ -1451,7 +1447,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 +1578,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) { @@ -1670,10 +1666,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 +1684,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 +1843,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 +1963,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,6 +2017,10 @@ 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); } } @@ -2073,7 +2078,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 +2113,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 +2247,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 +2301,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 +2322,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 +2341,6 @@ Perl_gp_ref(pTHX_ GP *gp) void Perl_gp_free(pTHX_ GV *gv) { - dVAR; GP* gp; int attempts = 100; @@ -2342,9 +2352,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,17 +2389,18 @@ 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_delete(PL_stashcache, HEK_KEY(hvname_hek), - (HEK_UTF8(hvname_hek) ? -HEK_LEN(hvname_hek) : HEK_LEN(hvname_hek)), - G_DISCARD); + (void)hv_deletehek(PL_stashcache, hvname_hek, G_DISCARD); SvREFCNT_dec(hv); } 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 @@ -2404,6 +2417,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); } @@ -2439,7 +2454,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); @@ -2466,6 +2480,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 */ @@ -2496,6 +2512,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: */ @@ -2562,7 +2582,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, @@ -2582,7 +2621,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; @@ -2634,7 +2672,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; @@ -2677,7 +2714,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; @@ -2732,11 +2768,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"); @@ -2745,6 +2789,8 @@ Perl_amagic_deref_call(pTHX_ SV *ref, int method) { return tmpsv; } ref = tmpsv; + if (!SvAMAGIC(ref)) + break; } return tmpsv ? tmpsv : ref; } @@ -2909,7 +2955,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: @@ -2917,7 +2963,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; } @@ -2984,7 +3030,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; @@ -3174,7 +3219,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); @@ -3322,6 +3366,8 @@ Perl_gv_try_downgrade(pTHX_ GV *gv) !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 */ @@ -3335,16 +3381,14 @@ Perl_gv_try_downgrade(pTHX_ GV *gv) cv = GvCV(gv); if (!cv) { HEK *gvnhek = GvNAME_HEK(gv); - (void)hv_delete(stash, HEK_KEY(gvnhek), - HEK_UTF8(gvnhek) ? -HEK_LEN(gvnhek) : HEK_LEN(gvnhek), G_DISCARD); - } else if (GvMULTI(gv) && cv && + (void)hv_deletehek(stash, gvnhek, G_DISCARD); + } else if (GvMULTI(gv) && cv && SvREFCNT(cv) == 1 && !SvOBJECT(cv) && !SvMAGICAL(cv) && !SvREADONLY(cv) && CvSTASH(cv) == stash && 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); @@ -3358,6 +3402,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