X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=xs%2FMOP.xs;h=fd4bf1d34f817df6f74f5f15c6734de5105f68f0;hb=4baf5adc6d23648dc169dc38f0693ed48c21d052;hp=5dfc0cd33e0cf32b56e7569d5ceda55fa9825753;hpb=efc98200d49cae9fb74285a58d12e3b988da0a97;p=gitmo%2FClass-MOP.git diff --git a/xs/MOP.xs b/xs/MOP.xs index 5dfc0cd..fd4bf1d 100644 --- a/xs/MOP.xs +++ b/xs/MOP.xs @@ -1,9 +1,5 @@ #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) { @@ -15,9 +11,38 @@ find_method (const char *key, STRLEN keylen, SV *val, void *ud) return FALSE; } +static bool +check_version (SV *klass, SV *required_version) +{ + bool ret = 0; + + dSP; + ENTER; + SAVETMPS; + PUSHMARK(SP); + EXTEND(SP, 2); + PUSHs(klass); + PUSHs(required_version); + PUTBACK; + + call_method("VERSION", G_DISCARD|G_VOID|G_EVAL); + + SPAGAIN; + + if (!SvTRUE(ERRSV)) { + ret = 1; + } + + PUTBACK; + FREETMPS; + LEAVE; + + return ret; +} + +EXTERN_C XS(boot_Class__MOP__Mixin__HasMethods); EXTERN_C XS(boot_Class__MOP__Package); -EXTERN_C XS(boot_Class__MOP__Class); -EXTERN_C XS(boot_Class__MOP__Attribute); +EXTERN_C XS(boot_Class__MOP__Mixin__AttributeCore); EXTERN_C XS(boot_Class__MOP__Method); MODULE = Class::MOP PACKAGE = Class::MOP @@ -27,13 +52,9 @@ PROTOTYPES: DISABLE BOOT: 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__Mixin__HasMethods); 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__Mixin__AttributeCore); MOP_CALL_BOOT (boot_Class__MOP__Method); # use prototype here to be compatible with get_code_info from Sub::Identify @@ -45,23 +66,23 @@ get_code_info(coderef) char *pkg = NULL; char *name = NULL; PPCODE: + SvGETMAGIC(coderef); if (mop_get_code_info(coderef, &pkg, &name)) { EXTEND(SP, 2); mPUSHs(newSVpv(pkg, 0)); 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) +is_class_loaded(klass, options=NULL) SV *klass + HV *options PREINIT: 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; } @@ -70,6 +91,15 @@ is_class_loaded(klass=&PL_sv_undef) XSRETURN_NO; } + if (options && hv_exists_ent(options, KEY_FOR(_version), HASH_FOR(_version))) { + HE *required_version = hv_fetch_ent(options, KEY_FOR(_version), 0, HASH_FOR(_version)); + if (check_version (klass, HeVAL(required_version))) { + XSRETURN_YES; + } + + XSRETURN_NO; + } + 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;