chiark / gitweb /
debian/libsod-dev.install: Fix name of manpage.
[sod] / doc / structures.tex
index 561075be45b8c66c8dc74c9b36c4429d6dc392f5..3826bdc8572e37923d3e6d25935379cd8d9f7135 100644 (file)
@@ -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}
@@ -87,57 +87,125 @@ 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{figure}[tbp]
   \begin{tabular}{p{10pt}p{10pt}}
-    \begin{prog}
+    \begin{nprog}
       struct SodObject__ilayout \{ \\ \ind
         union \{ \\ \ind
           struct SodObject__ichain_obj \{ \\ \ind
             const struct SodObject__vt_obj *_vt; \- \\
-          \}; \- \\
+          \} obj; \- \\
         \} obj; \- \\
       \};
-    \end{prog}
+    \end{nprog}
     &
-    \begin{prog}
+    \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{prog} \\
+    \end{nprog} \\
   \end{tabular}
   \caption{Instance and vtable layout of @|SodObject|}
   \label{fig:structures.root.sodobject}
 \end{figure}
 
 \begin{describe}[SodObject]{cls}
-    {[metaclass = SodClass, lisp_metaclass = sod_class] \\
-     class SodObject \{ \}}
+    {[nick = obj, metaclass = SodClass, lisp_metaclass = sod_class] \\
+     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}
 
+
 \subsection{The SodClass class} \label{sec:structures.root.sodclass}
 
 \begin{describe}[SodClass]{cls}
-    {class SodClass : SodObject \{ \\ \ind
+    {[nick = cls, link = SodObject] \\
+     class SodClass : SodObject \{ \\ \ind
        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; \\
@@ -151,9 +219,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
@@ -164,18 +232,14 @@ recommended.
 
   \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 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[n_supers] The number of direct superclasses.  (This is zero exactly
     in the case of @|SodObject|.)
 
@@ -189,7 +253,7 @@ recommended.
 
   \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
+    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;
@@ -197,21 +261,20 @@ recommended.
     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|$.
+    @|$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$.
+    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$.
+    $@|$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
@@ -234,33 +297,33 @@ recommended.
        size_t ichainsz; \- \\
      \};}
 
-   The @|struct sod_chain| structure describes an individual chain of
-   superclasses.  It has the following members.
-   \begin{description} \let\makelabel\code
+  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[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[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[off_ichain] The size of the @|ichain| structure for this chain.
+  \item[off_ichain] The size of the @|ichain| structure for this chain.
 
-   \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[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[ichainsz] The size of the @|ichain| structure for this chain.
+  \item[ichainsz] The size of the @|ichain| structure for this chain.
 
-   \end{description}
- \end{describe}
+  \end{description}
+\end{describe}
 
 %%%--------------------------------------------------------------------------
 \section{Class and vtable layout} \label{sec:structures.layout}
@@ -279,6 +342,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}
 
@@ -304,7 +368,7 @@ type @|struct $C$__ilayout|.
     union $B$__ichainu_$i$ $i$; \\
     \quad$\vdots$ \- \\
   \};
-  \\[\bigskipamount]
+  \\+
   typedef struct $C$__ichain_$h$ $C$;
 \end{prog}
 
@@ -369,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
@@ -408,7 +473,7 @@ structure.
       \quad$\vdots$ \- \\
     \} $c$; \- \\
   \};
-  \\[\bigskipamount]
+  \\+
   extern const union $C$__vtu_$h$ $C$__vtable_$h$;
 \end{prog}
 
@@ -522,10 +587,16 @@ 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>_m @<kw>_m @[= @<dflt>_m@]);
+\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); \\
@@ -533,7 +604,8 @@ list.
                    @<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$.
@@ -545,10 +617,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>)