Tweaks for less memory
[gitmo/Class-MOP.git] / xs / Instance.xs
CommitLineData
1bc0cb6b 1#include "mop.h"
2
e989c0df 3#define CHECK_INSTANCE(instance) STMT_START{ \
4 if(!(SvROK(instance) && SvTYPE(SvRV(instance)) == SVt_PVHV)){ \
5 croak("Invalid object"); \
6 } \
7 if(SvTIED_mg(SvRV(instance), PERL_MAGIC_tied)){ \
8 croak("MOP::Instance: tied HASH is not yet supported"); \
9 } \
10 } STMT_END
11
12static SV*
19b618cb 13mop_instance_create_instance(pTHX_ HV* const stash) {
14 return sv_bless( newRV_noinc((SV*)newHV()), stash );
e989c0df 15}
16
17static bool
19b618cb 18mop_instance_has_slot(pTHX_ SV* const instance, SV* const slot) {
e989c0df 19 CHECK_INSTANCE(instance);
19b618cb 20 return hv_exists_ent((HV*)SvRV(instance), slot, 0U);
e989c0df 21}
22
23static SV*
19b618cb 24mop_instance_get_slot(pTHX_ SV* const instance, SV* const slot) {
e989c0df 25 HE* he;
26 CHECK_INSTANCE(instance);
19b618cb 27 he = hv_fetch_ent((HV*)SvRV(instance), slot, FALSE, 0U);
e989c0df 28 return he ? HeVAL(he) : NULL;
29}
30
31static SV*
19b618cb 32mop_instance_set_slot(pTHX_ SV* const instance, SV* const slot, SV* const value) {
e989c0df 33 HE* he;
34 SV* sv;
35 CHECK_INSTANCE(instance);
19b618cb 36 he = hv_fetch_ent((HV*)SvRV(instance), slot, TRUE, 0U);
e989c0df 37 sv = HeVAL(he);
38 sv_setsv_mg(sv, value);
39 return sv;
40}
41
42static SV*
19b618cb 43mop_instance_delete_slot(pTHX_ SV* const instance, SV* const slot) {
e989c0df 44 CHECK_INSTANCE(instance);
19b618cb 45 return hv_delete_ent((HV*)SvRV(instance), slot, 0, 0U);
e989c0df 46}
47
48static void
19b618cb 49mop_instance_weaken_slot(pTHX_ SV* const instance, SV* const slot) {
e989c0df 50 HE* he;
51 CHECK_INSTANCE(instance);
19b618cb 52 he = hv_fetch_ent((HV*)SvRV(instance), slot, FALSE, 0U);
d83eddd0 53 if(he){
54 sv_rvweaken(HeVAL(he));
55 }
e989c0df 56}
57
58static 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,
65};
66
67
68const mop_instance_vtbl*
69mop_get_default_instance_vtbl(pTHX){
70 return &mop_default_instance;
71}
72
73
1bc0cb6b 74MODULE = Class::MOP::Instance PACKAGE = Class::MOP::Instance
75
76PROTOTYPES: DISABLE
77
78BOOT:
79 INSTALL_SIMPLE_READER(Instance, associated_metaclass);
e989c0df 80
81void*
82can_xs(SV* self)
83PREINIT:
4ea01f09 84 CV* const default_method = get_cv("Class::MOP::Instance::get_slot_value", FALSE);
e989c0df 85 SV* const can = newSVpvs_flags("can", SVs_TEMP);
4ea01f09 86 SV* const method = newSVpvs_flags("get_slot_value", SVs_TEMP);
87 SV* code_ref;
e989c0df 88CODE:
4ea01f09 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){
e989c0df 92 RETVAL = (void*)&mop_default_instance;
93 }
94 else{
95 RETVAL = NULL;
96 }
97OUTPUT:
98 RETVAL
99