X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/blobdiff_plain/e0808c472145fc81e52898bc9ac289e10c4f4f41..faf3eb58d676c3abbef538784e26ca398d339caf:/lib/sod-structs.3 diff --git a/lib/sod-structs.3 b/lib/sod-structs.3 index da12cc5..672fe59 100644 --- a/lib/sod-structs.3 +++ b/lib/sod-structs.3 @@ -10,18 +10,19 @@ .\" This file is part of the Sensible Object Design, an object system for C. .\" .\" SOD is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2 of the License, or -.\" (at your option) any later version. +.\" it under the terms of the GNU Library General Public License as +.\" published by the Free Software Foundation; either version 2 of the +.\" License, or (at your option) any later version. .\" .\" SOD is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. +.\" GNU Library General Public License for more details. .\" -.\" You should have received a copy of the GNU General Public License -.\" along with SOD; if not, write to the Free Software Foundation, -.\" Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +.\" You should have received a copy of the GNU Library General Public +.\" License along with SOD; if not, write to the Free +.\" Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +.\" MA 02111-1307, USA. . .\" Highlight using terminal escapes, rather than overstriking. .\"\X'tty: sgr 1' @@ -68,6 +69,11 @@ struct sod_vtable { struct SodObject__vt_obj { \h'2n'const SodClass *_class; \h'2n'size_t _base; +\h'2n'struct SodObject__vtmsgs_obj { +\h'4n'void (*init)(SodObject *\fIme\fB, ...); +\h'4n'void (*init__v)(SodObject *\fIme\fB, va_list); +\h'4n'int (*teardown)(SodObject *\fIme\fB); +\h'2n'} obj; }; struct SodObject__ilayout { @@ -84,9 +90,14 @@ extern const struct SodClass__ilayout SodObject__classobj; struct SodClass__vt_obj { \h'2n'const SodClass *_class; \h'2n'size_t _base; +\h'2n'struct SodClass__vtmsgs_obj { +\h'4n'void (*init)(SodClass *\fIme\fB, ...); +\h'4n'void (*init__v)(SodClass *\fIme\fB, va_list); +\h'4n'int (*teardown)(SodClass *\fIme\fB); +\h'2n'} obj; }; -struct SodObject__ilayout { +struct SodClass__ilayout { \h'2n'union { \h'4n'struct SodClass__ichain_obj { \h'6n'const struct SodClass__vt_obj *_vt; @@ -94,8 +105,8 @@ struct SodObject__ilayout { \h'8n'const char *name; \h'8n'const char *nick; \h'8n'size_t initsz; +\h'8n'size_t align; \h'8n'void *(*imprint)(void *\fIp\fB); -\h'8n'void *(*init)(void *\fIp\fB); \h'8n'size_t n_supers; \h'8n'const SodClass *const *supers; \h'8n'size_t n_cpl; @@ -211,7 +222,7 @@ and not really to be recommended. .SS The SodObject class The .B SodObject -class defines no slots or messages. +class defines no slots. Because .B SodObject has no direct superclasses, @@ -219,8 +230,7 @@ there is only one chain, and no inherited slots or messages, so the single chain contains only a vtable pointer. .PP -Since there are no messages, -and +Since .B SodClass also has only one chain, the vtable contains only the standard class pointer and offset-to-base @@ -231,6 +241,79 @@ In an actual instance of the class pointer contains the address of .B SodObject__class and the offset is zero. +.PP +The +.B init +message is used to initialize a newly allocated instance. +.PP +This message uses a custom method combination +which works like the standard method combination +except that default behaviour +specific to the receiver's direct class +is invoked if no primary or around method overrides. +This default behaviour may be invoked multiple times +if some method calls on its +.B next_method +function more than once. +.PP +This default behaviour is to initialize the instance's slots +using the defined slot initializers, +and execute the initialization fragments. +Each slot is initialized +using the most specific applicable initializer, +if any. +Slots without an initializer +are left uninitialized. +.PP +Slots are initialized and initialization fragments executed together, +a superclass at a time: +first, the superclass's slots are initialized (if any); +then the superclass's initialization fragments (if any) are executed, +starting with the least specific superclass first. +Slots and initialization fragments defined by the same class +are processed in the order in which they appear in the class definition. +.PP +There are no standard keyword arguments; +methods on subclasses are free to +introduce their own in the usual way. +.PP +It is usual to provide complex initialization behaviour as +.B after +methods. +This ensures that slots have been initialized as necessary +before the method executes. +.PP +The +.B teardown +message is used to tear down an instance which is no longer required. +.PP +The message returns an integer flag. +A zero value means that the instance is safe to deallocate. +A nonzero value means that the instance should not be deallocated, +and that it is safe for the caller to simply forget about it. +This simple protocol may be used, for example, +to implement a reference-counting system. +.PP +This message uses a custom method combination +which works like the standard method combination +except that default behaviour is invoked if +no primary or around method overrides. +This default behaviour is to execute +each superclass's teardown fragments, +most specific first, +and then return zero to indicate +that the object is ready for deallocation. +Teardown fragments defined by the same class +are processed in the order in which they appear +in the class definition. +.PP +It is usual to provide complex teardown behaviour as +.B before +methods. +Logic to decide whether to allow deallocation +is usually implemented as +.B around +methods. . .SS The SodClass class The @@ -252,6 +335,9 @@ A pointer to the class's nickname. .B size_t initsz; The size in bytes required to store an instance of the class. .TP +.B size_t align; +A sufficient alignment for the class's instance storage. +.TP .BI "void *(*imprint)(void *" p ); A pointer to a function: given a pointer @@ -266,20 +352,6 @@ but the slots are left untouched. The function returns its argument .IR p . .TP -.BI "void *(*init)(void *" p ); -A pointer to a function: -given a pointer -.I p -to at least -.I initsz -bytes of appropriately aligned memory, -initialize an instance of the class in it: -all of the vtable and class pointers are initialized, -as are slots for which initializers are defined. -Other slots are left untouched. -The function returns its argument -.IR p . -.TP .B size_t n_supers; The number of direct superclasses. (This is zero exactly in the case of @@ -470,7 +542,7 @@ struct \fIC\fB__ilayout { \h'6n'} \fIc\fB; \h'4n'} \fIc\fB; \h'4n'\fR...\fB -\h'4n'struct \fIH\fB__ichain_\fIh\fB \fIh\fB; +\h'4n'struct \fIA\fB__ichain_\fIh\fB \fIa\fB; \h'2n'} \fIh\fB; \h'2n'union \fIB\fB__ichainu_\fIi\fB \fIi\fB; \h'2n'\fR...\fB @@ -554,13 +626,9 @@ for each of superclasses .IR A in the same chain in some (unimportant) order. -A `pointer to -.IR C ' -is always assumed -(and, indeed, defined in C's type system) -to be a pointer to the -.B struct -.IB C __ichain_ h \fR. +The (somewhat obtuse) purpose of this union is to +engage the `common initial sequence' rule of +C99 (clause 6.5.2.3). .PP The .B ichain @@ -592,6 +660,14 @@ then the last member is .IB C __islots .IB c ; .PP +A `pointer to +.IR C ' +is always assumed +(and, indeed, defined in C's type system) +to be a pointer to the +.B struct +.IB C __ichain_ h \fR. +.PP Finally, the .B islots structure simply contains one member for each slot defined by @@ -663,6 +739,12 @@ extern const union \fIC\fB__vtu_\fIh\fB \fIC\fB__vtable_\fIh\fB; .ft P .fi .PP +In the following, +let +.I M +be the metaclass of +.IR C . +.PP The outer layer is a .B union .IB C __vtu_ h @@ -892,6 +974,27 @@ defined as .IB an , .B ...); .PP +or a standard message which takes keyword arguments, +defined as +.IP +.I tr +.IB m ( \c +.I t1 +.IB a1 , +.RB ... , +.I tn +.IB an ?\& +.IR tn +1 +.IR kn +1 +.RB [ = +.IR dn +1] \c +.B , +.I tm +.I km +.RB [ = +.IR dm ] \c +); +.PP two entry points are defined: the usual `main' entry point which accepts a variable number of @@ -899,7 +1002,8 @@ arguments, and a `valist' entry point which accepts an argument of type .B va_list -in place of the variable portion of the argument list. +in place of the variable portion of the argument list +or keywords. .IP .I tr .BI (* m )( \c @@ -949,6 +1053,7 @@ somewhat less ugly. If .I m takes a variable number of arguments, +or keyword arguments, the macro is more complicated and is only available in compilers advertising C99 support, but the effect is the same.