File Coverage

/usr/local/lib/perl5/site_perl/5.42.0/x86_64-linux/auto/share/module/Object-Pad/include/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 810
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             SV *attrdata; /* used to be called 'hookdata' */
57             };
58              
59             struct FieldHookFuncs {
60             U32 ver; /* caller must initialise to OBJECTPAD_VERSION */
61             U32 flags;
62             const char *permit_hintkey;
63              
64             /* optional; called when parsing `:ATTRNAME(ATTRVALUE)` source code */
65             SV *(*parse)(pTHX_ FieldMeta *fieldmeta, SV *valuesrc, void *funcdata);
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             union {
79             void (*post_makefield)(pTHX_ FieldMeta *fieldmeta, SV *attrdata, void *funcdata, SV *field);
80              
81             // This used to be called post_initfield but was badly named because it
82             // actually ran *before* initfields
83             void (*post_initfield)(pTHX_ FieldMeta *fieldmeta, SV *attrdata, void *funcdata, SV *field);
84             };
85             void (*post_construct)(pTHX_ FieldMeta *fieldmeta, SV *attrdata, void *funcdata, SV *field);
86              
87             /* called as part of constructor generation
88             * TODO: Not yet used by accessors, but maybe a future version will add a
89             * flag to do this.
90             */
91             OP *(*gen_valueassert_op)(pTHX_ FieldMeta *fieldmeta, SV *attrdata, void *funcdata, OP *valueop);
92             };
93              
94             struct FieldHook {
95             FIELDOFFSET fieldix; /* unused when in FieldMeta->hooks; used by ClassMeta->fieldhooks_* */
96             FieldMeta *fieldmeta;
97             const struct FieldHookFuncs *funcs;
98             void *funcdata;
99             SV *attrdata; /* used to be called 'hookdata' */
100             };
101              
102             enum MetaType {
103             METATYPE_CLASS,
104             METATYPE_ROLE,
105             };
106              
107             enum ReprType {
108             REPR_NATIVE, /* instances are in native format - blessed AV as backing */
109             REPR_HASH, /* instances are blessed HASHes; our backing lives in $self->{"Object::Pad/slots"} */
110             REPR_MAGIC, /* instances store backing AV via magic; superconstructor must be foreign */
111              
112             REPR_AUTOSELECT, /* pick one of the above depending on foreign_new and SvTYPE()==SVt_PVHV */
113              
114             REPR_KEYS, /* instances are blessed HASHes, each field lives in an individually-named key */
115              
116             REPR_PVOBJ, /* instances are SVt_PVOBJ on perl 5.38+ */
117             };
118              
119             /* Special pad indexes within `method` CVs */
120             enum {
121             PADIX_SELF = 1,
122             PADIX_FIELDS = 2,
123              
124             /* for role methods */
125             PADIX_EMBEDDING = 3,
126              
127             /* during initfields */
128             PADIX_PARAMS = 4,
129             };
130              
131             /* Function prototypes */
132              
133             #define get_compclassmeta() ObjectPad_get_compclassmeta(aTHX)
134             ClassMeta *ObjectPad_get_compclassmeta(pTHX);
135              
136             #define extend_pad_vars(meta) ObjectPad_extend_pad_vars(aTHX_ meta)
137             void ObjectPad_extend_pad_vars(pTHX_ const ClassMeta *meta);
138              
139             #define get_field_for_padix(padix) ObjectPad_get_field_for_padix(aTHX_ padix)
140             FieldMeta *ObjectPad_get_field_for_padix(pTHX_ PADOFFSET padix);
141              
142             enum {
143             /* Common flags for newMETHSTARTOP, newFIELDPADOP and newFIELDSVOP */
144             OPfMETHSTART_ROLE = (1 << 16),
145             };
146              
147             #define newMETHSTARTOP(flags) ObjectPad_newMETHSTARTOP(aTHX_ flags)
148             OP *ObjectPad_newMETHSTARTOP(pTHX_ U32 flags);
149              
150             #define newCOMMONMETHSTARTOP(flags) ObjectPad_newCOMMONMETHSTARTOP(aTHX_ flags)
151             OP *ObjectPad_newCOMMONMETHSTARTOP(pTHX_ U32 flags);
152              
153             /* op_private flags on FIELDPAD ops */
154             enum {
155             OPpFIELDPAD_SV, /* has $x */
156             OPpFIELDPAD_AV, /* has @y */
157             OPpFIELDPAD_HV, /* has %z */
158             };
159              
160             #define newFIELDPADOP(flags, padix, fieldix) ObjectPad_newFIELDPADOP(aTHX_ flags, padix, fieldix)
161             OP *ObjectPad_newFIELDPADOP(pTHX_ U32 flags, PADOFFSET padix, FIELDOFFSET fieldix);
162              
163             /* Deprecated */
164             #define get_obj_backingav(self, repr, create) ObjectPad_get_obj_backingav(aTHX_ self, repr, create)
165             SV *ObjectPad_get_obj_backingav(pTHX_ SV *self, enum ReprType repr, bool create);
166              
167             #define get_obj_fieldstore(self, repr, create) ObjectPad_get_obj_fieldstore(aTHX_ self, repr, create)
168             SV *ObjectPad_get_obj_fieldstore(pTHX_ SV *self, enum ReprType repr, bool create);
169              
170             #define get_obj_fieldsv(self, fieldmeta) ObjectPad_get_obj_fieldsv(aTHX_ self, fieldmeta)
171             SV *ObjectPad_get_obj_fieldsv(pTHX_ SV *self, FieldMeta *fieldmeta);
172              
173             /* Class API */
174             #define mop_create_class(type, name) ObjectPad_mop_create_class(aTHX_ type, name)
175             ClassMeta *ObjectPad_mop_create_class(pTHX_ enum MetaType type, SV *name);
176              
177             #define mop_get_class_for_stash(stash) ObjectPad_mop_get_class_for_stash(aTHX_ stash)
178             ClassMeta *ObjectPad_mop_get_class_for_stash(pTHX_ HV *stash);
179              
180             #define mop_class_get_name(class) ObjectPad_mop_class_get_name(aTHX_ class)
181             SV *ObjectPad_mop_class_get_name(pTHX_ ClassMeta *class);
182              
183             #define mop_class_load_and_set_superclass(class, supername, superver) ObjectPad_mop_class_load_and_set_superclass(aTHX_ class, supername, superver)
184             void ObjectPad_mop_class_load_and_set_superclass(pTHX_ ClassMeta *class, SV *supername, SV *superver);
185              
186             #define mop_class_set_superclass(class, super) ObjectPad_mop_class_set_superclass(aTHX_ class, super)
187             void ObjectPad_mop_class_set_superclass(pTHX_ ClassMeta *class, SV *superclassname);
188              
189             #define mop_class_inherit_from_superclass(class, args, nargs) ObjectPad_mop_class_inherit_from_superclass(aTHX_ class, args, nargs)
190             void ObjectPad_mop_class_inherit_from_superclass(pTHX_ ClassMeta *class, SV **args, size_t nargs);
191              
192             #define mop_class_prepare_parse(class) ObjectPad_mop_class_prepare_parse(aTHX_ class)
193             void ObjectPad_mop_class_prepare_parse(pTHX_ ClassMeta *meta);
194              
195             #define mop_class_begin(meta) ObjectPad_mop_class_begin(aTHX_ meta)
196             void ObjectPad_mop_class_begin(pTHX_ ClassMeta *meta);
197              
198             #define mop_class_seal(meta) ObjectPad_mop_class_seal(aTHX_ meta)
199             void ObjectPad_mop_class_seal(pTHX_ ClassMeta *meta);
200              
201             #define mop_class_load_and_add_role(class, rolename, rolever) ObjectPad_mop_class_load_and_add_role(aTHX_ class, rolename, rolever)
202             void ObjectPad_mop_class_load_and_add_role(pTHX_ ClassMeta *class, SV *rolename, SV *rolever);
203              
204             #define mop_class_add_role(class, role) ObjectPad_mop_class_add_role(aTHX_ class, role)
205             void ObjectPad_mop_class_add_role(pTHX_ ClassMeta *class, ClassMeta *role);
206              
207             #define mop_class_add_method(class, methodname) ObjectPad_mop_class_add_method(aTHX_ class, methodname)
208             MethodMeta *ObjectPad_mop_class_add_method(pTHX_ ClassMeta *meta, SV *methodname);
209              
210             #define mop_class_add_method_cv(class, methodname, cv) ObjectPad_mop_class_add_method_cv(aTHX_ class, methodname, cv)
211             MethodMeta *ObjectPad_mop_class_add_method_cv(pTHX_ ClassMeta *meta, SV *methodname, CV *cv);
212              
213             #define mop_class_add_field(class, fieldname) ObjectPad_mop_class_add_field(aTHX_ class, fieldname)
214             FieldMeta *ObjectPad_mop_class_add_field(pTHX_ ClassMeta *meta, SV *fieldname);
215              
216             enum {
217             FIND_FIELD_ONLY_DIRECT = (1<<0),
218             FIND_FIELD_ONLY_INHERITABLE = (1<<1),
219             };
220              
221             #define mop_class_find_field(class, fieldname, flags) ObjectPad_mop_class_find_field(aTHX_ class, fieldname, flags)
222             FieldMeta *ObjectPad_mop_class_find_field(pTHX_ ClassMeta *meta, SV *fieldname, U32 flags);
223              
224             #define mop_class_add_BUILD(class, cv) ObjectPad_mop_class_add_BUILD(aTHX_ class, cv)
225             void ObjectPad_mop_class_add_BUILD(pTHX_ ClassMeta *meta, CV *cv);
226              
227             #define mop_class_add_ADJUST(class, cv) ObjectPad_mop_class_add_ADJUST(aTHX_ class, cv)
228             void ObjectPad_mop_class_add_ADJUST(pTHX_ ClassMeta *meta, CV *cv);
229              
230             #define mop_class_add_APPLY(class, cv) ObjectPad_mop_class_add_APPLY(aTHX_ class, cv)
231             void ObjectPad_mop_class_add_APPLY(pTHX_ ClassMeta *meta, CV *cv);
232              
233             #define mop_class_add_required_method(class, methodname) ObjectPad_mop_class_add_required_method(aTHX_ class, methodname)
234             void ObjectPad_mop_class_add_required_method(pTHX_ ClassMeta *meta, SV *methodname);
235              
236             #define mop_class_apply_attribute(classmeta, name, value) ObjectPad_mop_class_apply_attribute(aTHX_ classmeta, name, value)
237             void ObjectPad_mop_class_apply_attribute(pTHX_ ClassMeta *classmeta, const char *name, SV *value);
238              
239             #define mop_class_get_attribute(classmeta, name) ObjectPad_mop_class_get_attribute(aTHX_ classmeta, name)
240             struct ClassHook *ObjectPad_mop_class_get_attribute(pTHX_ ClassMeta *classmeta, const char *name);
241              
242             #define mop_class_get_attribute_values(classmeta, name) ObjectPad_mop_class_get_attribute_values(aTHX_ classmeta, name)
243             AV *ObjectPad_mop_class_get_attribute_values(pTHX_ ClassMeta *classmeta, const char *name);
244              
245             #define register_class_attribute(name, funcs, funcdata) ObjectPad_register_class_attribute(aTHX_ name, funcs, funcdata)
246             void ObjectPad_register_class_attribute(pTHX_ const char *name, const struct ClassHookFuncs *funcs, void *funcdata);
247              
248             /* Field API */
249             #define mop_create_field(fieldname, fieldix, classmeta) ObjectPad_mop_create_field(aTHX_ fieldname, fieldix, classmeta)
250             FieldMeta *ObjectPad_mop_create_field(pTHX_ SV *fieldname, FIELDOFFSET fieldix, ClassMeta *classmeta);
251              
252             #define mop_field_seal(fieldmeta) ObjectPad_mop_field_seal(aTHX_ fieldmeta)
253             void ObjectPad_mop_field_seal(pTHX_ FieldMeta *fieldmeta);
254              
255             #define mop_field_get_class(fieldmeta) ObjectPad_mop_field_get_class(aTHX_ fieldmeta)
256             ClassMeta *ObjectPad_mop_field_get_class(pTHX_ FieldMeta *fieldmeta);
257              
258             #define mop_field_get_name(fieldmeta) ObjectPad_mop_field_get_name(aTHX_ fieldmeta)
259             SV *ObjectPad_mop_field_get_name(pTHX_ FieldMeta *fieldmeta);
260              
261             #define mop_field_get_sigil(fieldmeta) ObjectPad_mop_field_get_sigil(aTHX_ fieldmeta)
262             char ObjectPad_mop_field_get_sigil(pTHX_ FieldMeta *fieldmeta);
263              
264             #define mop_field_apply_attribute(fieldmeta, name, value) ObjectPad_mop_field_apply_attribute(aTHX_ fieldmeta, name, value)
265             void ObjectPad_mop_field_apply_attribute(pTHX_ FieldMeta *fieldmeta, const char *name, SV *value);
266              
267             #define mop_field_parse_and_apply_attribute(fieldmeta, name, value) ObjectPad_mop_field_parse_and_apply_attribute(aTHX_ fieldmeta, name, value)
268             void ObjectPad_mop_field_parse_and_apply_attribute(pTHX_ FieldMeta *fieldmeta, const char *name, SV *value);
269              
270             #define mop_field_get_attribute(fieldmeta, name) ObjectPad_mop_field_get_attribute(aTHX_ fieldmeta, name)
271             struct FieldHook *ObjectPad_mop_field_get_attribute(pTHX_ FieldMeta *fieldmeta, const char *name);
272              
273             #define mop_field_get_attribute_values(fieldmeta, name) ObjectPad_mop_field_get_attribute_values(aTHX_ fieldmeta, name)
274             AV *ObjectPad_mop_field_get_attribute_values(pTHX_ FieldMeta *fieldmeta, const char *name);
275              
276             #define mop_field_get_default_sv(fieldmeta) ObjectPad_mop_field_get_default_sv(aTHX_ fieldmeta)
277             SV *ObjectPad_mop_field_get_default_sv(pTHX_ FieldMeta *fieldmeta);
278              
279             #define mop_field_set_default_sv(fieldmeta, sv) ObjectPad_mop_field_set_default_sv(aTHX_ fieldmeta, sv)
280             void ObjectPad_mop_field_set_default_sv(pTHX_ FieldMeta *fieldmeta, SV *sv);
281              
282             #define register_field_attribute(name, funcs, funcdata) ObjectPad_register_field_attribute(aTHX_ name, funcs, funcdata)
283             void ObjectPad_register_field_attribute(pTHX_ const char *name, const struct FieldHookFuncs *funcs, void *funcdata);
284              
285             /* Integration with XS::Parse::Keyword v0.30
286             * To enable this you must #include "XSParseKeyword.h" before this file
287             */
288             #ifdef XPK_STAGED_ANONSUB
289             /* These are not really API functions but we need to see them to let these call it */
290             void ObjectPad__prepare_method_parse(pTHX_ ClassMeta *meta);
291             void ObjectPad__start_method_parse(pTHX_ ClassMeta *meta, bool is_common);
292             OP *ObjectPad__finish_method_parse(pTHX_ ClassMeta *meta, bool is_common, OP *body);
293              
294 2           static void opxpk_anonsub_prepare(pTHX_ void *hookdata)
295             {
296 2           ObjectPad__prepare_method_parse(aTHX_ get_compclassmeta());
297 2           }
298              
299 2           static void opxpk_anonsub_start(pTHX_ void *hookdata)
300             {
301 2           ObjectPad__start_method_parse(aTHX_ get_compclassmeta(), FALSE);
302 2           }
303              
304 2           static OP *opxpk_anonsub_wrap(pTHX_ OP *o, void *hookdata)
305             {
306 2           return ObjectPad__finish_method_parse(aTHX_ get_compclassmeta(), FALSE, o);
307             }
308              
309             /* OPXPK_ANONMETHOD is like XPK_ANONSUB but constructs an anonymous method
310             * CV in the currently compiling class. As usual it will have $self and all
311             * the field lexicals visible inside it
312             */
313             #define OPXPK_ANONMETHOD_PREPARE XPK_ANONSUB_PREPARE(&opxpk_anonsub_prepare)
314             #define OPXPK_ANONMETHOD_START XPK_ANONSUB_START (&opxpk_anonsub_start)
315             #define OPXPK_ANONMETHOD_WRAP XPK_ANONSUB_WRAP (&opxpk_anonsub_wrap)
316              
317             #define OPXPK_ANONMETHOD \
318             XPK_STAGED_ANONSUB( \
319             OPXPK_ANONMETHOD_PREPARE, \
320             OPXPK_ANONMETHOD_START, \
321             OPXPK_ANONMETHOD_WRAP \
322             )
323             #endif
324              
325             #endif