Add is_class_loaded() to MOP APIs so that extentions can use it
gfx [Fri, 28 Aug 2009 02:01:17 +0000 (11:01 +0900)]
mop.h
xs/MOP.xs

diff --git a/mop.h b/mop.h
index 7750264..b6bc799 100644 (file)
--- a/mop.h
+++ b/mop.h
@@ -46,6 +46,8 @@ SV *mop_call1(pTHX_ SV *const self, SV *const method, SV *const arg1);
 #define mop_call0_pvs(o, m)    mop_call0(aTHX_ o, newSVpvs_flags(m, SVs_TEMP))
 #define mop_call1_pvs(o, m, a) mop_call1(aTHX_ o, newSVpvs_flags(m, SVs_TEMP), a)
 
+bool mop_is_class_loaded(pTHX_ SV*);
+#define is_class_loaded(klass) mop_is_class_loaded(aTHX_ klass)
 
 typedef enum {
     TYPE_FILTER_NONE,
index 438ed4b..d6135af 100644 (file)
--- a/xs/MOP.xs
+++ b/xs/MOP.xs
@@ -13,10 +13,11 @@ SV *mop_package_cache_flag;
 SV *mop_VERSION;
 SV *mop_ISA;
 
+
 static bool
 find_method (const char *key, STRLEN keylen, SV *val, void *ud)
 {
-    bool *found_method = (bool *)ud;
+    bool * const found_method = (bool *)ud;
     PERL_UNUSED_ARG(key);
     PERL_UNUSED_ARG(keylen);
     PERL_UNUSED_ARG(val);
@@ -24,6 +25,51 @@ find_method (const char *key, STRLEN keylen, SV *val, void *ud)
     return FALSE;
 }
 
+
+bool
+mop_is_class_loaded(pTHX_ SV * const klass){
+    HV *stash;
+
+    if (!(SvPOKp(klass) && SvCUR(klass))) { /* XXX: SvPOK does not work with magical scalars */
+        return FALSE;
+    }
+
+    stash = gv_stashsv(klass, 0);
+    if (!stash) {
+        return FALSE;
+    }
+
+    if (hv_exists_ent (stash, mop_VERSION, 0U)) {
+        HE *version = hv_fetch_ent(stash, mop_VERSION, 0, 0U);
+        SV *version_sv;
+        if (version && HeVAL(version) && (version_sv = GvSV(HeVAL(version)))) {
+            if (SvROK(version_sv)) {
+                SV *version_sv_ref = SvRV(version_sv);
+
+                if (SvOK(version_sv_ref)) {
+                    return TRUE;
+                }
+            }
+            else if (SvOK(version_sv)) {
+                return TRUE;
+            }
+        }
+    }
+
+    if (hv_exists_ent (stash, mop_ISA, 0U)) {
+        HE *isa = hv_fetch_ent(stash, mop_ISA, 0, 0U);
+        if (isa && HeVAL(isa) && GvAV(HeVAL(isa)) && av_len(GvAV(HeVAL(isa))) != -1) {
+            return TRUE;;
+        }
+    }
+
+    {
+        bool found_method = FALSE;
+        mop_get_package_symbols(stash, TYPE_FILTER_CODE, find_method, &found_method);
+       return found_method;
+    }
+}
+
 EXTERN_C XS(boot_Class__MOP__Package);
 EXTERN_C XS(boot_Class__MOP__Attribute);
 EXTERN_C XS(boot_Class__MOP__Method);
@@ -69,53 +115,9 @@ get_code_info(coderef)
             mPUSHs(newSVpv(name, 0));
         }
 
-# This is some pretty grotty logic. It _should_ be parallel to the
-# pure Perl version in lib/Class/MOP.pm, so if you want to understand
-# it we suggest you start there.
-void
-is_class_loaded(klass=&PL_sv_undef)
-    SV *klass
-    PREINIT:
-        HV *stash;
-        bool found_method = FALSE;
-    PPCODE:
-        SvGETMAGIC(klass);
-        if (!(SvPOKp(klass) && SvCUR(klass))) { /* XXX: SvPOK does not work with magical scalars */
-            XSRETURN_NO;
-        }
 
-        stash = gv_stashsv(klass, 0);
-        if (!stash) {
-            XSRETURN_NO;
-        }
-
-        if (hv_exists_ent (stash, mop_VERSION, 0U)) {
-            HE *version = hv_fetch_ent(stash, mop_VERSION, 0, 0U);
-            SV *version_sv;
-            if (version && HeVAL(version) && (version_sv = GvSV(HeVAL(version)))) {
-                if (SvROK(version_sv)) {
-                    SV *version_sv_ref = SvRV(version_sv);
-
-                    if (SvOK(version_sv_ref)) {
-                        XSRETURN_YES;
-                    }
-                }
-                else if (SvOK(version_sv)) {
-                    XSRETURN_YES;
-                }
-            }
-        }
-
-        if (hv_exists_ent (stash, mop_ISA, 0U)) {
-            HE *isa = hv_fetch_ent(stash, mop_ISA, 0, 0U);
-            if (isa && HeVAL(isa) && GvAV(HeVAL(isa)) && av_len(GvAV(HeVAL(isa))) != -1) {
-                XSRETURN_YES;
-            }
-        }
-
-        mop_get_package_symbols(stash, TYPE_FILTER_CODE, find_method, &found_method);
-        if (found_method) {
-            XSRETURN_YES;
-        }
+bool
+is_class_loaded(SV* klass = &PL_sv_undef)
+INIT:
+    SvGETMAGIC(klass);
 
-        XSRETURN_NO;