/*
=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.
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;
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));
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))
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);
/* 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 :
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;
}
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(
: newSVpvn(name,len),
code, opnum
),
- 1
+ TRUE
)) != NULL) {
assert(GvCV(gv) == orig_cv);
if (opnum != OP_VEC && opnum != OP_SUBSTR && opnum != OP_POS
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;
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;
GV*
Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags)
{
- dVAR;
GV* gv;
CV* cv;
HV* varstash;
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);
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;
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",
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)
!(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)
{
case 'b':
if (len == 1 && sv_type == SVt_PV)
GvMULTI_on(gv);
- /* FALL THROUGH */
+ /* FALLTHROUGH */
default:
goto try_core;
}
if (!isDIGIT(*end))
return addmg;
}
- paren = strtoul(name, NULL, 10);
+ paren = grok_atou(name, NULL);
goto storeparen;
}
}
case '\023': /* $^S */
ro_magicalize:
SvREADONLY_on(GvSVn(gv));
- /* FALL THROUGH */
+ /* FALLTHROUGH */
case '0': /* $0 */
case '^': /* $^ */
case '~': /* $~ */
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;
}
/* 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;
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) != '_'
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));
GP*
Perl_gp_ref(pTHX_ GP *gp)
{
- dVAR;
if (!gp)
return NULL;
gp->gp_refcnt++;
void
Perl_gp_free(pTHX_ GV *gv)
{
- dVAR;
GP* gp;
int attempts = 100;
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;
}
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);
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
}
}
+ /* Possibly incremented by a destructor doing glob assignment */
+ if (gp->gp_refcnt > 1) goto borrowed;
Safefree(gp);
GvGP_set(gv, NULL);
}
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);
{
int filled = 0;
int i;
+ bool deref_seen = 0;
+
/* Work with "fallback" key, which we assume to be first in PL_AMG_names */
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: */
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,
CV*
Perl_gv_handler(pTHX_ HV *stash, I32 id)
{
- dVAR;
MAGIC *mg;
AMT *amtp;
U32 newgen;
bool
Perl_try_amagic_un(pTHX_ int method, int flags) {
- dVAR;
dSP;
SV* tmpsv;
SV* const arg = TOPs;
bool
Perl_try_amagic_bin(pTHX_ int method, int flags) {
- dVAR;
dSP;
SV* const left = TOPm1s;
SV* const right = TOPs;
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");
return tmpsv;
}
ref = tmpsv;
+ if (!SvAMAGIC(ref))
+ break;
}
return tmpsv ? tmpsv : ref;
}
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:
case to_cv_amg:
/* FAIL safe */
return left; /* Delegate operation to standard mechanisms. */
- break;
+
default:
goto not_found;
}
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;
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);