#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* const cv = (CV*)SvRV(tc_code);
+ assert(SvTYPE(cv) == Svt_PVCV);
+
+ 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);
+
+ /* call the check function directly, skipping call_sv() */
+ return CALL_FPTR((check_fptr_t)mg->mg_ptr)(aTHX_ mg->mg_obj, sv);
+ }
}
- else {
+
+ /* user-defined type constraints */
+ {
int ok;
dSP;
case MOUSE_TC_CLASS_NAME: return mouse_tc_ClassName(aTHX_ sv);
case MOUSE_TC_ROLE_NAME: return mouse_tc_RoleName(aTHX_ sv);
default:
- /* custom type constraints */
NOOP;
}
- croak("Custom type constraint is not yet implemented");
+ croak("Mouse-panic: unrecognized type constraint id: %d", (int)tc);
return FALSE; /* not reached */
}
int
mouse_tc_Bool(pTHX_ SV* const sv) {
assert(sv);
- if(SvOK(sv)){
+
+ if(SvTRUE(sv)){
if(SvIOKp(sv)){
- return SvIVX(sv) == 1 || SvIVX(sv) == 0;
+ return SvIVX(sv) == 1;
}
else if(SvNOKp(sv)){
- return SvNVX(sv) == 1.0 || SvNVX(sv) == 0.0;
+ return SvNVX(sv) == 1.0;
}
- else if(SvPOKp(sv)){ /* "" or "1" or "0" */
- return SvCUR(sv) == 0
- || ( SvCUR(sv) == 1 && ( SvPVX(sv)[0] == '1' || SvPVX(sv)[0] == '0' ) );
+ else if(SvPOKp(sv)){ /* "1" */
+ return SvCUR(sv) == 1 && SvPVX(sv)[0] == '1';
}
else{
return FALSE;
}
}
else{
+ /* false must be boolean */
return TRUE;
}
}
meta = POPs;
PUTBACK;
- ok = is_instance_of(meta, newSVpvs_flags("Mouse::Meta::Role", SVs_TEMP));
+ ok = is_an_instance_of("Mouse::Meta::Role", meta);
FREETMPS;
LEAVE;
}
}
- return is_instance_of(sv, newSVpvs_flags("IO::Handle", SVs_TEMP));
+ return is_an_instance_of("IO::Handle", sv);
}
int
assert(stash);
assert(SvTYPE(stash) == SVt_PVHV);
- if(SvROK(instance) && SvOBJECT(SvRV(instance))){
+ if(IsObject(instance)){
dMY_CXT;
HV* const instance_stash = SvSTASH(SvRV(instance));
GV* const instance_isa = gv_fetchmeth_autoload(instance_stash, "isa", sizeof("isa")-1, 0);
CvXSUBANY(xsub).any_ptr = sv_magicext(
(SV*)xsub,
- mg_obj,
+ mg_obj, /* refcnt will be increased */
PERL_MAGIC_ext,
&mouse_util_type_constraints_vtbl,
mg_ptr,
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");