%%% -*-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 @|<sod/sod.h>| 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(@<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 @|@<CLASS>{}__CONV_@<CLS>| conversion
  macros, which you are encouraged to use instead where possible.
\end{describe}

\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_CAR]{mac} {@<arg> SOD_CAR(@<arg>, @<other-arg>^*)}
  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 @<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_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}

\begin{describe}[SOD_CONVERT]{mac}
    {@<cls> *SOD_CONVERT(@<cls>, const void *@<obj>)}

  Perform general conversions (up-, down-, and cross-casts) on instance
  pointers.

  Given a class name @<cls> and a pointer @<obj> to an instance,
  @|SOD_CONVERT| returns an appropriately converted pointer to @<obj> if
  @<obj> is indeed an instance of (some subclass of) @<cls>; 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(@<cls>, @<var>)}
  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.

  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 @<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}

\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 @<cls> and an instance pointer @<obj>, @|sod_convert|
  returns an appropriately converted pointer to @<obj> in the case that
  @<obj> is an instance of (some subclass of) @<cls>; 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 @<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
  instead.
\end{describe}

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

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