summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/gv.c b/gv.c
index 8db44b42f0..fed7eca3dc 100644
--- a/gv.c
+++ b/gv.c
@@ -143,18 +143,19 @@ I32 level;
if (SvTYPE(topgv) != SVt_PVGV)
gv_init(topgv, stash, name, len, TRUE);
- if (cv = GvCV(topgv)) {
- if (CvXSUB(cv) || CvROOT(cv)) { /* Not undefed. */
- if (!GvCVGEN(topgv) || /* not an inheritance cache */
- GvCVGEN(topgv) >= sub_generation) /* valid inh. cache */
- return topgv;
+ if (cv=GvCV(topgv)) {
+ if (GvCVGEN(topgv) >= sub_generation)
+ return topgv; /* valid cached inheritance */
+ if (!GvCVGEN(topgv)) { /* not an inheritance cache */
+ return topgv;
+ }
+ else {
+ /* stale cached entry, just junk it */
+ GvCV(topgv) = cv = 0;
+ GvCVGEN(topgv) = 0;
}
- /* stale cached entry, just junk it */
- SvREFCNT_dec(cv);
- GvCV(topgv) = cv = 0;
- GvCVGEN(topgv) = 0;
}
- /* Now cv = 0, and there is no cv in topgv. */
+ /* if cv is still set, we have to free it if we find something to cache */
gvp = (GV**)hv_fetch(stash,"ISA",3,FALSE);
if (gvp && (gv = *gvp) != (GV*)&sv_undef && (av = GvAV(gv))) {
@@ -171,9 +172,13 @@ I32 level;
}
gv = gv_fetchmeth(basestash, name, len, level + 1);
if (gv) {
+ if (cv) { /* junk old undef */
+ assert(SvREFCNT(topgv) > 1);
+ SvREFCNT_dec(topgv);
+ SvREFCNT_dec(cv);
+ }
GvCV(topgv) = GvCV(gv); /* cache the CV */
GvCVGEN(topgv) = sub_generation; /* valid for now */
- SvREFCNT_inc(GvCV(gv));
return gv;
}
}
@@ -182,9 +187,13 @@ I32 level;
if (!level) {
if (lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE)) {
if (gv = gv_fetchmeth(lastchance, name, len, level + 1)) {
+ if (cv) { /* junk old undef */
+ assert(SvREFCNT(topgv) > 1);
+ SvREFCNT_dec(topgv);
+ SvREFCNT_dec(cv);
+ }
GvCV(topgv) = GvCV(gv); /* cache the CV */
GvCVGEN(topgv) = sub_generation; /* valid for now */
- SvREFCNT_inc(GvCV(gv));
return gv;
}
}