From 62f9852b653ff96c776418da9492ea644e4a23cf Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Thu, 17 Sep 2015 18:25:16 +0100 Subject: [PATCH] doc/{runtime,structures}.tex: Mostly translated from the manpages. --- doc/runtime.tex | 201 +++++++++++++++++++ doc/structures.tex | 560 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 761 insertions(+) create mode 100644 doc/runtime.tex create mode 100644 doc/structures.tex diff --git a/doc/runtime.tex b/doc/runtime.tex new file mode 100644 index 0000000..54113be --- /dev/null +++ b/doc/runtime.tex @@ -0,0 +1,201 @@ +%%% -*-latex-*- +%%% +%%% The runtime library +%%% +%%% (c) 2015 Straylight/Edgeware +%%% + +%%%----- Licensing notice --------------------------------------------------- +%%% +%%% This file is part of the Simple Object Definition system. +%%% +%%% SOD is free software; you can redistribute it and/or modify +%%% it under the terms of the GNU General Public License as published by +%%% the Free Software Foundation; either version 2 of the License, or +%%% (at your option) any later version. +%%% +%%% SOD is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%%% GNU General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% along with SOD; if not, write to the Free Software Foundation, +%%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +\chapter{The runtime library} \label{ch:runtime} + +This chapter describes the runtime support macros and functions defined in +the @|| header file. The corresponding types are defined in +\xref{ch:structures}. + +The runtime support functionality defined here generally expects that +instances and classes inherit from the standard @|SodObject| root object. +While the translator can (at some effort) support alternative roots, they +will require different run-time support machinery. + +%%%-------------------------------------------------------------------------- +\section{Infrastructure macros} \label{ch:runtime.infra} + +These macros are mostly intended for use in code generated by the Sod +translator. Others may find them useful for special effects, but they can be +tricky to understand and use correctly and can't really be recommended for +general use. + +\begin{describe}[SOD_XCHAIN]{mac} + {void *SOD_CHAIN(@, const @ *@);} + Performs a `cross-chain upcast'. + + Given a pointer @ to an instance of a class of type @ and the + nickname @ of the least specific class in one of @'s superclass + chains which does not contain @ itself, @|SOD_XCHAIN| returns the + address of that chain's storage within the instance layout as a raw + @|void~*| pointer. (Note that @ is not mentioned explicitly.) + + This macro is used by the generated @|@{}__CONV_@| conversion + macros, which you are encouraged to use instead where possible. +\end{describe} + +\begin{describe}[SOD_OFFSETDIFF]{mac} + {ptrdiff_t SOD_OFFSETDIFF(@, @_1, @_2)} + Returns the signed offset between two members of a structure or union type. + + Given a structure or union type @, and two member names @_1 + and @_2, then @|SOD_OFFSETDIFF| gives the difference, in bytes, + between the addresses of objects @|$x$.@_1| and @|$x$.@_2| + for any object $x$ of type @. + + This macro is used internally when generating vtables and is not expected + to be very useful elsewhere. +\end{describe} + +\begin{describe}[SOD_ILAYOUT]{mac} + {@{}__ilayout *SOD_ILAYOUT(@, @, const void *@)} + Recovers the instance layout base address from a pointer to one of its + instance chains. + + Specifically, given a class name @, the nickname @ of the least + specific class in one of @'s superclass chains, and a pointer @ + to the instance storage for the chain containing @ within a direct + instance of @ (i.e., not an instance of any proper subclass), + @|SOD_ILAYOUT| returns the a pointer to the layout structure containing + @. + + This macro is used internally in effective method bodies and is not + expected to be very useful elsewhere since it's unusual to have such + specific knowledge about the dynamic type of an instance. The + @|SOD_INSTBASE| macro (described below) is more suited to general use. +\end{describe} + +\begin{describe}[SOD_CAR]{mac} {@ SOD_CAR(@, @^*)} + Accepts one or more arguments and expands to just its first argument, + discarding the others. + + It is only defined if the C implementation advertises support for C99. It + is used in the definitions of message convenience macros for messages which + accept a variable number of arguments but no required arguments, and is + exported because the author has found such a thing useful in other + contexts. +\end{describe} + +%%%-------------------------------------------------------------------------- +\section{Utility macros} \label{sec:runtime.utility} + +The following macros are expected to be useful in Sod method definitions and +client code. + +\begin{describe}[SOD_CLASSOF]{mac} + {const void *SOD_CLASSOF(const @ *@)} + Returns the class object describing an instance's dynamic class. + + Given a pointer @ to an instance, @|SOD_CLASSOF| returns a pointer to + @'s dynamic class, which (assuming @ is typed correctly in the + first place) will be a subclass of @. (If you wanted the class object + for @ itself, it's called @|@{}__class|.) +\end{describe} + +\begin{describe}[SOD_INSTBASE]{mac}{void *SOD_INSTBASE(const @ *@)} + Finds the base address of an instance's layout. + + Given a pointer @ to an instance, @|SOD_INSTBASE| returns the base + address of the storage allocated to @. This is useful if you want to + free a dynamically allocated instance, for example. + + This macro needs to look up an offset in @'s vtable to do its work. + Compare @|SOD_ILAYOUT| above, which is faster but requires precise + knowledge of the instance's dynamic class. +\end{describe} + +\begin{describe}[SOD_CONVERT]{mac} + {@ *SOD_CONVERT(@, const void *@)} + + Perform general conversions (up-, down-, and cross-casts) on instance + pointers. + + Given a class name @ and a pointer @ to an instance, + @|SOD_CONVERT| returns an appropriately converted pointer to @ if + @ is indeed an instance of (some subclass of) @; otherwise it + returns a null pointer. + + This macro is a simple wrapper around the @|sod_convert| function described + below, which is useful in the common case that the target class is known + statically. +\end{describe} + +\begin{describe}[SOD_DECL]{mac}{SOD_DECL(@, @)} + Declares and initializes an instance with automatic storage duration. + + Given a class name @ and an identifier @, @|SOD_DECL| declares + @ to be a pointer to an instance of @. The instance is + initialized in the sense that its vtable and class pointers have been set + up, and slots for which initializers are defined are set to the appropriate + initial values. + + The instance has automatic storage duration: pointers to it will become + invalid when control exits the scope of the declaration. +\end{describe} + +%%%-------------------------------------------------------------------------- +\section{Functions} \label{sec:runtime.functions} + +The following functions are provided in @|libsod|. + +\begin{describe}[sod_subclassp]{fun} + {int sod_subclassp(const SodClass *sub, const SodClass *super)} + + Decide whether one class @ is actually a subclass of another class + @. + + The @ function returns nonzero if and only if + @ is a subclass of @. + + This involves a run-time trawl through the class structures: while some + effort has been made to make it perform well it's still not very fast. +\end{describe} + +\begin{describe}[sod_convert]{fun} + {void *sod_convert(const SodClass *cls, const void *obj)} + Performs general conversions (up-, down-, and cross-casts) on instance + pointers. + + Given a class pointer @ and an instance pointer @, @|sod_convert| + returns an appropriately converted pointer to @ in the case that + @ is an instance of (some subclass of) @; otherwise it returns + null. + + This involves a run-time trawl through the class structures: while some + effort has been made to make it perform well it's still not very fast. For + upcasts (where @ is a superclass of the static type of @) the + automatically defined conversion macros should be used instead, because + they're much faster and can't fail. When the target class is known + statically, it's slightly more convenient to use the @|SOD_CONVERT| macro + instead. +\end{describe} + +%%%----- That's all, folks -------------------------------------------------- + +%%% Local variables: +%%% mode: LaTeX +%%% TeX-master: "sod.tex" +%%% TeX-PDF-mode: t +%%% End: diff --git a/doc/structures.tex b/doc/structures.tex new file mode 100644 index 0000000..029f34c --- /dev/null +++ b/doc/structures.tex @@ -0,0 +1,560 @@ +%%% -*-latex-*- +%%% +%%% In-depth exploration of the generated structures +%%% +%%% (c) 2015 Straylight/Edgeware +%%% + +%%%----- Licensing notice --------------------------------------------------- +%%% +%%% This file is part of the Simple Object Definition system. +%%% +%%% SOD is free software; you can redistribute it and/or modify +%%% it under the terms of the GNU General Public License as published by +%%% the Free Software Foundation; either version 2 of the License, or +%%% (at your option) any later version. +%%% +%%% SOD is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%%% GNU General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% along with SOD; if not, write to the Free Software Foundation, +%%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +\chapter{Object structures} \label{ch:structures} + +This chapter describes the structure and layout of standard Sod objects, +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 definitions described in sections \ref{sec:structures.layout} are defined +in the header file generated by the containing module. + +%%%-------------------------------------------------------------------------- +\section{Common instance structure} \label{sec:structures.common} + +As described below, a pointer to an instance actually points to an +\emph{instance chain} structure within the instances overall layout +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} + +%%%-------------------------------------------------------------------------- +\section{Built-in root objects} \label{sec:structures.root} + +This section describes the built-in classes @|SodObject| and @|SodClass|, +which are the standard roots of the inheritance and metaclass graphs +respectively. Specifically, @|SodObject| has no direct superclasses, and +@|SodClass| is its own metaclass. It is not possible to define root classes +in module files because of circularities: @|SodObject| has @|SodClass| as its +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} + +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. + +\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|.) + +\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[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|$. + +\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} + +%%%-------------------------------------------------------------------------- +\section{Class and vtable layout} \label{sec:structures.layout} + +The layout algorithms for Sod instances and vtables are nontrivial. They are +defined here in full detail, since they're effectively fixed by Sod's ABI +compatibility guarantees, so they might as well be documented for the sake of +interoperating programs. + +Unfortunately, the descriptions are rather complicated, and, for the most +part not necessary to a working understanding of Sod. The skeleton structure +definitions shown should be more than enough for readers attempting to make +sense of the generated headers and tables. + +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} + +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 + @_1 @_1; \\ + \quad$\vdots$ \\ + @_n @_n; \- \\ + \} $c$; \- \\ + \} $c$; \\ + struct $H$__ichain_$h$ $h$; \\ + \quad$\vdots$ \- \\ + \} $h$; \\ + union $B$__ichainu_$i$ $i$; \\ + \quad$\vdots$ \- \\ + \}; + \\[\bigskipamount] + typedef struct $C$__ichain_$h$ $C$; +\end{prog} + +The set of superclasses of $C$, including itself, can be partitioned into +chains by following their distinguished superclass links. (Formally, the +chains are the equivalence classes determined by the reflexive, symmetric, +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.) + +\subsubsection{The ilayout structure} +The @|ilayout| structure contains one member for each of $C$'s superclass +chains. The first such member is +\begin{prog} + union $C$__ichainu_$h$ $h$; +\end{prog} +described below; this is followed by members +\begin{prog} + union $B$__ichainu_$i$ $i$; +\end{prog} +for each other chain, where $I$ is the head and $B$ the tail (most-specific) +class of the chain. The members are in decreasing order of the specificity +of the chains' most-specific classes. (Note that all but the first of these +unions has already been defined as part of the definition of the +corresponding $B$.) + +\subsubsection{The ichainu union} +The @|ichainu| union contains a member for each class in the chain. The +first is +\begin{prog} + struct $C$__ichain_$h$ $c$; +\end{prog} +and this is followed by corresponding members +\begin{prog} + struct $A$__ichain_$h$ $a$; +\end{prog} +for each of $C$'s superclasses $A$ in the same chain in some (unimportant) +order. + +\subsubsection{The ichain structure} +The +@|ichain| +structure contains (in order), a pointer +\begin{prog} + const struct $C$__vt_$h$ *_vt; +\end{prog} +followed by a structure +\begin{prog} + struct $A$__islots $a$; +\end{prog} +for each superclass $A$ of $C$ in the same chain which defines slots, from +least- to most-specific; if $C$ defines any slots, then the last member is +\begin{prog} + struct $C$__islots $c$; +\end{prog} +A `pointer to $C$' is always assumed (and, indeed, defined in C's +type system) to be a pointer to the @|struct $C$__ichain_$h$|. + +\subsubsection{The islots structure} +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 +vtable pointer +\begin{prog} + const struct $C$__vt_$h$ *_vt; +\end{prog} +In general, the vtables for the different chains will have \emph{different} +structures. + +The instance layout split 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. + +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 + @ (*@)($C$ *, $\dots$); \\ + \quad$\vdots$ \- \\ + \} $a$; \\ + \quad$\vdots$ \- \\ + \} $c$; \- \\ + \}; + \\[\bigskipamount] + extern const union $C$__vtu_$h$ $C$__vtable_$h$; +\end{prog} + +\subsubsection{The vtu union} +The outer layer is a @|union $C$__vtu_$h$| containing a member +\begin{prog} + struct $A$__vt_$h$ $a$; +\end{prog} +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 +\begin{prog} + const union $A$__vtu_$i$ $C$__vtable_$i$; +\end{prog} +where $A$ and $I$ are respectively the most and least specific classes in the +chain. + +\subsubsection{The vt structure} +The first member in the @|vt| structure is the \emph{root class pointer} +\begin{prog} + const $P$ *_class; +\end{prog} +Among the superclasses of $C$ there must be exactly one class $O$ which +itself has no direct superclasses; this is the \emph{root superclass} of $C$. +(This is a rule enforced by the Sod translator.) The metaclass $R$ of $O$ is +then the \emph{root metaclass} of $C$. The @|_class| member points to the +@|ichain| structure of most specific superclass $P$ of $M$ in the same chain +as $R$. + +This is followed by the \emph{base offset} +\begin{prog} + size_t _base; +\end{prog} +which is simply the offset of the @|ichain| structure from the instance base. + +The rest of the vtable structure is populated by walking the superclass chain +containing $C$ as follows. For each such superclass $B$, in increasing order +of specificity, walk the class precedence list of $B$, again starting with +its least-specific superclass. (This complex procedure guarantees that the +vtable structure for a class is a prefix of the vtable structure for any of +its subclasses in the same chain.) + +So, let $A$ be some superclass of $C$ which has been encountered during this +traversal. + +\begin{itemize} + +\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 + \begin{prog} + const $Q$ *_cls_$j$; + \end{prog} + to the vtable pointing to the appropriate @|islots| structure within $M$'s + class object. + +\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. + If there is currently no member @|_off_$i$| then add a member + \begin{prog} + ptrdiff_t _off_$i$; + \end{prog} + to the vtable, containing the (signed) offset from the @|ichain| structure + of the chain headed by $h$ to that of the chain headed by $i$ within the + instance's layout. + +\item If class $A$ defines any messages, and there is currently no member + $a$, then add a member + \begin{prog} + struct $C$__vtmsgs_$a$ $a$; + \end{prog} + to the vtable. See below. + +\end{itemize} + +\subsubsection{The vtmsgs structure} +Finally, the @|vtmsgs| structures contain pointers to the effective method +entry functions for the messages defined by a superclass. There may be more +than one method entry for a message, but all of the entry pointers for a +message appear together, and entry pointers for separate messages appear in +the order in which the messages are defined. If the receiver class has no +applicable primary method for a message then it's usual for the method entry +pointer to be null (though, as with a lot of things in Sod, extensions may do +something different). + +For a standard message which takes a fixed number of arguments, defined as +\begin{prog} + @_0 $m$(@_1 @_1, $\ldots$, @_n @_n); +\end{prog} +there is always a `main' entry point, +\begin{prog} + @_0 $m$($C$ *me, @_1 @_1, $\ldots$, @_n @_n); +\end{prog} + +For a standard message which takes a variable number of arguments, +defined as +\begin{prog} + @_0 $m$(@_1 @_1, $\ldots$, @_n @_n, \dots); +\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. +\begin{prog} + @_0 $m$($C$ *me, @_1 @_1, $\ldots$, + @_n @_n, \dots); \\ + @_0 $m$__v($C$ *me, @_1 @_1, $\ldots$, + @_n @_n, va_list sod__ap); +\end{prog} + +\subsection{Additional definitions} \label{sec:structures.additional} + +In addition to the instance and vtable structures described above, the +following definitions are made for each class $C$. + +For each message $m$ directly defined by $C$ there is a macro definition +\begin{prog} + \#define $C$_$m$(@, $\ldots$) @@->_vt@->$c$.$m$(@, $\ldots$) +\end{prog} +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. +\begin{prog} + \#define $C$_$m$__v(@, $\ldots$, @) + @@->_vt@->$c$.$m$__v(@, $\ldots$, @) +\end{prog} + +For each proper superclass $A$ of $C$, there is a macro defined +\begin{prog} + $A$ *$C$__CONV_$a$($C$ *_obj); +\end{prog} +(named in \emph{upper case}) which converts a (static-type) pointer to $C$ to +a pointer to the same actual instance, but statically typed as a pointer to +$A$. This is most useful when $A$ is not in the same chain as $C$ since +in-chain upcasts are both trivial and rarely needed, but the full set is +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$) +\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~*|. + +%%%----- That's all, folks -------------------------------------------------- + +%%% Local variables: +%%% mode: LaTeX +%%% TeX-master: "sod.tex" +%%% TeX-PDF-mode: t +%%% End: -- 2.11.0