1 #ifndef __OBJECT_PAD__TYPES_H__
2 #define __OBJECT_PAD__TYPES_H__
3 
4 #define OBJECTPAD_ABIVERSION_MINOR 57
5 #define OBJECTPAD_ABIVERSION_MAJOR 0
6 
7 #define OBJECTPAD_ABIVERSION  ((OBJECTPAD_ABIVERSION_MAJOR << 16) | (OBJECTPAD_ABIVERSION_MINOR))
8 
9 /* A SLOTOFFSET is an offset within the AV of an object instance */
10 typedef IV SLOTOFFSET;
11 
12 typedef struct ClassMeta ClassMeta;
13 typedef struct SlotMeta SlotMeta;
14 typedef struct MethodMeta MethodMeta;
15 
16 enum AccessorType {
17   ACCESSOR,
18   ACCESSOR_READER,
19   ACCESSOR_WRITER,
20   ACCESSOR_LVALUE_MUTATOR,
21   ACCESSOR_COMBINED,
22 };
23 
24 struct AccessorGenerationCtx {
25   PADOFFSET padix;
26   OP *bodyop;       /* OP_SASSIGN for :writer, empty for :reader, :mutator */
27   OP *post_bodyops;
28   OP *retop;        /* OP_RETURN */
29 };
30 
31 enum {
32   OBJECTPAD_FLAG_ATTR_NO_VALUE = (1<<0),
33   OBJECTPAD_FLAG_ATTR_MUST_VALUE = (1<<1),
34 };
35 
36 struct ClassHookFuncs {
37   U32 ver;  /* caller must initialise to OBJECTPAD_VERSION */
38   U32 flags;
39   const char *permit_hintkey;
40 
41   /* called immediately at apply time; return FALSE means it did its thing immediately, so don't store it */
42   bool (*apply)(pTHX_ ClassMeta *classmeta, SV *value, SV **hookdata_ptr, void *funcdata);
43 
44   /* called by mop_class_add_slot() */
45   void (*post_add_slot)(pTHX_ ClassMeta *classmeta, SV *hookdata, void *funcdata, SlotMeta *slotmeta);
46 };
47 
48 struct ClassHook {
49   const struct ClassHookFuncs *funcs;
50   void *funcdata;
51   SV *hookdata;
52 };
53 
54 struct SlotHookFuncs {
55   U32 ver;   /* caller must initialise to OBJECTPAD_VERSION */
56   U32 flags;
57   const char *permit_hintkey;
58 
59   /* called immediately at apply time; return FALSE means it did its thing immediately, so don't store it */
60   bool (*apply)(pTHX_ SlotMeta *slotmeta, SV *value, SV **hookdata_ptr, void *funcdata);
61 
62   /* called at the end of `has` statement compiletime */
63   void (*seal_slot)(pTHX_ SlotMeta *slotmeta, SV *hookdata, void *funcdata);
64 
65   /* called as part of accessor generation */
66   void (*gen_accessor_ops)(pTHX_ SlotMeta *slotmeta, SV *hookdata, void *funcdata,
67           enum AccessorType type, struct AccessorGenerationCtx *ctx);
68 
69   /* called by constructor */
70   void (*post_initslot)(pTHX_ SlotMeta *slotmeta, SV *hookdata, void *funcdata, SV *slot);
71   void (*post_construct)(pTHX_ SlotMeta *slotmeta, SV *hookdata, void *funcdata, SV *slot);
72 };
73 
74 struct SlotHook {
75   SLOTOFFSET slotix; /* unused when in SlotMeta->hooks; used by ClassMeta->slothooks_* */
76   SlotMeta *slotmeta;
77   const struct SlotHookFuncs *funcs;
78   void *funcdata;
79   SV *hookdata;
80 };
81 
82 enum MetaType {
83   METATYPE_CLASS,
84   METATYPE_ROLE,
85 };
86 
87 enum ReprType {
88   REPR_NATIVE,       /* instances are in native format - blessed AV as slots */
89   REPR_HASH,         /* instances are blessed HASHes; our slots live in $self->{"Object::Pad/slots"} */
90   REPR_MAGIC,        /* instances store slot AV via magic; superconstructor must be foreign */
91 
92   REPR_AUTOSELECT,   /* pick one of the above depending on foreign_new and SvTYPE()==SVt_PVHV */
93 };
94 
95 /* Special pad indexes within `method` CVs */
96 enum {
97   PADIX_SELF = 1,
98   PADIX_SLOTS = 2,
99 
100   /* for role methods */
101   PADIX_EMBEDDING = 3,
102 
103   /* during initslots */
104   PADIX_INITSLOTS_PARAMS = 4,
105 };
106 
107 /* Function prototypes */
108 
109 #define extend_pad_vars(meta)  ObjectPad_extend_pad_vars(aTHX_ meta)
110 void ObjectPad_extend_pad_vars(pTHX_ const ClassMeta *meta);
111 
112 #define newMETHSTARTOP(flags)  ObjectPad_newMETHSTARTOP(aTHX_ flags)
113 OP *ObjectPad_newMETHSTARTOP(pTHX_ U32 flags);
114 
115 /* op_private flags on SLOTPAD ops */
116 enum {
117   OPpSLOTPAD_SV,  /* has $x */
118   OPpSLOTPAD_AV,  /* has @y */
119   OPpSLOTPAD_HV,  /* has %z */
120 };
121 
122 #define newSLOTPADOP(flags, padix, slotix)  ObjectPad_newSLOTPADOP(aTHX_ flags, padix, slotix)
123 OP *ObjectPad_newSLOTPADOP(pTHX_ U32 flags, PADOFFSET padix, SLOTOFFSET slotix);
124 
125 #define get_obj_slotsav(self, repr, create)  ObjectPad_get_obj_slotsav(aTHX_ self, repr, create)
126 SV *ObjectPad_get_obj_slotsav(pTHX_ SV *self, enum ReprType repr, bool create);
127 
128 /* Class API */
129 #define mop_create_class(type, name)  ObjectPad_mop_create_class(aTHX_ type, name)
130 ClassMeta *ObjectPad_mop_create_class(pTHX_ enum MetaType type, SV *name);
131 
132 #define mop_class_set_superclass(class, super)  ObjectPad_mop_class_set_superclass(aTHX_ class, super)
133 void ObjectPad_mop_class_set_superclass(pTHX_ ClassMeta *class, SV *superclassname);
134 
135 #define mop_class_begin(meta)  ObjectPad_mop_class_begin(aTHX_ meta)
136 void ObjectPad_mop_class_begin(pTHX_ ClassMeta *meta);
137 
138 #define mop_class_seal(meta)  ObjectPad_mop_class_seal(aTHX_ meta)
139 void ObjectPad_mop_class_seal(pTHX_ ClassMeta *meta);
140 
141 #define mop_class_load_and_add_role(class, rolename, rolever)  ObjectPad_mop_class_load_and_add_role(aTHX_ class, rolename, rolever)
142 void ObjectPad_mop_class_load_and_add_role(pTHX_ ClassMeta *class, SV *rolename, SV *rolever);
143 
144 #define mop_class_add_role(class, role)  ObjectPad_mop_class_add_role(aTHX_ class, role)
145 void ObjectPad_mop_class_add_role(pTHX_ ClassMeta *class, ClassMeta *role);
146 
147 #define mop_class_add_method(class, methodname)  ObjectPad_mop_class_add_method(aTHX_ class, methodname)
148 MethodMeta *ObjectPad_mop_class_add_method(pTHX_ ClassMeta *meta, SV *methodname);
149 
150 #define mop_class_add_slot(class, slotname)  ObjectPad_mop_class_add_slot(aTHX_ class, slotname)
151 SlotMeta *ObjectPad_mop_class_add_slot(pTHX_ ClassMeta *meta, SV *slotname);
152 
153 #define mop_class_add_BUILD(class, cv)  ObjectPad_mop_class_add_BUILD(aTHX_ class, cv)
154 void ObjectPad_mop_class_add_BUILD(pTHX_ ClassMeta *meta, CV *cv);
155 
156 #define mop_class_add_ADJUST(class, cv)  ObjectPad_mop_class_add_ADJUST(aTHX_ class, cv)
157 void ObjectPad_mop_class_add_ADJUST(pTHX_ ClassMeta *meta, CV *cv);
158 
159 #define mop_class_add_ADJUSTPARAMS(class, cv)  ObjectPad_mop_class_add_ADJUSTPARAMS(aTHX_ class, cv)
160 void ObjectPad_mop_class_add_ADJUSTPARAMS(pTHX_ ClassMeta *meta, CV *cv);
161 
162 #define mop_class_apply_attribute(classmeta, name, value)  ObjectPad_mop_class_apply_attribute(aTHX_ classmeta, name, value)
163 void ObjectPad_mop_class_apply_attribute(pTHX_ ClassMeta *classmeta, const char *name, SV *value);
164 
165 #define register_class_attribute(name, funcs, funcdata)  ObjectPad_register_class_attribute(aTHX_ name, funcs, funcdata)
166 void ObjectPad_register_class_attribute(pTHX_ const char *name, const struct ClassHookFuncs *funcs, void *funcdata);
167 
168 /* Slot API */
169 #define mop_create_slot(slotname, classmeta)  ObjectPad_mop_create_slot(aTHX_ slotname, classmeta)
170 SlotMeta *ObjectPad_mop_create_slot(pTHX_ SV *slotname, ClassMeta *classmeta);
171 
172 #define mop_slot_seal(slotmeta)  ObjectPad_mop_slot_seal(aTHX_ slotmeta)
173 void ObjectPad_mop_slot_seal(pTHX_ SlotMeta *slotmeta);
174 
175 #define mop_slot_get_name(slotmeta)  ObjectPad_mop_slot_get_name(aTHX_ slotmeta)
176 SV *ObjectPad_mop_slot_get_name(pTHX_ SlotMeta *slotmeta);
177 
178 #define mop_slot_get_sigil(slotmeta)  ObjectPad_mop_slot_get_sigil(aTHX_ slotmeta)
179 char ObjectPad_mop_slot_get_sigil(pTHX_ SlotMeta *slotmeta);
180 
181 #define mop_slot_apply_attribute(slotmeta, name, value)  ObjectPad_mop_slot_apply_attribute(aTHX_ slotmeta, name, value)
182 void ObjectPad_mop_slot_apply_attribute(pTHX_ SlotMeta *slotmeta, const char *name, SV *value);
183 
184 #define mop_slot_get_attribute(slotmeta, name)  ObjectPad_mop_slot_get_attribute(aTHX_ slotmeta, name)
185 struct SlotHook *ObjectPad_mop_slot_get_attribute(pTHX_ SlotMeta *slotmeta, const char *name);
186 
187 #define mop_slot_get_default_sv(slotmeta)  ObjectPad_mop_slot_get_default_sv(aTHX_ slotmeta)
188 SV *ObjectPad_mop_slot_get_default_sv(pTHX_ SlotMeta *slotmeta);
189 
190 #define mop_slot_set_default_sv(slotmeta, sv)  ObjectPad_mop_slot_set_default_sv(aTHX_ slotmeta, sv)
191 void ObjectPad_mop_slot_set_default_sv(pTHX_ SlotMeta *slotmeta, SV *sv);
192 
193 #define register_slot_attribute(name, funcs, funcdata)  ObjectPad_register_slot_attribute(aTHX_ name, funcs, funcdata)
194 void ObjectPad_register_slot_attribute(pTHX_ const char *name, const struct SlotHookFuncs *funcs, void *funcdata);
195 
196 #endif
197