3 #define CHECK_INSTANCE(instance) STMT_START{ \
4 if(!(SvROK(instance) && SvTYPE(SvRV(instance)) == SVt_PVHV)){ \
5 croak("Invalid object"); \
7 if(SvTIED_mg(SvRV(instance), PERL_MAGIC_tied)){ \
8 croak("MOP::Instance: tied HASH is not yet supported"); \
13 mop_instance_create_instance(pTHX_ SV* const mi PERL_UNUSED_DECL) {
14 return newRV_noinc((SV*)newHV());
18 mop_instance_has_slot(pTHX_ SV* const mi, SV* const instance) {
19 CHECK_INSTANCE(instance);
20 return hv_exists_ent((HV*)SvRV(instance), MOP_mi_slot(mi), 0U);
24 mop_instance_get_slot(pTHX_ SV* const mi, SV* const instance) {
26 CHECK_INSTANCE(instance);
27 he = hv_fetch_ent((HV*)SvRV(instance), MOP_mi_slot(mi), FALSE, 0U);
28 return he ? HeVAL(he) : NULL;
32 mop_instance_set_slot(pTHX_ SV* const mi, SV* const instance, SV* const value) {
35 CHECK_INSTANCE(instance);
36 he = hv_fetch_ent((HV*)SvRV(instance), MOP_mi_slot(mi), TRUE, 0U);
38 sv_setsv_mg(sv, value);
43 mop_instance_delete_slot(pTHX_ SV* const mi, SV* const instance) {
44 CHECK_INSTANCE(instance);
45 return hv_delete_ent((HV*)SvRV(instance), MOP_mi_slot(mi), 0, 0U);
49 mop_instance_weaken_slot(pTHX_ SV* const mi, SV* const instance) {
51 CHECK_INSTANCE(instance);
52 he = hv_fetch_ent((HV*)SvRV(instance), MOP_mi_slot(mi), FALSE, 0U);
54 sv_rvweaken(HeVAL(he));
58 static const mop_instance_vtbl mop_default_instance = {
59 mop_instance_create_instance,
60 mop_instance_has_slot,
61 mop_instance_get_slot,
62 mop_instance_set_slot,
63 mop_instance_delete_slot,
64 mop_instance_weaken_slot,
68 const mop_instance_vtbl*
69 mop_get_default_instance_vtbl(pTHX){
70 return &mop_default_instance;
74 MODULE = Class::MOP::Instance PACKAGE = Class::MOP::Instance
79 INSTALL_SIMPLE_READER(Instance, associated_metaclass);
84 CV* const default_method = get_cv("Class::MOP::Instance::get_slot_value", FALSE);
85 SV* const can = newSVpvs_flags("can", SVs_TEMP);
86 SV* const method = newSVpvs_flags("get_slot_value", SVs_TEMP);
89 /* $self->can("get_slot_value") == \&Class::MOP::Instance::get_slot_value */
90 code_ref = mop_call1(aTHX_ self, can, method);
91 if(SvROK(code_ref) && SvRV(code_ref) == (SV*)default_method){
92 RETVAL = (void*)&mop_default_instance;