X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/62f9852b653ff96c776418da9492ea644e4a23cf..e5573634ce3668f2a4eac74be125262d28a5cb8a:/doc/structures.tex?ds=sidebyside
diff --git a/doc/structures.tex b/doc/structures.tex
index 029f34c..9c0451e 100644
--- a/doc/structures.tex
+++ b/doc/structures.tex
@@ -43,23 +43,37 @@ As described below, a pointer to an instance actually points to an
structure.
Instance chains contain slots and vtable pointers, as described below. All
-instances have the basic structure of a @|struct sod_instance|, which has the
-following member.
-\begin{description} \let\makelabel\code
-\item[const struct sod_vtable *_vt] A pointer to a \emph{vtable}, which has
- the basic structure of a @|struct sod_vtable|, described below.
-\end{description}
-
-A vtable contains static metadata needed for efficient conversions and
-message dispatch, and pointers to the instance's class. Each chain points to
-a different vtable. All vtables have the basic structure of a @|struct
-sod_vtable|, which has the following members.
-\begin{description} \let\makelabel\code
-\item[const SodClass *_class] A pointer to the instance's class object.
-\item[size_t _base] The offset of this chain structure above the start of the
- overall instance layout, in bytes. Subtracting @|_base| from the instance
- chain pointer finds the layout base address.
-\end{description}
+instances have the basic structure of a @|struct sod_instance|.
+
+\begin{describe}[struct sod_instance]{type}
+ {struct sod_instance \{ \\ \ind
+ const struct sod_vtable *_vt; \- \\
+ \};}
+
+ The basic structure of all instances. Members are as follows.
+ \begin{description} \let\makelabel\code
+ \item[_vt] A pointer to a \emph{vtable}, which has the basic structure of a
+ @|struct sod_vtable|, described below.
+ \end{description}
+\end{describe}
+
+\begin{describe}[struct sod_vtable]{type}
+ {struct sod_vtable \{ \\ \ind
+ const SodClass *_class; \\
+ size_t _base; \- \\
+ \};}
+
+ A vtable contains static metadata needed for efficient conversions and
+ message dispatch, and pointers to the instance's class. Each chain points
+ to a different vtable. All vtables have the basic structure of a @|struct
+ sod_vtable|, which has the following members.
+ \begin{description} \let\makelabel\code
+ \item[_class] A pointer to the instance's class object.
+ \item[_base] The offset of this chain structure above the start of the
+ overall instance layout, in bytes. Subtracting @|_base| from the
+ instance chain pointer finds the layout base address.
+ \end{description}
+\end{describe}
%%%--------------------------------------------------------------------------
\section{Built-in root objects} \label{sec:structures.root}
@@ -73,170 +87,182 @@ metaclass, and @|SodClass| is a subclass of @|SodObject|. Extensions can
define additional root classes, but this is tricky, and not really to be
recommended.
-\subsection{The SodObject class} \label{sec:structures.root.sodobject}
-\begin{prog}
- struct SodObject__vt_obj \{ \\ \ind
- const SodClass *_class; \\
- size_t _base; \- \\
- \};
- \\[\bigskipamount]
- struct SodObject__ilayout \{ \\ \ind
- union \{ \\ \ind
- struct SodObject__ichain_obj \{ \\ \ind
- const struct SodObject__vt_obj *_vt; \- \\
- \}; \- \\
- \} obj; \- \\
- \};
-\end{prog}
+\subsection{The SodObject class} \label{sec:structures.root.sodobject}
-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.
+\begin{figure}[tbp]
+ \begin{tabular}{p{10pt}p{10pt}}
+ \begin{nprog}
+ struct SodObject__ilayout \{ \\ \ind
+ union \{ \\ \ind
+ struct SodObject__ichain_obj \{ \\ \ind
+ const struct SodObject__vt_obj *_vt; \- \\
+ \} obj; \- \\
+ \} obj; \- \\
+ \};
+ \end{nprog}
+ &
+ \begin{nprog}
+ struct SodObject__vt_obj \{ \\ \ind
+ const SodClass *_class; \\
+ size_t _base; \- \\
+ \};
+ \end{nprog} \\
+ \end{tabular}
+ \caption{Instance and vtable layout of @|SodObject|}
+ \label{fig:structures.root.sodobject}
+\end{figure}
+
+\begin{describe}[SodObject]{cls}
+ {[nick = obj, metaclass = SodClass, lisp_metaclass = sod_class] \\
+ class SodObject \{ \}}
+
+ 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.
+
+ 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.
+
+ The instance and vtable layout of @|SodObject| is shown in
+ \xref{fig:structures.root.sodobject}.
+\end{describe}
-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.
\subsection{The SodClass class} \label{sec:structures.root.sodclass}
-\begin{prog}
- struct SodClass__vt_obj \{ \\ \ind
- const SodClass *_class; \\
- size_t _base; \- \\
- \};
- \\[\bigskipamount]
- struct SodObject__ilayout \{ \\ \ind
- union \{ \\ \ind
- struct SodClass__ichain_obj \{ \\ \ind
- const struct SodClass__vt_obj *_vt; \\
- struct SodClass__islots \{ \\ \ind
- const char *name; \\
- const char *nick; \\
- size_t initsz; \\
- void *(*imprint)(void *@
); \\
- void *(*init)(void *@
); \\
- size_t n_supers; \\
- const SodClass *const *supers; \\
- size_t n_cpl; \\
- const SodClass *const *cpl; \\
- const SodClass *link; \\
- const SodClass *head; \\
- size_t level; \\
- size_t n_chains; \\
- const struct sod_chain *chains; \\
- size_t off_islots; \\
- size_t islotsz; \- \\
- \} cls; \- \\
- \}; \\
- SodObject obj; \- \\
- \} obj; \- \\
- \};
-\end{prog}
-
-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 slots defined are as follows.
-\begin{description} \let\makelabel\code
-
-\item[const char *name] A pointer to the class's name.
-
-\item[const char *nick] A pointer to the class's nickname.
-
-\item[size_t initsz] The size in bytes required to store an instance of the
- class.
-
-\item[void *(*imprint)(void *@
)] A pointer to a function: given a pointer
- @
to at least @ 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 @.
-
-\item[void *(*init)(void *@
)] A pointer to a function: given a pointer
- @
to at least @ 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 @.
-
-\item[size_t n_supers] The number of direct superclasses. (This is zero
- exactly in the case of @|SodObject|.)
+\begin{describe}[SodClass]{cls}
+ {[nick = cls, link = SodObject] \\
+ class SodClass : SodObject \{ \\ \ind
+ const char *name; \\
+ const char *nick; \\
+ size_t initsz; \\
+ void *(*imprint)(void *@
); \\
+ void *(*init)(void *@
); \\
+ size_t n_supers; \\
+ const SodClass *const *supers; \\
+ size_t n_cpl; \\
+ const SodClass *const *cpl; \\
+ const SodClass *link; \\
+ const SodClass *head; \\
+ size_t level; \\
+ size_t n_chains; \\
+ const struct sod_chain *chains; \\
+ size_t off_islots; \\
+ 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 slots defined are as follows.
+ \begin{description} \let\makelabel\code
+
+ \item[name] A pointer to the class's name.
+
+ \item[nick] A pointer to the class's nickname.
+
+ \item[initsz] The size in bytes required to store an instance of the class.
+
+ \item[imprint] A pointer to a function: given a pointer @
to at least
+ @ 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 @.
+
+ \item[init] A pointer to a function: given a pointer @
to at least
+ @ 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 @.
+
+ \item[n_supers] The number of direct superclasses. (This is zero exactly
+ in the case of @|SodObject|.)
+
+ \item[supers] A pointer to an array of @ pointers to class
+ objects listing the class's direct superclasses, in the order in which
+ they were listed in the class definition. If @ is zero, then
+ this pointer is null.
+
+ \item[n_cpl] The number of superclasses in the class's class precedence
+ list.
+
+ \item[cpl] A pointer to an array of pointers to class objects listing all
+ of the class's superclasses, from most- to least-specific, starting with
+ the class itself, so $@|$c$@->cls.cpl[0]| = c$ for all class objects
+ $c$.
+
+ \item[link] If the class is a chain head, then this is a null pointer;
+ otherwise it points to the class's distinguished link superclass (which
+ might or might not be a direct superclass).
+
+ \item[head] A pointer to the least-specific class in this class's chain; so
+ @|$c$@->cls.head@->cls.link| is always null, and either @|$c$@->cls.link|
+ is null (in which case $@|$c$@->cls.head| = c$) or $@|$c$@->cls.head| =
+ @|$c$@->cls.link@->cls.head|$.
+
+ \item[level] The number of less specific superclasses in this class's
+ chain. If @|$c$@->cls.link| is null then @|$c$@->cls.level| is zero;
+ otherwise $@|$c$@->cls.level| = @|$c$@->cls.link@->cls.level| + 1$.
+
+ \item[n_chains] The number of chains formed by the class's superclasses.
+
+ \item[chains] A pointer to an array of @|struct sod_chain| structures (see
+ below) describing the class's superclass chains, in decreasing order of
+ specificity of their most specific classes. It is always the case that
+ $@|$c$@->cls.chains[0].classes[$c$@->cls.level]| = c$.
+
+ \item[off_islots] The offset of the class's @|islots| structure relative to
+ its containing @|ichain| structure. The class doesn't define any slots
+ if and only if this is zero. (The offset can't be zero because the
+ vtable pointer is at offset zero.)
+
+ \item[islotsz] The size required to store the class's direct slots, i.e.,
+ the size of its @|islots| structure. The class doesn't define any slots
+ if and only if this is zero.
+
+ \end{description}
+\end{describe}
+
+\begin{describe}[struct sod_chain]{type}
+ {struct sod_chain \{ \\ \ind
+ size_t n_classes; \\
+ const SodClass *const *classes; \\
+ size_t off_ichain; \\
+ const struct sod_vtable *vt; \\
+ size_t ichainsz; \- \\
+ \};}
+
+ The @|struct sod_chain| structure describes an individual chain of
+ superclasses. It has the following members.
+ \begin{description} \let\makelabel\code
+
+ \item[n_classes] The number of classes in the chain. This is always at
+ least one.
+
+ \item[classes] A pointer to an array of class pointers listing the classes
+ in the chain from least- to most-specific. So
+ $@|@[$i$]@->cls.head| = @|@[0]|$ for all $0 \le i <
+ @$, @|@[0]@->cls.link| is always null, and
+ $@|@[$i$]@->cls.link| = @|@[$i - 1$]|$ if $1 \le i <
+ @$.
-\item[const SodClass *const *supers] A pointer to an array of @
- pointers to class objects listing the class's direct superclasses, in the
- order in which they were listed in the class definition. If @ is
- zero, then this pointer is null.
+ \item[off_ichain] The size of the @|ichain| structure for this chain.
-\item[size_t n_cpl] The number of superclasses in the class's class
- precedence list.
+ \item[vt] The vtable for this chain. (It is possible, therefore, to
+ partially duplicate the behaviour of the @ function by walking
+ the chain structure.\footnote{%
+ There isn't enough information readily available to fill in the class
+ pointers correctly.} %
+ The @ function is much faster, though.)
-\item[const SodClass *const *cpl] A pointer to an array of pointers to class
- objects listing all of the class's superclasses, from most- to
- least-specific, starting with the class itself, so $c@->@|cls|.@|cpl|[0] =
- c$ for all class objects $c$.
+ \item[ichainsz] The size of the @|ichain| structure for this chain.
-\item[const SodClass *link] If the class is a chain head, then this is a null
- pointer; otherwise it points to the class's distinguished link superclass
- (which might or might not be a direct superclass).
-
-\item[const SodClass *head] A pointer to the least-specific class in this
- class's chain; so $c@->@|cls|.@|head|@->@|cls|.@|link|$ is always null, and either
- $c@->@|cls|.@|link|$ is null (in which case $c@->@|cls|.@|head| = c$) or
- $c@->@|cls|.@|head| = c@->@|cls|.@|link|@->@|cls|.@|head|$.
-
-\item[size_t level] The number of less specific superclasses in this class's
- chain. If $c@->@|cls|.@|link|$ is null then $c@->@|cls|.@|level|$ is zero;
- otherwise $c@->@|cls|.@|level| = c@->@|cls|.@|link|@->@|cls|.@|level| +
- 1$.
-
-\item[size_t n_chains]
-The number of chains formed by the class's superclasses.
-
-\item[const struct sod_chain *chains] A pointer to an array of @|struct
- sod_chain| structures (see below) describing the class's superclass chains,
- in decreasing order of specificity of their most specific classes. It is
- always the case that
- $c@->@|cls|.@|chains|[0].@|classes|[c@->@|cls|.@|level|] = c$.
-
-\item[size_t off_islots] The offset of the class's @|islots| structure
- relative to its containing @|ichain| structure. The class doesn't define
- any slots if and only if this is zero. (The offset can't be zero because
- the vtable pointer is at offset zero.)
-
-\item[size_t islotsz] The size required to store the class's direct slots,
- i.e., the size of its @|islots| structure. The class doesn't define any
- slots if and only if this is zero.
-
-\end{description}
-
-The
-@|struct sod_chain|
-structure describes an individual chain of superclasses.
-It has the following members.
-\begin{description} \let\makelabel\code
-
-\item[size_t n_classes] The number of classes in the chain. This is always
- at least one.
-
-\item[const SodClass *const *classes] A pointer to an array of class pointers
- listing the classes in the chain from least- to most-specific. So
- $@[i]@->@|cls|.@|head| = @[0]$ for all $0 \le i <
- @$, $@[0]@->@|cls|.@|link|$ is always null, and
- $@[i]@->@|cls|.@|link| = @[i - 1]$ if $1 \le i <
- @$.
-
-\item[size_t off_ichain] The size of the @|ichain| structure for this chain.
-
-\item[const struct sod_vtable *vt] The vtable for this chain. (It is
- possible, therefore, to duplicate the behaviour of the @ function
- by walking the chain structure. The @ function is much faster,
- though.)
-
-\item[size_t ichainsz] The size of the @|ichain| structure for this chain.
-
-\end{description}
+ \end{description}
+\end{describe}
%%%--------------------------------------------------------------------------
\section{Class and vtable layout} \label{sec:structures.layout}
@@ -255,6 +281,7 @@ In the description that follows, uppercase letters vary over class names,
while the corresponding lowercase letters indicate the class nicknames.
Throughout, we consider a class $C$ (therefore with nickname $c$).
+
\subsection{Generic instance structure}
\label{sec:structures.layout.instance}
@@ -280,7 +307,7 @@ type @|struct $C$__ilayout|.
union $B$__ichainu_$i$ $i$; \\
\quad$\vdots$ \- \\
\};
- \\[\bigskipamount]
+ \\+
typedef struct $C$__ichain_$h$ $C$;
\end{prog}
@@ -345,6 +372,7 @@ type system) to be a pointer to the @|struct $C$__ichain_$h$|.
Finally, the @|islots| structure simply contains one member for each slot
defined by $C$ in the order they appear in the class definition.
+
\subsection{Generic vtable structure} \label{sec:structures.layout.vtable}
As described above, each @|ichain| structure of an instance's storage has a
@@ -384,7 +412,7 @@ structure.
\quad$\vdots$ \- \\
\} $c$; \- \\
\};
- \\[\bigskipamount]
+ \\+
extern const union $C$__vtu_$h$ $C$__vtable_$h$;
\end{prog}
@@ -509,7 +537,8 @@ list.
@_n @_n, va_list sod__ap);
\end{prog}
-\subsection{Additional definitions} \label{sec:structures.additional}
+
+\subsection{Additional definitions} \label{sec:structures.layout.additional}
In addition to the instance and vtable structures described above, the
following definitions are made for each class $C$.