%%% -*-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 provided by
the Sod library.  The common structure of object instances and classes is
described in \xref{ch:structures}.

%%%--------------------------------------------------------------------------
\section{Keyword argument support} \label{sec:runtime.keywords}

This section describes the types, macros, and functions exposed in the
@|<sod/keyword.h>| header file which provides support for defining and
calling functions which make use of keyword arguments; see \xref{sec:concepts.keywords}.


\subsection{Type definitions} \label{sec:sec:runtime.keywords.types}

The header file defines two simple structure types, and a function type which
will be described later.

\begin{describe}[struct kwval]{type}
    {struct kwval \{ \\ \ind
       const char *kw; \\
       const void *val; \- \\
     \};}

  The @|kwval| structure describes a keyword argument name/value pair.  The
  @|kw| member points to the name, as a null-terminated string.  The @|val|
  member always contains the \emph{address} of the value.  (This somewhat
  inconvenient arrangement makes the size of a @|kwval| object independent of
  the actual argument type.)
\end{describe}

\begin{describe}[struct kwtab]{type}
    {struct kwtab \{ \\ \ind
       const struct kwval *v; \\
       size_t n; \- \\
     \};}

  The @|kwtab| structure describes a list of keyword arguments, represented
  as a vector of @|kwval| structures.  The @|v| member points to the start of
  the vector; the @|n| member contains the number of elements in the vector.
\end{describe}


\subsection{Calling functions with keyword arguments}
\label{sec:runtime.keywords.calling}

Functions which accept keyword arguments are ordinary C functions with
variable-length argument tails.  Hence, they can be called using ordinary C
(of the right kind) and all will be well.  However, argument lists must
follow certain rules (which will be described in full below); failure to do
this will result in \emph{undefined behaviour}.

The header file provides integration with some C compilers in the form of
macros which can be used to help the compiler diagnose errors in calls to
keyword-accepting functions; but such support is rather limited at the
moment.  Some additional macros are provided for use in calls to such
functions, and it is recommended that, where possible, these are used.  In
particular, it's all too easy to forget the trailing null terminator which
marks the end of a list of keyword arguments.

That said, the underlying machinery is presented first, and the convenience
macros are described later.

\subsubsection{Keyword argument mechanism}
The argument tail, following the mandatory arguments, consists of a sequence
of zero or more alternating keyword names, as pointers to null-terminated
strings (with type @|const char~*|), and their argument values.  This
sequence is finally terminated by a null pointer (again with type @|const
char~*|) in place of a keyword name.

Each function may define for itself which keyword names it accepts,
and what types the corresponding argument values should have.
There are also (currently) three special keyword names.
\begin{description} \let\makelabel\code

\item[kw.valist] This special keyword is followed by a pointer to a
  variable-length argument tail cursor object, of type @|va_list~*|.  This
  cursor object will be modified as the function extracts successive
  arguments from the tail.  The argument tail should consist of alternating
  keyword names and argument values, as described above, including the first
  keyword name.  (This is therefore different from the convention used when
  calling keyword argument parser functions: see the description of the
  \descref{KWSET_PARSEFN}[macro]{mac} for more details about these.)  The
  argument tail may itself contain the special keywords.

\item[kw.tab] This special keyword is followed by \emph{two} argument values:
  a pointer to the base of a vector of @|kwval| structures, and the number of
  elements in this vector (as a @|size_t|).  Each element of the vector
  describes a single keyword argument: the @|kw| member points to the
  keyword's name, and the @|val| member points to the value.

  The vector may contain special keywords.  The @|val| pointer for a
  @|kw.valist| argument should contain the address of an object of type
  @|va_list~*| (and not point directly to the cursor object, since @|val| is
  has type @|const void~*| but the cursor will be modified as its argument
  tail is traversed).  The @|val| pointer for a @|kw.tab| argument should
  contain the address of a @|kwtab| structure which itself contains the base
  address and length of the argument vector to be processed.

\item[kw.unknown] This keyword is never accepted by any function.  If it is
  encountered, the @|kw_unknown| function is called to report the situation
  as an error; see below.

\end{description}
It is possible to construct a circular structure of indirect argument lists
(in a number of ways).  Don't try to pass such a structure to a function: the
result will be unbounded recursion or some other bad outcome.

\subsubsection{Argument list structuring macros}
The following macros are intended to help with constructing keyword argument
lists.  Their use is not essential, but may help prevent errors.

\begin{describe}[KWARGS]{mac}{KWARGS(@<body>)}
  The @<body> encloses a sequence of keyword arguments expressed as calls to
  argument consists of a sequence of calls to the keyword-argument macros
  described below, one after another without any separation.

  In C89, macro actual arguments are not permitted to be empty; if there are
  no keyword arguments to provide, and you're using a C89 compiler, then use
  @|NO_KWARGS| (below) instead.  If your compiler supports C99 or later, it's
  fine to just write @|KWARGS()| instead.
\end{describe}

\begin{describe}{mac}{NO_KWARGS}
  A marker, to be written instead of a @|KWARGS| invocation, to indicate that
  no keyword arguments are to be passed to a function.

  This is unnecessary with compilers which support C99 or later, since once
  can use @|KWARGS()| with an empty @<body> argument.
\end{describe}

The following keyword-argument macros can be used within the @|KWARGS|
@<body> argument.

\begin{describe}[K]{mac}{K(@<name>, @<value>)}
  Passes a keyword @<name> and its corresponding @<value>, as a pair of
  arguments.  The @<name> should be a single identifier (not a quoted
  string).  The @<value> may be any C expression of the appropriate type.
\end{describe}

\begin{describe}[K_VALIST]{mac}{K_VALIST(@<ap>)}
  Passes an indirect variable-length argument tail.  The argument @<ap>
  should be an lvalue of type @|va_list|, which will be passed by reference.
\end{describe}

\begin{describe}[K_TAB]{mac}{K_TAB(@<v>, @<n>)}
  Passes a vector of keyword arguments.  The argument @<v> should be the base
  address of the vector, and @<n> should be the number of elements in the
  vector.
\end{describe}


\subsection{Defining functions with keyword arguments}
\label{sec:runtime.keywords.defining}

\subsubsection{Keyword sets}
A \emph{keyword set} defines the collection of keyword arguments accepted by
a particular function.  The same keyword set may be used by several
functions.  (If your function currently accepts no keyword arguments, but you
plan to add some later, do not define a keyword set; instead, use the
@|KWPARSE_EMPTY| macro described below.)

Each keyword set has a name, which is a C identifier.  It's good to choose
meaningful and distinctive names for keyword sets.  Keyword set names are
meaningful at runtime: they are used as part of the @|kw_unknown| protocol
(\xref{sec:runtime.keywords.unknown}), and may be examined by handler
functions, or reported to a user in error messages.  For a keyword set which
is used only by a single function, it is recommended that the set be given
the same name as the function.

The keyword arguments for a keyword set named @<set> are described by a `list
macro' named @|@<set>{}_KWSET|.  This macro takes a single argument,
conventionally named @`_'.  It should expand to a sequence of one or more
list items of the form
\begin{prog}
  _(@<type>, @<name>, @<default>)
\end{prog}
with no separation between them.  For example:
\begin{prog}
  \#define example_KWSET(_) @\\ \\ \ind
    _(int, x, 0) @\\ \\
    _(const char *, y, NULL)
\end{prog}

Each @<name> should be a distinct C identifier; they will be used to name
structure members.  An argument @<name> should not end with the suffix
@`_suppliedp' (for reasons which will soon become apparent).

Each @<type> should be a C @<type-name> such that
\begin{prog}
  @<type> @<name> ;
\end{prog}
is a valid declaration: so it may consist of declaration specifiers and
(possibly qualified) pointer declarator markers, but not array or function
markers (since they would have to be placed after the @<name>).  This is the
same requirement made by the standard \man{va_arg}{3} macro.

Each @<default> should be an initializer expression or brace-enclosed list,
suitable for use in an aggregate initializer for a variable with automatic
storage duration.  (In C89, aggregate initializers may contain only constant
expressions; this restriction was lifted in C99.)

\subsubsection{Function declaration markers}
The following marker macros are intended to be used in both declarations and
definitions of functions which accept keyword arguments.

\begin{describe}{mac}{KWTAIL}
  The @|KWTAIL| is expected to be used at the end of function parameter type
  list to indicate that the function accepts keyword arguments; if there are
  preceding mandatory arguments then the @|KWTAIL| marker should be separated
  from them with a comma @`,'.  (It is permitted for a function parameter
  type list to contain only a @|KWTAIL| marker.)

  Specifically, the macro declares a mandatory argument @|const char
  *kwfirst_| (to collect the first keyword name), and a variable-length
  argument tail.

  The \descref{KWPARSE}[macro]{mac} assumes that the enclosing function's
  argument list ends with a @|KWTAIL| marker.
\end{describe}

\begin{describe}{mac}{KWCALL}
  The @|KWCALL| macro acts as a declaration specifier for functions which
  accept keyword arguments.  Its effect is to arrange for the compiler to
  check, as far as is possible, that calls to the function are well-formed
  according to the keyword-argument rules.  The exact checking performed
  depends on the compiler's abilities (and how well supported the compiler
  is): it may check that every other argument is a string; it may check that
  the list is terminated with a null pointer; it may not do anything at all.
  Again, this marker should be included in a function's definition and in any
  declarations.
\end{describe}

\subsubsection{Auxiliary definitions}
The following macros define data types and functions used for collecting
keyword arguments.

\begin{describe}[KWSET_STRUCT]{mac}{KWSET_STRUCT(@<set>);}
  The @|KWSET_STRUCT| macro defines a \emph{keyword structure} named @|struct
  @<set>{}_kwargs|.  For each argument defined in the keyword set, this
  structure contains two members: one has exactly the @<name> and @<type>
  listed in the keyword set definition; the other is a 1-bit-wide bitfield of
  type @|unsigned int| named @|@<name>{}_suppliedp|.
\end{describe}

\begin{describe}[KWDECL]{mac}
    {@<declaration-specifiers> KWDECL(@<set>, @<kw>);}
  The macro declares and initializes a keyword argument structure variable
  named @<kw> for the named keyword @<set>.  The optional
  @<declaration-specifiers> may provide additional storage-class specifiers,
  qualifiers, or other declaration specifiers.  The @`_suppliedp' flags are
  initialized to zero; the other members are initialized with the
  corresponding defaults from the keyword-set definition.
\end{describe}

\begin{describe}[KWSET_PARSEFN]{mac}
    {@<declaration-specifiers> KWSET_PARSEFN(@<set>)}

  The macro @|KWSET_PARSEFN| defines a keyword argument \emph{parser
  function}
  \begin{prog}
    void @<set>{}_kwparse(\=struct @<set>{}_kwargs *@<kw>,
                            const char *@<kwfirst>, va_list *@<ap>, \+ \\
                            const struct kwval *@<v>, size_t @<n>);
  \end{prog}
  The macro call can (and usually will) be preceded by storage class
  specifiers such as @|static|, for example to adjust the linkage of the
  name.\footnote{%
    I don't recommend declaring parser functions @|inline|: parser functions
    are somewhat large, and modern compilers are pretty good at figuring out
    whether to inline static functions.} %

  The function's behaviour is as follows.  It parses keyword arguments from a
  variable-length argument tail, and/or a vector of @|kwval| structures.
  When a keyword argument is recognized, for some keyword @<name>, the
  keyword argument structure pointed to by @<kw> is updated: the flag
  @|@<name>{}_suppliedp| is set to 1; and the argument value is stored (by
  simple assignment) in the @<name> member.

  Hence, if the @`_suppliedp' members are initialized to zero, the caller can
  determine which keyword arguments were supplied.  It is not possible to
  discover whether two or more arguments have the same keyword: in this case,
  the value from the last such argument is left in the keyword argument
  structure, and any values from earlier arguments are lost.  (For this
  purpose, the argument vector @<v> is scanned \emph{after} the
  variable-length argument tail captured in @<ap>.)

  The variable-argument tail is read from the list described by @|* @<ap>|.
  The argument tail is expected to consist of alternating keyword strings (as
  ordinary null-terminated strings) and the corresponding values, terminated
  by a null pointer of type @|const char~*| in place of a keyword; except
  that the first keyword (or terminating null pointer, if no arguments are
  provided) is expected to have been extracted already and provided as the
  @<kwfirst> argument; the first argument retrieved using the @|va_list|
  cursor object should then be the value corresponding to the keyword named
  by @<kwfirst>.\footnote{%
    This slightly unusual convention makes it possible for a function to
    collect the first keyword as a separate mandatory argument, which is
    essential if there are no other mandatory arguments.  It also means that
    the compiler will emit a diagnostic if you attempt to call a function
    which expects keyword arguments, but don't supply any and forget the null
    pointer which terminates the (empty) list.} %
  If @<kwfirst> is a null pointer, then @<ap> need not be a valid pointer;
  otherwise, the cursor object @|* @<ap>| will be modified as the function
  extracts successive arguments from the tail.

  The keyword vector is read from the vector of @|kwval| structures starting
  at address @<v> and containing the following @<n> items.  If @<n> is zero
  then @<v> need not be a valid pointer.

  The function also handles the special @|kw.valist| and @|kw.tab| arguments
  described above (\xref{sec:runtime.keywords.calling}).  If an unrecognized
  keyword argument is encountered, then \descref{kw_unknown}{fun} is called.
\end{describe}

\subsubsection{Parsing keywords}
The following macros make use of the definitions described above to actually
make a function's keyword arguments available to it.

\begin{describe}[KW_PARSE]{mac}{KW_PARSE(@<set>, @<kw>, @<kwfirst>);}
  The @|KW_PARSE| macro invokes a keyword argument parsing function.  The
  @<set> argument should name a keyword set; @<kw> should be an lvalue of
  type @|struct @<set>{}_kwargs|; and @<kwfirst> should be the name of the
  enclosing function's last mandatory argument, which must have type @|const
  char~*|.

  It calls the function @|@<set>{}_kwparse| with five arguments: the address
  of the keyword argument structure @<kw>; the string pointer @<kwfirst>; the
  address of a temporary argument-tail cursor object of type @|va_list|,
  constructed on the assumption that @<kwfirst> is the enclosing function's
  final keyword argument; a null pointer; and the value zero (signifying an
  empty keyword-argument vector).

  If the variable @<kw> was declared using \descref{KWDECL}{mac} and the
  function @|@<set>{}_kwparse| has been defined using
  \descref{KWSET_PARSEFN}{mac} then the effect is to parse the keyword
  arguments passed to the function and set the members of @<kw>
  appropriately.
\end{describe}

\begin{describe}[KWPARSE]{mac}{KWPARSE(@<set>);}
  The macro @|KWPARSE| (note the lack of underscore) combines
  \descref{KWDECL}{mac} and \descref{KW_PARSE}{mac}.  It declares and
  initializes a keyword argument structure variable with the fixed name
  @|kw|, and parses the keyword arguments provided to the enclosing function,
  storing the results in @|kw|.  It assumes that the first keyword name is in
  an argument named @|kwfirst_|, as set up by the
  \descref{KWTAIL}[marker]{mac}.

  The macro expands both to a variable declaration and a statement: in C89,
  declarations must precede statements, so under C89 rules this macro must
  appear exactly between the declarations at the head of a brace-enclosed
  block (typically the function body) and the statements at the end.  This
  restriction was lifted in C99, so the macro may appear anywhere in the
  function body.  However, it is recommended that callers avoid taking
  actions which might require cleanup before attempting to parse their
  keyword arguments, since keyword argument parsing functions invoke the
  @|kw_unknown| handler (\xref{sec:runtime.keywords.unknown}) if they
  encounter an unknown keyword, and the calling function will not get a
  chance to tidy up after itself if this happens.
\end{describe}

As mentioned above, it is not permitted to define an empty keyword set.
(Specifically, invoking \descref{KWSET_STRUCT}{mac} for an empty keyword set
would result in attempting to define a structure with no members, which C
doesn't allow.)  On the other hand, keyword arguments are a useful extension
mechanism, and it's useful to be able to define a function which doesn't
currently accept any keywords, but which might in the future be extended to
allow keyword arguments.

\begin{describe}[KW_PARSE_EMPTY]{mac}{KW_PARSE_EMPTY(@<set>, @<kwfirst>);}
  This is an analogue to \descref{KW_PARSE}{mac} which checks the keyword
  argument list for a function which accepts no keyword arguments.

  It calls the \descref{kw_parseempty}[function]{fun} with five arguments:
  the @<set> name, as a string; the string pointer @<kwfirst>; the address of
  a temporary argument-tail cursor object of type @|va_list|, constructed on
  the assumption that @<kwfirst> is the enclosing function's final keyword
  argument; a null pointer; and the value zero (signifying an empty
  keyword-argument vector).

  The effect is to check that the argument tail contains no keyword arguments
  other than the special predefined ones.
\end{describe}

\begin{describe}[KWPARSE_EMPTY]{mac}{KWPARSE_EMPTY(@<set>);}
  This is an analogue to \descref{KWPARSE}{mac} which checks that the
  enclosing function has been passed no keyword arguments other than the
  special predefined ones.  It assumes that the first keyword name is in an
  argument named @|kwfirst_|, as set up by the \descref{KWTAIL}[marker]{mac}.
\end{describe}

\begin{describe}[kw_parseempty]{fun}
    {void kw_parseempty(\=const char *@<set>,
                          const char *@<kwfirst>, va_list *@<ap>, \+ \\
                          const struct kwval *@<v>, size_t @<n>);}
  This function checks an keyword argument list to make sure that contains no
  keyword arguments (other than the special ones described in
  \xref{sec:runtime.keywords.calling}).

  The @<set> argument should point to a null-terminated string: this will be
  reported as the keyword set name to \descref{kw_unknown}{fun}, though it
  need not (and likely will not) refer to any defined keyword set.  The
  remaining arguments are as for the keyword parsing functions defined by the
  \descref{KWSET_PARSEFN}[macro]{mac}.
\end{describe}

\subsection{Function wrappers} \label{sec:runtime.keywords.wrappers}

Most users will not need the hairy machinery involving argument vectors.
Their main use is in defining \emph{wrapper functions}.  Suppose there is a
function @<f> which accepts some keyword arguments, and we want to write a
function @<g> which accepts the same keywords recognized by @<f> and some
additional ones.  Unfortunately @<f> may behave differently depending on
whether or not a particular keyword argument is supplied at all, but it's not
possible to synthesize a valid @|va_list| other than by simply capturing a
live argument tail, and it's not possible to decide at runtime whether or not
to include some arguments in a function call.  It's still possible to write
@<g>, by building a vector of keyword arguments, collected one-by-one
depending on the corresponding @`_suppliedp' flags.

A few macros are provided to make this task easier.

\begin{describe}[KW_COUNT]{mac}{KW_COUNT(@<set>)}
  Returns the number of keywords defined in a keyword set named @<set>.
\end{describe}

\begin{describe}[KW_COPY]{mac}
    {KW_COPY(@<fromset>, @<toset>, @<kw>, @<v>, @<n>);}

  The macro @|KW_COPY| populates a vector of @|kwval| structures from a
  keyword-argument structure.

  The @<fromset> and @<toset> arguments should be the names of keyword sets;
  @<kw> should be an lvalue of type @|@<fromset>{}_kwargs|; @<v> should be
  the base address of a sufficiently large vector of @|struct kwval| objects;
  and @<n> should be an lvalue of some appropriate integer type.  The
  @<toset> must be a subset of @<fromset>: i.e., for every keyword defined in
  @<toset> there is a keyword defined in @<fromset> with the same name and
  type.

  Successive elements of @<v>, starting at index @<n>, are filled in to refer
  to the keyword arguments defined in @<toset> whose @`_suppliedp' flag is
  set in the argument structure pointed to by @<kw>; for each such argument,
  a pointer to the keyword name is stored in the corresponding vector
  element's @|kw| member, and a pointer to the argument value, held in the
  keyword argument structure, is stored in the vector element's @|val|
  member.

  At the end of this, the index @<n> is advanced so as to contain the index
  of the first unused element of @<v>.  Hence, at most @|KW_COUNT(@<toset>)|
  elements of @<v> will be used.
\end{describe}


\subsection{Handling unknown-keyword errors}
\label{sec:runtime.keywords.unknown}

When parsing a variable-length argument tail, it is not possible to continue
after encountering an unknown keyword name.  This is because it is necessary
to know the (promoted) type of the following argument value in order to skip
past it; but the only clue provided as to the type is the keyword name, which
in this case is meaningless.

In this situation, the parser functions generated by
\descref{KWSET_PARSEFN}{mac} (and the \descref{kw_parseempty}[function]{fun})
call @|kw_unknown|.

\begin{describe}[kw_unknown]{fun}
    {void kw_unknown(const char *@<set>, const char *@<kw>);}

  This is a function of two arguments: @<set> points to the name of the
  keyword set expected by the caller, as a null-terminated string; and @<kw>
  is the unknown keyword which was encountered.  All that @|kw_unknown| does
  is invoke the function whose address is stored in the global variable
  \descref{kw_unkhook}{var} with the same arguments.

  This function never returns to its caller: if the @|kw_unkhook| function
  returns (which it shouldn't) then @|kw_unknown| writes a fatal error
  message to the standard error stream and calls \man{abort}{3}.
\end{describe}

\begin{describe}[kw_unkhookfn]{type}
    {typedef void kw_unkhookfn(const char *@<set>, const char *@<kw>);}

  The @|kw_unkhookfn| type is the type of unknown-keyword handler functions.
  A handler function is given two arguments, both of which are pointers to
  null-terminated strings: @<set> is the name of the keyword set expected;
  and @<kw> is the name of the offending unknown keyword.
\end{describe}

\begin{describe}[kw_unkhook]{var}{kw_unkhookfn *kw_unkhook}
  This variable\footnote{%
    Having a single global hook variable is obviously inadequate for a modern
    library, but dealing with multiple threads isn't currently possible
    without writing (moderately complex) system-specific code which would be
    out of place in this library.  The author's intention is that the hook
    variable @|kw_unkhook| be `owned' by some external library which can make
    its functionality available to client programs in a safer and more
    convenient way.  On Unix-like platforms (including Cygwin) that library
    will be (a later version of) \textbf{mLib}; other platforms will likely
    need different arrangements.  The author is willing to coordinate any
    such efforts.} %
  holds the current unknown-keyword handler function.  It will be invoked by
  \descref{kw_unknown}{fun}.  The function may take whatever action seems
  appropriate, but should not return to its caller.

  Initially, this variable points to the
  \descref{kw_defunknown}[function]{fun}.
\end{describe}

\begin{describe}[kw_defunknown]{fun}
    {void kw_defunknown(const char *@<set>, const char *@<kw>);}
  This function simply writes a message to standard error, to the effect that
  the keyword named by @<kw> is not known in the keyword set @<set>, and
  calls \man{abort}{3}.

  This function is the default value of the \descref{kw_unkhook}[hook
  variable]{var}.
\end{describe}

As an example of the kind of special effect which can be achieved using this
hook, the following hacking answers whether a function recognizes a
particular keyword argument.

\begin{prog}
  \#define KWARGS_TEST(k, val) KWARGS(K(k, val) K(kw.unknown, 0))
  \\+
  static jmp_buf kw_test_jmp;
  \\+
  static void kw_test_unknown(const char *set, const char *kw) \\
  \{ \\ \ind
    if (strcmp(kw, "kw.unknown")) longjmp(kw_test_jmp, 1); \\
    else longjmp(kw_test_jmp, 2); \- \\
  \}
  \\+
  \#define KW_TEST(flag, set, call) do \{ @\\ \\ \ind
    kw_unkhookfn *oldunk = kw_unkhook; @\\ \\
    kw_unkhook = kw_test_unknown; @\\ \\
    switch (setjmp(kw_test_jmp)) \{ @\\ \\ \ind
      case 0: call; abort(); @\\ \\
      case 1: flag = 1; break; @\\ \\
      case 2: flag = 0; break; @\\ \\
      default: abort(); \- @\\ \\
    \} @\\ \\
    kw_unkhook = oldunk; \- @\\ \\
  \} while (0)
  \\+
  /* Example of use */ \\
  int f; \\
  KW_TEST(f, somefunc(1, "two", 3, KWARGS_TEST("shiny", 68.7))); \\
  /\=* now f is nonzero if `somefunc' accepts the `shiny' keyword \+ \\
   {}* (which we hope wants a double argument) \\
   {}*/
\end{prog}

%%%--------------------------------------------------------------------------
\section{Object system support} \label{sec:runtime.object}

This section describes the macros and functions exposed in the @|<sod/sod.h>|
header file which provide assistance for working with Sod classes and
objects.

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.


\subsection{Layout utilities} \label{sec:runtime.object.layout}

The following macros are useful in finding one's way around an instance
layout structure, given various levels of information about what kind of
object one is dealing with, or for computing the tables which are used for
this kind of navigation.

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_OFFSETDIFF]{mac}
    {ptrdiff_t SOD_OFFSETDIFF(@<type>, @<member>_1, @<member>_2);}
  Returns the signed offset between two members of a structure or union type.

  Given a structure or union type @<type>, and two member names @<member>_1
  and @<member>_2, then @|SOD_OFFSETDIFF| gives the difference, in bytes,
  between the addresses of objects @|$x$.@<member>_1| and @|$x$.@<member>_2|
  for any object $x$ of type @<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}
    {@<cls>{}__ilayout *SOD_ILAYOUT(@<cls>, @<chead>, const void *@<obj>);}
  Recovers the instance layout base address from a pointer to one of its
  instance chains.

  Specifically, given a class name @<cls>, the nickname @<chead> of the least
  specific class in one of @<cls>'s superclass chains, and a pointer @<obj>
  to the instance storage for the chain containing @<chead> within a direct
  instance of @<cls> (i.e., not an instance of any proper subclass),
  @|SOD_ILAYOUT| returns the a pointer to the layout structure containing
  @<obj>.

  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_INSTBASE]{mac}{void *SOD_INSTBASE(const @<cls> *@<obj>)}
  Finds the base address of an instance's layout.

  Given a pointer @<obj> to an instance, @|SOD_INSTBASE| returns the base
  address of the storage allocated to @<obj>.  This is useful if you want to
  free a dynamically allocated instance, for example.

  This macro needs to look up an offset in @<obj>'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}


\subsection{Classes} \label{sec:runtime.object.class}

The following macros and functions query the runtime relationships between
instances and classes.

\begin{describe}[SOD_CLASSOF]{mac}
    {const SodClass *SOD_CLASSOF(const @<cls> *@<obj>);}
  Returns the class object describing an instance's dynamic class.

  Given a pointer @<obj> to an instance, @|SOD_CLASSOF| returns a pointer to
  @<obj>'s dynamic class, which (assuming @<obj> is typed correctly in the
  first place) will be a subclass of @<cls>.  (If you wanted the class object
  for @<cls> itself, it's called @|@<cls>{}__class|.)
\end{describe}

\begin{describe}[sod_subclassp]{fun}
    {int sod_subclassp(const SodClass *@<sub>, const SodClass *@<super>);}

  Decide whether one class @<sub> is actually a subclass of another class
  @<super>.

  The @<sod_subclassp> function returns nonzero if and only if
  @<sub> is a subclass of @<super>.

  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}


\subsection{Conversions} \label{sec:runtime.object.conversions}

The following macros and functions are used to convert instance pointers of
some (static) type into instance pointers of other static types to the same
instance.

\begin{describe}[SOD_XCHAIN]{mac}
    {void *SOD_CHAIN(@<chead>, const @<cls> *@<obj>);}
  Performs a `cross-chain upcast'.

  Given a pointer @<obj> to an instance of a class of type @<cls> and the
  nickname @<chead> of the least specific class in one of @<cls>'s superclass
  chains which does not contain @<cls> itself, @|SOD_XCHAIN| returns the
  address of that chain's storage within the instance layout as a raw
  @|void~*| pointer.  (Note that @<cls> is not mentioned explicitly.)

  This macro is used by the generated @|@<cls>{}__CONV_@<c>| conversion
  macros, which you are encouraged to use instead where possible.
\end{describe}

\begin{describe*}
    {\dhead[SOD_CONVERT]{mac}
       {@<cls> *SOD_CONVERT(@<cls>, const void *@<obj>);}
     \dhead[sod_convert]{fun}
       {void *sod_convert(const SodClass *@<cls>, const void *@<obj>);}}
  Perform general conversions (up-, down-, and cross-casts) on instance
  pointers.

  Given a class @<cls> and a pointer @<obj> to an instance, return an
  appropriately converted pointer to @<obj> if @<obj> is indeed an instance
  of (some subclass of) @<cls>; otherwise return a null pointer.

  The @|SOD_CONVERT| macro expects @<cls> to be a class name; the
  @|sod_convert| function expects a pointer to a class object instead.

  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 @<cls> is a superclass of the static type of @<obj>) 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 than the @|sod_convert| function, since the
  class object name is longer and uglier, and the macro returns a pointer of
  the correct type.
\end{describe*}


\subsection{Instance lifecycle}
\label{sec:runtime.object.lifecycle}

The following macros and functions manage the standard steps along an
instance's lifecycle.

\subsubsection{Low-level operations}
The following macros and functions are agnostic with respect to storage
allocation strategies.  They don't concern themselves with allocation or
deallocation, and applications are free to use any suitable mechanism.

\begin{describe*}
    {\dhead[SOD_INIT]{mac}
       {@<cls> *SOD_INIT(@<cls>, void *@<p>, @<keywords>);}
     \dhead[sod_init]{fun}
       {void *sod_init(const SodClass *@<cls>, void *@<p>, \dots);}
     \dhead[sod_initv]{fun}
       {void *sod_initv(const SodClass *@<cls>, void *@<p>, va_list @<ap>);}}
  Imprints and initializes an instance of a class @<cls> in the storage
  starting at address~@<p>.

  The direct class for the new instance is specified as a class name to
  @|SOD_INIT|, or a pointer to a class object to the functions.

  Keyword arguments for the initialization message may be provided.  The
  @|SOD_INIT| macro expects a single preprocessor-time argument which is
  a use of one of \descref{KWARGS}{mac} or \descref{NO_KWARGS}{mac}; the
  @|sod_init| function expects the keywords as a variable-length argument
  tail; and @|sod_initv| expects the keywords to be passed indirectly,
  through the captured argument-tail cursor @<ap>.

  The return value is an instance pointer for the class @<cls>; the
  @|SOD_INIT| macro will have converted it to the correct type, so it should
  probably be used where possible.  In fact, this is guaranteed to be equal
  to @<p> by the layout rules described in
  \xref{sec:structures.layout.instance}.
\end{describe*}

\begin{describe}[sod_teardown]{fun}{int sod_teardown(void *@<p>);}
  Tears down an instance of a class, releasing any resources it holds.

  This function is a very thin wrapper around sending the @|obj.teardown|
  message.  See the description of that message
  (page~\pageref{msg:obj.teardown}) and \xref{sec:concepts.lifecycle.death}
  for details.
\end{describe}

\subsubsection{Automatic storage duration}
The following macro constructs an instance with automatic storage duration.

\begin{describe}[SOD_DECL]{mac}{SOD_DECL(@<cls>, @<var>, @<keywords>);}
  Declares and initializes an instance with automatic storage duration.

  Given a class name @<cls> and an identifier @<var>, @|SOD_DECL| declares
  @<var> to be a pointer to an instance of @<cls>.  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.

  Keyword arguments for the initialization message may be provided.  The
  macro expects a single preprocessor-time argument which is a use of one of
  \descref{KWARGS}{mac} or \descref{NO_KWARGS}{mac}.

  The instance has automatic storage duration: pointers to it will become
  invalid when control exits the scope of the declaration.  If necessary, the
  instance should be torn down before this happens, using the
  \descref{sod_teardown}[function]{fun}.
\end{describe}

\subsubsection{Dynamic allocation}
The following macros and functions deal with objects allocated from the
standard C heap.  They don't work in freestanding implementations where
@|malloc| and @|free| are not available.

\begin{describe*}
    {\dhead[SOD_MAKE]{mac}{@<cls> *SOD_MAKE(@<cls>, @<keywords>);}
     \dhead[sod_make]{fun}{void *sod_make(const SodClass *@<cls>, \dots);}
     \dhead[sod_makev]{fun}
       {void *sod_makev(const SodClass *@<cls>, va_list @<ap>);}}
  Constructs and returns a pointer to a new instance of @<cls>.

  The direct class for the new instance is specified as a class name to
  @|SOD_MAKE|, or a class object to the functions.

  Keyword arguments for the initialization message may be provided.  The
  @|SOD_MAKE| macro expects a single preprocessor-time argument which is
  a use of one of \descref{KWARGS}{mac} or \descref{NO_KWARGS}{mac}; the
  @|sod_make| function expects the keywords as a variable-length argument
  tail; and @|sod_makev| expects the keywords to be passed indirectly,
  through the captured argument-tail cursor @<ap>.

  Storage for the new instance will have been allocated using the standard
  @|malloc| function.  The easiest way to destroy the instance, when it is no
  longer needed, is probably to call the
  \descref{sod_destroy}[function]{fun}.

  The return value is an instance pointer for the class @<cls>; the
  @|SOD_MAKE| macro will have converted it to the correct type, so it should
  probably be used where possible.
\end{describe*}

\begin{describe}[sod_destroy]{fun}{int sod_destroy(void *@<p>);}
  Tears down and frees an instance allocated using @|malloc|.

  The pointer @<p> should be an instance pointer, i.e., a pointer to any of
  an instance's chains.  The instance is torn down, by sending it the
  \descref{obj.teardown}[message]{msg}.  If the instance reports itself ready
  for deallocation, then its storage is released using @|free|.  The return
  value is the value returned by the @|obj.teardown| message.
\end{describe}

%%%----- That's all, folks --------------------------------------------------

%%% Local variables:
%%% mode: LaTeX
%%% TeX-master: "sod.tex"
%%% TeX-PDF-mode: t
%%% End:
