struct mro_meta {
/* repurposed as a hash holding the different MROs private data. */
AV *mro_linear_dfs; /* cached dfs @ISA linearization */
- /* repurposed as a pointer directly to the current MROs private data. */
- AV *mro_linear_c3; /* cached c3 @ISA linearization */
+ /* a pointer directly to the current MROs private data. If mro_linear_all
+ is NULL, this owns the SV reference, else it is just a pointer to a
+ value stored in and owned by mro_linear_all. */
+ SV *mro_linear_current;
HV *mro_nextmethod; /* next::method caching */
U32 cache_gen; /* Bumping this invalidates our method cache */
U32 pkg_gen; /* Bumps when local methods/@ISA change */
#define MRO_GET_PRIVATE_DATA(smeta, which) \
(((smeta)->mro_which && (which) == (smeta)->mro_which) \
- ? MUTABLE_SV((smeta)->mro_linear_c3) \
+ ? (smeta)->mro_linear_current \
: Perl_mro_get_private_data(aTHX_ (smeta), (which)))
/* Subject to change.
/* If we've been asked to look up the private data for the current MRO, then
cache it. */
if (smeta->mro_which == which)
- smeta->mro_linear_c3 = MUTABLE_AV(*data);
+ smeta->mro_linear_current = *data;
return *data;
}
/* If all we need to store is the current MRO's data, then don't use
memory on a hash with 1 element - store it direct, and signal
this by leaving the would-be-hash NULL. */
- smeta->mro_linear_c3 = MUTABLE_AV(data);
+ smeta->mro_linear_current = data;
return data;
} else {
HV *const hv = newHV();
HvMAX(hv) = 1;
smeta->mro_linear_dfs = MUTABLE_AV(hv);
- if (smeta->mro_linear_c3) {
+ if (smeta->mro_linear_current) {
/* If we were storing something directly, put it in the hash
before we lose it. */
Perl_mro_set_private_data(aTHX_ smeta, smeta->mro_which,
- MUTABLE_SV(smeta->mro_linear_c3));
+ smeta->mro_linear_current);
}
}
}
if (smeta->mro_which == which) {
/* If we've been asked to store the private data for the current MRO,
then cache it. */
- smeta->mro_linear_c3 = MUTABLE_AV(data);
+ smeta->mro_linear_current = data;
}
if (!Perl_hv_common(aTHX_ MUTABLE_HV(smeta->mro_linear_dfs), NULL,
= MUTABLE_AV(SvREFCNT_inc(sv_dup((const SV *)newmeta->mro_linear_dfs, param)));
/* This is just acting as a shortcut pointer, and will be automatically
updated on the first get. */
- newmeta->mro_linear_c3 = NULL;
- } else if (newmeta->mro_linear_c3) {
+ newmeta->mro_linear_current = NULL;
+ } else if (newmeta->mro_linear_current) {
/* Only the current MRO is stored, so this owns the data. */
- newmeta->mro_linear_c3
- = MUTABLE_AV(SvREFCNT_inc(sv_dup((const SV *)newmeta->mro_linear_c3, param)));
+ newmeta->mro_linear_current
+ = SvREFCNT_inc(sv_dup((const SV *)newmeta->mro_linear_current,
+ param));
}
if (newmeta->mro_nextmethod)
SvREFCNT_dec(MUTABLE_SV(meta->mro_linear_dfs));
meta->mro_linear_dfs = NULL;
/* This is just acting as a shortcut pointer. */
- meta->mro_linear_c3 = NULL;
- } else if (meta->mro_linear_c3) {
+ meta->mro_linear_current = NULL;
+ } else if (meta->mro_linear_current) {
/* Only the current MRO is stored, so this owns the data. */
- SvREFCNT_dec(MUTABLE_SV(meta->mro_linear_c3));
- meta->mro_linear_c3 = NULL;
+ SvREFCNT_dec(meta->mro_linear_current);
+ meta->mro_linear_current = NULL;
}
if (meta->isa) {
SvREFCNT_dec(meta->isa);
SvREFCNT_dec(MUTABLE_SV(revmeta->mro_linear_dfs));
revmeta->mro_linear_dfs = NULL;
/* This is just acting as a shortcut pointer. */
- revmeta->mro_linear_c3 = NULL;
- } else if (revmeta->mro_linear_c3) {
+ revmeta->mro_linear_current = NULL;
+ } else if (revmeta->mro_linear_current) {
/* Only the current MRO is stored, so this owns the data. */
- SvREFCNT_dec(MUTABLE_SV(revmeta->mro_linear_c3));
- revmeta->mro_linear_c3 = NULL;
+ SvREFCNT_dec(revmeta->mro_linear_current);
+ revmeta->mro_linear_current = NULL;
}
if(!is_universal)
revmeta->cache_gen++;
Perl_croak(aTHX_ "Invalid mro name: '%"SVf"'", name);
if(meta->mro_which != which) {
- if (meta->mro_linear_c3 && !meta->mro_linear_dfs) {
+ if (meta->mro_linear_current && !meta->mro_linear_dfs) {
/* If we were storing something directly, put it in the hash before
we lose it. */
Perl_mro_set_private_data(aTHX_ meta, meta->mro_which,
- MUTABLE_SV(meta->mro_linear_c3));
+ MUTABLE_SV(meta->mro_linear_current));
}
meta->mro_which = which;
/* Scrub our cached pointer to the private data. */
- meta->mro_linear_c3 = NULL;
+ meta->mro_linear_current = NULL;
/* Only affects local method cache, not
even child classes */
meta->cache_gen++;