From: gfx Date: Fri, 28 Aug 2009 02:01:17 +0000 (+0900) Subject: Add is_class_loaded() to MOP APIs so that extentions can use it X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=eaca11410966ab53b77e4a5f161701e1bce6237f;p=gitmo%2FClass-MOP.git Add is_class_loaded() to MOP APIs so that extentions can use it --- diff --git a/mop.h b/mop.h index 7750264..b6bc799 100644 --- 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, diff --git a/xs/MOP.xs b/xs/MOP.xs index 438ed4b..d6135af 100644 --- 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;