use Mouse::Meta::Module;
our @ISA = qw(Mouse::Meta::Module);
-sub method_metaclass() { 'Mouse::Meta::Method' }
-sub attribute_metaclass() { 'Mouse::Meta::Attribute' }
+sub method_metaclass;
+sub attribute_metaclass;
-sub constructor_class();
-sub destructor_class();
+sub constructor_class;
+sub destructor_class;
sub _construct_meta {
my($class, %args) = @_;
use Mouse::Meta::Module;
our @ISA = qw(Mouse::Meta::Module);
-sub method_metaclass(){ 'Mouse::Meta::Role::Method' } # required for get_method()
+sub method_metaclass;
sub _construct_meta {
my $class = shift;
package
Mouse::Meta::Class;
-sub constructor_class() { 'Mouse::Meta::Method::Constructor' }
-sub destructor_class() { 'Mouse::Meta::Method::Destructor' }
+sub method_metaclass { $_[0]->{method_metaclass} || 'Mouse::Meta::Method' }
+sub attribute_metaclass { $_[0]->{attribute_metaclass} || 'Mouse::Meta::Attribute' }
+
+sub constructor_class { $_[0]->{constructor_class} || 'Mouse::Meta::Method::Constructor' }
+sub destructor_class { $_[0]->{destructor_class} || 'Mouse::Meta::Method::Destructor' }
sub is_anon_class{
return exists $_[0]->{anon_serial_id};
package
Mouse::Meta::Role;
+sub method_metaclass{ $_[0]->{method_metaclass} || 'Mouse::Meta::Role::Method' }
+
sub is_anon_role{
return exists $_[0]->{anon_serial_id};
}
package
Mouse::Meta::Attribute;
-use Mouse::Meta::Method::Accessor;
+require Mouse::Meta::Method::Accessor;
+
+sub accessor_metaclass{ $_[0]->{accessor_metaclass} || 'Mouse::Meta::Method::Accessor' }
# readers
sub has_documentation { exists $_[0]->{documentation} }
-sub accessor_metaclass(){ 'Mouse::Meta::Method::Accessor' }
-
package
Mouse::Meta::TypeConstraint;
#define set_slots(self, key, value) set_slot(self, sv_2mortal(newSVpvs_share(key)), value)
/* mouse_simle_accessor.xs */
-#define INSTALL_SIMPLE_READER(klass, name) INSTALL_SIMPLE_READER_WITH_KEY(klass, name, name)
-#define INSTALL_SIMPLE_READER_WITH_KEY(klass, name, key) (void)mouse_install_simple_accessor(aTHX_ "Mouse::Meta::" #klass "::" #name, #key, sizeof(#key)-1, XS_Mouse_simple_reader)
-
-#define INSTALL_SIMPLE_WRITER(klass, name) INSTALL_SIMPLE_WRITER_WITH_KEY(klass, name, name)
-#define INSTALL_SIMPLE_WRITER_WITH_KEY(klass, name, key) (void)mouse_install_simple_accessor(aTHX_ "Mouse::Meta::" #klass "::" #name, #key, sizeof(#key)-1, XS_Mouse_simple_writer)
-
-#define INSTALL_SIMPLE_PREDICATE(klass, name) INSTALL_SIMPLE_PREDICATE_WITH_KEY(klass, name, name)
-#define INSTALL_SIMPLE_PREDICATE_WITH_KEY(klass, name, key) (void)mouse_install_simple_accessor(aTHX_ "Mouse::Meta::" #klass "::" #name, #key, sizeof(#key)-1, XS_Mouse_simple_predicate)
-
-CV* mouse_install_simple_accessor(pTHX_ const char* const fq_name, const char* const key, I32 const keylen, XSUBADDR_t const accessor_impl);
+#define INSTALL_SIMPLE_READER(klass, name) \
+ INSTALL_SIMPLE_READER_WITH_KEY(klass, name, name)
+#define INSTALL_SIMPLE_READER_WITH_KEY(klass, name, key) \
+ (void)mouse_install_simple_accessor(aTHX_ "Mouse::Meta::" #klass "::" #name, #key, sizeof(#key)-1, XS_Mouse_simple_reader, NULL, 0)
+#define INSTALL_SIMPLE_READER_WITH_DEFAULTSV(klass, name, dsv) \
+ (void)mouse_install_simple_accessor(aTHX_ "Mouse::Meta::" #klass "::" #name, #name, sizeof(#name)-1, XS_Mouse_simple_reader, (dsv), HEf_SVKEY)
+#define INSTALL_SIMPLE_READER_WITH_DEFAULTS(klass, name, ds) \
+ INSTALL_SIMPLE_READER_WITH_DEFAULTSV(klass, name, newSVpvs(ds))
+
+#define INSTALL_SIMPLE_WRITER(klass, name) \
+ NSTALL_SIMPLE_WRITER_WITH_KEY(klass, name, name)
+#define INSTALL_SIMPLE_WRITER_WITH_KEY(klass, name, key) \
+ (void)mouse_install_simple_accessor(aTHX_ "Mouse::Meta::" #klass "::" #name, #key, sizeof(#key)-1, XS_Mouse_simple_writer, NULL, 0)
+
+#define INSTALL_SIMPLE_PREDICATE(klass, name) \
+ INSTALL_SIMPLE_PREDICATE_WITH_KEY(klass, name, name)
+#define INSTALL_SIMPLE_PREDICATE_WITH_KEY(klass, name, key) \
+ (void)mouse_install_simple_accessor(aTHX_ "Mouse::Meta::" #klass "::" #name, #key, sizeof(#key)-1, XS_Mouse_simple_predicate, NULL, 0)
+
+CV* 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);
XS(XS_Mouse_simple_reader);
XS(XS_Mouse_simple_writer);
BOOT:
INSTALL_SIMPLE_READER(Class, roles);
INSTALL_SIMPLE_PREDICATE_WITH_KEY(Class, is_anon_class, anon_serial_id);
- newCONSTSUB(gv_stashpvs("Mouse::Meta::Class", TRUE), "constructor_class",
- newSVpvs("Mouse::Meta::Method::Constructor::XS"));
- newCONSTSUB(gv_stashpvs("Mouse::Meta::Class", TRUE), "destructor_class",
- newSVpvs("Mouse::Meta::Method::Destructor::XS"));
+ INSTALL_SIMPLE_READER_WITH_DEFAULTS(Class, method_metaclass, "Mouse::Meta::Method");
+ INSTALL_SIMPLE_READER_WITH_DEFAULTS(Class, attribute_metaclass, "Mouse::Meta::Attribute");
+ INSTALL_SIMPLE_READER_WITH_DEFAULTS(Class, constructor_class, "Mouse::Meta::Method::Constructor::XS");
+ INSTALL_SIMPLE_READER_WITH_DEFAULTS(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)));
INSTALL_SIMPLE_READER_WITH_KEY(Role, get_roles, roles);
INSTALL_SIMPLE_PREDICATE_WITH_KEY(Role, is_anon_role, anon_serial_id);
+ INSTALL_SIMPLE_READER_WITH_DEFAULTS(Role, method_metaclass, "Mouse::Meta::Role::Method");
+
MODULE = Mouse PACKAGE = Mouse::Object
SV*
*/
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;
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)
{
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);
}
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
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
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"));
+ INSTALL_SIMPLE_READER_WITH_DEFAULTS(Attribute, accessor_metaclass, "Mouse::Meta::Method::Accessor::XS");