\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}
\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}
const char *name; \\
const char *nick; \\
size_t initsz; \\
+ size_t align; \\
void *(*imprint)(void *@<p>); \\
- void *(*init)(void *@<p>); \\
size_t n_supers; \\
const SodClass *const *supers; \\
size_t n_cpl; \\
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
\item[initsz] The size in bytes required to store an instance of the class.
+ \item[align] A sufficient alignment for the class's instance storage.
+
\item[imprint] A pointer to a function: given a pointer @<p> to at least
@<initsz> bytes of appropriately aligned memory, `imprint' this memory it
so that it becomes a minimally functional instance of the class: all of
the vtable and class pointers are properly initialized, but the slots are
left untouched. The function returns its argument @<p>.
- \item[init] A pointer to a function: given a pointer @<p> to an imprinted
- instance, initialize all of its slots for which initializers are defined.
- Other slots are left untouched. The function returns its argument @<p>.
-
\item[n_supers] The number of direct superclasses. (This is zero exactly
in the case of @|SodObject|.)