X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=xs-src%2FMouseAccessor.xs;h=6af6b03558dd57183b7a6511242e8c1b9417b7a7;hb=dfbc05003792a24ba9d4212c49c63f437e519119;hp=a9de90397a873dfb4525fdef4ec92ffc4ccbc51e;hpb=646c0371bdfda5817f842c54577c4d5605a4c3c0;p=gitmo%2FMouse.git diff --git a/xs-src/MouseAccessor.xs b/xs-src/MouseAccessor.xs index a9de903..6af6b03 100644 --- a/xs-src/MouseAccessor.xs +++ b/xs-src/MouseAccessor.xs @@ -2,7 +2,7 @@ #define CHECK_INSTANCE(instance) STMT_START{ \ if(!(SvROK(instance) && SvTYPE(SvRV(instance)) == SVt_PVHV)){ \ - croak("Invalid object for instance managers"); \ + croak("Invalid object instance"); \ } \ } STMT_END @@ -52,8 +52,6 @@ static MGVTBL mouse_accessor_vtbl; /* MAGIC identity */ SV* mouse_accessor_get_self(pTHX_ I32 const ax, I32 const items, CV* const cv) { - SV* self; - if(items < 1){ croak("Too few arguments for %s", GvNAME(CvGV(cv))); } @@ -62,11 +60,7 @@ mouse_accessor_get_self(pTHX_ I32 const ax, I32 const items, CV* const cv) { * before calling methods, so SvGETMAGIC(self) is not necessarily needed here. */ - self = ST(0); - if(!IsObject(self)){ - croak("Cant call %s as a class method", GvNAME(CvGV(cv))); - } - return self; + return ST(0); } @@ -168,18 +162,11 @@ 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"); + av_store(xa, MOUSE_XA_TC_CODE, newSVsv(tc_code)); - 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)); + if(!(SvROK(tc_code) && SvTYPE(SvRV(tc_code)) == SVt_PVCV)){ + mouse_throw_error(MOUSE_xa_attribute(xa), tc, "Not a CODE reference"); } } else{ @@ -196,51 +183,58 @@ mouse_apply_type_constraint(pTHX_ AV* const xa, SV* value, U16 const flags){ return value; } +#define PUSH_VALUE(value, flags) STMT_START { \ + if((flags) & MOUSEf_ATTR_SHOULD_AUTO_DEREF && GIMME_V == G_ARRAY){ \ + mouse_push_values(aTHX_ value, (flags)); \ + } \ + else{ \ + dSP; \ + XPUSHs(value ? value : &PL_sv_undef); \ + PUTBACK; \ + } \ + } STMT_END \ /* pushes return values, does auto-deref if needed */ static void mouse_push_values(pTHX_ SV* const value, U16 const flags){ dSP; - if(flags & MOUSEf_ATTR_SHOULD_AUTO_DEREF && GIMME_V == G_ARRAY){ - if(!(value && SvOK(value))){ - return; - } + assert( flags & MOUSEf_ATTR_SHOULD_AUTO_DEREF && GIMME_V == G_ARRAY ); - if(flags & MOUSEf_TC_IS_ARRAYREF){ - AV* const av = (AV*)SvRV(value); - I32 len; - I32 i; + if(!(value && SvOK(value))){ + return; + } - if(SvTYPE(av) != SVt_PVAV){ - croak("Mouse-panic: Not an ARRAY reference"); - } + if(flags & MOUSEf_TC_IS_ARRAYREF){ + AV* const av = (AV*)SvRV(value); + I32 len; + I32 i; - len = av_len(av) + 1; - EXTEND(SP, len); - for(i = 0; i < len; i++){ - SV** const svp = av_fetch(av, i, FALSE); - PUSHs(svp ? *svp : &PL_sv_undef); - } + if(SvTYPE(av) != SVt_PVAV){ + croak("Mouse-panic: Not an ARRAY reference"); } - else if(flags & MOUSEf_TC_IS_HASHREF){ - HV* const hv = (HV*)SvRV(value); - HE* he; - if(SvTYPE(hv) != SVt_PVHV){ - croak("Mouse-panic: Not a HASH reference"); - } - - hv_iterinit(hv); - while((he = hv_iternext(hv))){ - EXTEND(SP, 2); - PUSHs(hv_iterkeysv(he)); - PUSHs(hv_iterval(hv, he)); - } + len = av_len(av) + 1; + EXTEND(SP, len); + for(i = 0; i < len; i++){ + SV** const svp = av_fetch(av, i, FALSE); + PUSHs(svp ? *svp : &PL_sv_undef); } } - else{ - XPUSHs(value ? value : &PL_sv_undef); + else if(flags & MOUSEf_TC_IS_HASHREF){ + HV* const hv = (HV*)SvRV(value); + HE* he; + + if(SvTYPE(hv) != SVt_PVHV){ + croak("Mouse-panic: Not a HASH reference"); + } + + hv_iterinit(hv); + while((he = hv_iternext(hv))){ + EXTEND(SP, 2); + PUSHs(hv_iterkeysv(he)); + PUSHs(hv_iterval(hv, he)); + } } PUTBACK; @@ -285,7 +279,7 @@ mouse_attr_get(pTHX_ SV* const self, MAGIC* const mg){ value = mouse_instance_set_slot(aTHX_ self, slot, value); } - mouse_push_values(aTHX_ value, flags); + PUSH_VALUE(value, flags); } static void @@ -317,7 +311,7 @@ mouse_attr_set(pTHX_ SV* const self, MAGIC* const mg, SV* value){ /* need not SPAGAIN */ } - mouse_push_values(aTHX_ value, flags); + PUSH_VALUE(value, flags); } XS(mouse_xs_accessor) @@ -468,7 +462,7 @@ XS(mouse_xs_simple_predicate) XSRETURN(1); } -/* simple instance slot accessor */ +/* simple instance slot accessor (or Mouse::Meta::Instance) */ SV* mouse_instance_create(pTHX_ HV* const stash) {