1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
|
.\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "PERLCLASSGUTS 1"
.TH PERLCLASSGUTS 1 2024-05-30 "perl v5.38.2" "Perl Programmers Reference Guide"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH NAME
perlclassguts \- Internals of how "feature \*(Aqclass\*(Aq" and class syntax works
.SH DESCRIPTION
.IX Header "DESCRIPTION"
This document provides in-depth information about the way in which the perl
interpreter implements the \f(CW\*(C`feature \*(Aqclass\*(Aq\*(C'\fR syntax and overall behaviour.
It is not intended as an end-user guide on how to use the feature. For that,
see perlclass.
.PP
The reader is assumed to be generally familiar with the perl interpreter
internals overall. For a more general overview of these details, see also
perlguts.
.SH "DATA STORAGE"
.IX Header "DATA STORAGE"
.SS Classes
.IX Subsection "Classes"
A class is fundamentally a package, and exists in the symbol table as an HV
with an aux structure in exactly the same way as a non-class package. It is
distinguished from a non-class package by the fact that the
\&\f(CWHvSTASH_IS_CLASS()\fR macro will return true on it.
.PP
Extra information relating to it being a class is stored in the
\&\f(CW\*(C`struct xpvhv_aux\*(C'\fR structure attached to the stash, in the following fields:
.PP
.Vb 6
\& HV *xhv_class_superclass;
\& CV *xhv_class_initfields_cv;
\& AV *xhv_class_adjust_blocks;
\& PADNAMELIST *xhv_class_fields;
\& PADOFFSET xhv_class_next_fieldix;
\& HV *xhv_class_param_map;
.Ve
.IP \(bu 4
\&\f(CW\*(C`xhv_class_superclass\*(C'\fR will be \f(CW\*(C`NULL\*(C'\fR for a class with no superclass. It
will point directly to the stash of the parent class if one has been set with
the \f(CW:isa()\fR class attribute.
.IP \(bu 4
\&\f(CW\*(C`xhv_class_initfields_cv\*(C'\fR will contain a \f(CW\*(C`CV *\*(C'\fR pointing to a function to be
invoked as part of the constructor of this class or any subclass thereof. This
CV is responsible for initializing all the fields defined by this class for a
new instance. This CV will be an anonymous real function \- i.e. while it has no
name and no GV, it is \fInot\fR a protosub and may be directly invoked.
.IP \(bu 4
\&\f(CW\*(C`xhv_class_adjust_blocks\*(C'\fR may point to an AV containing CV pointers to each of
the \f(CW\*(C`ADJUST\*(C'\fR blocks defined on the class. If the class has a superclass, this
array will additionally contain duplicate pointers of the CVs of its parent
class. The AV is created lazily the first time an element is pushed to it; it
is valid for there not to be one, and this pointer will be \f(CW\*(C`NULL\*(C'\fR in that
case.
.Sp
The CVs are stored directly, not via RVs. Each CV will be an anonymous real
function.
.IP \(bu 4
\&\f(CW\*(C`xhv_class_fields\*(C'\fR will point to a \f(CW\*(C`PADNAMELIST\*(C'\fR containing \f(CW\*(C`PADNAME\*(C'\fRs,
each being one defined field of the class. They are stored in order of
declaration. Note however, that the index into this array will not necessarily
be equal to the \f(CW\*(C`fieldix\*(C'\fR of each field, because in the case of a subclass,
the array will begin at zero but the index of the first field in it will be
non-zero if its parent class contains any fields at all.
.Sp
For more information on how individual fields are represented, see "Fields".
.IP \(bu 4
\&\f(CW\*(C`xhv_class_next_fieldix\*(C'\fR gives the field index that will be assigned to the
next field to be added to the class. It is only useful at compile-time.
.IP \(bu 4
\&\f(CW\*(C`xhv_class_param_map\*(C'\fR may point to an HV which maps field \f(CW\*(C`:param\*(C'\fR attribute
names to the field index of the field with that name. This mapping is copied
from parent classes; each class will contain the sum total of all its parents
in addition to its own.
.SS Fields
.IX Subsection "Fields"
A field is still fundamentally a lexical variable declared in a scope, and
exists in the \f(CW\*(C`PADNAMELIST\*(C'\fR of its corresponding CV. Methods and other
method-like CVs can still capture them exactly as they can with regular
lexicals. A field is distinguished from other kinds of pad entry in that the
\&\f(CWPadnameIsFIELD()\fR macro will return true on it.
.PP
Extra information relating to it being a field is stored in an additional
structure accessible via the \f(CWPadnameFIELDINFO()\fR macro on the padname. This
structure has the following fields:
.PP
.Vb 6
\& PADOFFSET fieldix;
\& HV *fieldstash;
\& OP *defop;
\& SV *paramname;
\& bool def_if_undef;
\& bool def_if_false;
.Ve
.IP \(bu 4
\&\f(CW\*(C`fieldix\*(C'\fR stores the "field index" of the field; that is, the index into the
instance field array where this field's value will be stored. Note that the
first index in the array is not specially reserved. The first field in a class
will start from field index 0.
.IP \(bu 4
\&\f(CW\*(C`fieldstash\*(C'\fR stores a pointer to the stash of the class that defined this
field. This is necessary in case there are multiple classes defined within the
same scope; it is used to disambiguate the fields of each.
.Sp
.Vb 4
\& {
\& class C1; field $x;
\& class C2; field $x;
\& }
.Ve
.IP \(bu 4
\&\f(CW\*(C`defop\*(C'\fR may store a pointer to a defaulting expression optree for this field.
Defaulting expressions are optional; this field may be \f(CW\*(C`NULL\*(C'\fR.
.IP \(bu 4
\&\f(CW\*(C`paramname\*(C'\fR may point to a regular string SV containing the \f(CW\*(C`:param\*(C'\fR name
attribute given to the field. If none, it will be \f(CW\*(C`NULL\*(C'\fR.
.IP \(bu 4
One of \f(CW\*(C`def_if_undef\*(C'\fR and \f(CW\*(C`def_if_false\*(C'\fR will be true if the defaulting
expression was set using the \f(CW\*(C`//=\*(C'\fR or \f(CW\*(C`||=\*(C'\fR operators respectively.
.SS Methods
.IX Subsection "Methods"
A method is still fundamentally a CV, and has the same basic representation as
one. It has an optree and a pad, and is stored via a GV in the stash of its
containing package. It is distinguished from a non-method CV by the fact that
the \f(CWCvIsMETHOD()\fR macro will return true on it.
.PP
(Note: This macro should not be confused with the one that was previously
called \f(CWCvMETHOD()\fR. That one does not relate to the class system, and was
renamed to \f(CWCvNOWARN_AMBIGUOUS()\fR to avoid this confusion.)
.PP
There is currently no extra information that needs to be stored about a method
CV, so the structure does not add any new fields.
.SS Instances
.IX Subsection "Instances"
Object instances are represented by an entirely new SV type, whose base type
is \f(CW\*(C`SVt_PVOBJ\*(C'\fR. This should still be blessed into its class stash and wrapped
in an RV in the usual manner for classical object.
.PP
As these are their own unique container type, distinct from hashes or arrays,
the core \f(CW\*(C`builtin::reftype\*(C'\fR function returns a new value when asked about
these. That value is \f(CW"OBJECT"\fR.
.PP
Internally, such an object is an array of SV pointers whose size is fixed at
creation time (because the number of fields in a class is known after
compilation). An object instance stores the max field index within it (for
basic error-checking on access), and a fixed-size array of SV pointers storing
the individual field values.
.PP
Fields of array and hash type directly store AV or HV pointers into the array;
they are not stored via an intervening RV.
.SH API
.IX Header "API"
The data structures described above are supported by the following API
functions.
.SS "Class Manipulation"
.IX Subsection "Class Manipulation"
\fIclass_setup_stash\fR
.IX Subsection "class_setup_stash"
.PP
.Vb 1
\& void class_setup_stash(HV *stash);
.Ve
.PP
Called by the parser on encountering the \f(CW\*(C`class\*(C'\fR keyword. It upgrades the
stash into being a class and prepares it for receiving class-specific items
like methods and fields.
.PP
\fIclass_seal_stash\fR
.IX Subsection "class_seal_stash"
.PP
.Vb 1
\& void class_seal_stash(HV *stash);
.Ve
.PP
Called by the parser at the end of a \f(CW\*(C`class\*(C'\fR block, or for unit classes its
containing scope. This function performs various finalisation activities that
are required before instances of the class can be constructed, but could not
have been done until all the information about the members of the class is
known.
.PP
Any additions to or modifications of the class under compilation must be
performed between these two function calls. Classes cannot be modified once
they have been sealed.
.PP
\fIclass_add_field\fR
.IX Subsection "class_add_field"
.PP
.Vb 1
\& void class_add_field(HV *stash, PADNAME *pn);
.Ve
.PP
Called by \fIpad.c\fR as part of defining a new field name in the current pad.
Note that this function does \fInot\fR create the padname; that must already be
done by \fIpad.c\fR. This API function simply informs the class that the new
field name has been created and is now available for it.
.PP
\fIclass_add_ADJUST\fR
.IX Subsection "class_add_ADJUST"
.PP
.Vb 1
\& void class_add_ADJUST(HV *stash, CV *cv);
.Ve
.PP
Called by the parser once it has parsed and constructed a CV for a new
\&\f(CW\*(C`ADJUST\*(C'\fR block. This gets added to the list stored by the class.
.SS "Field Manipulation"
.IX Subsection "Field Manipulation"
\fIclass_prepare_initfield_parse\fR
.IX Subsection "class_prepare_initfield_parse"
.PP
.Vb 1
\& void class_prepare_initfield_parse();
.Ve
.PP
Called by the parser just before parsing an initializing expression for a
field variable. This makes use of a suspended compcv to combine all the field
initializing expressions into the same CV.
.PP
\fIclass_set_field_defop\fR
.IX Subsection "class_set_field_defop"
.PP
.Vb 1
\& void class_set_field_defop(PADNAME *pn, OPCODE defmode, OP *defop);
.Ve
.PP
Called by the parser after it has parsed an initializing expression for the
field. Sets the defaulting expression and mode of application. \f(CW\*(C`defmode\*(C'\fR
should either be zero, or one of \f(CW\*(C`OP_ORASSIGN\*(C'\fR or \f(CW\*(C`OP_DORASSIGN\*(C'\fR depending
on the defaulting mode.
.PP
\fIpadadd_FIELD\fR
.IX Subsection "padadd_FIELD"
.PP
.Vb 1
\& #define padadd_FIELD
.Ve
.PP
This flag constant tells the \f(CW\*(C`pad_add_name_*\*(C'\fR family of functions that the
new name should be added as a field. There is no need to call
\&\f(CWclass_add_field()\fR; this will be done automatically.
.SS "Method Manipulation"
.IX Subsection "Method Manipulation"
\fIclass_prepare_method_parse\fR
.IX Subsection "class_prepare_method_parse"
.PP
.Vb 1
\& void class_prepare_method_parse(CV *cv);
.Ve
.PP
Called by the parser after \f(CWstart_subparse()\fR but immediately before doing
anything else. This prepares the \f(CW\*(C`PL_compcv\*(C'\fR for parsing a method; arranging
for the \f(CW\*(C`CvIsMETHOD\*(C'\fR test to be true, adding the \f(CW$self\fR lexical, and any
other activities that may be required.
.PP
\fIclass_wrap_method_body\fR
.IX Subsection "class_wrap_method_body"
.PP
.Vb 1
\& OP *class_wrap_method_body(OP *o);
.Ve
.PP
Called by the parser at the end of parsing a method body into an optree but
just before wrapping it in the eventual CV. This function inserts extra ops
into the optree to make the method work correctly.
.SS "Object Instances"
.IX Subsection "Object Instances"
\fISVt_PVOBJ\fR
.IX Subsection "SVt_PVOBJ"
.PP
.Vb 1
\& #define SVt_PVOBJ
.Ve
.PP
An SV type constant used for comparison with the \f(CWSvTYPE()\fR macro.
.PP
\fIObjectMAXFIELD\fR
.IX Subsection "ObjectMAXFIELD"
.PP
.Vb 1
\& SSize_t ObjectMAXFIELD(sv);
.Ve
.PP
A function-like macro that obtains the maximum valid field index that can be
accessed from the \f(CW\*(C`ObjectFIELDS\*(C'\fR array.
.PP
\fIObjectFIELDS\fR
.IX Subsection "ObjectFIELDS"
.PP
.Vb 1
\& SV **ObjectFIELDS(sv);
.Ve
.PP
A function-like macro that obtains the fields array directly out of an object
instance. Fields can be accessed by their field index, from 0 up to the maximum
valid index given by \f(CW\*(C`ObjectMAXFIELD\*(C'\fR.
.SH OPCODES
.IX Header "OPCODES"
.SS OP_METHSTART
.IX Subsection "OP_METHSTART"
.Vb 1
\& newUNOP_AUX(OP_METHSTART, ...);
.Ve
.PP
An \f(CW\*(C`OP_METHSTART\*(C'\fR is an \f(CW\*(C`UNOP_AUX\*(C'\fR which must be present at the start of a
method CV in order to make it work properly. This is inserted by
\&\f(CWclass_wrap_method_body()\fR, and even appears before any optree fragment
associated with signature argument checking or extraction.
.PP
This op is responsible for shifting the value of \f(CW$self\fR out of the arguments
list and binding any field variables that the method requires access to into
the pad. The AUX vector will contain details of the field/pad index pairings
required.
.PP
This op also performs sanity checking on the invocant value. It checks that it
is definitely an object reference of a compatible class type. If not, an
exception is thrown.
.PP
If the \f(CW\*(C`op_private\*(C'\fR field includes the \f(CW\*(C`OPpINITFIELDS\*(C'\fR flag, this indicates
that the op begins the special \f(CW\*(C`xhv_class_initfields_cv\*(C'\fR CV. In this case it
should additionally take the second value from the arguments list, which
should be a plain HV pointer (\fIdirectly\fR, not via RV). and bind it to the
second pad slot, where the generated optree will expect to find it.
.SS OP_INITFIELD
.IX Subsection "OP_INITFIELD"
An \f(CW\*(C`OP_INITFIELD\*(C'\fR is only invoked as part of the \f(CW\*(C`xhv_class_initfields_cv\*(C'\fR
CV during the construction phase of an instance. This is the time that the
individual SVs that make up the mutable fields of the instance (including AVs
and HVs) are actually assigned into the \f(CW\*(C`ObjectFIELDS\*(C'\fR array. The
\&\f(CW\*(C`OPpINITFIELD_AV\*(C'\fR and \f(CW\*(C`OPpINITFIELD_HV\*(C'\fR private flags indicate whether it is
creating an AV or HV; if neither is set then an SV is created.
.PP
If the op has the \f(CW\*(C`OPf_STACKED\*(C'\fR flag it expects to find an initializing value
on the stack. For SVs this is the topmost SV on the data stack. For AVs and
HVs it expects a marked list.
.SH "COMPILE-TIME BEHAVIOUR"
.IX Header "COMPILE-TIME BEHAVIOUR"
.ie n .SS """ADJUST"" Phasers"
.el .SS "\f(CWADJUST\fP Phasers"
.IX Subsection "ADJUST Phasers"
During compiletime, parsing of an \f(CW\*(C`ADJUST\*(C'\fR phaser is handled in a
fundamentally different way to the existing perl phasers (\f(CW\*(C`BEGIN\*(C'\fR, etc...)
.PP
Rather than taking the usual route, the tokenizer recognises that the
\&\f(CW\*(C`ADJUST\*(C'\fR keyword introduces a phaser block. The parser then parses the body
of this block similarly to how it would parse an (anonymous) method body,
creating a CV that has no name GV. This is then inserted directly into the
class information by calling \f(CW\*(C`class_add_ADJUST\*(C'\fR, entirely bypassing the
symbol table.
.SS Attributes
.IX Subsection "Attributes"
During compilation, attributes of both classes and fields are handled in a
different way to existing perl attributes on subroutines and lexical
variables.
.PP
The parser still forms an \f(CW\*(C`OP_LIST\*(C'\fR optree of \f(CW\*(C`OP_CONST\*(C'\fR nodes, but these
are passed to the \f(CW\*(C`class_apply_attributes\*(C'\fR or \f(CW\*(C`class_apply_field_attributes\*(C'\fR
functions. Rather than using a class lookup for a method in the class being
parsed, a fixed internal list of known attributes is used to find functions to
apply the attribute to the class or field. In future this may support
user-supplied extension attribute, though at present it only recognises ones
defined by the core itself.
.SS "Field Initializing Expressions"
.IX Subsection "Field Initializing Expressions"
During compilation, the parser makes use of a suspended compcv when parsing
the defaulting expression for a field. All the expressions for all the fields
in the class share the same suspended compcv, which is then compiled up into
the same internal CV called by the constructor to initialize all the fields
provided by that class.
.SH "RUNTIME BEHAVIOUR"
.IX Header "RUNTIME BEHAVIOUR"
.SS Constructor
.IX Subsection "Constructor"
The generated constructor for a class itself is an XSUB which performs three
tasks in order: it creates the instance SV itself, invokes the field
initializers, then invokes the ADJUST block CVs. The constructor for any class
is always the same basic shape, regardless of whether the class has a
superclass or not.
.PP
The field initializers are collected into a generated optree-based CV called
the field initializer CV. This is the CV which contains all the optree
fragments for the field initializing expressions. When invoked, the field
initializer CV might make a chained call to the superclass initializer if one
exists, before invoking all of the individual field initialization ops. The
field initializer CV is invoked with two items on the stack; being the
instance SV and a direct HV containing the constructor parameters. Note
carefully: this HV is passed \fIdirectly\fR, not via an RV reference. This is
permitted because both the caller and the callee are directly generated code
and not arbitrary pure-perl subroutines.
.PP
The ADJUST block CVs are all collected into a single flat list, merging all of
the ones defined by the superclass as well. They are all invoked in order,
after the field initializer CV.
.ie n .SS "$self Access During Methods"
.el .SS "\f(CW$self\fP Access During Methods"
.IX Subsection "$self Access During Methods"
When \f(CWclass_prepare_method_parse()\fR is called, it arranges that the pad of
the new CV body will begin with a lexical called \f(CW$self\fR. Because the pad
should be freshly-created at this point, this will have the pad index of 1.
The function checks this and aborts if that is not true.
.PP
Because of this fact, code within the body of a method or method-like CV can
reliably use pad index 1 to obtain the invocant reference. The \f(CW\*(C`OP_INITFIELD\*(C'\fR
opcode also relies on this fact.
.PP
In similar fashion, during the \f(CW\*(C`xhv_class_initfields_cv\*(C'\fR the next pad slot is
relied on to store the constructor parameters HV, at pad index 2.
.SH AUTHORS
.IX Header "AUTHORS"
Paul Evans
|