Include method name in immutable methods (fixes #49680)
[gitmo/Class-MOP.git] / xs / MOP.xs
index f0132e9..959df7a 100644 (file)
--- a/xs/MOP.xs
+++ b/xs/MOP.xs
@@ -1,46 +1,36 @@
 #include "mop.h"
 
+SV *mop_method_metaclass;
+SV *mop_associated_metaclass;
+SV *mop_wrap;
+
 static bool
 find_method (const char *key, STRLEN keylen, SV *val, void *ud)
 {
     bool *found_method = (bool *)ud;
+    PERL_UNUSED_ARG(key);
+    PERL_UNUSED_ARG(keylen);
+    PERL_UNUSED_ARG(val);
     *found_method = TRUE;
     return FALSE;
 }
 
-DECLARE_KEY(name);
-DECLARE_KEY(package);
-DECLARE_KEY(package_name);
-DECLARE_KEY(body);
-DECLARE_KEY(package_cache_flag);
-DECLARE_KEY(methods);
-DECLARE_KEY(VERSION);
-DECLARE_KEY(ISA);
-
-SV *method_metaclass;
-SV *associated_metaclass;
-SV *wrap;
+EXTERN_C XS(boot_Class__MOP__Package);
+EXTERN_C XS(boot_Class__MOP__Attribute);
+EXTERN_C XS(boot_Class__MOP__Method);
 
 MODULE = Class::MOP   PACKAGE = Class::MOP
 
 PROTOTYPES: DISABLE
 
 BOOT:
-    PREHASH_KEY(name);
-    PREHASH_KEY(body);
-    PREHASH_KEY(package);
-    PREHASH_KEY(package_name);
-    PREHASH_KEY(methods);
-    PREHASH_KEY(ISA);
-    PREHASH_KEY(VERSION);
-    PREHASH_KEY_WITH_VALUE(package_cache_flag, "_package_cache_flag");
-
-    method_metaclass     = newSVpvs("method_metaclass");
-    wrap                 = newSVpvs("wrap");
-    associated_metaclass = newSVpvs("associated_metaclass");
+    mop_prehash_keys();
+
+    mop_method_metaclass     = newSVpvs("method_metaclass");
+    mop_wrap                 = newSVpvs("wrap");
+    mop_associated_metaclass = newSVpvs("associated_metaclass");
 
     MOP_CALL_BOOT (boot_Class__MOP__Package);
-    MOP_CALL_BOOT (boot_Class__MOP__Class);
     MOP_CALL_BOOT (boot_Class__MOP__Attribute);
     MOP_CALL_BOOT (boot_Class__MOP__Method);
 
@@ -53,10 +43,11 @@ get_code_info(coderef)
         char *pkg  = NULL;
         char *name = NULL;
     PPCODE:
-        if (get_code_info(coderef, &pkg, &name)) {
+        SvGETMAGIC(coderef);
+        if (mop_get_code_info(coderef, &pkg, &name)) {
             EXTEND(SP, 2);
-            PUSHs(newSVpv(pkg, 0));
-            PUSHs(newSVpv(name, 0));
+            mPUSHs(newSVpv(pkg, 0));
+            mPUSHs(newSVpv(name, 0));
         }
 
 # This is some pretty grotty logic. It _should_ be parallel to the
@@ -69,7 +60,8 @@ is_class_loaded(klass=&PL_sv_undef)
         HV *stash;
         bool found_method = FALSE;
     PPCODE:
-        if (!SvPOK(klass) || !SvCUR(klass)) {
+        SvGETMAGIC(klass);
+        if (!(SvPOKp(klass) && SvCUR(klass))) { /* XXX: SvPOK does not work with magical scalars */
             XSRETURN_NO;
         }
 
@@ -78,8 +70,8 @@ is_class_loaded(klass=&PL_sv_undef)
             XSRETURN_NO;
         }
 
-        if (hv_exists_ent (stash, key_VERSION, hash_VERSION)) {
-            HE *version = hv_fetch_ent(stash, key_VERSION, 0, hash_VERSION);
+        if (hv_exists_ent (stash, KEY_FOR(VERSION), HASH_FOR(VERSION))) {
+            HE *version = hv_fetch_ent(stash, KEY_FOR(VERSION), 0, HASH_FOR(VERSION));
             SV *version_sv;
             if (version && HeVAL(version) && (version_sv = GvSV(HeVAL(version)))) {
                 if (SvROK(version_sv)) {
@@ -95,14 +87,14 @@ is_class_loaded(klass=&PL_sv_undef)
             }
         }
 
-        if (hv_exists_ent (stash, key_ISA, hash_ISA)) {
-            HE *isa = hv_fetch_ent(stash, key_ISA, 0, hash_ISA);
-            if (isa && HeVAL(isa) && GvAV(HeVAL(isa))) {
+        if (hv_exists_ent (stash, KEY_FOR(ISA), HASH_FOR(ISA))) {
+            HE *isa = hv_fetch_ent(stash, KEY_FOR(ISA), 0, HASH_FOR(ISA));
+            if (isa && HeVAL(isa) && GvAV(HeVAL(isa)) && av_len(GvAV(HeVAL(isa))) != -1) {
                 XSRETURN_YES;
             }
         }
 
-        get_package_symbols(stash, TYPE_FILTER_CODE, find_method, &found_method);
+        mop_get_package_symbols(stash, TYPE_FILTER_CODE, find_method, &found_method);
         if (found_method) {
             XSRETURN_YES;
         }