#include "perl.h"
#include "XSUB.h"
-/* Most of this code is backported from bleadperl's
+/* Most of this code is backported from the bleadperl patch's
mro.c, and then modified to work with Class::C3's
internals.
*/
stashname);
if(!cache) {
- cache = newHV();
+ cache = (HV*)sv_2mortal((SV*)newHV());
}
else {
- /* XXX return cached entry for stashname if available */
+ sv_dump(cache);
+ SV** cache_entry = hv_fetch(cache, stashname, stashname_len, 0);
+ if(cache_entry)
+ return (AV*)SvREFCNT_inc(*cache_entry);
}
/* not in cache, make a new one */
SvREADONLY_on(retval);
SvREFCNT_inc(retval); /* for cache storage */
- SvREFCNT_inc(retval); /* for return to caller */
- /* XXX store in cache storage */
+ SvREFCNT_inc(retval); /* for return */
+ hv_store(cache, stashname, stashname_len, (SV*)retval, 0);
return retval;
}
stashname_len = subname - fq_subname - 2;
stashname = sv_2mortal(newSVpvn(fq_subname, stashname_len));
- linear_av = __mro_linear_isa_c3(selfstash, NULL, 0); /* has ourselves at the top of the list */
- sv_2mortal((SV*)linear_av);
+ linear_av = (AV*)sv_2mortal((SV*)__mro_linear_isa_c3(selfstash, NULL, 0));
linear_svp = AvARRAY(linear_av);
items = AvFILLp(linear_av) + 1;
}
if(items > 0) {
+ SV* sub_sv = sv_2mortal(newSVpv(subname, subname_len));
+ HV* cc3_mro = get_hv("Class::C3::MRO", 0);
+
while (items--) {
linear_sv = *linear_svp++;
assert(linear_sv);
+
+ if(cc3_mro) {
+ HE* he_cc3_mro_class = hv_fetch_ent(cc3_mro, linear_sv, 0, 0);
+ if(he_cc3_mro_class) {
+ HV* cc3_mro_class = (HV*)SvRV(HeVAL(he_cc3_mro_class));
+ SV** svp_cc3_mro_class_methods = hv_fetch(cc3_mro_class, "methods", 7, 0);
+ if(svp_cc3_mro_class_methods) {
+ HV* cc3_mro_class_methods = (HV*)SvRV(*svp_cc3_mro_class_methods);
+ if(hv_exists_ent(cc3_mro_class_methods, sub_sv, 0))
+ continue;
+ }
+ }
+ }
+
cstash = gv_stashsv(linear_sv, FALSE);
if (!cstash) {
assert(cstash);
-/* XXX we need to fetch from %Class::C3::MRO, not the real stash table */
-
gvp = (GV**)hv_fetch(cstash, subname, subname_len, 0);
if (!gvp) continue;
croak("Usage: calculateMRO(classname[, cache])");
classname = ST(0);
- if(items == 2) cache = (HV*)ST(1);
+ if(items == 2) cache = (HV*)SvRV(ST(1));
class_stash = gv_stashsv(classname, 0);
if(!class_stash) croak("No such class: '%s'!", SvPV_nolen(classname));
res = (AV*)sv_2mortal((SV*)__mro_linear_isa_c3(class_stash, cache, 0));
-
res_items = ret_items = AvFILLp(res) + 1;
res_ptr = AvARRAY(res);