X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=xs-src%2FMouseAccessor.xs;h=a16b2ae4ee41a8db68d5fadabefdea7a253d865e;hb=8ab2c6ab8d7a229539e3464298c59a8823a18cec;hp=5d6bcbf42fcf19e07a1df50e5e1aa4bf782e498b;hpb=2468f1d7c798da84418ca56ba71f69b6f921996d;p=gitmo%2FMouse.git diff --git a/xs-src/MouseAccessor.xs b/xs-src/MouseAccessor.xs index 5d6bcbf..a16b2ae 100644 --- a/xs-src/MouseAccessor.xs +++ b/xs-src/MouseAccessor.xs @@ -1,9 +1,9 @@ #include "mouse.h" -#define CHECK_INSTANCE(instance) STMT_START{ \ - if(!(SvROK(instance) && SvTYPE(SvRV(instance)) == SVt_PVHV)){ \ - croak("Invalid object instance"); \ - } \ +#define CHECK_INSTANCE(instance) STMT_START{ \ + if(!(SvROK(instance) && SvTYPE(SvRV(instance)) == SVt_PVHV)){ \ + croak("Invalid object instance"); \ + } \ } STMT_END @@ -88,10 +88,12 @@ mouse_push_values(pTHX_ SV* const value, U16 const flags){ PUSHs(svp ? *svp : &PL_sv_undef); } } - else if(flags & MOUSEf_TC_IS_HASHREF){ + else{ HV* hv; HE* he; + assert(flags & MOUSEf_TC_IS_HASHREF); + if(!IsHashRef(value)){ croak("Mouse-panic: Not a HASH reference"); } @@ -132,7 +134,7 @@ mouse_attr_set(pTHX_ SV* const self, MAGIC* const mg, SV* value){ value = mouse_xa_apply_type_constraint(aTHX_ MOUSE_mg_xa(mg), value, flags); } - set_slot(self, slot, value); + value = set_slot(self, slot, value); if(flags & MOUSEf_ATTR_IS_WEAK_REF){ weaken_slot(self, slot); @@ -142,6 +144,12 @@ mouse_attr_set(pTHX_ SV* const self, MAGIC* const mg, SV* value){ SV* const trigger = mcall0s(MOUSE_mg_attribute(mg), "trigger"); dSP; + /* NOTE: triggers can remove value, so + value must be copied here, + revealed by Net::Google::DataAPI (DANJOU). + */ + value = sv_mortalcopy(value); + PUSHMARK(SP); EXTEND(SP, 2); PUSHs(self); @@ -150,6 +158,8 @@ mouse_attr_set(pTHX_ SV* const self, MAGIC* const mg, SV* value){ PUTBACK; call_sv(trigger, G_VOID | G_DISCARD); /* need not SPAGAIN */ + + assert(SvTYPE(value) != SVTYPEMASK); } PUSH_VALUE(value, flags); @@ -245,30 +255,6 @@ mouse_simple_accessor_generate(pTHX_ const char* const fq_name, const char* cons return xsub; } -XS(XS_Mouse_simple_accessor) -{ - dVAR; dXSARGS; - dMOUSE_self; - MAGIC* const mg = (MAGIC*)XSANY.any_ptr; - SV* value; - - if(items == 1){ /* reader */ - value = get_slot(self, MOUSE_mg_slot(mg)); - if(!value){ - value = &PL_sv_undef; - } - } - else if(items == 2){ /* writer */ - value = set_slot(self, MOUSE_mg_slot(mg), ST(1)); - } - else { - croak("Expected exactly one or two argument for an accessor for '%"SVf"'", MOUSE_mg_slot(mg)); - } - - ST(0) = value; - XSRETURN(1); -} - XS(XS_Mouse_simple_reader) { dVAR; dXSARGS; @@ -412,7 +398,7 @@ mouse_instance_weaken_slot(pTHX_ SV* const instance, SV* const slot) { sv_rvweaken(HeVAL(he)); } } - + MODULE = Mouse::Meta::Method::Accessor::XS PACKAGE = Mouse::Meta::Method::Accessor::XS PROTOTYPES: DISABLE @@ -449,7 +435,7 @@ CV* _generate_clearer(klass, SV* attr, metaclass) CODE: { - SV* const slot = mcall0s(attr, "name"); + SV* const slot = mcall0(attr, mouse_name); STRLEN len; const char* const pv = SvPV_const(slot, len); RETVAL = mouse_simple_accessor_generate(aTHX_ NULL, pv, len, XS_Mouse_simple_clearer, NULL, 0); @@ -461,7 +447,7 @@ CV* _generate_predicate(klass, SV* attr, metaclass) CODE: { - SV* const slot = mcall0s(attr, "name"); + SV* const slot = mcall0(attr, mouse_name); STRLEN len; const char* const pv = SvPV_const(slot, len); RETVAL = mouse_simple_accessor_generate(aTHX_ NULL, pv, len, XS_Mouse_simple_predicate, NULL, 0);