3 #define CHECK_INSTANCE(instance) STMT_START{ \
4 if(!(SvROK(instance) && SvTYPE(SvRV(instance)) == SVt_PVHV)){ \
5 croak("Invalid object for instance managers"); \
10 mop_instance_create(pTHX_ SV* const mi PERL_UNUSED_DECL, HV* const stash) {
12 return sv_bless( newRV_noinc((SV*)newHV()), stash );
16 mop_instance_clone(pTHX_ SV* const mi PERL_UNUSED_DECL, SV* const instance) {
20 CHECK_INSTANCE(instance);
21 proto = newHVhv((HV*)SvRV(instance));
22 return sv_bless( newRV_noinc((SV*)proto), SvSTASH(SvRV(instance)) );
28 mop_instance_has_slot(pTHX_ SV* const mi PERL_UNUSED_DECL, SV* const instance, SV* const slot) {
31 CHECK_INSTANCE(instance);
32 return hv_exists_ent((HV*)SvRV(instance), slot, 0U);
36 mop_instance_get_slot(pTHX_ SV* const mi PERL_UNUSED_DECL, SV* const instance, SV* const slot) {
40 CHECK_INSTANCE(instance);
41 he = hv_fetch_ent((HV*)SvRV(instance), slot, FALSE, 0U);
42 return he ? HeVAL(he) : NULL;
46 mop_instance_set_slot(pTHX_ SV* const mi PERL_UNUSED_DECL, SV* const instance, SV* const slot, SV* const value) {
52 CHECK_INSTANCE(instance);
53 he = hv_fetch_ent((HV*)SvRV(instance), slot, TRUE, 0U);
55 sv_setsv_mg(sv, value);
60 mop_instance_delete_slot(pTHX_ SV* const mi PERL_UNUSED_DECL, SV* const instance, SV* const slot) {
63 CHECK_INSTANCE(instance);
64 return hv_delete_ent((HV*)SvRV(instance), slot, 0, 0U);
68 mop_instance_weaken_slot(pTHX_ SV* const mi PERL_UNUSED_DECL, SV* const instance, SV* const slot) {
72 CHECK_INSTANCE(instance);
73 he = hv_fetch_ent((HV*)SvRV(instance), slot, FALSE, 0U);
75 sv_rvweaken(HeVAL(he));
79 static const mop_instance_vtbl mop_default_instance_vtbl = {
82 mop_instance_has_slot,
83 mop_instance_get_slot,
84 mop_instance_set_slot,
85 mop_instance_delete_slot,
86 mop_instance_weaken_slot,
90 const mop_instance_vtbl*
91 mop_get_default_instance_vtbl(pTHX){
92 return &mop_default_instance_vtbl;
95 MODULE = Class::MOP::Instance PACKAGE = Class::MOP::Instance
102 INSTALL_SIMPLE_READER(Instance, associated_metaclass);
107 CV* const default_method = get_cv("Class::MOP::Instance::get_slot_value", FALSE);
108 SV* const method = newSVpvs_flags("get_slot_value", SVs_TEMP);
111 /* $self->can("get_slot_value") == \&Class::MOP::Instance::get_slot_value */
112 code_ref = mop_call1(aTHX_ self, mop_can, method);
113 if(SvROK(code_ref) && SvRV(code_ref) == (SV*)default_method){
114 RETVAL = (void*)&mop_default_instance_vtbl;
123 create_instance(SV* self)
127 class_name = mop_call0_pvs(self, "_class_name");
128 RETVAL = mop_instance_create(aTHX_ NULL, gv_stashsv(class_name, TRUE));
133 clone_instance(SV* self, SV* instance)
135 PERL_UNUSED_VAR(self);
136 RETVAL = mop_instance_clone(aTHX_ NULL, instance);
141 is_slot_initialized(SV* self, SV* instance, SV* slot)
143 PERL_UNUSED_VAR(self);
144 RETVAL = mop_instance_has_slot(aTHX_ NULL, instance, slot);
149 get_slot_value(SV* self, SV* instance, SV* slot)
151 PERL_UNUSED_VAR(self);
152 RETVAL = mop_instance_get_slot(aTHX_ NULL, instance, slot);
153 RETVAL = RETVAL ? newSVsv(RETVAL) : &PL_sv_undef;
158 set_slot_value(SV* self, SV* instance, SV* slot, SV* value)
160 PERL_UNUSED_VAR(self);
161 RETVAL = mop_instance_set_slot(aTHX_ NULL, instance, slot, value);
162 SvREFCNT_inc_simple_void_NN(RETVAL);
167 deinitialize_slot(SV* self, SV* instance, SV* slot)
169 PERL_UNUSED_VAR(self);
170 RETVAL = mop_instance_delete_slot(aTHX_ NULL, instance, slot);
172 SvREFCNT_inc_simple_void_NN(RETVAL);
175 RETVAL = &PL_sv_undef;
181 weaken_slot_value(SV* self, SV* instance, SV* slot)
183 PERL_UNUSED_VAR(self);
184 mop_instance_weaken_slot(aTHX_ NULL, instance, slot);