X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=blobdiff_plain;f=xs-src%2FMouseAccessor.xs;h=aa87df388c02385a1cccafca24a8ec93f400a152;hp=e398c58497eeba190da8feeb1403771341bbb3a4;hb=aa2d2e2c0621cdcb8b2ec7cf49beb3a9de11803c;hpb=208ffaebb193ae2c8218f11f144f98e69df25850 diff --git a/xs-src/MouseAccessor.xs b/xs-src/MouseAccessor.xs index e398c58..aa87df3 100644 --- a/xs-src/MouseAccessor.xs +++ b/xs-src/MouseAccessor.xs @@ -2,12 +2,14 @@ #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 -/* Moose XS Attribute object */ +/* Mouse XS Attribute object */ enum mouse_xa_ix_t{ + MOUSE_XA_SLOT, /* for constructors, sync to mg_obj */ + MOUSE_XA_FLAGS, /* for constructors, sync to mg_private */ MOUSE_XA_ATTRIBUTE, MOUSE_XA_TC, MOUSE_XA_TC_CODE, @@ -25,7 +27,7 @@ enum mouse_xa_flags_t{ MOUSEf_ATTR_HAS_TC = 0x0001, MOUSEf_ATTR_HAS_DEFAULT = 0x0002, MOUSEf_ATTR_HAS_BUILDER = 0x0004, - MOUSEf_ATTR_HAS_INITIALIZER = 0x0008, /* not used in Mouse */ + MOUSEf_ATTR_HAS_INITIALIZER = 0x0008, MOUSEf_ATTR_HAS_TRIGGER = 0x0010, MOUSEf_ATTR_IS_LAZY = 0x0020, @@ -52,8 +54,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 +62,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 +164,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(!IsCodeRef(tc_code)){ + mouse_throw_error(MOUSE_xa_attribute(xa), tc, "Not a CODE reference"); } } else{ @@ -219,14 +208,15 @@ mouse_push_values(pTHX_ SV* const value, U16 const flags){ } if(flags & MOUSEf_TC_IS_ARRAYREF){ - AV* const av = (AV*)SvRV(value); + AV* av; I32 len; I32 i; - if(SvTYPE(av) != SVt_PVAV){ + if(!IsArrayRef(value)){ croak("Mouse-panic: Not an ARRAY reference"); } + av = (AV*)SvRV(value); len = av_len(av) + 1; EXTEND(SP, len); for(i = 0; i < len; i++){ @@ -235,13 +225,14 @@ mouse_push_values(pTHX_ SV* const value, U16 const flags){ } } else if(flags & MOUSEf_TC_IS_HASHREF){ - HV* const hv = (HV*)SvRV(value); + HV* hv; HE* he; - if(SvTYPE(hv) != SVt_PVHV){ + if(!IsHashRef(value)){ croak("Mouse-panic: Not a HASH reference"); } + hv = (HV*)SvRV(value); hv_iterinit(hv); while((he = hv_iternext(hv))){ EXTEND(SP, 2); @@ -259,28 +250,24 @@ mouse_attr_get(pTHX_ SV* const self, MAGIC* const mg){ SV* const slot = MOUSE_mg_slot(mg); SV* value; - value = mouse_instance_get_slot(aTHX_ self, slot); + value = get_slot(self, slot); /* check_lazy */ if( !value && flags & MOUSEf_ATTR_IS_LAZY ){ - AV* const xa = MOUSE_mg_xa(mg); + AV* const xa = MOUSE_mg_xa(mg); SV* const attr = MOUSE_xa_attribute(xa); - /* get default value by $attr->default or $attr->builder */ - if(flags & MOUSEf_ATTR_HAS_DEFAULT){ - value = mcall0s(attr, "default"); - - if(SvROK(value) && SvTYPE(SvRV(value)) == SVt_PVCV){ - value = mcall0(self, value); - } - } - else if(flags & MOUSEf_ATTR_HAS_BUILDER){ + /* get default value by $attr->builder or $attr->default */ + if(flags & MOUSEf_ATTR_HAS_BUILDER){ SV* const builder = mcall0s(attr, "builder"); value = mcall0(self, builder); } + else { + value = mcall0s(attr, "default"); - if(!value){ - value = sv_newmortal(); + if(IsCodeRef(value)){ + value = mcall0(self, value); + } } /* apply coerce and type constraint */ @@ -289,7 +276,7 @@ mouse_attr_get(pTHX_ SV* const self, MAGIC* const mg){ } /* store value to slot */ - value = mouse_instance_set_slot(aTHX_ self, slot, value); + value = set_slot(self, slot, value); } PUSH_VALUE(value, flags); @@ -304,10 +291,10 @@ mouse_attr_set(pTHX_ SV* const self, MAGIC* const mg, SV* value){ value = mouse_apply_type_constraint(aTHX_ MOUSE_mg_xa(mg), value, flags); } - mouse_instance_set_slot(aTHX_ self, slot, value); + set_slot(self, slot, value); if(flags & MOUSEf_ATTR_IS_WEAK_REF){ - mouse_instance_weaken_slot(aTHX_ self, slot); + weaken_slot(self, slot); } if(flags & MOUSEf_ATTR_HAS_TRIGGER){ @@ -327,7 +314,7 @@ mouse_attr_set(pTHX_ SV* const self, MAGIC* const mg, SV* value){ PUSH_VALUE(value, flags); } -XS(mouse_xs_accessor) +XS(XS_Mouse_accessor) { dVAR; dXSARGS; dMOUSE_self; @@ -349,7 +336,7 @@ XS(mouse_xs_accessor) } -XS(mouse_xs_reader) +XS(XS_Mouse_reader) { dVAR; dXSARGS; dMOUSE_self; @@ -366,7 +353,7 @@ XS(mouse_xs_reader) mouse_attr_get(aTHX_ self, mg); } -XS(mouse_xs_writer) +XS(XS_Mouse_writer) { dVAR; dXSARGS; dMOUSE_self; @@ -414,7 +401,7 @@ mouse_install_simple_accessor(pTHX_ const char* const fq_name, const char* const return xsub; } -XS(mouse_xs_simple_reader) +XS(XS_Mouse_simple_reader) { dVAR; dXSARGS; dMOUSE_self; @@ -425,13 +412,13 @@ XS(mouse_xs_simple_reader) croak("Expected exactly one argument for a reader for '%"SVf"'", slot); } - value = mouse_instance_get_slot(aTHX_ self, slot); + value = get_slot(self, slot); ST(0) = value ? value : &PL_sv_undef; XSRETURN(1); } -XS(mouse_xs_simple_writer) +XS(XS_Mouse_simple_writer) { dVAR; dXSARGS; dMOUSE_self; @@ -441,11 +428,11 @@ XS(mouse_xs_simple_writer) croak("Expected exactly two argument for a writer for '%"SVf"'", slot); } - ST(0) = mouse_instance_set_slot(aTHX_ self, slot, ST(1)); + ST(0) = set_slot(self, slot, ST(1)); XSRETURN(1); } -XS(mouse_xs_simple_clearer) +XS(XS_Mouse_simple_clearer) { dVAR; dXSARGS; dMOUSE_self; @@ -456,12 +443,12 @@ XS(mouse_xs_simple_clearer) croak("Expected exactly one argument for a clearer for '%"SVf"'", slot); } - value = mouse_instance_delete_slot(aTHX_ self, slot); + value = delete_slot(self, slot); ST(0) = value ? value : &PL_sv_undef; XSRETURN(1); } -XS(mouse_xs_simple_predicate) +XS(XS_Mouse_simple_predicate) { dVAR; dXSARGS; dMOUSE_self; @@ -471,15 +458,16 @@ XS(mouse_xs_simple_predicate) croak("Expected exactly one argument for a predicate for '%"SVf"'", slot); } - ST(0) = boolSV( mouse_instance_has_slot(aTHX_ self, slot) ); + ST(0) = boolSV( has_slot(self, slot) ); XSRETURN(1); } -/* simple instance slot accessor */ +/* simple instance slot accessor (or Mouse::Meta::Instance) */ SV* mouse_instance_create(pTHX_ HV* const stash) { assert(stash); + assert(SvTYPE(stash) == SVt_PVHV); return sv_bless( newRV_noinc((SV*)newHV()), stash ); } @@ -554,7 +542,7 @@ CV* _generate_accessor(klass, SV* attr, metaclass) CODE: { - RETVAL = mouse_instantiate_xs_accessor(aTHX_ attr, mouse_xs_accessor); + RETVAL = mouse_instantiate_xs_accessor(aTHX_ attr, XS_Mouse_accessor); } OUTPUT: RETVAL @@ -563,7 +551,7 @@ CV* _generate_reader(klass, SV* attr, metaclass) CODE: { - RETVAL = mouse_instantiate_xs_accessor(aTHX_ attr, mouse_xs_reader); + RETVAL = mouse_instantiate_xs_accessor(aTHX_ attr, XS_Mouse_reader); } OUTPUT: RETVAL @@ -572,7 +560,7 @@ CV* _generate_writer(klass, SV* attr, metaclass) CODE: { - RETVAL = mouse_instantiate_xs_accessor(aTHX_ attr, mouse_xs_writer); + RETVAL = mouse_instantiate_xs_accessor(aTHX_ attr, XS_Mouse_writer); } OUTPUT: RETVAL @@ -584,7 +572,7 @@ CODE: SV* const slot = mcall0s(attr, "name"); STRLEN len; const char* const pv = SvPV_const(slot, len); - RETVAL = mouse_install_simple_accessor(aTHX_ NULL, pv, len, mouse_xs_simple_clearer); + RETVAL = mouse_install_simple_accessor(aTHX_ NULL, pv, len, XS_Mouse_simple_clearer); } OUTPUT: RETVAL @@ -596,7 +584,7 @@ CODE: SV* const slot = mcall0s(attr, "name"); STRLEN len; const char* const pv = SvPV_const(slot, len); - RETVAL = mouse_install_simple_accessor(aTHX_ NULL, pv, len, mouse_xs_simple_predicate); + RETVAL = mouse_install_simple_accessor(aTHX_ NULL, pv, len, XS_Mouse_simple_predicate); } OUTPUT: RETVAL