X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/54fa3df9560fe739b5fe20ca561749092cef0fd5..a42893dda5f4dd2b89fbfe4e497da261159225ca:/doc/structures.tex diff --git a/doc/structures.tex b/doc/structures.tex index c8d9daf..42739ef 100644 --- a/doc/structures.tex +++ b/doc/structures.tex @@ -105,7 +105,12 @@ recommended. \begin{nprog} struct SodObject__vt_obj \{ \\ \ind const SodClass *_class; \\ - size_t _base; \- \\ + size_t _base; \\ + struct SodObject__vtmsgs_obj \{ \\ \ind + void (*init)(SodObject *me, ...); \\ + void (*init__v)(SodObject *me, va_list); \\ + int (*teardown)(SodObject *me); \- \\ + \} obj; \- \\ \}; \end{nprog} \\ \end{tabular} @@ -115,19 +120,79 @@ recommended. \begin{describe}[SodObject]{cls} {[nick = obj, metaclass = SodClass, lisp_metaclass = sod_class] \\ - class SodObject \{ \}} + class SodObject \{ \\ \ind + void init(?); + \}} - The @|SodObject| class defines no slots or messages. Because @|SodObject| - has no direct superclasses, there is only one chain, and no inherited - slots or messages, so the single chain contains only a vtable pointer. + The @|SodObject| class defines no slots. Because @|SodObject| has no + direct superclasses, there is only one chain, and no inherited slots or + messages, so the single chain contains only a vtable pointer. - Since there are no messages, and @|SodClass| also has only one chain, the - vtable contains only the standard class pointer and offset-to-base members. - In a direct instance of @|SodObject| (why would you want one?) the class - pointer contains the address of @|SodObject__class| and the offset is zero. + Since @|SodClass| also has only one chain, the vtable contains only the + standard class pointer and offset-to-base members. In a direct instance of + @|SodObject| (why would you want one?) the class pointer contains the + address of @|SodObject__class| and the offset is zero. The instance and vtable layout of @|SodObject| is shown in \xref{fig:structures.root.sodobject}. + + The following messages are defined. + + \begin{describe}[obj.init]{msg}{void init(?);} + Initialize a newly allocated instance. + + 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 @|next_method| function more than once. + + 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. + + 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. + + There are no standard keyword arguments; methods on subclasses are free + to introduce their own in the usual way. + + It is usual to provide complex initialization behaviour as @|after| + methods. This ensures that slots have been initialized as necessary + before the method executes. + + For more details on instance construction, see + \xref{sec:concepts.lifecycle.birth}. + \end{describe} + + \begin{describe}[obj.teardown]{msg}{int teardown();} + Teardown an instance which is no longer required. + + 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. + + 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. + + It is usual to provide complex teardown behaviour as @|before| methods. + Logic to decide whether to allow deallocation is usually implemented as + @|around| methods. + \end{describe} \end{describe} @@ -140,7 +205,6 @@ recommended. const char *nick; \\ size_t initsz; \\ void *(*imprint)(void *@

); \\ - void *(*init)(void *@

); \\ size_t n_supers; \\ const SodClass *const *supers; \\ size_t n_cpl; \\ @@ -154,9 +218,9 @@ recommended. size_t islotsz; \- \\ \}} - The @|SodClass| class defines no messages, but there are a number of slots. - Its only direct superclass is @|SodObject| and so (like its superclass) its - vtable is trivial. + The @|SodClass| class defines no additional messages , but there are a + number of slots. Its only direct superclass is @|SodObject| and so (like + its superclass) its vtable is simple. The slots defined are as follows. \begin{description} \let\makelabel\code @@ -173,10 +237,6 @@ recommended. the vtable and class pointers are properly initialized, but the slots are left untouched. The function returns its argument @

. - \item[init] A pointer to a function: given a pointer @

to an imprinted - instance, initialize all of its slots for which initializers are defined. - Other slots are left untouched. The function returns its argument @

. - \item[n_supers] The number of direct superclasses. (This is zero exactly in the case of @|SodObject|.)