X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/62f9852b653ff96c776418da9492ea644e4a23cf..756e9293611d2b1dc34fba6cca89fd70098f5546:/doc/structures.tex?ds=inline

diff --git a/doc/structures.tex b/doc/structures.tex
index 029f34c..b2835fe 100644
--- a/doc/structures.tex
+++ b/doc/structures.tex
@@ -32,8 +32,8 @@ 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 @|<sod/sod.h>|.
-The definitions described in sections \ref{sec:structures.layout} are defined
-in the header file generated by the containing module.
+The definitions described in \xref{sec:structures.layout} are defined in the
+header file generated by the containing module.
 
 %%%--------------------------------------------------------------------------
 \section{Common instance structure} \label{sec:structures.common}
@@ -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,244 @@ 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;                                           \\
+        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}
+  \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 \{                                         \\ \ind
+       void init(?);
+     \}}
+
+  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 @|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}
 
-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 *@<p>); \\
-          void *(*init)(void *@<p>); \\
-          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 *@<p>)] 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[void *(*init)(void *@<p>)] A pointer to a function: given a pointer
-  @<p> to at least @<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 @<p>.
-
-\item[size_t n_supers] The number of direct superclasses.  (This is zero
-  exactly in the case of @|SodObject|.)
-
-\item[const SodClass *const *supers] A pointer to an array of @<n_supers>
-  pointers to class objects listing the class's direct superclasses, in the
-  order in which they were listed in the class definition.  If @<n_supers> is
-  zero, then this pointer is null.
-
-\item[size_t n_cpl] The number of superclasses in the class's class
-  precedence list.
-
-\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[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|$.
+\begin{describe}[SodClass]{cls}
+    {[nick = cls, link = SodObject]                             \\
+     class SodClass: SodObject \{                               \\ \ind
+       const char *name;                                        \\
+       const char *nick;                                        \\
+       size_t initsz;                                           \\
+       size_t align;                                            \\
+       void *(*imprint)(void *@<p>);                            \\
+       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 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[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[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[n_supers] The number of direct superclasses.  (This is zero exactly
+    in the case of @|SodObject|.)
+
+  \item[supers] A pointer to an array of @<n_supers> pointers to class
+    objects listing the class's direct superclasses, in the order in which
+    they were listed in the class definition.  If @<n_supers> 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
+    $@|@<classes>[$i$]@->cls.head| = @|@<classes>[0]|$ for all $0 \le i <
+    @<n_classes>$, @|@<classes>[0]@->cls.link| is always null, and
+    $@|@<classes>[$i$]@->cls.link| = @|@<classes>[$i - 1$]|$ if $1 \le i <
+    @<n_classes>$.
 
-\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[off_ichain] The size of the @|ichain| structure for this chain.
 
-\item[size_t n_chains]
-The number of chains formed by the class's superclasses.
+  \item[vt] The vtable for this chain.  (It is possible, therefore, to
+    partially duplicate the behaviour of the @<imprint> function by walking
+    the chain structure.\footnote{%
+      There isn't enough information readily available to fill in the class
+      pointers correctly.} %
+    The @<imprint> function is much faster, though.)
 
-\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[ichainsz] The size of the @|ichain| structure for this chain.
 
-\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
-  $@<classes>[i]@->@|cls|.@|head| = @<classes>[0]$ for all $0 \le i <
-  @<n_classes>$, $@<classes>[0]@->@|cls|.@|link|$ is always null, and
-  $@<classes>[i]@->@|cls|.@|link| = @<classes>[i - 1]$ if $1 \le i <
-  @<n_classes>$.
-
-\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 @<imprint> function
-  by walking the chain structure.  The @<imprint> 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 +343,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}
 
@@ -262,25 +351,25 @@ The entire state of an instance of $C$ is contained in a single structure of
 type @|struct $C$__ilayout|.
 
 \begin{prog}
-  struct $C$__ilayout \{ \\ \ind
-    union $C$__ichainu_$h$ \{ \\ \ind
-      struct $C$__ichain_$h$ \{ \\ \ind
-        const struct $C$__vt_$h$ *_vt; \\
-        struct $H$__islots $h$; \\
-        \quad$\vdots$ \\
-        struct $C$__islots \{ \\ \ind
-          @<type>_1 @<slot>_1; \\
-          \quad$\vdots$ \\
-          @<type>_n @<slot>_n; \- \\
-        \} $c$; \- \\
-      \} $c$; \\
-      struct $H$__ichain_$h$ $h$; \\
-      \quad$\vdots$ \- \\
-    \} $h$; \\
-    union $B$__ichainu_$i$ $i$; \\
-    \quad$\vdots$ \- \\
-  \};
-  \\[\bigskipamount]
+  struct $C$__ilayout \{                                        \\ \ind
+    union $C$__ichainu_$h$ \{                                   \\ \ind
+      struct $C$__ichain_$h$ \{                                 \\ \ind
+        const struct $C$__vt_$h$ *_vt;                          \\
+        struct $H$__islots $h$;                                 \\
+        \quad$\vdots$                                           \\
+        struct $C$__islots \{                                   \\ \ind
+          @<type>_1 @<slot>_1;                                  \\
+          \quad$\vdots$                                         \\
+          @<type>_n @<slot>_n;                                \-\\
+        \} $c$;                                               \-\\
+      \} $c$;                                                   \\
+      struct $A$__ichain_$h$ $a$;                               \\
+      \quad$\vdots$                                           \-\\
+    \} $h$;                                                     \\
+    union $B$__ichainu_$i$ $i$;                                 \\
+    \quad$\vdots$                                             \-\\
+  \};                                                           \\+
+
   typedef struct $C$__ichain_$h$ $C$;
 \end{prog}
 
@@ -291,7 +380,7 @@ transitive closure of the `links to' relation.)  Chains are identified by
 naming their least specific classes; the least specific class in a chain is
 called the \emph{chain head}.  Suppose that the chain head of the chain
 containing $C$ itself is named $H$ (though keep in mind that it's possible
-that .$H$ is in fact $C$ itself.)
+that $H$ is in fact $C$ itself.)
 
 \subsubsection{The ilayout structure}
 The @|ilayout| structure contains one member for each of $C$'s superclass
@@ -320,12 +409,11 @@ and this is followed by corresponding members
   struct $A$__ichain_$h$ $a$;
 \end{prog}
 for each of $C$'s superclasses $A$ in the same chain in some (unimportant)
-order.
+order.  The (somewhat obtuse) purpose of this union is to engage the `common
+initial sequence' rule of \cite[6.5.2.3]{FIXME:C99}.
 
 \subsubsection{The ichain structure}
-The
-@|ichain|
-structure contains (in order), a pointer
+The @|ichain| structure contains (in order), a pointer
 \begin{prog}
   const struct $C$__vt_$h$ *_vt;
 \end{prog}
@@ -345,6 +433,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
@@ -355,7 +444,7 @@ 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
@@ -368,26 +457,28 @@ method.
 A vtable for a class $C$ with chain head $H$ has the following general
 structure.
 \begin{prog}
-  union $C$__vtu_$h$ \{ \\ \ind
-    struct $C$__vt_$h$ \{ \\ \ind
-      const $P$ *_class; \\
-      size_t _base; \\
-      \quad$\vdots$ \\
-      const $Q$ *_cls_$j$; \\
-      \quad$\vdots$ \\
-      ptrdiff_t _off_$i$; \\
-      \quad$\vdots$ \\
-      struct $C$__vtmsgs_$a$ \{ \\ \ind
-        @<type> (*@<msg>)($C$ *, $\dots$); \\
-        \quad$\vdots$ \- \\
-      \} $a$; \\
-      \quad$\vdots$ \- \\
-    \} $c$; \- \\
-  \};
-  \\[\bigskipamount]
+  union $C$__vtu_$h$ \{                                         \\ \ind
+    struct $C$__vt_$h$ \{                                       \\ \ind
+      const $P$ *_class;                                        \\
+      size_t _base;                                             \\
+      \quad$\vdots$                                             \\
+      const $Q$ *_cls_$j$;                                      \\
+      \quad$\vdots$                                             \\
+      ptrdiff_t _off_$i$;                                       \\
+      \quad$\vdots$                                             \\
+      struct $C$__vtmsgs_$a$ \{                                 \\ \ind
+        @<type> (*@<msg>)($C$ *, $\dots$);                      \\
+        \quad$\vdots$                                         \-\\
+      \} $a$;                                                   \\
+      \quad$\vdots$                                           \-\\
+    \} $c$;                                                   \-\\
+  \};                                                           \\+
+
   extern const union $C$__vtu_$h$ $C$__vtable_$h$;
 \end{prog}
 
+In the following, let $M$ be the metaclass of $C$.
+
 \subsubsection{The vtu union}
 The outer layer is a @|union $C$__vtu_$h$| containing a member
 \begin{prog}
@@ -396,18 +487,11 @@ The outer layer is a @|union $C$__vtu_$h$| containing a member
 for each of $C$'s superclasses $A$ in the same chain, with $C$ itself listed
 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
+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
 \begin{prog}
   const union $A$__vtu_$i$ $C$__vtable_$i$;
 \end{prog}
@@ -498,18 +582,28 @@ defined as
 \begin{prog}
   @<type>_0 $m$(@<type>_1 @<arg>_1, $\ldots$, @<type>_n @<arg>_n, \dots);
 \end{prog}
+or a standard message which takes keyword arguments, defined as
+\begin{prog}
+  @<type>_0 $m$(\=@<type>_1 @<arg>_1,
+                    $\ldots$,
+                    @<type>_n @<arg>_n?                       \+\\
+                  @<type>_{n+1} @<kw>_{n+1} @[= @<dflt>_{n+1}@],
+                    $\ldots$,
+                    @<type>_{n'} @<kw>_{n'} @[= @<dflt>_{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
 argument of type @|va_list| in place of the variable portion of the argument
-list.
+list or keywords.
 \begin{prog}
   @<type>_0 $m$($C$ *me, @<type>_1 @<arg>_1, $\ldots$,
-                @<type>_n @<arg>_n, \dots); \\
+                @<type>_n @<arg>_n, \dots);                     \\
   @<type>_0 $m$__v($C$ *me, @<type>_1 @<arg>_1, $\ldots$,
                    @<type>_n @<arg>_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$.
@@ -521,10 +615,10 @@ For each message $m$ directly defined by $C$ there is a macro definition
 which makes sending the message $m$ to an instance of (any subclass of) $C$
 somewhat less ugly.
 
-If $m$ takes a variable number of arguments, the macro is more complicated
-and is only available in compilers advertising C99 support, but the effect is
-the same.  For each variable-argument message, there is also an additional
-macro for calling the `valist' entry point.
+If $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.  For each variable-argument message,
+there is also an additional macro for calling the `valist' entry point.
 \begin{prog}
   \#define $C$_$m$__v(@<me>, $\ldots$, @<sod__ap>)
     @<me>@->_vt@->$c$.$m$__v(@<me>, $\ldots$, @<sod__ap>)
@@ -542,7 +636,7 @@ defined for the sake of completeness.
 
 Finally, the class object is defined as
 \begin{prog}
-  extern const struct $R$__ilayout $C$__classobj; \\
+  extern const struct $R$__ilayout $C$__classobj;               \\
   \#define $C$__class (\&$C$__classobj.$j$.$r$)
 \end{prog}
 The exported symbol @|$C$__classobj| contains the entire class instance.
