diff options
Diffstat (limited to 'upstream/debian-unstable/man1/perlclassguts.1')
-rw-r--r-- | upstream/debian-unstable/man1/perlclassguts.1 | 466 |
1 files changed, 466 insertions, 0 deletions
diff --git a/upstream/debian-unstable/man1/perlclassguts.1 b/upstream/debian-unstable/man1/perlclassguts.1 new file mode 100644 index 00000000..863617d8 --- /dev/null +++ b/upstream/debian-unstable/man1/perlclassguts.1 @@ -0,0 +1,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-01-12 "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 |