X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=xs-src%2FMouseAccessor.xs;h=ea086484f480ba874741d5e7fb972f35653b3572;hb=441964ce2aaf63287281b9084b131ecb124a3405;hp=a9de90397a873dfb4525fdef4ec92ffc4ccbc51e;hpb=646c0371bdfda5817f842c54577c4d5605a4c3c0;p=gitmo%2FMouse.git diff --git a/xs-src/MouseAccessor.xs b/xs-src/MouseAccessor.xs index a9de903..ea08648 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); } @@ -196,51 +190,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 +286,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 +318,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 +469,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) {