From: gfx Date: Sat, 31 Oct 2009 06:23:02 +0000 (+0900) Subject: Refactor type constraint check function to make class_type faster X-Git-Tag: 0.40_04~18 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=commitdiff_plain;h=d33d884067cd7e0451429470e5036d9fe98798c1 Refactor type constraint check function to make class_type faster --- diff --git a/xs-src/MouseAccessor.xs b/xs-src/MouseAccessor.xs index ea08648..ee7bf8d 100644 --- a/xs-src/MouseAccessor.xs +++ b/xs-src/MouseAccessor.xs @@ -162,18 +162,10 @@ mouse_apply_type_constraint(pTHX_ AV* const xa, SV* value, U16 const flags){ } if(!SvOK(MOUSE_xa_tc_code(xa))){ - XS(XS_Mouse__Util__TypeConstraints_Item); /* prototype defined in Mouse.xs */ - tc_code = mcall0s(tc, "_compiled_type_constraint"); - - if(SvROK(tc_code) && SvTYPE(SvRV(tc_code)) - && CvXSUB((CV*)SvRV(tc_code)) == XS_Mouse__Util__TypeConstraints_Item){ - /* built-in type constraints */ - mouse_tc const id = CvXSUBANY((CV*)SvRV(tc_code)).any_i32; - av_store(xa, MOUSE_XA_TC_CODE, newSViv(id)); - } - else{ - av_store(xa, MOUSE_XA_TC_CODE, newSVsv(tc_code)); + av_store(xa, MOUSE_XA_TC_CODE, newSVsv(tc_code)); + if(!(SvROK(tc_code) && SvTYPE(SvRV(tc_code)) == SVt_PVCV)){ + mouse_throw_error(MOUSE_xa_attribute(xa), tc, "Not a CODE reference"); } } else{ diff --git a/xs-src/MouseTypeConstraints.xs b/xs-src/MouseTypeConstraints.xs index 08e49af..ca31b66 100644 --- a/xs-src/MouseTypeConstraints.xs +++ b/xs-src/MouseTypeConstraints.xs @@ -14,12 +14,31 @@ #define SvRXOK(sv) (SvROK(sv) && SvMAGICAL(SvRV(sv)) && mg_find(SvRV(sv), PERL_MAGIC_qr)) #endif +typedef int (*check_fptr_t)(pTHX_ SV* const data, SV* const sv); + int mouse_tc_check(pTHX_ SV* const tc_code, SV* const sv) { - if(SvIOK(tc_code)){ /* built-in type constraints */ - return mouse_builtin_tc_check(aTHX_ SvIVX(tc_code), sv); + CV* cv; + assert(SvROK(tc_code) && SvTYPE(SvRV(tc_code))); + + cv = (CV*)SvRV(tc_code); + + if(CvISXSUB(cv)){ /* can be built-in tc */ + if(CvXSUB(cv) == XS_Mouse__Util__TypeConstraints_Item){ + assert(CvXSUBANY(cv).any_iv > 0); + + return mouse_builtin_tc_check(aTHX_ CvXSUBANY(cv).any_iv, sv); + } + else if(CvXSUB(cv) == XS_Mouse_parameterized_check){ + MAGIC* const mg = (MAGIC*)CvXSUBANY(cv).any_ptr; + + assert(CvXSUBANY(cv).any_ptr != NULL); + return CALL_FPTR((check_fptr_t)mg->mg_ptr)(aTHX_ mg->mg_obj /* stash */, sv); + } } - else { + + /* user-defined type constraints */ + { int ok; dSP; @@ -403,7 +422,6 @@ XS(XS_Mouse_parameterized_check) { dVAR; dXSARGS; MAGIC* const mg = (MAGIC*)XSANY.any_ptr; - typedef int (*check_fptr_t)(pTHX_ SV* const data, SV* const sv); if(items < 1){ croak("Too few arguments for parameterized check functions");