File Coverage

object_pad.h
Criterion Covered Total %
statement 8 8 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1             #ifndef __OBJECT_PAD__TYPES_H__
2             #define __OBJECT_PAD__TYPES_H__
3              
4             #define OBJECTPAD_ABIVERSION_MINOR 76
5             #define OBJECTPAD_ABIVERSION_MAJOR 0
6              
7             #define OBJECTPAD_ABIVERSION ((OBJECTPAD_ABIVERSION_MAJOR << 16) | (OBJECTPAD_ABIVERSION_MINOR))
8              
9             /* A FIELDOFFSET is an offset within the AV of an object instance */
10             typedef IV FIELDOFFSET;
11              
12             typedef struct ClassMeta ClassMeta;
13             typedef struct FieldMeta FieldMeta;
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 **attrdata_ptr, void *funcdata);
43              
44             /* called immediately before class seal */
45             void (*pre_seal)(pTHX_ ClassMeta *classmeta, SV *attrdata, void *funcdata);
46             /* called immediately after class seal */
47             void (*post_seal)(pTHX_ ClassMeta *classmeta, SV *attrdata, void *funcdata);
48              
49             /* called by mop_class_add_field() */
50             void (*post_add_field)(pTHX_ ClassMeta *classmeta, SV *attrdata, void *funcdata, FieldMeta *fieldmeta);
51             };
52              
53             struct ClassHook {
54             const struct ClassHookFuncs *funcs;
55             void *funcdata;
56             union {
57             SV *attrdata;
58             SV *hookdata; // old name
59             };
60             };
61              
62             struct FieldHookFuncs {
63             U32 ver; /* caller must initialise to OBJECTPAD_VERSION */
64             U32 flags;
65             const char *permit_hintkey;
66              
67             /* called immediately at apply time; return FALSE means it did its thing immediately, so don't store it */
68             bool (*apply)(pTHX_ FieldMeta *fieldmeta, SV *value, SV **attrdata_ptr, void *funcdata);
69              
70             /* called at the end of `has` statement compiletime */
71             void (*seal)(pTHX_ FieldMeta *fieldmeta, SV *attrdata, void *funcdata);
72              
73             /* called as part of accessor generation */
74             void (*gen_accessor_ops)(pTHX_ FieldMeta *fieldmeta, SV *attrdata, void *funcdata,
75             enum AccessorType type, struct AccessorGenerationCtx *ctx);
76              
77             /* called by constructor */
78             void (*post_initfield)(pTHX_ FieldMeta *fieldmeta, SV *attrdata, void *funcdata, SV *field);
79             void (*post_construct)(pTHX_ FieldMeta *fieldmeta, SV *attrdata, void *funcdata, SV *field);
80             };
81              
82             struct FieldHook {
83             FIELDOFFSET fieldix; /* unused when in FieldMeta->hooks; used by ClassMeta->fieldhooks_* */
84             FieldMeta *fieldmeta;
85             const struct FieldHookFuncs *funcs;
86             void *funcdata;
87             union {
88             SV *attrdata;
89             SV *hookdata; // old name
90             };
91             };
92              
93             enum MetaType {
94             METATYPE_CLASS,
95             METATYPE_ROLE,
96             };
97              
98             enum ReprType {
99             REPR_NATIVE, /* instances are in native format - blessed AV as backing */
100             REPR_HASH, /* instances are blessed HASHes; our backing lives in $self->{"Object::Pad/slots"} */
101             REPR_MAGIC, /* instances store backing AV via magic; superconstructor must be foreign */
102              
103             REPR_AUTOSELECT, /* pick one of the above depending on foreign_new and SvTYPE()==SVt_PVHV */
104             };
105              
106             /* Special pad indexes within `method` CVs */
107             enum {
108             PADIX_SELF = 1,
109             PADIX_SLOTS = 2,
110              
111             /* for role methods */
112             PADIX_EMBEDDING = 3,
113              
114             /* during initfields */
115             PADIX_PARAMS = 4,
116             };
117              
118             /* Function prototypes */
119              
120             #define get_compclassmeta() ObjectPad_get_compclassmeta(aTHX)
121             ClassMeta *ObjectPad_get_compclassmeta(pTHX);
122              
123             #define extend_pad_vars(meta) ObjectPad_extend_pad_vars(aTHX_ meta)
124             void ObjectPad_extend_pad_vars(pTHX_ const ClassMeta *meta);
125              
126             #define newMETHSTARTOP(flags) ObjectPad_newMETHSTARTOP(aTHX_ flags)
127             OP *ObjectPad_newMETHSTARTOP(pTHX_ U32 flags);
128              
129             #define newCOMMONMETHSTARTOP(flags) ObjectPad_newCOMMONMETHSTARTOP(aTHX_ flags)
130             OP *ObjectPad_newCOMMONMETHSTARTOP(pTHX_ U32 flags);
131              
132             /* op_private flags on FIELDPAD ops */
133             enum {
134             OPpFIELDPAD_SV, /* has $x */
135             OPpFIELDPAD_AV, /* has @y */
136             OPpFIELDPAD_HV, /* has %z */
137             };
138              
139             #define newFIELDPADOP(flags, padix, fieldix) ObjectPad_newFIELDPADOP(aTHX_ flags, padix, fieldix)
140             OP *ObjectPad_newFIELDPADOP(pTHX_ U32 flags, PADOFFSET padix, FIELDOFFSET fieldix);
141              
142             #define get_obj_backingav(self, repr, create) ObjectPad_get_obj_backingav(aTHX_ self, repr, create)
143             SV *ObjectPad_get_obj_backingav(pTHX_ SV *self, enum ReprType repr, bool create);
144              
145             /* Class API */
146             #define mop_create_class(type, name) ObjectPad_mop_create_class(aTHX_ type, name)
147             ClassMeta *ObjectPad_mop_create_class(pTHX_ enum MetaType type, SV *name);
148              
149             #define mop_get_class_for_stash(stash) ObjectPad_mop_get_class_for_stash(aTHX_ stash)
150             ClassMeta *ObjectPad_mop_get_class_for_stash(pTHX_ HV *stash);
151              
152             #define mop_class_get_name(class) ObjectPad_mop_class_get_name(aTHX_ class)
153             SV *ObjectPad_mop_class_get_name(pTHX_ ClassMeta *class);
154              
155             #define mop_class_set_superclass(class, super) ObjectPad_mop_class_set_superclass(aTHX_ class, super)
156             void ObjectPad_mop_class_set_superclass(pTHX_ ClassMeta *class, SV *superclassname);
157              
158             #define mop_class_begin(meta) ObjectPad_mop_class_begin(aTHX_ meta)
159             void ObjectPad_mop_class_begin(pTHX_ ClassMeta *meta);
160              
161             #define mop_class_seal(meta) ObjectPad_mop_class_seal(aTHX_ meta)
162             void ObjectPad_mop_class_seal(pTHX_ ClassMeta *meta);
163              
164             #define mop_class_load_and_add_role(class, rolename, rolever) ObjectPad_mop_class_load_and_add_role(aTHX_ class, rolename, rolever)
165             void ObjectPad_mop_class_load_and_add_role(pTHX_ ClassMeta *class, SV *rolename, SV *rolever);
166              
167             #define mop_class_add_role(class, role) ObjectPad_mop_class_add_role(aTHX_ class, role)
168             void ObjectPad_mop_class_add_role(pTHX_ ClassMeta *class, ClassMeta *role);
169              
170             #define mop_class_add_method(class, methodname) ObjectPad_mop_class_add_method(aTHX_ class, methodname)
171             MethodMeta *ObjectPad_mop_class_add_method(pTHX_ ClassMeta *meta, SV *methodname);
172              
173             #define mop_class_add_method_cv(class, methodname, cv) ObjectPad_mop_class_add_method_cv(aTHX_ class, methodname, cv)
174             MethodMeta *ObjectPad_mop_class_add_method_cv(pTHX_ ClassMeta *meta, SV *methodname, CV *cv);
175              
176             #define mop_class_add_field(class, fieldname) ObjectPad_mop_class_add_field(aTHX_ class, fieldname)
177             FieldMeta *ObjectPad_mop_class_add_field(pTHX_ ClassMeta *meta, SV *fieldname);
178              
179             #define mop_class_add_BUILD(class, cv) ObjectPad_mop_class_add_BUILD(aTHX_ class, cv)
180             void ObjectPad_mop_class_add_BUILD(pTHX_ ClassMeta *meta, CV *cv);
181              
182             #define mop_class_add_ADJUST(class, cv) ObjectPad_mop_class_add_ADJUST(aTHX_ class, cv)
183             void ObjectPad_mop_class_add_ADJUST(pTHX_ ClassMeta *meta, CV *cv);
184              
185             #define mop_class_add_required_method(class, methodname) ObjectPad_mop_class_add_required_method(aTHX_ class, methodname)
186             void ObjectPad_mop_class_add_required_method(pTHX_ ClassMeta *meta, SV *methodname);
187              
188             #define mop_class_apply_attribute(classmeta, name, value) ObjectPad_mop_class_apply_attribute(aTHX_ classmeta, name, value)
189             void ObjectPad_mop_class_apply_attribute(pTHX_ ClassMeta *classmeta, const char *name, SV *value);
190              
191             #define register_class_attribute(name, funcs, funcdata) ObjectPad_register_class_attribute(aTHX_ name, funcs, funcdata)
192             void ObjectPad_register_class_attribute(pTHX_ const char *name, const struct ClassHookFuncs *funcs, void *funcdata);
193              
194             /* Field API */
195             #define mop_create_field(fieldname, classmeta) ObjectPad_mop_create_field(aTHX_ fieldname, classmeta)
196             FieldMeta *ObjectPad_mop_create_field(pTHX_ SV *fieldname, ClassMeta *classmeta);
197              
198             #define mop_field_seal(fieldmeta) ObjectPad_mop_field_seal(aTHX_ fieldmeta)
199             void ObjectPad_mop_field_seal(pTHX_ FieldMeta *fieldmeta);
200              
201             #define mop_field_get_name(fieldmeta) ObjectPad_mop_field_get_name(aTHX_ fieldmeta)
202             SV *ObjectPad_mop_field_get_name(pTHX_ FieldMeta *fieldmeta);
203              
204             #define mop_field_get_sigil(fieldmeta) ObjectPad_mop_field_get_sigil(aTHX_ fieldmeta)
205             char ObjectPad_mop_field_get_sigil(pTHX_ FieldMeta *fieldmeta);
206              
207             #define mop_field_apply_attribute(fieldmeta, name, value) ObjectPad_mop_field_apply_attribute(aTHX_ fieldmeta, name, value)
208             void ObjectPad_mop_field_apply_attribute(pTHX_ FieldMeta *fieldmeta, const char *name, SV *value);
209              
210             #define mop_field_get_attribute(fieldmeta, name) ObjectPad_mop_field_get_attribute(aTHX_ fieldmeta, name)
211             struct FieldHook *ObjectPad_mop_field_get_attribute(pTHX_ FieldMeta *fieldmeta, const char *name);
212              
213             #define mop_field_get_attribute_values(fieldmeta, name) ObjectPad_mop_field_get_attribute_values(aTHX_ fieldmeta, name)
214             AV *ObjectPad_mop_field_get_attribute_values(pTHX_ FieldMeta *fieldmeta, const char *name);
215              
216             #define mop_field_get_default_sv(fieldmeta) ObjectPad_mop_field_get_default_sv(aTHX_ fieldmeta)
217             SV *ObjectPad_mop_field_get_default_sv(pTHX_ FieldMeta *fieldmeta);
218              
219             #define mop_field_set_default_sv(fieldmeta, sv) ObjectPad_mop_field_set_default_sv(aTHX_ fieldmeta, sv)
220             void ObjectPad_mop_field_set_default_sv(pTHX_ FieldMeta *fieldmeta, SV *sv);
221              
222             #define register_field_attribute(name, funcs, funcdata) ObjectPad_register_field_attribute(aTHX_ name, funcs, funcdata)
223             void ObjectPad_register_field_attribute(pTHX_ const char *name, const struct FieldHookFuncs *funcs, void *funcdata);
224              
225             /* Integration with XS::Parse::Keyword v0.30
226             * To enable this you must #include "XSParseKeyword.h" before this file
227             */
228             #ifdef XPK_STAGED_ANONSUB
229             /* These are not really API functions but we need to see them to let these call it */
230             void ObjectPad__prepare_method_parse(pTHX_ ClassMeta *meta);
231             void ObjectPad__start_method_parse(pTHX_ ClassMeta *meta, bool is_common);
232             OP *ObjectPad__finish_method_parse(pTHX_ ClassMeta *meta, bool is_common, OP *body);
233              
234 2           static void opxpk_anonsub_prepare(pTHX_ void *hookdata)
235             {
236 2           ObjectPad__prepare_method_parse(aTHX_ get_compclassmeta());
237 2           }
238              
239 2           static void opxpk_anonsub_start(pTHX_ void *hookdata)
240             {
241 2           ObjectPad__start_method_parse(aTHX_ get_compclassmeta(), FALSE);
242 2           }
243              
244 2           static OP *opxpk_anonsub_wrap(pTHX_ OP *o, void *hookdata)
245             {
246 2           return ObjectPad__finish_method_parse(aTHX_ get_compclassmeta(), FALSE, o);
247             }
248              
249             /* OPXPK_ANONMETHOD is like XPK_ANONSUB but constructs an anonymous method
250             * CV in the currently compiling class. As usual it will have $self and all
251             * the field lexicals visible inside it
252             */
253             #define OPXPK_ANONMETHOD_PREPARE XPK_ANONSUB_PREPARE(&opxpk_anonsub_prepare)
254             #define OPXPK_ANONMETHOD_START XPK_ANONSUB_START (&opxpk_anonsub_start)
255             #define OPXPK_ANONMETHOD_WRAP XPK_ANONSUB_WRAP (&opxpk_anonsub_wrap)
256              
257             #define OPXPK_ANONMETHOD \
258             XPK_STAGED_ANONSUB( \
259             OPXPK_ANONMETHOD_PREPARE, \
260             OPXPK_ANONMETHOD_START, \
261             OPXPK_ANONMETHOD_WRAP \
262             )
263             #endif
264              
265             #endif