0.04 (MRO::Compat helper)
[gitmo/Class-C3-XS.git] / XS.xs
diff --git a/XS.xs b/XS.xs
index 4cd089c..cf6880a 100644 (file)
--- 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__);