From: Yuval Kogman Date: Mon, 11 Aug 2008 02:39:14 +0000 (+0000) Subject: XS versions of the most common readsers X-Git-Tag: 0_64_01~38 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=cc856b56d46c0867b9585240cc7e3c8b556316b4;p=gitmo%2FClass-MOP.git XS versions of the most common readsers --- diff --git a/MOP.xs b/MOP.xs index f9f5d9b..8506f36 100644 --- a/MOP.xs +++ b/MOP.xs @@ -6,6 +6,15 @@ #define NEED_sv_2pv_nolen #include "ppport.h" +SV *key_name; +U32 hash_name; + +SV *key_package; +U32 hash_package; + +SV *key_body; +U32 hash_body; + /* get_code_info: Pass in a coderef, returns: @@ -15,8 +24,19 @@ get_code_info: MODULE = Class::MOP PACKAGE = Class::MOP +BOOT: + key_name = newSVpvs("name"); + key_body = newSVpvs("body"); + key_package = newSVpvs("package"); + + PERL_HASH(hash_name, "name", 4); + PERL_HASH(hash_body, "body", 4); + PERL_HASH(hash_package, "package", 7); + + PROTOTYPES: ENABLE + void get_code_info(coderef) SV* coderef @@ -51,11 +71,11 @@ get_code_info(coderef) MODULE = Class::MOP PACKAGE = Class::MOP::Package void -get_all_package_symbols(package, ...) - SV *package +get_all_package_symbols(self, ...) + SV *self PROTOTYPE: $;$ PREINIT: - HV *stash; + HV *stash = NULL; SV *type_filter = NULL; PPCODE: @@ -68,18 +88,12 @@ get_all_package_symbols(package, ...) PUTBACK; - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(package); - PUTBACK; - call_method("name", 0); - SPAGAIN; - stash = gv_stashsv(POPs, 0); - FREETMPS; - LEAVE; - - PUTBACK; + if ( SvROK(self) ) { + SV **val = hv_fetchs((HV *)SvRV(self), "package", 0); + if ( val ) { + stash = gv_stashsv(*val, 0); + } + } if ( stash ) { register HE *entry; @@ -118,7 +132,7 @@ get_all_package_symbols(package, ...) fqlen = pkglen + SvCUR(key) + 3; fq = (char *)alloca(fqlen); snprintf(fq, fqlen, "%s::%s", package, SvPV_nolen(key)); - sv = get_cv(fq, 0); + sv = (SV*)get_cv(fq, 0); break; default: continue; @@ -147,3 +161,50 @@ get_all_package_symbols(package, ...) } +SV * +name(self) + SV *self + PREINIT: + register HE *he; + PPCODE: + if (SvROK(self) && (he = hv_fetch_ent((HV *)SvRV(self), key_package, 0, hash_package))) + XPUSHs(HeVAL(he)); + else + ST(0) = &PL_sv_undef; + +MODULE = Class::MOP PACKAGE = Class::Attribute + +SV * +name(self) + SV *self + PREINIT: + register HE *he; + PPCODE: + if (SvROK(self) && (he = hv_fetch_ent((HV *)SvRV(self), key_name, 0, hash_name))) + XPUSHs(HeVAL(he)); + else + ST(0) = &PL_sv_undef; + +MODULE = Class::MOP PACKAGE = Class::Method + +SV * +name(self) + SV *self + PREINIT: + register HE *he; + PPCODE: + if (SvROK(self) && (he = hv_fetch_ent((HV *)SvRV(self), key_name, 0, hash_name))) + XPUSHs(HeVAL(he)); + else + ST(0) = &PL_sv_undef; + +SV * +body(self) + SV *self + PREINIT: + register HE *he; + PPCODE: + if (SvROK(self) && (he = hv_fetch_ent((HV *)SvRV(self), key_body, 0, hash_body))) + XPUSHs(HeVAL(he)); + else + ST(0) = &PL_sv_undef;