X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=gv.c;h=9ad44340e51498cdd4de062b1f89bf71d0cf82a3;hb=6b29934bd65555b7f172ba7a683ba95b59eb919b;hp=9b68820428bdeba48e7c0bc1484b6a00268ce735;hpb=95b63a389ed86efed1a2fa9fd24931d56aac6070;p=p5sagit%2Fp5-mst-13.2.git diff --git a/gv.c b/gv.c index 9b68820..9ad4434 100644 --- a/gv.c +++ b/gv.c @@ -157,11 +157,36 @@ Perl_gv_const_sv(pTHX_ GV *gv) return SvROK(gv) ? SvRV(gv) : NULL; } +GP * +Perl_newGP(pTHX_ GV *const gv) +{ + GP *gp; + const char *const file = CopFILE(PL_curcop) ? CopFILE(PL_curcop) : ""; + STRLEN len = strlen(file); + U32 hash; + + PERL_HASH(hash, file, len); + + Newxz(gp, 1, GP); + +#ifndef PERL_DONT_CREATE_GVSV + gp->gv_sv = newSV(0); +#endif + + gp->gp_line = CopLINE(PL_curcop); + /* XXX Ideally this cast would be replaced with a change to const char* + in the struct. */ + gp->gp_file_hek = share_hek(file, len, hash); + gp->gp_egv = gv; + gp->gp_refcnt = 1; + + return gp; +} + void Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) { dVAR; - register GP *gp; const U32 old_type = SvTYPE(gv); const bool doproto = old_type > SVt_NULL; const char * const proto = (doproto && SvPOK(gv)) ? SvPVX_const(gv) : NULL; @@ -179,6 +204,7 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) 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); @@ -198,20 +224,9 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) } else Safefree(SvPVX_mutable(gv)); } - Newxz(gp, 1, GP); SvSCREAM_on(gv); - GvGP(gv) = gp_ref(gp); -#ifdef PERL_DONT_CREATE_GVSV - GvSV(gv) = NULL; -#else - GvSV(gv) = newSV(0); -#endif - GvLINE(gv) = CopLINE(PL_curcop); - /* XXX Ideally this cast would be replaced with a change to const char* - in the struct. */ - GvFILE(gv) = CopFILE(PL_curcop) ? CopFILE(PL_curcop) : (char *) ""; - GvCVGEN(gv) = 0; - GvEGV(gv) = gv; + + GvGP(gv) = Perl_newGP(aTHX_ gv); GvSTASH(gv) = stash; if (stash) Perl_sv_add_backref(aTHX_ (SV*)stash, (SV*)gv); @@ -298,6 +313,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) GV** gvp; CV* cv; const char *hvname; + HV* lastchance = NULL; /* UNIVERSAL methods should be callable without a stash */ if (!stash) { @@ -385,7 +401,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) /* if at top level, try UNIVERSAL */ if (level == 0 || level == -1) { - HV* const lastchance = gv_stashpvs("UNIVERSAL", FALSE); + lastchance = gv_stashpvs("UNIVERSAL", FALSE); if (lastchance) { if ((gv = gv_fetchmeth(lastchance, name, len, @@ -639,7 +655,6 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method) sv_setpvn(varsv, packname, packname_len); sv_catpvs(varsv, "::"); sv_catpvn(varsv, name, len); - SvTAINTED_off(varsv); return gv; } @@ -929,10 +944,16 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, : sv_type == SVt_PVAV ? "@" : sv_type == SVt_PVHV ? "%" : ""), name); + GV *gv; if (USE_UTF8_IN_NAMES) SvUTF8_on(err); qerror(err); - stash = GvHV(gv_fetchpvn_flags("::", 8, GV_ADDMULTI, SVt_PVHV)); + gv = gv_fetchpvn_flags("::", 8, GV_ADDMULTI, SVt_PVHV); + if(!gv) { + /* symbol table under destruction */ + return NULL; + } + stash = GvHV(gv); } else return NULL; @@ -988,6 +1009,9 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, 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)) @@ -1164,10 +1188,14 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, goto magicalize; case '+': + GvMULTI_on(gv); { AV* const av = GvAVn(gv); + HV* const hv = GvHVn(gv); sv_magic((SV*)av, (SV*)av, PERL_MAGIC_regdata, NULL, 0); SvREADONLY_on(av); + hv_magic(hv, NULL, PERL_MAGIC_regdata_names); + SvREADONLY_on(hv); /* FALL THROUGH */ } case '\023': /* $^S */ @@ -1299,7 +1327,7 @@ Perl_newIO(pTHX) } void -Perl_gv_check(pTHX_ HV *stash) +Perl_gv_check(pTHX_ const HV *stash) { dVAR; register I32 i; @@ -1408,6 +1436,7 @@ Perl_gp_free(pTHX_ GV *gv) return; } + unshare_hek(gp->gp_file_hek); SvREFCNT_dec(gp->gp_sv); SvREFCNT_dec(gp->gp_av); /* FIXME - another reference loop GV -> symtab -> GV ? @@ -1453,13 +1482,16 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) { dVAR; MAGIC* const mg = mg_find((SV*)stash, PERL_MAGIC_overload_table); - AMT * const amtp = (mg) ? (AMT*)mg->mg_ptr: (AMT *) NULL; AMT amt; - if (mg && amtp->was_ok_am == PL_amagic_generation - && amtp->was_ok_sub == PL_sub_generation) - return (bool)AMT_OVERLOADED(amtp); - sv_unmagic((SV*)stash, PERL_MAGIC_overload_table); + if (mg) { + const AMT * const amtp = (AMT*)mg->mg_ptr; + if (amtp->was_ok_am == PL_amagic_generation + && amtp->was_ok_sub == PL_sub_generation) { + return (bool)AMT_OVERLOADED(amtp); + } + sv_unmagic((SV*)stash, PERL_MAGIC_overload_table); + } DEBUG_o( Perl_deb(aTHX_ "Recalcing overload magic in package %s\n",HvNAME_get(stash)) ); @@ -1526,7 +1558,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) DEBUG_o( Perl_deb(aTHX_ "Resolving method \"%"SVf256\ "\" for overloaded \"%s\" in package \"%.256s\"\n", - GvSV(gv), cp, hvname) ); + (void*)GvSV(gv), cp, hvname) ); if (!gvsv || !SvPOK(gvsv) || !(ngv = gv_fetchmethod_autoload(stash, SvPVX_const(gvsv), FALSE))) @@ -1586,6 +1618,7 @@ Perl_gv_handler(pTHX_ HV *stash, I32 id) Gv_AMupdate(stash); mg = mg_find((SV*)stash, PERL_MAGIC_overload_table); } + assert(mg); amtp = (AMT*)mg->mg_ptr; if ( amtp->was_ok_am != PL_amagic_generation || amtp->was_ok_sub != PL_sub_generation ) @@ -1800,6 +1833,9 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) notfound = 1; lr = -1; } else if (cvp && (cv=cvp[nomethod_amg])) { notfound = 1; lr = 1; + } else if ((amtp && amtp->fallback >= AMGfallYES) && !DEBUG_o_TEST) { + /* Skip generating the "no method found" message. */ + return NULL; } else { SV *msg; if (off==-1) off=method;