X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=XS.xs;h=cf6880ad1d405d96cf1476364119cfecdd8e8b2d;hb=8feecaf97e81e3d1ef573a1bfef9abde9d55e0b1;hp=4cd089cbbb48ae8f53758b055d63ddbb2292bb4f;hpb=625e16dfbecc5e29ae723d2dfbacd14a9dade6e9;p=gitmo%2FClass-C3-XS.git diff --git a/XS.xs b/XS.xs index 4cd089c..cf6880a 100644 --- a/XS.xs +++ b/XS.xs @@ -387,6 +387,21 @@ XS(XS_Class_C3_XS_calculateMRO) return; } +XS(XS_Class_C3_XS_plsubgen); +XS(XS_Class_C3_XS_plsubgen) +{ + #ifdef dVAR + dVAR; dXSARGS; + #else + dXSARGS; + #endif + + SP -= items; + XPUSHs(sv_2mortal(newSViv(PL_sub_generation))); + PUTBACK; + return; +} + XS(XS_Class_C3_XS_calc_mdt); XS(XS_Class_C3_XS_calc_mdt) { @@ -401,14 +416,13 @@ XS(XS_Class_C3_XS_calc_mdt) HV* class_stash; AV* class_mro; HV* our_c3mro; /* $Class::C3::MRO{classname} */ - SV* has_ovf; + SV* has_ovf = NULL; HV* methods; I32 mroitems; /* temps */ HV* hv; HE* he; - SV* rv; SV** svp; if(items < 1 || items > 2) @@ -427,6 +441,7 @@ XS(XS_Class_C3_XS_calc_mdt) hv_store(our_c3mro, "MRO", 3, (SV*)newRV_inc((SV*)class_mro), 0); hv = get_hv("Class::C3::MRO", 1); + hv_delete_ent(hv, classname, G_DISCARD, 0); hv_store_ent(hv, classname, (SV*)newRV_noinc((SV*)our_c3mro), 0); methods = newHV(); @@ -440,41 +455,45 @@ XS(XS_Class_C3_XS_calc_mdt) if(!mro_stash) continue; - /*if(!has_ovf) { + if(!has_ovf) { SV** ovfp = hv_fetch(mro_stash, "()", 2, 0); if(ovfp) has_ovf = *ovfp; - }*/ + } hv_iterinit(mro_stash); while(he = hv_iternext(mro_stash)) { CV* code; SV* mskey; - SV* msval = hv_iterval(mro_stash, he); - if(SvTYPE(msval) != SVt_PVGV || !(code = GvCVu(msval))) - continue; + SV* msval; + HE* ourent; + HV* meth_hash; + SV* orig; mskey = hv_iterkeysv(he); if(hv_exists_ent(methods, mskey, 0)) continue; - if((he = hv_fetch_ent(class_stash, mskey, 0, 0))) { - SV* val = HeVAL(he); - if(val && SvTYPE(val) == SVt_PVGV && GvCVu(msval)) + + msval = hv_iterval(mro_stash, he); + if(SvTYPE(msval) != SVt_PVGV || !(code = GvCVu(msval))) + continue; + + if((ourent = hv_fetch_ent(class_stash, mskey, 0, 0))) { + SV* val = HeVAL(ourent); + if(val && SvTYPE(val) == SVt_PVGV && GvCVu(val)) continue; } - { - HV* meth_hash = newHV(); - SV* orig = newSVsv(mro_class); - sv_catpvn(orig, "::", 2); - sv_catsv(orig, mskey); - hv_store(meth_hash, "orig", 4, orig, 0); - hv_store(meth_hash, "code", 4, newRV_inc((SV*)code), 0); - hv_store_ent(methods, mskey, newRV_noinc((SV*)meth_hash), 0); - } + meth_hash = newHV(); + orig = newSVsv(mro_class); + sv_catpvn(orig, "::", 2); + sv_catsv(orig, mskey); + hv_store(meth_hash, "orig", 4, orig, 0); + hv_store(meth_hash, "code", 4, newRV_inc((SV*)code), 0); + hv_store_ent(methods, mskey, newRV_noinc((SV*)meth_hash), 0); } } hv_store(our_c3mro, "methods", 7, newRV_noinc((SV*)methods), 0); - hv_store(our_c3mro, "has_overload_fallback", 21, has_ovf ? SvREFCNT_inc(has_ovf) : &PL_sv_undef, 0); + if(has_ovf) hv_store(our_c3mro, "has_overload_fallback", 21, SvREFCNT_inc(has_ovf), 0); XSRETURN_EMPTY; } @@ -535,6 +554,7 @@ MODULE = Class::C3::XS PACKAGE = Class::C3::XS BOOT: newXS("Class::C3::XS::calculateMRO", XS_Class_C3_XS_calculateMRO, __FILE__); + newXS("Class::C3::XS::_plsubgen", XS_Class_C3_XS_plsubgen, __FILE__); newXS("Class::C3::XS::_calculate_method_dispatch_table", XS_Class_C3_XS_calc_mdt, __FILE__); newXS("next::can", XS_next_can, __FILE__); newXS("next::method", XS_next_method, __FILE__);