Merge branch 'stable'
[gitmo/Class-MOP.git] / mop.c
diff --git a/mop.c b/mop.c
index 16d8f53..71c043f 100644 (file)
--- a/mop.c
+++ b/mop.c
@@ -1,7 +1,7 @@
 #include "mop.h"
 
 void
-mop_call_xs (pTHX_ void (*subaddr) (pTHX_ CV *), CV *cv, SV **mark)
+mop_call_xs (pTHX_ XSPROTO(subaddr), CV *cv, SV **mark)
 {
     dSP;
     PUSHMARK(mark);
@@ -93,21 +93,20 @@ mop_get_code_info (SV *coderef, char **pkg, char **name)
        we hit it without the guard, we segfault. The slightly odd return
        value strikes me as an improvement (mst)
     */
-#ifdef isGV_with_GP
+
     if ( isGV_with_GP(CvGV(coderef)) ) {
-#endif
-        *pkg     = HvNAME( GvSTASH(CvGV(coderef)) );
+        GV *gv   = CvGV(coderef);
+        *pkg     = HvNAME( GvSTASH(gv) ? GvSTASH(gv) : CvSTASH(coderef) );
         *name    = GvNAME( CvGV(coderef) );
-#ifdef isGV_with_GP
     } else {
         *pkg     = "__UNKNOWN__";
         *name    = "__ANON__";
     }
-#endif
 
     return 1;
 }
 
+/* XXX: eventually this should just use the implementation in Package::Stash */
 void
 mop_get_package_symbols (HV *stash, type_filter_t filter, get_package_symbols_cb_t cb, void *ud)
 {
@@ -127,54 +126,31 @@ mop_get_package_symbols (HV *stash, type_filter_t filter, get_package_symbols_cb
     }
 
     while ( (he = hv_iternext(stash)) ) {
-        SV *const gv = HeVAL(he);
-        SV *sv = NULL;
-        char *key;
+        GV * const gv          = (GV*)HeVAL(he);
         STRLEN keylen;
-        char *package;
-        SV *fq;
+        const char * const key = HePV(he, keylen);
+        SV *sv = NULL;
 
-        switch( SvTYPE(gv) ) {
-#ifndef SVt_RV
-            case SVt_RV:
-#endif
-            case SVt_PV:
-            case SVt_IV:
-                /* expand the gv into a real typeglob if it
-                 * contains stub functions and we were asked to
-                 * return CODE symbols */
-                if (filter == TYPE_FILTER_CODE) {
-                    if (SvROK(gv)) {
-                        /* we don't really care about the length,
-                           but that's the API */
-                        key = HePV(he, keylen);
-                        package = HvNAME(stash);
-                        fq = newSVpvf("%s::%s", package, key);
-                        sv = (SV *)get_cv(SvPV_nolen(fq), 0);
-                        break;
-                    }
-
-                    key = HePV(he, keylen);
-                    gv_init((GV *)gv, stash, key, keylen, GV_ADDMULTI);
-                }
-                /* fall through */
-            case SVt_PVGV:
-                switch (filter) {
-                    case TYPE_FILTER_CODE:   sv = (SV *)GvCVu(gv); break;
-                    case TYPE_FILTER_ARRAY:  sv = (SV *)GvAV(gv);  break;
-                    case TYPE_FILTER_IO:     sv = (SV *)GvIO(gv);  break;
-                    case TYPE_FILTER_HASH:   sv = (SV *)GvHV(gv);  break;
-                    case TYPE_FILTER_SCALAR: sv = (SV *)GvSV(gv);  break;
-                    default:
-                        croak("Unknown type");
-                }
-                break;
-            default:
-                continue;
+        if(isGV(gv)){
+            switch (filter) {
+                case TYPE_FILTER_CODE:   sv = (SV *)GvCVu(gv); break;
+                case TYPE_FILTER_ARRAY:  sv = (SV *)GvAV(gv);  break;
+                case TYPE_FILTER_IO:     sv = (SV *)GvIO(gv);  break;
+                case TYPE_FILTER_HASH:   sv = (SV *)GvHV(gv);  break;
+                case TYPE_FILTER_SCALAR: sv = (SV *)GvSV(gv);  break;
+                default:
+                    croak("Unknown type");
+            }
+        }
+        /* expand the gv into a real typeglob if it
+        * contains stub functions or constants and we
+        * were asked to return CODE references */
+        else if (filter == TYPE_FILTER_CODE) {
+            gv_init(gv, stash, key, keylen, GV_ADDMULTI);
+            sv = (SV *)GvCV(gv);
         }
 
         if (sv) {
-            const char *key = HePV(he, keylen);
             if (!cb(key, keylen, sv, ud)) {
                 return;
             }
@@ -212,14 +188,39 @@ static struct {
     SV *key;
     U32 hash;
 } prehashed_keys[key_last] = {
+    DECLARE_KEY(_expected_method_class),
+    DECLARE_KEY(ISA),
+    DECLARE_KEY(VERSION),
+    DECLARE_KEY(accessor),
+    DECLARE_KEY(associated_class),
+    DECLARE_KEY(associated_metaclass),
+    DECLARE_KEY(associated_methods),
+    DECLARE_KEY(attribute_metaclass),
+    DECLARE_KEY(attributes),
+    DECLARE_KEY(body),
+    DECLARE_KEY(builder),
+    DECLARE_KEY(clearer),
+    DECLARE_KEY(constructor_class),
+    DECLARE_KEY(constructor_name),
+    DECLARE_KEY(definition_context),
+    DECLARE_KEY(destructor_class),
+    DECLARE_KEY(immutable_trait),
+    DECLARE_KEY(init_arg),
+    DECLARE_KEY(initializer),
+    DECLARE_KEY(insertion_order),
+    DECLARE_KEY(instance_metaclass),
+    DECLARE_KEY(is_inline),
+    DECLARE_KEY(method_metaclass),
+    DECLARE_KEY(methods),
     DECLARE_KEY(name),
     DECLARE_KEY(package),
     DECLARE_KEY(package_name),
-    DECLARE_KEY(body),
+    DECLARE_KEY(predicate),
+    DECLARE_KEY(reader),
+    DECLARE_KEY(wrapped_method_metaclass),
+    DECLARE_KEY(writer),
     DECLARE_KEY_WITH_VALUE(package_cache_flag, "_package_cache_flag"),
-    DECLARE_KEY(methods),
-    DECLARE_KEY(VERSION),
-    DECLARE_KEY(ISA)
+    DECLARE_KEY_WITH_VALUE(_version, "-version")
 };
 
 SV *
@@ -253,7 +254,7 @@ XS(mop_xs_simple_reader)
     dXSARGS;
 #endif
     register HE *he;
-    mop_prehashed_key_t key = CvXSUBANY(cv).any_i32;
+    mop_prehashed_key_t key = (mop_prehashed_key_t)CvXSUBANY(cv).any_i32;
     SV *self;
 
     if (items != 1) {