X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/f9bc613cce1e164f09addcb7013510d5fabc801b..1edb774eed8bea3f6dbde5b02db6ecd209394cf8:/doc/structures.tex diff --git a/doc/structures.tex b/doc/structures.tex index 7cc825a..01e1ecd 100644 --- a/doc/structures.tex +++ b/doc/structures.tex @@ -30,8 +30,14 @@ classes and associated metadata. Note that Sod's object system is very flexible and it's possible for an extension to define a new root class which works very differently from the standard @|SodObject| described here. -The concrete types described in \xref{sec:structures.common} and -\ref{sec:structures.root} are declared by the header file @||. +The concrete types described in +\xref[\instead{sections}]{sec:structures.common} and +\ref{sec:structures.root} are declared by the header file +@||.\footnote{% + This isn't completely true. The @|SodObject| and @|SodClass| structures + are defined in a header called @||, which is generated by + the Sod translator; but @|| includes @||, so you + can forget about this detail.} % The definitions described in \xref{sec:structures.layout} are defined in the header file generated by the containing module. @@ -45,7 +51,7 @@ structure. Instance chains contain slots and vtable pointers, as described below. All instances have the basic structure of a @|struct sod_instance|. -\begin{describe}[struct sod_instance]{type} +\begin{describe}{ty}[struct sod_instance] {struct sod_instance \{ \\ \ind const struct sod_vtable *_vt; \-\\ \};} @@ -57,7 +63,7 @@ instances have the basic structure of a @|struct sod_instance|. \end{description} \end{describe} -\begin{describe}[struct sod_vtable]{type} +\begin{describe}{ty}[struct sod_vtable] {struct sod_vtable \{ \\ \ind const SodClass *_class; \\ size_t _base; \-\\ @@ -87,6 +93,12 @@ metaclass, and @|SodClass| is a subclass of @|SodObject|. Extensions can define additional root classes, but this is tricky, and not really to be recommended. +The class definitions shown in the synopses are intended to be informative, +but are fictional and can't really work: these classes are really defined by +Lisp code in the Sod translator, in order to deal with the circularities +involved at the top of the class/metaclass graph (see +\xref{sec:concepts.metaclasses.runtime}). + \subsection{The SodObject class} \label{sec:structures.root.sodobject} @@ -118,11 +130,11 @@ recommended. \label{fig:structures.root.sodobject} \end{figure} -\begin{describe}[SodObject]{cls} +\begin{describe}{cls}[SodObject] {[nick = obj, metaclass = SodClass, lisp_metaclass = sod_class] \\ class SodObject \{ \\ \ind - void init(?); + void init(?); \-\\ \}} The @|SodObject| class defines no slots. Because @|SodObject| has no @@ -139,7 +151,7 @@ recommended. The following messages are defined. - \begin{describe}[obj.init]{msg}{void init(?);} + \begin{describe}{msg}[obj.init]{void init(?);} Initialize a newly allocated instance. This message uses a custom method combination which works like the @@ -171,7 +183,7 @@ recommended. \xref{sec:concepts.lifecycle.birth}. \end{describe} - \begin{describe}[obj.teardown]{msg}{int teardown();} + \begin{describe}{msg}[obj.teardown]{int teardown();} Teardown an instance which is no longer required. The message returns an integer flag. A zero value means that the @@ -199,9 +211,9 @@ recommended. \subsection{The SodClass class} \label{sec:structures.root.sodclass} -\begin{describe}[SodClass]{cls} +\begin{describe}{cls}[SodClass] {[nick = cls, link = SodObject] \\ - class SodClass : SodObject \{ \\ \ind + class SodClass: SodObject \{ \\ \ind const char *name; \\ const char *nick; \\ size_t initsz; \\ @@ -289,7 +301,7 @@ recommended. \end{description} \end{describe} -\begin{describe}[struct sod_chain]{type} +\begin{describe}{ty}[struct sod_chain] {struct sod_chain \{ \\ \ind size_t n_classes; \\ const SodClass *const *classes; \\ @@ -363,7 +375,7 @@ type @|struct $C$__ilayout|. @_n @_n; \-\\ \} $c$; \-\\ \} $c$; \\ - struct $H$__ichain_$h$ $h$; \\ + struct $A$__ichain_$h$ $a$; \\ \quad$\vdots$ \-\\ \} $h$; \\ union $B$__ichainu_$i$ $i$; \\ @@ -410,7 +422,7 @@ and this is followed by corresponding members \end{prog} for each of $C$'s superclasses $A$ in the same chain in some (unimportant) order. The (somewhat obtuse) purpose of this union is to engage the `common -initial sequence' rule of \cite[6.5.2.3]{FIXME:C99}. +initial sequence' rule of \cite[6.5.2.3]{iso-1990:c,ansi-1999:c}. \subsubsection{The ichain structure} The @|ichain| structure contains (in order), a pointer @@ -444,15 +456,15 @@ vtable pointer In general, the vtables for the different chains will have \emph{different} structures. -The instance layout split neatly into disjoint chains. This is necessary +The instance layout splits neatly into disjoint chains. This is necessary because each @|ichain| must have as a prefix the @|ichain| for each superclass in the same chain, and each slot must be stored in exactly one place. The layout of vtables doesn't have this second requirement: it doesn't matter that there are multiple method entry pointers for the same effective method as long as they all work correctly. Indeed, it's essential -that they do, because each chain's method entry function will need to apply a -different offset to the receiver pointer before invoking the effective -method. +that there are multiple entry pointers, because each chain's method entry +function will need to apply a different offset to the receiver pointer before +invoking the effective method. A vtable for a class $C$ with chain head $H$ has the following general structure. @@ -489,9 +501,9 @@ first. This is mostly an irrelevant detail, whose purpose is to defend against malicious compilers: pointers are always to one of the inner @|vt| -structures. It's important only because it's the outer @|vtu| union which is -exported by name. Specifically, for each chain of $C$'s superclasses there is -an external object +structures. It's important only because it's the outer @|vtu| union which is +exported by name. Specifically, for each chain of $C$'s superclasses there +is an external object \begin{prog} const union $A$__vtu_$i$ $C$__vtable_$i$; \end{prog} @@ -530,14 +542,14 @@ traversal. \item Let $N$ be the metaclass of $A$. Examine the superclass chains of $N$ in order of decreasing specificity of their most-specific classes. Let $J$ - be the chain head of such a chain, and let $Q$ be the most specific - superclass of $M$ in the same chain as $J$. Then, if there is currently no - class pointer of type $Q$, then add a member + be the chain head of such a chain. If there is currently no class pointer + for the chain headed by $J$, then add a member \begin{prog} const $Q$ *_cls_$j$; \end{prog} to the vtable pointing to the appropriate @|islots| structure within $M$'s - class object. + class object, where $Q$ is the most specific superclass of $M$ in the same + chain as $J$. \item Examine the superclass chains of $A$ in order of decreasing specificity of their most-specific classes. Let $I$ be the chain head of such a chain. @@ -589,7 +601,7 @@ or a standard message which takes keyword arguments, defined as @_n @_n? \+\\ @_{n+1} @_{n+1} @[= @_{n+1}@], $\ldots$, - @_m @_m @[= @_m@]); + @_{n'} @_{n'} @[= @_{n'}@]); \end{prog} two entry points are defined: the usual `main' entry point which accepts a variable number of arguments, and a `valist' entry point which accepts an @@ -637,13 +649,22 @@ defined for the sake of completeness. Finally, the class object is defined as \begin{prog} extern const struct $R$__ilayout $C$__classobj; \\ - \#define $C$__class (\&$C$__classobj.$j$.$r$) + \#define $C$__class (\&$C$__classobj.$j$.$r$) \\ + \#define $C$__cls_$k$ (\&$C$__classobj.$k$.$n$) \\ + \quad$\vdots$ \end{prog} The exported symbol @|$C$__classobj| contains the entire class instance. This is usually rather unwieldy. The macro @|$C$__class| is usable as a pointer of type @|const $R$~*|, where $R$ is the root metaclass of $C$, i.e., the metaclass of the least specific superclass of $C$; usually this is -@|const SodClass~*|. +@|const SodClass~*|. For each chain of $C$'s metaclass, a macro +@|$C$__cls_$k$| is defined, usable as a pointer of type @|const $N$~*|, where +$K$ and $N$ are the chain's head and tail classes (i.e., the least- and +most-specific classes in the chain) respectively; this macro is +\emph{omitted} if $N = R$, i.e., in the common case where $C$'s metaclass is +precisely the root metaclass, since the existing @|$C$__class| macro is +already sufficient. + %%%----- That's all, folks --------------------------------------------------