X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=mop.c;h=71c043fa55f0c9c6e0ff6eae84be12afa45f1079;hb=d004c8d565f9b314da7652e9368aeb4587ffaa3d;hp=ada6c0ec46fe54148d29c4f086d1bdbd70a7e09b;hpb=384bb6c99e7c8e724e67a7c8073efeed3b682973;p=gitmo%2FClass-MOP.git diff --git a/mop.c b/mop.c index ada6c0e..71c043f 100644 --- 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; } @@ -202,6 +178,9 @@ mop_get_all_package_symbols (HV *stash, type_filter_t filter) return ret; } +#define DECLARE_KEY(name) { #name, #name, NULL, 0 } +#define DECLARE_KEY_WITH_VALUE(name, value) { #name, value, NULL, 0 } + /* the order of these has to match with those in mop.h */ static struct { const char *name; @@ -209,23 +188,48 @@ 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") }; -inline SV * +SV * mop_prehashed_key_for (mop_prehashed_key_t key) { return prehashed_keys[key].key; } -inline U32 +U32 mop_prehashed_hash_for (mop_prehashed_key_t key) { return prehashed_keys[key].hash; @@ -235,7 +239,6 @@ void mop_prehash_keys () { int i; - for (i = 0; i < key_last; i++) { const char *value = prehashed_keys[i].value; prehashed_keys[i].key = newSVpv(value, strlen(value)); @@ -251,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) { @@ -268,11 +271,11 @@ XS(mop_xs_simple_reader) croak("object is not a hashref"); } - if (!(he = hv_fetch_ent((HV *)SvRV(self), prehashed_keys[key].key, 0, prehashed_keys[key].hash))) { - ST(0) = &PL_sv_undef; + if ((he = hv_fetch_ent((HV *)SvRV(self), prehashed_keys[key].key, 0, prehashed_keys[key].hash))) { + ST(0) = HeVAL(he); } else { - ST(0) = HeVAL(he); + ST(0) = &PL_sv_undef; } XSRETURN(1);