X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=MOP.xs;h=4fbf38f2f1a09d1e5f4dc9675fa91236614f5d8b;hb=69b950261dbccf60b607713bc7a4c60a1245b04a;hp=038f590b846b42809a750940de05be3a8eec166b;hpb=7d0839dc3b4afef6352bdd190987e482fe4ce295;p=gitmo%2FClass-MOP.git diff --git a/MOP.xs b/MOP.xs index 038f590..4fbf38f 100644 --- a/MOP.xs +++ b/MOP.xs @@ -21,7 +21,16 @@ This shuts up warnings from gcc -Wall PERL_HASH(hash_##name, value, sizeof(value) - 1); \ } while (0) -#define PREHASH_KEY(name) PREHASH_KEY_WITH_VALUE(name, #name) +/* this is basically the same as the above macro, except that the value will be + * the stringified name. However, we can't just implement this in terms of + * PREHASH_KEY_WITH_VALUE as that'd cause macro expansion on the value of + * 'name' when it's being passed to the other macro. suggestions on how to make + * this more elegant would be much appreciated */ + +#define PREHASH_KEY(name) do { \ + key_##name = newSVpvs(#name); \ + PERL_HASH(hash_##name, #name, sizeof(#name) - 1); \ +} while (0) DECLARE_KEY(name); DECLARE_KEY(package); @@ -310,21 +319,21 @@ BOOT: PREHASH_KEY(package_name); PREHASH_KEY(methods); PREHASH_KEY(ISA); + PREHASH_KEY(VERSION); PREHASH_KEY_WITH_VALUE(package_cache_flag, "_package_cache_flag"); - /* we can't stringify VERSION as it's a define already */ - PREHASH_KEY_WITH_VALUE(VERSION, "VERSION"); method_metaclass = newSVpvs("method_metaclass"); wrap = newSVpvs("wrap"); associated_metaclass = newSVpvs("associated_metaclass"); -PROTOTYPES: ENABLE - +PROTOTYPES: DISABLE +# use prototype here to be compatible with get_code_info from Sub::Identify void get_code_info(coderef) SV *coderef + PROTOTYPE: $ PREINIT: char *pkg = NULL; char *name = NULL; @@ -335,8 +344,9 @@ get_code_info(coderef) PUSHs(newSVpv(name, 0)); } -PROTOTYPES: DISABLE - +# 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 @@ -344,7 +354,7 @@ is_class_loaded(klass=&PL_sv_undef) HV *stash; char *key; I32 keylen; - GV *gv; + SV *gv; PPCODE: if (!SvPOK(klass) || !SvCUR(klass)) { XSRETURN_NO; @@ -357,8 +367,18 @@ is_class_loaded(klass=&PL_sv_undef) if (hv_exists_ent (stash, key_VERSION, hash_VERSION)) { HE *version = hv_fetch_ent(stash, key_VERSION, 0, hash_VERSION); - if (version && HeVAL(version) && GvSV(HeVAL(version))) { - XSRETURN_YES; + 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; + } } } @@ -370,7 +390,7 @@ is_class_loaded(klass=&PL_sv_undef) } (void)hv_iterinit(stash); - while ((gv = (GV *)hv_iternextsv(stash, &key, &keylen))) { + while ((gv = hv_iternextsv(stash, &key, &keylen))) { if (keylen <= 0) { continue; } @@ -379,7 +399,7 @@ is_class_loaded(klass=&PL_sv_undef) continue; } - if (!isGV(gv) || GvCV(gv) || GvSV(gv) || GvAV(gv) || GvHV(gv) || GvIO(gv) || GvFORM(gv)) { + if (!isGV(gv) || GvCV(gv)) { XSRETURN_YES; } } @@ -388,13 +408,10 @@ is_class_loaded(klass=&PL_sv_undef) MODULE = Class::MOP PACKAGE = Class::MOP::Package -PROTOTYPES: ENABLE - void get_all_package_symbols(self, filter=TYPE_FILTER_NONE) SV *self type_filter_t filter - PROTOTYPE: $;$ PREINIT: HV *stash = NULL; HV *symbols = NULL; @@ -408,7 +425,6 @@ get_all_package_symbols(self, filter=TYPE_FILTER_NONE) XSRETURN_EMPTY; } - PUTBACK; if ( (he = hv_fetch_ent((HV *)SvRV(self), key_package, 0, hash_package)) ) { @@ -417,34 +433,11 @@ get_all_package_symbols(self, filter=TYPE_FILTER_NONE) if (!stash) { - switch (GIMME_V) { - case G_SCALAR: XSRETURN_UNDEF; break; - case G_ARRAY: XSRETURN_EMPTY; break; - } + XSRETURN_UNDEF; } symbols = get_all_package_symbols(stash, filter); - - switch (GIMME_V) { - case G_SCALAR: - PUSHs(sv_2mortal(newRV_inc((SV *)symbols))); - break; - case G_ARRAY: - warn("Class::MOP::Package::get_all_package_symbols in list context is deprecated. use scalar context instead."); - - EXTEND(SP, HvKEYS(symbols) * 2); - - while ((he = hv_iternext(symbols))) { - PUSHs(hv_iterkeysv(he)); - PUSHs(sv_2mortal(SvREFCNT_inc(HeVAL(he)))); - } - - break; - default: - break; - } - - SvREFCNT_dec((SV *)symbols); + PUSHs(sv_2mortal(newRV_noinc((SV *)symbols))); void name(self)