X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=xs-src%2FMouse.xs;h=c4ba5f14796e036f38ba96d6ef2725148e049b63;hb=3ea28db6c35f2f60bfcce151cb4fcee58d6edcf7;hp=d5e784212bca9adc647b8f3b3305298093933df2;hpb=431657256f423bda264c0cb76c28de72fd879b20;p=gitmo%2FMouse.git diff --git a/xs-src/Mouse.xs b/xs-src/Mouse.xs index d5e7842..c4ba5f1 100644 --- a/xs-src/Mouse.xs +++ b/xs-src/Mouse.xs @@ -1,9 +1,17 @@ #include "mouse.h" +SV* mouse_package; +SV* mouse_namespace; + MODULE = Mouse PACKAGE = Mouse::Util PROTOTYPES: DISABLE +BOOT: + mouse_package = newSVpvs_share("package"); + mouse_namespace = newSVpvs_share("namespace"); + + bool is_class_loaded(SV* sv = &PL_sv_undef) @@ -33,6 +41,77 @@ CODE: OUTPUT: RETVAL +CV* +get_code_ref(SV* package, SV* name) +CODE: +{ + HV* stash; + HE* he; + + if(!SvOK(package)){ + croak("You must define a package name"); + } + if(!SvOK(name)){ + croak("You must define a subroutine name"); + } + + stash = gv_stashsv(package, FALSE); + if(!stash){ + XSRETURN_UNDEF; + } + he = hv_fetch_ent(stash, name, FALSE, 0U); + if(he){ + GV* const gv = (GV*)hv_iterval(stash, he); + if(!isGV(gv)){ /* special constant or stub */ + STRLEN len; + const char* const pv = SvPV_const(name, len); + gv_init(gv, stash, pv, len, GV_ADDMULTI); + } + RETVAL = GvCVu(gv); + } + else{ + RETVAL = NULL; + } + + if(!RETVAL){ + XSRETURN_UNDEF; + } +} +OUTPUT: + RETVAL + + +MODULE = Mouse PACKAGE = Mouse::Util::TypeConstraints + +void +Item(SV* sv = &PL_sv_undef) +ALIAS: + Any = MOUSE_TC_ANY + Item = MOUSE_TC_ITEM + Undef = MOUSE_TC_UNDEF + Defined = MOUSE_TC_DEFINED + Bool = MOUSE_TC_BOOL + Value = MOUSE_TC_VALUE + Ref = MOUSE_TC_REF + Str = MOUSE_TC_STR + Num = MOUSE_TC_NUM + Int = MOUSE_TC_INT + ScalarRef = MOUSE_TC_SCALAR_REF + ArrayRef = MOUSE_TC_ARRAY_REF + HashRef = MOUSE_TC_HASH_REF + CodeRef = MOUSE_TC_CODE_REF + GlobRef = MOUSE_TC_GLOB_REF + FileHandle = MOUSE_TC_FILEHANDLE + RegexpRef = MOUSE_TC_REGEXP_REF + Object = MOUSE_TC_OBJECT + ClassName = MOUSE_TC_CLASS_NAME + RoleName = MOUSE_TC_ROLE_NAME +CODE: + SvGETMAGIC(sv); + ST(0) = boolSV( mouse_tc_check(aTHX_ ix, sv) ); + XSRETURN(1); + + MODULE = Mouse PACKAGE = Mouse::Meta::Module BOOT: @@ -40,19 +119,50 @@ BOOT: INSTALL_SIMPLE_READER_WITH_KEY(Module, _method_map, methods); INSTALL_SIMPLE_READER_WITH_KEY(Module, _attribute_map, attributes); +HV* +namespace(SV* self) +CODE: +{ + SV* const package = mouse_instance_get_slot(aTHX_ self, mouse_package); + if(!(package && SvOK(package))){ + croak("No package name"); + } + RETVAL = gv_stashsv(package, GV_ADDMULTI); +} +OUTPUT: + RETVAL + MODULE = Mouse PACKAGE = Mouse::Meta::Class BOOT: INSTALL_SIMPLE_READER(Class, roles); INSTALL_SIMPLE_PREDICATE_WITH_KEY(Class, is_anon_class, anon_serial_id); +void +linearized_isa(SV* self) +PPCODE: +{ + SV* const stash_ref = mcall0(self, mouse_namespace); /* $self->namespace */ + AV* linearized_isa; + I32 len; + I32 i; + if(!(SvROK(stash_ref) && SvTYPE(SvRV(stash_ref)) == SVt_PVHV)){ + croak("namespace() didn't return a HASH reference"); + } + linearized_isa = mro_get_linear_isa((HV*)SvRV(stash_ref)); + len = AvFILLp(linearized_isa) + 1; + EXTEND(SP, len); + for(i = 0; i < len; i++){ + PUSHs(AvARRAY(linearized_isa)[i]); + } +} + MODULE = Mouse PACKAGE = Mouse::Meta::Role BOOT: INSTALL_SIMPLE_READER_WITH_KEY(Role, get_roles, roles); INSTALL_SIMPLE_PREDICATE_WITH_KEY(Role, is_anon_role, anon_serial_id); - MODULE = Mouse PACKAGE = Mouse::Meta::Attribute BOOT: @@ -94,6 +204,9 @@ BOOT: INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_builder, builder); INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_documentation, documentation); + newCONSTSUB(gv_stashpvs("Mouse::Meta::Attribute", TRUE), "accessor_metaclass", + newSVpvs("Mouse::Meta::Method::Accessor::XS")); + MODULE = Mouse PACKAGE = Mouse::Meta::TypeConstraint BOOT: @@ -106,3 +219,63 @@ BOOT: INSTALL_SIMPLE_PREDICATE_WITH_KEY(TypeConstraint, has_coercion, _compiled_type_coercion); + +MODULE = Mouse PACKAGE = Mouse::Meta::Method::Accessor::XS + +BOOT: +{ + AV* const isa = get_av("Mouse::Meta::Method::Accessor::XS::ISA", TRUE); + av_push(isa, newSVpvs("Mouse::Meta::Method::Accessor")); +} + +CV* +_generate_accessor(klass, SV* attr, metaclass) +CODE: +{ + RETVAL = mouse_instantiate_xs_accessor(aTHX_ attr, mouse_xs_accessor); +} +OUTPUT: + RETVAL + +CV* +_generate_reader(klass, SV* attr, metaclass) +CODE: +{ + RETVAL = mouse_instantiate_xs_accessor(aTHX_ attr, mouse_xs_reader); +} +OUTPUT: + RETVAL + +CV* +_generate_writer(klass, SV* attr, metaclass) +CODE: +{ + RETVAL = mouse_instantiate_xs_accessor(aTHX_ attr, mouse_xs_writer); +} +OUTPUT: + RETVAL + +CV* +_generate_clearer(klass, SV* attr, metaclass) +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, mouse_xs_simple_clearer); +} +OUTPUT: + RETVAL + +CV* +_generate_predicate(klass, SV* attr, metaclass) +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, mouse_xs_simple_predicate); +} +OUTPUT: + RETVAL +