X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=gv.c;h=d02f741e44c1442b08f56bfe988663ed6dde65f7;hb=c5375c28ff9f285618d7079f4044f72aad1773ab;hp=0cf779f0b180b83cf7376b425544fdfce0609a19;hpb=71315bf2ed5c47e3f417cdce95f41fe9b0da6b1f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/gv.c b/gv.c index 0cf779f..d02f741 100644 --- a/gv.c +++ b/gv.c @@ -80,7 +80,8 @@ Perl_gv_IOadd(pTHX_ register GV *gv) * if it walks like a dirhandle, then let's assume that * this is a dirhandle. */ - const char *fh = PL_op->op_type == OP_READDIR || + const char * const fh = + PL_op->op_type == OP_READDIR || PL_op->op_type == OP_TELLDIR || PL_op->op_type == OP_SEEKDIR || PL_op->op_type == OP_REWINDDIR || @@ -110,7 +111,7 @@ Perl_gv_fetchfile(pTHX_ const char *name) GV *gv; if (!PL_defstash) - return Nullgv; + return NULL; tmplen = strlen(name) + 2; if (tmplen < sizeof smallbuf) @@ -130,7 +131,7 @@ Perl_gv_fetchfile(pTHX_ const char *name) sv_setpvn(GvSV(gv), name, tmplen - 2); #endif if (PERLDB_LINE) - hv_magic(GvHVn(gv_AVadd(gv)), Nullgv, PERL_MAGIC_dbfile); + hv_magic(GvHVn(gv_AVadd(gv)), NULL, PERL_MAGIC_dbfile); } if (tmpbuf != smallbuf) Safefree(tmpbuf); @@ -161,7 +162,8 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) { dVAR; register GP *gp; - const bool doproto = SvTYPE(gv) > SVt_NULL; + const U32 old_type = SvTYPE(gv); + const bool doproto = old_type > SVt_NULL; const char * const proto = (doproto && SvPOK(gv)) ? SvPVX_const(gv) : NULL; SV *const has_constant = doproto && SvROK(gv) ? SvRV(gv) : NULL; @@ -182,7 +184,12 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) SvROK_off(gv); } - sv_upgrade((SV*)gv, SVt_PVGV); + + if (old_type < SVt_PVGV) { + if (old_type >= SVt_PV) + SvCUR_set(gv, 0); + sv_upgrade((SV*)gv, SVt_PVGV); + } if (SvLEN(gv)) { if (proto) { SvPV_set(gv, NULL); @@ -192,6 +199,7 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) Safefree(SvPVX_mutable(gv)); } Newxz(gp, 1, GP); + SvSCREAM_on(gv); GvGP(gv) = gp_ref(gp); #ifdef PERL_DONT_CREATE_GVSV GvSV(gv) = NULL; @@ -204,12 +212,10 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) GvFILE(gv) = CopFILE(PL_curcop) ? CopFILE(PL_curcop) : (char *) ""; GvCVGEN(gv) = 0; GvEGV(gv) = gv; - sv_magic((SV*)gv, (SV*)gv, PERL_MAGIC_glob, Nullch, 0); GvSTASH(gv) = stash; if (stash) Perl_sv_add_backref(aTHX_ (SV*)stash, (SV*)gv); - GvNAME(gv) = savepvn(name, len); - GvNAMELEN(gv) = len; + gv_name_set(gv, name, len, GV_ADD); if (multi || doproto) /* doproto means it _was_ mentioned */ GvMULTI_on(gv); if (doproto) { /* Replicate part of newSUB here. */ @@ -313,7 +319,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) gvp = (GV**)hv_fetch(stash, name, len, (level >= 0)); if (!gvp) - topgv = Nullgv; + topgv = NULL; else { topgv = *gvp; if (SvTYPE(topgv) != SVt_PVGV) @@ -324,7 +330,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) return topgv; /* Stale cached entry: junk it */ SvREFCNT_dec(cv); - GvCV(topgv) = cv = Nullcv; + GvCV(topgv) = cv = NULL; GvCVGEN(topgv) = 0; } else if (GvCVGEN(topgv) == PL_sub_generation) @@ -351,7 +357,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level) if (SvTYPE(gv) != SVt_PVGV) gv_init(gv, stash, "ISA", 3, TRUE); SvREFCNT_dec(GvAV(gv)); - GvAV(gv) = (AV*)SvREFCNT_inc(av); + GvAV(gv) = (AV*)SvREFCNT_inc_simple(av); } } } @@ -508,7 +514,7 @@ Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload) --nsplit; if ((nsplit - origname) == 5 && strnEQ(origname, "SUPER", 5)) { /* ->SUPER::method should really be looked up in original stash */ - SV *tmpstr = sv_2mortal(Perl_newSVpvf(aTHX_ "%s::SUPER", + SV * const tmpstr = sv_2mortal(Perl_newSVpvf(aTHX_ "%s::SUPER", CopSTASHPV(PL_curcop))); /* __PACKAGE__::SUPER stash should be autovivified */ stash = gv_stashpvn(SvPVX_const(tmpstr), SvCUR(tmpstr), TRUE); @@ -572,7 +578,7 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method) STRLEN packname_len; if (len == S_autolen && strnEQ(name, S_autoload, S_autolen)) - return Nullgv; + return NULL; if (stash) { if (SvTYPE(stash) < SVt_PVHV) { packname = SvPV_const((SV*)stash, packname_len); @@ -584,11 +590,11 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method) } } if (!(gv = gv_fetchmeth(stash, S_autoload, S_autolen, FALSE))) - return Nullgv; + return NULL; cv = GvCV(gv); if (!(CvROOT(cv) || CvXSUB(cv))) - return Nullgv; + return NULL; /* * Inheriting AUTOLOAD for non-methods works ... for now. @@ -600,7 +606,7 @@ Perl_gv_autoload4(pTHX_ HV *stash, const char *name, STRLEN len, I32 method) "Use of inherited AUTOLOAD for non-method %s::%.*s() is deprecated", packname, (int)len, name); - if (CvXSUB(cv)) { + if (CvISXSUB(cv)) { /* rather than lookup/init $AUTOLOAD here * only to have the XSUB do another lookup for $AUTOLOAD * and split that value on the last '::', @@ -652,7 +658,7 @@ S_require_errno(pTHX_ GV *gv) ENTER; save_scalar(gv); /* keep the value of $! */ Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, - newSVpvs("Errno"), Nullsv); + newSVpvs("Errno"), NULL); LEAVE; SPAGAIN; stash = gv_stashpvs("Errno", FALSE); @@ -762,10 +768,17 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, HV *stash = NULL; const I32 no_init = flags & (GV_NOADD_NOINIT | GV_NOINIT); const I32 no_expand = flags & GV_NOEXPAND; - const I32 add = flags & ~SVf_UTF8 & ~GV_NOADD_NOINIT & ~GV_NOEXPAND; + const I32 add = + flags & ~SVf_UTF8 & ~GV_NOADD_NOINIT & ~GV_NOEXPAND & ~GV_NOTQUAL; const char *const name_end = nambeg + full_len; const char *const name_em1 = name_end - 1; + if (flags & GV_NOTQUAL) { + /* Caller promised that there is no stash, so we can skip the check. */ + len = full_len; + goto no_stash; + } + if (full_len > 2 && *name == '*' && isALPHA(name[1])) { /* accidental stringify on a GV? */ name++; @@ -779,7 +792,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, if (!stash) stash = PL_defstash; if (!stash || !SvREFCNT(stash)) /* symbol table under destruction */ - return Nullgv; + return NULL; len = name_cursor - name; if (len > 0) { @@ -795,7 +808,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, tmpbuf[len++] = ':'; tmpbuf[len] = '\0'; gvp = (GV**)hv_fetch(stash,tmpbuf,len,add); - gv = gvp ? *gvp : Nullgv; + gv = gvp ? *gvp : NULL; if (gv && gv != (GV*)&PL_sv_undef) { if (SvTYPE(gv) != SVt_PVGV) gv_init(gv, stash, tmpbuf, len, (add & GV_ADDMULTI)); @@ -805,7 +818,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, if (tmpbuf != smallbuf) Safefree(tmpbuf); if (!gv || gv == (GV*)&PL_sv_undef) - return Nullgv; + return NULL; if (!(stash = GvHV(gv))) stash = GvHV(gv) = newHV(); @@ -827,6 +840,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, /* No stash in name, so see how we can default */ if (!stash) { + no_stash: if (len && isIDFIRST_lazy(name)) { bool global = FALSE; @@ -921,15 +935,15 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, stash = GvHV(gv_fetchpvn_flags("::", 8, GV_ADDMULTI, SVt_PVHV)); } else - return Nullgv; + return NULL; } if (!SvREFCNT(stash)) /* symbol table under destruction */ - return Nullgv; + return NULL; gvp = (GV**)hv_fetch(stash,name,len,add); if (!gvp || *gvp == (GV*)&PL_sv_undef) - return Nullgv; + return NULL; gv = *gvp; if (SvTYPE(gv) == SVt_PVGV) { if (add) { @@ -960,6 +974,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, if (len > 1) { #ifndef EBCDIC if (*name > 'V' ) { + /*EMPTY*/; /* 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 @@ -982,7 +997,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, if (strEQ(name2, "SA")) { AV* const av = GvAVn(gv); GvMULTI_on(gv); - sv_magic((SV*)av, (SV*)gv, PERL_MAGIC_isa, Nullch, 0); + sv_magic((SV*)av, (SV*)gv, PERL_MAGIC_isa, NULL, 0); /* NOTE: No support for tied ISA */ if ((add & GV_ADDMULTI) && strEQ(nambeg,"AnyDBM_File::ISA") && AvFILLp(av) == -1) @@ -1005,7 +1020,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, if (strEQ(name2, "VERLOAD")) { HV* const hv = GvHVn(gv); GvMULTI_on(gv); - hv_magic(hv, Nullgv, PERL_MAGIC_overload); + hv_magic(hv, NULL, PERL_MAGIC_overload); } break; case 'S': @@ -1019,7 +1034,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, } GvMULTI_on(gv); hv = GvHVn(gv); - hv_magic(hv, Nullgv, PERL_MAGIC_sig); + 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) @@ -1125,7 +1140,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, case '-': { AV* const av = GvAVn(gv); - sv_magic((SV*)av, Nullsv, PERL_MAGIC_regdata, Nullch, 0); + sv_magic((SV*)av, NULL, PERL_MAGIC_regdata, NULL, 0); SvREADONLY_on(av); goto magicalize; } @@ -1142,7 +1157,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, case '+': { AV* const av = GvAVn(gv); - sv_magic((SV*)av, (SV*)av, PERL_MAGIC_regdata, Nullch, 0); + sv_magic((SV*)av, (SV*)av, PERL_MAGIC_regdata, NULL, 0); SvREADONLY_on(av); /* FALL THROUGH */ } @@ -1348,7 +1363,7 @@ Perl_gp_ref(pTHX_ GP *gp) if (gp->gp_cvgen) { /* multi-named GPs cannot be used for method cache */ SvREFCNT_dec(gp->gp_cv); - gp->gp_cv = Nullcv; + gp->gp_cv = NULL; gp->gp_cvgen = 0; } else { @@ -1365,7 +1380,7 @@ Perl_gp_free(pTHX_ GV *gv) dVAR; GP* gp; - if (!gv || !(gp = GvGP(gv))) + if (!gv || !isGV_with_GP(gv) || !(gp = GvGP(gv))) return; if (gp->gp_refcnt == 0) { if (ckWARN_d(WARN_INTERNAL)) @@ -1381,6 +1396,7 @@ Perl_gp_free(pTHX_ GV *gv) if (--gp->gp_refcnt > 0) { if (gp->gp_egv == gv) gp->gp_egv = 0; + GvGP(gv) = 0; return; } @@ -1413,9 +1429,9 @@ Perl_magic_freeovrld(pTHX_ SV *sv, MAGIC *mg) int i; for (i = 1; i < NofAMmeth; i++) { CV * const cv = amtp->table[i]; - if (cv != Nullcv) { + if (cv) { SvREFCNT_dec((SV *) cv); - amtp->table[i] = Nullcv; + amtp->table[i] = NULL; } } } @@ -1460,7 +1476,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) lim = DESTROY_amg; /* Skip overloading entries. */ #ifdef PERL_DONT_CREATE_GVSV else if (!sv) { - /* Equivalent to !SvTRUE and !SvOK */ + /*EMPTY*/; /* Equivalent to !SvTRUE and !SvOK */ } #endif else if (SvTRUE(sv)) @@ -1469,7 +1485,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) amt.fallback=AMGfallNEVER; for (i = 1; i < lim; i++) - amt.table[i] = Nullcv; + amt.table[i] = NULL; for (; i < NofAMmeth; i++) { const char * const cooky = PL_AMG_names[i]; /* Human-readable form, for debugging: */ @@ -1527,7 +1543,7 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) cv = (CV*)gv; filled = 1; } - amt.table[i]=(CV*)SvREFCNT_inc(cv); + amt.table[i]=(CV*)SvREFCNT_inc_simple(cv); } if (filled) { AMT_AMAGIC_on(&amt); @@ -1555,7 +1571,7 @@ Perl_gv_handler(pTHX_ HV *stash, I32 id) AMT *amtp; if (!stash || !HvNAME_get(stash)) - return Nullcv; + return NULL; mg = mg_find((SV*)stash, PERL_MAGIC_overload_table); if (!mg) { do_update: @@ -1581,7 +1597,7 @@ Perl_gv_handler(pTHX_ HV *stash, I32 id) return ret; } - return Nullcv; + return NULL; } @@ -1859,7 +1875,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) CATCH_SET(TRUE); Zero(&myop, 1, BINOP); myop.op_last = (OP *) &myop; - myop.op_next = Nullop; + myop.op_next = NULL; myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED; PUSHSTACKi(PERLSI_OVERLOAD); @@ -1968,6 +1984,7 @@ pointers returned by SvPV. bool Perl_is_gv_magical(pTHX_ const char *name, STRLEN len, U32 flags) { + PERL_UNUSED_CONTEXT; PERL_UNUSED_ARG(flags); if (len > 1) { @@ -2086,6 +2103,25 @@ Perl_is_gv_magical(pTHX_ const char *name, STRLEN len, U32 flags) return FALSE; } +void +Perl_gv_name_set(pTHX_ GV *gv, const char *name, U32 len, U32 flags) +{ + dVAR; + U32 hash; + + PERL_UNUSED_ARG(flags); + + 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) = name ? share_hek(name, len, hash) : 0; +} + /* * Local variables: * c-indentation-style: bsd