X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=xs-src%2FMouse.xs;h=47ef5c9886352559bf5ea40ac88fd91f292d9d1d;hb=bc97157e163ca3ec82a442141232f2cb2d55b106;hp=efd1e94a5996a1cdf73a24e4901145aa5b903e26;hpb=fe5044b1eadf100f8cfa55cdc3b8d59e9aa52d5b;p=gitmo%2FMouse.git diff --git a/xs-src/Mouse.xs b/xs-src/Mouse.xs index efd1e94..47ef5c9 100644 --- a/xs-src/Mouse.xs +++ b/xs-src/Mouse.xs @@ -88,7 +88,7 @@ mouse_class_has_custom_buildargs(pTHX_ HV* const stash) { static void mouse_class_update_xc(pTHX_ SV* const metaclass PERL_UNUSED_DECL, HV* const stash, AV* const xc) { AV* const linearized_isa = mro_get_linear_isa(stash); - I32 const len = AvFILLp(linearized_isa); + I32 const len = AvFILLp(linearized_isa) + 1; I32 i; U32 flags = 0x00; AV* const attrall = newAV(); @@ -236,13 +236,12 @@ mouse_buildargs(pTHX_ SV* metaclass, SV* const klass, I32 ax, I32 items) { else{ I32 i; - args = newHV_mortal(); - if( (items % 2) != 0 ){ if(!metaclass){ metaclass = get_metaclass(klass); } mouse_throw_error(metaclass, NULL, "Odd number of parameters to new()"); } + args = newHV_mortal(); for(i = 0; i < items; i += 2){ (void)hv_store_ent(args, ST(i), newSVsv(ST(i+1)), 0U); } @@ -297,7 +296,7 @@ mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const I32 const len = AvFILLp(attrs) + 1; I32 i; AV* triggers_queue = NULL; - U32 used = 0; + I32 used = 0; assert(meta || object); assert(args); @@ -352,7 +351,8 @@ mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const } } /* for each attribute */ - if(MOUSE_xc_flags(xc) & MOUSEf_XC_CONSTRUCTOR_IS_STRICT && used < HvUSEDKEYS(args)){ + if(MOUSE_xc_flags(xc) & MOUSEf_XC_CONSTRUCTOR_IS_STRICT + && used < (I32)HvUSEDKEYS(args)){ mouse_report_unknown_args(aTHX_ meta, attrs, args); } @@ -370,7 +370,6 @@ mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const if(MOUSE_xc_flags(xc) & MOUSEf_XC_IS_ANON){ (void)set_slot(object, newSVpvs_flags("__METACLASS__", SVs_TEMP), meta); } - } static SV* @@ -378,7 +377,8 @@ mouse_initialize_metaclass(pTHX_ SV* const klass) { SV* meta = get_metaclass(klass); if(!SvOK(meta)){ - meta = mcall1s(newSVpvs_flags("Mouse::Meta::Class", SVs_TEMP), "initialize", klass); + meta = mcall1s(newSVpvs_flags("Mouse::Meta::Class", SVs_TEMP), + "initialize", klass); } return meta; @@ -445,6 +445,16 @@ mouse_get_modifier_storage(pTHX_ return (AV*)SvRV(storage_ref); } +static void +XS_Mouse_value_holder(pTHX_ CV* const cv PERL_UNUSED_DECL) { + dVAR; dXSARGS; + SV* const value = (SV*)XSANY.any_ptr; + assert(value); + PERL_UNUSED_VAR(items); + ST(0) = value; + XSRETURN(1); +} + DECL_BOOT(Mouse__Util); DECL_BOOT(Mouse__Util__TypeConstraints); DECL_BOOT(Mouse__Meta__Method__Accessor__XS); @@ -455,6 +465,7 @@ MODULE = Mouse PACKAGE = Mouse PROTOTYPES: DISABLE BOOT: +{ mouse_package = newSVpvs_share("package"); mouse_namespace = newSVpvs_share("namespace"); mouse_methods = newSVpvs_share("methods"); @@ -468,7 +479,7 @@ BOOT: CALL_BOOT(Mouse__Util__TypeConstraints); CALL_BOOT(Mouse__Meta__Method__Accessor__XS); CALL_BOOT(Mouse__Meta__Attribute); - +} MODULE = Mouse PACKAGE = Mouse::Meta::Module @@ -526,19 +537,31 @@ CODE: MODULE = Mouse PACKAGE = Mouse::Meta::Class BOOT: +{ + CV* xsub; + INSTALL_SIMPLE_READER(Class, roles); INSTALL_SIMPLE_PREDICATE_WITH_KEY(Class, is_anon_class, anon_serial_id); INSTALL_SIMPLE_READER(Class, is_immutable); + INSTALL_INHERITABLE_CLASS_ACCESSOR(strict_constructor); + INSTALL_CLASS_HOLDER(Class, method_metaclass, "Mouse::Meta::Method"); INSTALL_CLASS_HOLDER(Class, attribute_metaclass, "Mouse::Meta::Attribute"); INSTALL_CLASS_HOLDER(Class, constructor_class, "Mouse::Meta::Method::Constructor::XS"); INSTALL_CLASS_HOLDER(Class, destructor_class, "Mouse::Meta::Method::Destructor::XS"); - newCONSTSUB(gv_stashpvs("Mouse::Meta::Method::Constructor::XS", TRUE), "_generate_constructor", - newRV_inc((SV*)get_cvs("Mouse::Object::new", TRUE))); - newCONSTSUB(gv_stashpvs("Mouse::Meta::Method::Destructor::XS", TRUE), "_generate_destructor", - newRV_inc((SV*)get_cvs("Mouse::Object::DESTROY", TRUE))); + xsub = newXS("Mouse::Meta::Method::Constructor::XS::_generate_constructor", + XS_Mouse_value_holder, file); + CvXSUBANY(xsub).any_ptr + = newRV_inc((SV*)get_cvs("Mouse::Object::new", GV_ADD)); + + xsub = newXS("Mouse::Meta::Method::Destructor::XS::_generate_destructor", + XS_Mouse_value_holder, file); + CvXSUBANY(xsub).any_ptr + = newRV_inc((SV*)get_cvs("Mouse::Object::DESTROY", GV_ADD)); +} + void linearized_isa(SV* self) @@ -616,45 +639,6 @@ CODE: mouse_class_initialize_object(aTHX_ meta, object, args, is_cloning); } -void -strict_constructor(SV* self, SV* value = NULL) -CODE: -{ - SV* const slot = sv_2mortal(newSVpvs_share("strict_constructor")); - SV* const stash_ref = mcall0(self, mouse_namespace); - HV* stash; - - if(!(SvROK(stash_ref) && SvTYPE(SvRV(stash_ref)) == SVt_PVHV)) { - croak("namespace() didn't return a HASH reference"); - } - stash = (HV*)SvRV(stash_ref); - - if(value) { /* setter */ - set_slot(self, slot, value); - mro_method_changed_in(stash); - } - - value = get_slot(self, slot); - - if(!value) { - AV* const isa = mro_get_linear_isa(stash); - I32 const len = av_len(isa) + 1; - I32 i; - for(i = 1; i < len; i++) { - SV* const klass = MOUSE_av_at(isa, i); - SV* const meta = get_metaclass(klass); - if(!SvOK(meta)){ - continue; /* skip non-Mouse classes */ - } - value = get_slot(meta, slot); - if(value) { - break; - } - } - } - ST(0) = value ? value : &PL_sv_no; -} - MODULE = Mouse PACKAGE = Mouse::Meta::Role BOOT: @@ -696,6 +680,18 @@ PPCODE: } } +void +add_metaclass_accessor(SV* self, SV* name) +CODE: +{ + SV* const klass = mcall0(self, mouse_name); + const char* fq_name = form("%"SVf"::%"SVf, klass, name); + STRLEN keylen; + const char* const key = SvPV_const(name, keylen); + mouse_simple_accessor_generate(aTHX_ fq_name, key, keylen, + XS_Mouse_inheritable_class_accessor, NULL, 0); +} + MODULE = Mouse PACKAGE = Mouse::Object void