view doc/manual/manual_overview.tex @ 665:ef356272a1c7 default tip

- introduced Makefile var APP_SUFFIX to handle cases where compilers implicitly add an extension to executables (e.g. llvm/mingw64 adds .exe even of not specified via -o)
author Tassilo Philipp
date Thu, 20 Jun 2024 17:10:12 +0200
parents bf78e6542ef9
children
line wrap: on
line source

%//////////////////////////////////////////////////////////////////////////////
%
% Copyright (c) 2007-2019 Daniel Adler <dadler@uni-goettingen.de>, 
%                         Tassilo Philipp <tphilipp@potion-studios.com>
%
% Permission to use, copy, modify, and distribute this software for any
% purpose with or without fee is hereby granted, provided that the above
% copyright notice and this permission notice appear in all copies.
%
% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
%
%//////////////////////////////////////////////////////////////////////////////

\clearpage

\section{Overview}

The \product{dyncall} library encapsulates architecture-, OS- and compiler-specific
function call semantics in a virtual %
%
\casehtml{\Tg<span class="marker">}{\begin{center}}%
\emph{bind argument parameters from left to right and then call}
\casehtml{\Tg</span>}{\end{center}}%
 %
interface allowing programmers to call C functions 
in a completely dynamic manner. In other words, instead of calling a function 
directly, the \product{dyncall} library provides a mechanism to push the function parameters 
manually and to issue the call afterwards.\\
Since the idea behind this concept is similar to call dispatching mechanisms
of virtual machines, the object that can be dynamically loaded with arguments,
and then used to actually invoke the call, is called CallVM. It is possible to
change the calling convention used by the CallVM at run-time.
Due to the fact that nearly every platform comes with one or more distinct calling
conventions, the \product{dyncall} library project intends to be a portable and open-source
approach to the variety of compiler-specific binary interfaces, platform specific
subtleties, and so on\ldots\\
\\
The core of the library consists of dynamic implementations of different 
calling conventions written in assembler.
Although the library aims to be highly portable, some assembler code needs to 
be written for nearly every platform/compiler/OS combination.
Unfortunately, there are architectures we just don't have at home or work. If 
you want to see \product{dyncall} running on such a platform, feel free to send
in code and patches, or even to donate hardware you don't need anymore.
Check the \textbf{supported platforms} section for an overview of the supported 
platforms and the different calling convention sections for details about the 
support.
\\
\begin{comment}
@@@
A typical binary library consists of symbolic names that map to variables and
functions, the latter being pre-compiled for a
specific calling convention and architecture. Given \product{dyncall} has been ported to
that binary platform, it is possible to call such a function dynamically 
without writing glue code or prototypes or even knowing its C declaration - 
all that is needed is a pointer to it.\\
To avoid confusion, note that from the point of view of the library all 
parameters are handled the same way, even though the implementation might use
other ways to pass parameters in order to suit specific calling conventions.\\
\end{comment}


\subsection{Features}

\begin{itemize}
\item A portable and extendable function call interface for the C programming 
language.
\item Ports to major platforms including Windows, Mac OS X, Linux, BSD derivates, iPhone and embedded devices and more, including lesser known and/or older platforms like Plan 9, Playstation Portable, Nintendo DS, etc..
\item Add-on language bindings to Python, R, Ruby, Go, Erlang, Java, Lua, sh, ...
\item High-level state machine design using C to model calling convention
parameter transfer.
\item One assembly \emph{hybrid} call routine per calling convention.
\item Formatted call, vararg function API.
\item Comprehensive test suite.
\end{itemize}

\pagebreak

\subsection{Showcase}

\paragraph{Foreign function call in C}
This section demonstrates how the foreign function call is issued without, and then 
with, the help of the \product{dyncall} library and scripting language
bindings.

\begin{lstlisting}[language=c,caption=Foreign function call in C]
double call_as_sqrt(void* funptr, double x)
{
  return ( ( double (*)(double) )funptr)(x);
}
\end{lstlisting}

\paragraph{\product{Dyncall} C library example}

The same operation can be broken down into atomic pieces 
(specify calling convention, binding arguments, invoking the call)
using the \dc\ library.

\begin{lstlisting}[language=c,caption=Dyncall C library example]
#include <dyncall.h>
double call_as_sqrt(void* funptr, double x)
{
  double r;
  DCCallVM* vm = dcNewCallVM(4096);
  dcMode(vm, DC_CALL_C_DEFAULT);
  dcReset(vm);
  dcArgDouble(vm, x);  
  r = dcCallDouble(vm, funptr);
  dcFree(vm);
  return r;
}
\end{lstlisting}

This is more code than a direct, hardcoded function call, however it's completely dynamic.
Also, despite this coming with an overhead of more executed code per single function call,
compared to function interface wrapper tools that generate per call glue-code less code is
used overall, . % might want to test this claim against swig, etc.

The following are examples from script bindings:

\paragraph{Python example}

\begin{lstlisting}[language=python,caption=Dyncall Python bindings example]
import pydc
def call_as_sqrt(funptr,x):
  return pydc.call(funptr,"d)d", x)
\end{lstlisting}


\paragraph{R example}

\begin{lstlisting}[language=R,caption=Dyncall R bindings example,escapeinside={TEX}{XET}] % escapeinside is a workaround for issues with '<' in lstlisting+tex4ht
library(rdyncall)
call.as.sqrt TEX\textlessXET- function(funptr,x)
  .dyncall(funptr,"d)d", x)
\end{lstlisting}


\pagebreak

\subsection{Supported platforms/architectures}

The feature matrix below gives a brief overview of the currently supported
platforms. Different colors are used, where a green cell indicates a supported
platform, with both, call and callback support, yellow a platform that might
work (but is untested) and red a platform that is currently unsupported. Gray
cells are combinations that don't exist at the time of writing, or that are not
taken into account.\\
Light green cells mark complete feature support, including passing aggregates
(struct, union) by value. Dark green means basic support but lacking lesser
used features (e.g. no aggregate-by-value support). Please note that a green
cell (even a light-green one) doesn't imply that all existing calling
conventions/features/build tools are supported for that platform (but the most
important).
% @@@ The rightmost column gives a brief info about calling convention support or other notes.


% colors used to signalize undefined, not used, supported, etc. states.
\newcommand{\marknull}{\cellcolor{white}}
\newcommand{\markcmpl}{\cellcolor{lightgreen}}
\newcommand{\markimpl}{\cellcolor{darkgreen}}
\newcommand{\marknimp}{\cellcolor{red}}
\newcommand{\markunkn}{\cellcolor{yellow}}
\newcommand{\marknotx}{\cellcolor{gray1}}

\newcommand{\OSwinfam} {\ninety{Windows family}             }
\newcommand{\OSlinux}  {\ninety{Linux}                      }
\newcommand{\OSdarwin} {\ninety{macOS / iOS / Darwin}       }
\newcommand{\OSfreebsd}{\ninety{FreeBSD}                    }
\newcommand{\OSnetbsd} {\ninety{NetBSD}                     }
\newcommand{\OSopenbsd}{\ninety{OpenBSD}                    }
\newcommand{\OSdflybsd}{\ninety{DragonFlyBSD}               }
\newcommand{\OSsunos}  {\ninety{Solaris / SunOS}            }
\newcommand{\OSplanN}  {\ninety{Plan 9 / 9front}            }
\newcommand{\OSbeos}   {\ninety{Haiku / BeOS}               }
\newcommand{\OSminix}  {\ninety{Minix}                      }
\newcommand{\OSpsp}    {\ninety{Playstation Portable (EABI)}}
\newcommand{\OSnds}    {\ninety{Nintendo DS}                }

% also include hardfloat/softfloat @@@
\begin{table}[h]
\begin{tabular}{r>{\rule{0pt}{2.5ex}\tiny}l*{12}{c!{\color{gray3}\vrule}}c>{\tiny}l}
                           &            & \OSwinfam  & \OSlinux   & \OSdarwin  & \OSfreebsd & \OSnetbsd  & \OSopenbsd & \OSdflybsd & \OSsunos   & \OSplanN   & \OSbeos    & \OSminix   & \OSpsp     & \OSnds    \\%& \\
\arrayrulecolor{gray3}%            
\multirow{2}{*}{ARM}       & EB         & \marknotx  & \markunkn  & \marknotx  & \markunkn  & \markunkn  & \markunkn  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \multirow{2}{*}{atpcs (arm \& thumb), eabi (arm \& thumb), armhf} \\
\hhline{*{1}{|~}*{14}{|-}}%               ^- checked   ^- find@@@   ^- checked   ^- find@@@   ^- find@@@   ^- find@@@   ^- checked   ^- checked   ^- checked   ^- new@@@   ^- checked    ^- checked   ^- checked
                           & EL         & \markunkn  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \marknotx  & \marknotx  & \marknimp  & \marknotx  & \markunkn  & \marknotx  & \markimpl \\%& \\
\hline%                                   ^- dynOS     ^- dynOS     ^- real/iPho ^- dynOS     ^- dynOS     ^- real/bbb  ^- checked   ^- checked   ^- checked   ^- new@@@   ^- new@@@     ^- checked   ^- checked
\multirow{2}{*}{ARM64}     & EB         & \marknotx  & \markunkn  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \multirow{2}{*}{aapcs64, apple} \\
\hhline{*{1}{|~}*{14}{|-}}%               ^- checked   ^- find@@@   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
                           & EL         & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markunkn  & \markimpl  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hline%                                   ^- checked   ^- find@@@   ^- real/iPho ^- checked   ^- find@@@   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
\multirow{2}{*}{MIPS}      & EB         & \marknotx  & \markimpl  & \marknotx  & \markimpl  & \markunkn  & \marknotx  & \marknotx  & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \multirow{2}{*}{o32 (hf \& sf), eabi (hf only)} \\
\hhline{*{1}{|~}*{14}{|-}}%               ^- checked   ^- dynOS     ^- checked   ^- checked   ^- find@@@   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
                           & EL         & \marknotx  & \markunkn  & \marknotx  & \markimpl  & \markimpl  & \markunkn  & \marknotx  & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \markimpl  & \marknotx \\%& \\
\hline%                                   ^- checked   ^- find@@@   ^- checked   ^- checked   ^- dynOS     ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
\multirow{2}{*}{MIPS64}    & EB         & \marknotx  & \markunkn  & \marknotx  & \markimpl  & \markunkn  & \markimpl  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \multirow{2}{*}{n64 (hf only), n32 (hf only)} \\
\hhline{*{1}{|~}*{14}{|-}}%               ^- checked   ^- find@@@   ^- checked   ^- checked   ^- find@@@   ^- real/ERlt ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
                           & EL         & \marknotx  & \markimpl  & \marknotx  & \markimpl  & \markunkn  & \markunkn  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hline%                                   ^- checked   ^- dynOS     ^- checked   ^- checked   ^- find@@@   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
\multirow{2}{*}{SuperH}    & EB         & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hhline{*{1}{|~}*{14}{|-}}%               ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
                           & EL         & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \marknimp  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hline%                                   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
\multirow{2}{*}{PowerPC}   & EB         & \marknotx  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markunkn  & \marknotx  & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \multirow{2}{*}{apple, sysv}\\
\hhline{*{1}{|~}*{14}{|-}}%               ^- checked   ^- dynOS     ^-dynOS      ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
                           & EL         & \marknotx  & \markunkn  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hline%                                   ^- checked   ^- find@@@   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
\multirow{2}{*}{PowerPC64} & EB         & \marknotx  & \markimpl  & \markunkn  & \markimpl  & \marknotx  & \markunkn  & \marknotx  & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \multirow{2}{*}{elf} \\
\hhline{*{1}{|~}*{14}{|-}}%               ^- checked   ^- masanori@ ^- checked   ^- dynOS     ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
                           & EL         & \marknotx  & \markimpl  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hline%                                   ^- checked   ^- masanori@ ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
m68k                       &            & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \marknimp  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hline
m88k                       &            & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \marknimp  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hline
x86                        &            & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \markimpl  & \marknotx  & \marknotx \\%& cdecl, stdcall, fastcall (MS \& GNU), thiscall (MS \& GNU), plan9 \\
\hline
x64                        &            & \markcmpl  & \markcmpl  & \markcmpl  & \markcmpl  & \markcmpl  & \markcmpl  & \markcmpl  & \markcmpl  & \marknimp  & \markcmpl  & \marknotx  & \marknotx  & \marknotx \\%& ms, sysv\\
\hline
Itanium                    &            & \marknimp  & \marknimp  & \marknotx  & \marknimp  & \marknimp  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hline
SPARC                      &            & \marknotx  & \markimpl  & \marknotx  & \marknotx  & \markimpl  & \markimpl  & \marknotx  & \markimpl  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& v7, v8\\
\hline
SPARC64                    &            & \marknotx  & \markimpl  & \marknotx  & \markimpl  & \markimpl  & \markimpl  & \marknotx  & \markimpl  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& v9 \\
\hline
RISC-V                     &            & \marknotx  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hline
\multirow{2}{*}{RISC-V 64} & rv64imac   & \marknotx  & \marknimp  & \marknotx  & \marknimp  & \marknimp  & \marknimp  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx  & \marknotx \\%& \\
\hhline{*{1}{|~}*{14}{|-}}%               ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked   ^- checked
                           & rv64imafdc & \marknotx  & \markimpl  & \marknotx  & \markimpl  & \markunkn  & \markunkn  & \marknotx  & \marknotx  & \marknotx  & \markimpl  & \marknotx  & \marknotx  & \marknotx \\%& \\
%                                         ^- checked   ^- dynOS     ^- checked   ^- dynOS     ^- find@@@   ^- find@@@   ^- checked   ^- checked   ^- checked   ^- dynOS     ^- checked   ^- checked   ^- checked

\end{tabular}
\caption{Supported platforms}%
\end{table}


\subsection{Build Requirements}

The library needs at least a c99 compiler with additional support for anonymous
structs/unions (which were introduced officially in c11). Given that those are
generally supported by pretty much all major c99 conforming compilers (as
default extension), it should build fine with a c99 toolchain.