Refactor type constraint check function to make class_type faster
gfx [Sat, 31 Oct 2009 06:23:02 +0000 (15:23 +0900)]
xs-src/MouseAccessor.xs
xs-src/MouseTypeConstraints.xs

index ea08648..ee7bf8d 100644 (file)
@@ -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{
index 08e49af..ca31b66 100644 (file)
 #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");