X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=xs-src%2FMouseAccessor.xs;h=27be7b9dab53cafce1780df446eb099315acd579;hb=8fcdb9973a1df1958b61059c8cef572780daf91d;hp=2d26088477dd2bdd38d8e8f5fe5c7b4c8b6dfdab;hpb=346a3ab8a10ac61eae8021ccfd068d80ccccd56a;p=gitmo%2FMouse.git diff --git a/xs-src/MouseAccessor.xs b/xs-src/MouseAccessor.xs index 2d26088..27be7b9 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,14 +144,22 @@ 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); PUSHs(value); PUTBACK; - call_sv(trigger, G_VOID | G_DISCARD); + call_sv_safe(trigger, G_VOID | G_DISCARD); /* need not SPAGAIN */ + + assert(SvTYPE(value) != SVTYPEMASK); } PUSH_VALUE(value, flags); @@ -425,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); @@ -437,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);