4 static MGVTBL mop_accessor_vtbl; /* the MAGIC identity */
7 mop_accessor_get_mg(pTHX_ CV* const xsub){
8 return mop_mg_find(aTHX_ (SV*)xsub, &mop_accessor_vtbl, MOPf_DIE_ON_FAIL);
12 mop_install_accessor(pTHX_ const char* const fq_name, const char* const key, I32 const keylen, XSPROTO(accessor_impl), const mop_instance_vtbl* vtbl){
13 CV* const xsub = newXS((char*)fq_name, accessor_impl, __FILE__);
14 SV* const keysv = newSVpvn_share(key, keylen, 0U);
15 AV* const meta = newAV();
18 vtbl = mop_get_default_instance_vtbl(aTHX);
21 sv_magicext((SV*)xsub, (SV*)meta, PERL_MAGIC_ext, &mop_accessor_vtbl, (char*)vtbl, 0);
22 SvREFCNT_dec(meta); /* sv_magicext() increases refcnt in mg_obj */
24 av_store(meta, 0, keysv);
31 mop_instantiate_xs_accessor(pTHX_ SV* const accessor, XSPROTO(accessor_impl), mop_instance_vtbl* const vtbl){
32 /* $key = $accessor->associated_attribute->name */
33 SV* const attr = mop_call0(aTHX_ accessor, mop_associated_attribute);
34 SV* const key = mop_call0(aTHX_ attr, mop_name);
36 const char* const kpv = SvPV_const(key, klen);
38 return mop_install_accessor(aTHX_ NULL /* anonymous */, kpv, klen, accessor_impl, vtbl);
42 mop_accessor_get_self(pTHX_ I32 const ax, I32 const items, CV* const cv) {
46 croak("too few arguments for %s", GvNAME(CvGV(cv)));
50 if(!(SvROK(self) && SvOBJECT(SvRV(self)))){
51 croak("cant call %s as a class method", GvNAME(CvGV(cv)));
56 XS(mop_xs_simple_accessor)
59 dMOP_METHOD_COMMON; /* self, mg */
61 if(items == 1){ /* reader */
62 value = MOP_mg_vtbl(mg)->get_slot(aTHX_ self, MOP_mg_key(mg));
64 else if (items == 2){ /* writer */
65 value = MOP_mg_vtbl(mg)->set_slot(aTHX_ self, MOP_mg_key(mg), ST(1));
68 croak("expected exactly one or two argument");
71 ST(0) = value ? value : &PL_sv_undef;
76 XS(mop_xs_simple_reader)
79 dMOP_METHOD_COMMON; /* self, mg */
83 croak("expected exactly one argument");
86 value = MOP_mg_vtbl(mg)->get_slot(aTHX_ self, MOP_mg_key(mg));
87 ST(0) = value ? value : &PL_sv_undef;
91 XS(mop_xs_simple_writer)
94 dMOP_METHOD_COMMON; /* self, mg */
97 croak("expected exactly two argument");
100 ST(0) = MOP_mg_vtbl(mg)->set_slot(aTHX_ self, MOP_mg_key(mg), ST(1));
104 XS(mop_xs_simple_clearer)
107 dMOP_METHOD_COMMON; /* self, mg */
111 croak("expected exactly one argument");
114 value = MOP_mg_vtbl(mg)->delete_slot(aTHX_ self, MOP_mg_key(mg));
115 ST(0) = value ? value : &PL_sv_undef;
120 XS(mop_xs_simple_predicate)
123 dMOP_METHOD_COMMON; /* self, mg */
126 croak("expected exactly one argument");
129 ST(0) = boolSV( MOP_mg_vtbl(mg)->has_slot(aTHX_ self, MOP_mg_key(mg)) );
134 XS(mop_xs_simple_predicate_for_metaclass)
137 dMOP_METHOD_COMMON; /* self, mg */
141 croak("expected exactly one argument");
144 value = MOP_mg_vtbl(mg)->get_slot(aTHX_ self, MOP_mg_key(mg));
145 ST(0) = boolSV( value && SvOK(value ));
149 MODULE = Class::MOP::Method::Accessor PACKAGE = Class::MOP::Method::Accessor
154 INSTALL_SIMPLE_READER_WITH_KEY(Method::Accessor, associated_attribute, attribute);
155 INSTALL_SIMPLE_READER(Method::Accessor, accessor_type);
159 _generate_accessor_method_xs(SV* self, void* instance_vtbl)
161 RETVAL = mop_instantiate_xs_accessor(aTHX_ self, mop_xs_simple_accessor, instance_vtbl);
166 _generate_reader_method_xs(SV* self, void* instance_vtbl)
168 RETVAL = mop_instantiate_xs_accessor(aTHX_ self, mop_xs_simple_reader, instance_vtbl);
173 _generate_writer_method_xs(SV* self, void* instance_vtbl)
175 RETVAL = mop_instantiate_xs_accessor(aTHX_ self, mop_xs_simple_writer, instance_vtbl);
180 _generate_predicate_method_xs(SV* self, void* instance_vtbl)
182 RETVAL = mop_instantiate_xs_accessor(aTHX_ self, mop_xs_simple_predicate, instance_vtbl);
187 _generate_clearer_method_xs(SV* self, void* instance_vtbl)
189 RETVAL = mop_instantiate_xs_accessor(aTHX_ self, mop_xs_simple_clearer, instance_vtbl);