Mercurial > pub > dyncall > dyncall
view doc/manual/manual_dyncall_api.tex @ 36:93f315f02a32
- armhf dyncall optimization/cleanup
author | cslag |
---|---|
date | Fri, 18 Dec 2015 01:07:40 +0100 |
parents | 3e629dc19168 |
children | 9bd3c5219505 |
line wrap: on
line source
%////////////////////////////////////////////////////////////////////////////// % % Copyright (c) 2007,2010 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. % %////////////////////////////////////////////////////////////////////////////// \newpage \section{\emph{Dyncall} C library API} The library provides low-level functionality to make foreign function calls from different run-time environments. The flexibility is constrained by the set of supported types. \paragraph{C interface style conventions} This manual and the \product{dyncall} library's C interface {\tt "dyncall.h"} use the following C source code style. \begin{table}[h] \begin{center} \begin{tabular*}{0.8\textwidth}{llll} \hline Subject & C symbol & Details & Example \\ \hline Types & {\tt DC\group{type name}} & lower-case & \capi{DCint}, \capi{DCfloat}, \capi{DClong}, \ldots\\ Structures & {\tt DC\group{structure name}} & camel-case & \capi{DCCallVM}\\ Functions & {\tt dc\group{function name}} & camel-case & \capi{dcNewCallVM}, \capi{dcArgInt}, \ldots\\ \hline \end{tabular*} \caption{C interface conventions} \label{sourcecode} \end{center} \end{table} \subsection{Supported C/C++ argument and return types} \begin{table}[h] \begin{center} \begin{tabular*}{0.75\textwidth}{ll} \hline Type alias & C/C++ data type\\ \hline DCbool & \_Bool, bool\\ DCchar & char\\ DCshort & short\\ DCint & int\\ DClong & long\\ DClonglong & long long\\ DCfloat & float\\ DCdouble & double\\ DCpointer & void*\\ DCvoid & void\\ \hline \end{tabular*} \caption{Supported C/C++ argument and return types} \label{types} \end{center} \end{table} \pagebreak \subsection{Call Virtual Machine - CallVM} This \emph{CallVM} is the main entry to the functionality of the library. \paragraph{Types} \begin{lstlisting}[language=c] typedef void DCCallVM; /* abstract handle */ \end{lstlisting} \paragraph{Details} The \emph{CallVM} is a state machine that manages all aspects of a function call from configuration, argument passing up the actual function call on the processor. \subsection{Allocation} \paragraph{Functions} \begin{lstlisting}[language=c] DCCallVM* dcNewCallVM (DCsize size); void dcFree(DCCallVM* vm); \end{lstlisting} \lstinline{dcNewCallVM} creates a new \emph{CallVM} object, where \lstinline{size} specifies the max size of the internal stack that will be allocated and used to bind arguments to. Use \lstinline{dcFree} to destroy the \emph{CallVM} object.\\ \\ This will allocate memory using the system allocators or custom ones provided custom \capi{dcAllocMem} and \capi{dcFreeMem} macros are defined to override the default behaviour. See \capi{dyncall\_alloc.h} for defails. \subsection{Error Reporting} \paragraph{Function} \begin{lstlisting}[language=c] DCint dcGetError(DCCallVM* vm); \end{lstlisting} Returns the most recent error state code out of the following: \paragraph{Errors} \begin{table}[h] \begin{center} \begin{tabular*}{0.75\textwidth}{ll} \hline Constant & Description\\ \hline \lstinline@DC_ERROR_NONE@ & No error occured. \\ \lstinline@DC_ERROR_UNSUPPORTED_MODE@ & Unsupported mode, caused by \lstinline@dcMode()@ \\ \hline \end{tabular*} \caption{CallVM calling convention modes} \label{errorcodes} \end{center} \end{table} \pagebreak \subsection{Configuration} \paragraph{Function} \begin{lstlisting}[language=c] void dcMode (DCCallVM* vm, DCint mode); \end{lstlisting} Sets the calling convention to use. Note that some mode/platform combination don't make any sense (e.g. using a PowerPC calling convention on a MIPS platform) and are silently ignored. \paragraph{Modes} \begin{table}[h] \begin{center} \begin{tabular*}{0.75\textwidth}{ll} \hline Constant & Description\\ \hline \lstinline@DC_CALL_C_DEFAULT@ & C default function call for current platform\\ \lstinline@DC_CALL_C_ELLIPSIS@ & C ellipsis function call (named arguments (before '...'))\\ \lstinline@DC_CALL_C_ELLIPSIS_VARARGS@ & C ellipsis function call (variable/unnamed arguments (after '...'))\\ \lstinline@DC_CALL_C_X86_CDECL@ & C x86 platforms standard call\\ \lstinline@DC_CALL_C_X86_WIN32_STD@ & C x86 Windows standard call\\ \lstinline@DC_CALL_C_X86_WIN32_FAST_MS@ & C x86 Windows Microsoft fast call\\ \lstinline@DC_CALL_C_X86_WIN32_FAST_GNU@ & C x86 Windows GCC fast call\\ \lstinline@DC_CALL_C_X86_WIN32_THIS_MS@ & C x86 Windows Microsoft this call\\ \lstinline@DC_CALL_C_X86_WIN32_THIS_GNU@ & C x86 Windows GCC this call\\ \lstinline@DC_CALL_C_X86_PLAN9@ & C x86 Plan9 call\\ \lstinline@DC_CALL_C_X64_WIN64@ & C x64 Windows standard call\\ \lstinline@DC_CALL_C_X64_SYSV@ & C x64 System V standard call\\ \lstinline@DC_CALL_C_PPC32_DARWIN@ & C ppc32 Mac OS X standard call\\ \lstinline@DC_CALL_C_PPC32_OSX@ & alias for DC\_CALL\_C\_PPC32\_DARWIN\\ \lstinline@DC_CALL_C_PPC32_SYSV@ & C ppc32 SystemV standard call\\ \lstinline@DC_CALL_C_PPC32_LINUX@ & alias for DC\_CALL\_C\_PPC32\_SYSV\\ \lstinline@DC_CALL_C_PPC64@ & C ppc64 SystemV standard call\\ \lstinline@DC_CALL_C_PPC64_LINUX@ & alias for DC\_CALL\_C\_PPC64\\ \lstinline@DC_CALL_C_ARM_ARM@ & C arm call (arm mode)\\ \lstinline@DC_CALL_C_ARM_THUMB@ & C arm call (thumb mode)\\ \lstinline@DC_CALL_C_ARM_ARM_EABI@ & C arm eabi call (arm mode)\\ \lstinline@DC_CALL_C_ARM_THUMB_EABI@ & C arm eabi call (thumb mode)\\ \lstinline@DC_CALL_C_ARM_ARMHF@ & C arm call (arm hardfloat - e.g. raspberry pi)\\ \lstinline@DC_CALL_C_ARM64@ & C arm64 call (AArch64)\\ \lstinline@DC_CALL_C_MIPS32_EABI@ & C mips32 eabi call\\ \lstinline@DC_CALL_C_MIPS32_PSPSDK@ & alias for DC\_CALL\_C\_MIPS32\_EABI (deprecated)\\ \lstinline@DC_CALL_C_MIPS32_O32@ & C mips32 o32 call\\ \lstinline@DC_CALL_C_MIPS64_N64@ & C mips64 n64 call\\ \lstinline@DC_CALL_C_MIPS64_N32@ & C mips64 n32 call\\ \lstinline@DC_CALL_C_SPARC32@ & C sparc32 call\\ \lstinline@DC_CALL_C_SPARC64@ & C sparc64 call\\ \lstinline@DC_CALL_SYS_DEFAULT@ & C default syscall for current platform\\ \lstinline@DC_CALL_SYS_X86_INT80H_BSD@ & C syscall for x86 BSD platforms\\ \lstinline@DC_CALL_SYS_X86_INT80H_LINUX@ & C syscall for x86 Linux\\ \lstinline@DC_CALL_SYS_PPC32@ & C syscall for ppc32 Linux\\ \hline \end{tabular*} \caption{CallVM calling convention modes} \label{callingconventionmodes} \end{center} \end{table} \paragraph{Details} \lstinline@DC_CALL_C_DEFAULT@ is the default standard C call on the target platform. It uses the standard C calling convention. \lstinline@DC_CALL_C_ELLIPSIS@ is used for C ellipsis calls which allow to build up a variable argument list. On many platforms, there is only one C calling convention. The X86 platform provides a rich family of different calling conventions. \\ \subsection{Machine state reset} \begin{lstlisting}[language=c] void dcReset(DCCallVM* vm); \end{lstlisting} Resets the internal stack of arguments and prepares it for the selected mode. This function should be called after setting the call mode (using dcMode), but prior to binding arguments to the CallVM. Use it also when reusing a CallVM, as arguments don't get flushed automatically after a function call invocation.\\ \subsection{Argument binding} \paragraph{Functions} \begin{lstlisting}[language=c] void dcArgBool (DCCallVM* vm, DCbool arg); void dcArgChar (DCCallVM* vm, DCchar arg); void dcArgShort (DCCallVM* vm, DCshort arg); void dcArgInt (DCCallVM* vm, DCint arg); void dcArgLong (DCCallVM* vm, DClong arg); void dcArgLongLong(DCCallVM* vm, DClonglong arg); void dcArgFloat (DCCallVM* vm, DCfloat arg); void dcArgDouble (DCCallVM* vm, DCdouble arg); void dcArgPointer (DCCallVM* vm, DCpointer arg); \end{lstlisting} \paragraph{Details} Used to bind arguments of the named types to the CallVM object. Arguments should be bound in \emph{left-to-right} order regarding the C function prototype.\\ \subsection{Call invocation} \paragraph{Functions} \begin{lstlisting}[language=c] DCvoid dcCallVoid (DCCallVM* vm, DCpointer funcptr); DCbool dcCallBool (DCCallVM* vm, DCpointer funcptr); DCchar dcCallChar (DCCallVM* vm, DCpointer funcptr); DCshort dcCallShort (DCCallVM* vm, DCpointer funcptr); DCint dcCallInt (DCCallVM* vm, DCpointer funcptr); DClong dcCallLong (DCCallVM* vm, DCpointer funcptr); DClonglong dcCallLongLong(DCCallVM* vm, DCpointer funcptr); DCfloat dcCallFloat (DCCallVM* vm, DCpointer funcptr); DCdouble dcCallDouble (DCCallVM* vm, DCpointer funcptr); DCpointer dcCallPointer (DCCallVM* vm, DCpointer funcptr); \end{lstlisting} \paragraph{Details} Calls the function specified by \emph{funcptr} with the arguments bound to the \emph{CallVM} and returns. Use the function that corresponds to the dynamically called function's return value.\\ \\ After the invocation of the foreign function call, the argument values are still bound and a second call using the same arguments can be issued. If you need to clear the argument bindings, you have to reset the \emph{CallVM}. \subsection{Formatted argument binding and calls (ANSI C ellipsis interface)} \paragraph{Functions} \begin{lstlisting}[language=c] void dcArgF (DCCallVM* vm, const DCsigchar* signature, ...); void dcVArgF(DCCallVM* vm, const DCsigchar* signature, va_list args); void dcCallF (DCCallVM* vm, DCValue* result, DCpointer funcptr, const DCsigchar* signature, ...); void dcVCallF(DCCallVM* vm, DCValue* result, DCpointer funcptr, const DCsigchar* signature, va_list args); \end{lstlisting} \paragraph{Details} These functions can be used to operate \product{dyncall} via a printf-style functional interface, using a signature string encoding the argument types and return type. \capi{dcArgF()} and \capi{dcVArgF()} just bind arguments to the \capi{DCCallVM} object, so any return value specified in the signature is ignored. \capi{dcCallF()} and \capi{dcVCallF()} also take a function pointer to call after binding the arguments. The return value will be stored in what \lstinline{result} points to. For more information about the signature format, refer to \ref{sigchar}.