X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=blobdiff_plain;f=xs-src%2FMouse.xs;h=b3d411c1e8029dfa8c10033f27d0b3934a35787f;hp=0a94ec82675926c5f06efd4aaf8f5ddf54d7813a;hb=1b3644156b3851b66b0ede7cbbd127ce441ccc9a;hpb=ca861dd989ddc9868e5c69a39844e1e888bb9508 diff --git a/xs-src/Mouse.xs b/xs-src/Mouse.xs index 0a94ec8..b3d411c 100644 --- a/xs-src/Mouse.xs +++ b/xs-src/Mouse.xs @@ -335,6 +335,24 @@ mouse_initialize_metaclass(pTHX_ SV* const klass) { return meta; } +static void +mouse_buildall(pTHX_ AV* const xc, SV* const object, SV* const args) { + AV* const buildall = MOUSE_xc_buildall(xc); + I32 const len = AvFILLp(buildall) + 1; + I32 i; + for(i = 0; i < len; i++){ + dSP; + + PUSHMARK(SP); + EXTEND(SP, 2); + PUSHs(object); + PUSHs(args); + PUTBACK; + + call_sv(AvARRAY(buildall)[i], G_VOID | G_DISCARD); + } +} + MODULE = Mouse PACKAGE = Mouse PROTOTYPES: DISABLE @@ -436,6 +454,7 @@ MODULE = Mouse PACKAGE = Mouse::Meta::Class BOOT: INSTALL_SIMPLE_READER(Class, roles); INSTALL_SIMPLE_PREDICATE_WITH_KEY(Class, is_anon_class, anon_serial_id); + INSTALL_SIMPLE_READER(Class, is_immutable); INSTALL_CLASS_HOLDER(Class, method_metaclass, "Mouse::Meta::Method"); INSTALL_CLASS_HOLDER(Class, attribute_metaclass, "Mouse::Meta::Attribute"); @@ -520,11 +539,10 @@ CODE: AV* const xc = mouse_get_xc(aTHX_ meta); UV const flags = MOUSE_xc_flags(xc); SV* args; - AV* buildall; - I32 len, i; /* BUILDARGS */ if(flags & MOUSEf_XC_HAS_BUILDARGS){ + I32 i; SPAGAIN; PUSHMARK(SP); @@ -552,32 +570,24 @@ CODE: RETVAL = mouse_instance_create(aTHX_ MOUSE_xc_stash(xc)); mouse_class_initialize_object(aTHX_ meta, RETVAL, (HV*)SvRV(args), FALSE); - /* BUILDALL */ - buildall = MOUSE_xc_buildall(xc); - len = AvFILLp(buildall) + 1; - for(i = 0; i < len; i++){ - dSP; - - PUSHMARK(SP); - EXTEND(SP, 2); - PUSHs(RETVAL); /* self */ - PUSHs(args); - PUTBACK; - - call_sv(AvARRAY(buildall)[i], G_VOID | G_DISCARD); - } + mouse_buildall(aTHX_ xc, RETVAL, args); } OUTPUT: RETVAL void DESTROY(SV* object) +ALIAS: + DESTROY = 0 + DEMOLISHALL = 1 CODE: { SV* const meta = get_metaclass(object); AV* demolishall; I32 len, i; + PERL_UNUSED_VAR(ix); + if(!IsObject(object)){ croak("You must not call DESTROY as a class method"); } @@ -587,7 +597,7 @@ CODE: demolishall = MOUSE_xc_demolishall(xc); } - else { + else { /* The metaclass is already destroyed */ AV* const linearized_isa = mro_get_linear_isa(SvSTASH(SvRV(object))); len = AvFILLp(linearized_isa) + 1; @@ -603,17 +613,16 @@ CODE: } } - /* DEMOLISHALL */ len = AvFILLp(demolishall) + 1; if(len > 0){ GV* const statusvalue = gv_fetchpvs("?", 0, SVt_PV); SAVESPTR(GvSV(statusvalue)); /* local $? */ SAVESPTR(ERRSV); /* local $@ */ - GvSV(statusvalue) = sv_2mortal(newSViv(0)); - ERRSV = sv_2mortal(newSVpvs("")); + GvSV(statusvalue) = sv_newmortal(); + ERRSV = newSVpvs_flags("", SVs_TEMP); for(i = 0; i < len; i++){ - dSP; + SPAGAIN; PUSHMARK(SP); XPUSHs(object); @@ -644,3 +653,18 @@ OUTPUT: RETVAL +void +BUILDALL(SV* self, SV* args) +CODE: +{ + SV* const meta = get_metaclass(self); + AV* const xc = mouse_get_xc(aTHX_ meta); + + if(!IsHashRef(args)){ + croak("You must pass a HASH reference to BUILDALL"); + } + if(mg_find(SvRV(args), PERL_MAGIC_tied)){ + croak("You cannot use tie HASH reference as args"); + } + mouse_buildall(aTHX_ xc, self, args); +}