X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=blobdiff_plain;f=xs-src%2FMouseAccessor.xs;h=fbe8ab803789694d5872356b3c3d064996997c87;hp=ef5009a6a6ef031ca666053aad04704bd86076b5;hb=e058b279f94cfd76ca59d7972209e1b346492db9;hpb=4e7e3250fdc8eeccfd656270b40f6aa9817da9a9 diff --git a/xs-src/MouseAccessor.xs b/xs-src/MouseAccessor.xs index ef5009a..fbe8ab8 100644 --- a/xs-src/MouseAccessor.xs +++ b/xs-src/MouseAccessor.xs @@ -11,8 +11,9 @@ static MGVTBL mouse_accessor_vtbl; /* MAGIC identity */ +#define dMOUSE_self SV* const self = mouse_accessor_get_self(aTHX_ ax, items, cv) -SV* +static inline SV* mouse_accessor_get_self(pTHX_ I32 const ax, I32 const items, CV* const cv) { if(items < 1){ croak("Too few arguments for %s", GvNAME(CvGV(cv))); @@ -220,7 +221,7 @@ mouse_accessor_get_mg(pTHX_ CV* const xsub){ */ CV* -mouse_install_simple_accessor(pTHX_ const char* const fq_name, const char* const key, I32 const keylen, XSUBADDR_t const accessor_impl){ +mouse_install_simple_accessor(pTHX_ const char* const fq_name, const char* const key, I32 const keylen, XSUBADDR_t const accessor_impl, void* const dptr, I32 const dlen){ CV* const xsub = newXS((char*)fq_name, accessor_impl, __FILE__); SV* const slot = newSVpvn_share(key, keylen, 0U); MAGIC* mg; @@ -230,8 +231,11 @@ mouse_install_simple_accessor(pTHX_ const char* const fq_name, const char* const sv_2mortal((SV*)xsub); } - mg = sv_magicext((SV*)xsub, slot, PERL_MAGIC_ext, &mouse_accessor_vtbl, NULL, 0); + mg = sv_magicext((SV*)xsub, slot, PERL_MAGIC_ext, &mouse_accessor_vtbl, (char*)dptr, dlen); SvREFCNT_dec(slot); /* sv_magicext() increases refcnt in mg_obj */ + if(dlen == HEf_SVKEY){ + SvREFCNT_dec(dptr); + } /* NOTE: * although we use MAGIC for gc, we also store mg to CvXSUBANY for efficiency (gfx) @@ -245,15 +249,25 @@ XS(XS_Mouse_simple_reader) { dVAR; dXSARGS; dMOUSE_self; - SV* const slot = MOUSE_mg_slot((MAGIC*)XSANY.any_ptr); + MAGIC* const mg = (MAGIC*)XSANY.any_ptr; SV* value; if (items != 1) { - croak("Expected exactly one argument for a reader for '%"SVf"'", slot); + croak("Expected exactly one argument for a reader for '%"SVf"'", MOUSE_mg_slot(mg)); } - value = get_slot(self, slot); - ST(0) = value ? value : &PL_sv_undef; + value = get_slot(self, MOUSE_mg_slot(mg)); + if(!value) { + if(MOUSE_mg_ptr(mg)){ + /* the default value must be a SV */ + assert(MOUSE_mg_len(mg) == HEf_SVKEY); + value = (SV*)MOUSE_mg_ptr(mg); + } + else{ + value = &PL_sv_undef; + } + } + ST(0) = value; XSRETURN(1); } @@ -412,7 +426,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, XS_Mouse_simple_clearer); + RETVAL = mouse_install_simple_accessor(aTHX_ NULL, pv, len, XS_Mouse_simple_clearer, NULL, 0); } OUTPUT: RETVAL @@ -424,7 +438,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, XS_Mouse_simple_predicate); + RETVAL = mouse_install_simple_accessor(aTHX_ NULL, pv, len, XS_Mouse_simple_predicate, NULL, 0); } OUTPUT: RETVAL