view release on metacpan or search on metacpan
- Provide default values in Struct[]
- Ignore perl's PTRSIZE which might be different than the system's actual pointer size
- Cleanup VM on Affix::END()
- Simplify API around named subs
- Support for WStr (wchar_t *, PWSTR, etc.)
0.09 2023-01-26T01:36:55Z
- Structs may now contain a CodeRef
- CodeRef, Any, etc. are now properly handled as aggregate members
- Nesting CodeRefs used as callbacks work now
- Bind to exported values with pin()
- Expose aggregate by value and syscall support in Affix::Feature
- Survive callbacks with unexpectedly empty return values
- Delayed type resolution with InstanceOf
0.08 2022-12-19T22:29:53Z
- Correct struct alignment for perls with quadmath and/or longdouble enabled
0.07 2022-12-17T02:41:44Z
- Pull upstream changes to dyncall 1.5 (unstable)
t/01_types_and_pointers.t
t/02_affix_wrap_sin.t
t/06_affix_synopsis.t
t/07_affix_locate_lib.t
t/41_affix_argless.t
t/42_affix_simple_args.t
t/43_affix_simple_returns.t
t/44_affix_aggr_args.t
t/50_affix_pointers.t
t/51_affix_sizeof_offsetof.t
t/54_affix_callbacks.t
t/55_affix_enum.t
t/56_affix_arrayref.t
t/58_affix_import_vars.t
t/63_affix_raw_pointer.t
t/64_affix_wchar_t.t
t/70_affix_varargs.t
t/80_affix_mangle.t
t/82_affix_mangle_itanium.t
t/85_affix_mangle_rust.t
t/99_valgrind.t
t/lib/nativecall.pm
t/src/41_argless.c
t/src/42_simple_args.c
t/src/43_simple_returns.c
t/src/44_affix_aggr_args.c
t/src/50_affix_pointers.c
t/src/51_affix_sizeof_offsetof.c
t/src/54_affix_callbacks.c
t/src/55_affix_enum.c
t/src/56_affix_arrayref.c
t/src/58_affix_import_vars.c
t/src/64_affix_wchar_t.c
t/src/70_affix_varargs.c
t/src/82_affix_mangle_itanium.cxx
t/src/85_affix_mangle_rust/Cargo.toml
t/src/85_affix_mangle_rust/src/lib.rs
t/src/99_valgrind.c
t/src/std.h
```perl
Union[
c => ArrayRef[Char, 5],
f => Float
];
```
## `CodeRef[ ... ]`
A value where `ref($value)` equals `CODE`. This would be how callbacks are
defined.
The argument list and return value must be defined. For example,
`CodeRef[[Int, Int]=`Int\]> ~~ `typedef int (*fuc)(int a, int b);`; that is to
say our function accepts two integers and returns an integer.
```perl
CodeRef[[] => Void]; # typedef void (*function)();
CodeRef[[Pointer[Int]] => Int]; # typedef Int (*function)(int * a);
CodeRef[[Str, Int] => Struct[...]]; # typedef struct Person (*function)(chat * name, int age);
dyncall/ChangeLog view on Meta::CPAN
dynload:
o build fix for ReactOS with RosBE/cmake/mingw-make environment
general:
o more robust detection of platform endianness (on some platforms inclusion
of endian.h led to wrong assumptions)
tests:
o call_suite: simplified and extended to test also unsigned types, and _Bool
o callback_suite: refactored to be much more like call_suite test
o call_suite_aggrs: new test suite for calls with aggregate arguments and
return types (structs, unions and arrays as aggregate members)
o callback_suite_aggrs: new test suite, like call_suite_aggrs but for callbacks
o plain: added some aggregate-as-vararg-by-value tests
o plain_c++: added non-trivial C++ aggregate tests
o callback_plain_c++: new test, focusing on methods and non-trivial C++ aggregates
o simplifications and major refactoring to share more code (especially
signature and case generator) across test suites
o dynload_plain: simplified build and robustness fixes on some platforms
buildsys:
o ./configure output for sun make builds: set correct C++ compiler flag var
o ./configure for SunOS now uses isainfo(1) to deduce native instruction set
o added explicit arm64 target, and clang tool options to Windows' configure.bat
dyncall/ChangeLog view on Meta::CPAN
o new platform support: arm/iphone (armv6), x86/Plan9
o new MIPS calling conventions: o32, n64 (both endian models)
o cleanup: unexported functions in MASM files, b/c export not needed (thanks Olivier)
o interface update: added error reporting facility 'dcGetError'
o bugfix for ppc32/sysv: ellipsis calls were broken
o interface update: added new abstract mode for ellipsis calls (DC_CALL_C_ELLIPSIS)
docs:
o comprehensive update
tests:
o plain: split "plain" test up in C and C++ part
o callbacksuite: added multiple configuration support for callback_suite
Version 0.5 (2010/02/01)
o renamed arm9 stuff to arm32
o added non-EABI ABI for arm32 (before, EABI was the default implementation)
o added dyncallback support for x64/windows (thanks Olivier), x64/darwin, arm32/arm, arm32/thumb
o synced documentation again with current state of the source (lots of small changes)
o updated ruby binding to current state of signature string (still some features missing, though)
o added a couple of new options to configure scripts (e.g. prefix-bd, new targets, etc.)
dyncall/ChangeLog view on Meta::CPAN
o fixed nmake buildfiles and configure.bat (were out of date and wrong)
o test suite clean up (GNUmake, BSDmake):
target "config" modified, phony without dependencies to other builds
o bugfix: GNU fastcall calling convention for float and double arguments was wrong (no skip of register)
o update: x86win32* suite tests are built on cygwin now, added total result output
o signature char (breaking) changes:
C Strings: 'S' -> 'Z'
long: 'l' -> 'j'
long long: 'L' -> 'l'
added unsigned integer type signature characters: upper case encoding
o added: callbacks component (support only for some platforms ATM)
o added: test cases for alloc_wx, thunk
o updated Documentation
Version 0.3 (2009/01/17)
o added Linux PPC32 support
o added ARM THUMB mode support
o cosmetic changes, documentation updated
o bugfix: on cygwin exported C symbols in GNU as are prefixed with '_' now.
dyncall/ToDo view on Meta::CPAN
- add tests using alloca(), as this might depend on the frame pointer being correctly set (we don't
check for this, currently, at all - but might not affect dyncall's stubs, anyways) - verify
portasm:
--------
- add solaris support for x64
dyncall:
--------
- dyncall sparc v7/v8: -xO3 on SunPro segfaults in tests (observed years ago)
- callbacks and use of CC signature characters (only x86 has any support for different CCs for callbacks):
* support for arm (arm/thumb on same platform)
* check if ellipsis support is needed (is there any need for calling back into an ellipse function?)
* check if syscalls support is needed (is there any need for calling back into a syscall?)
- think about using 'inline' for all/most dyncall_api.c functions?
- support for where syscalls originate from on OpenBSD: http://undeadly.org/cgi?action=article;sid=20191202105849
- merge arm32_thumb_{gas/apple} and include thumb support for portasm
- x64 verification: return values are passed via RAX and RDX, and XMM0 and XMM1.
- find big endian arm box (also hardfloat), e.g. cubietruck: http://blog.netbsd.org/tnf/entry/working_arm_multiprocessor_support
- test if armhf/thumb is actually working... pulls in arm mode code in dyncall_callvm.c
- dyncall_call_mips_n32.h and dyncall_call_mips_n64.h are pretty much the same, share code
dyncall/doc/manual/callconvs/callconv_arm64.tex view on Meta::CPAN
\subsection{ARM64 Calling Conventions}
\paragraph{Overview}
ARMv8 introduced the AArch64 calling convention. ARM64 chips can be run in 64 or 32bit mode, but not by the same process. Interworking is only intra-process.\\
The word size is defined to be 32 bits, a dword 64 bits. Note that this is due to historical reasons (terminology didn't change from ARM32).\\
For more details, take a look at the Procedure Call Standard for the ARM 64-bit Architecture \cite{AAPCS64}.\\
\paragraph{\product{dyncall} support}
The \product{dyncall} library supports the ARM 64-bit AArch64 PCS ABI, as well as Apple's and Microsoft's conventions which are derived from it, for both, calls and callbacks.
\subsubsection{AAPCS64 Calling Convention}
\paragraph{Registers and register usage}
ARM64 features thirty-one 64 bit general purpose registers, namely {\bf r0-r30},
which are referred to as either {\bf x0-x30} for 64bit access, or {\bf w0-w30}
for 32bit access (with upper bits either cleared or sign extended on load).\\
Also, there is {\bf sp/xzr/wzr}, a register with restricted use, used for the
stack pointer in instructions dealing with the stack ({\bf sp}) or a hardware
dyncall/doc/manual/callconvs/callconv_mips32.tex view on Meta::CPAN
\item [MIPS MT] multithreading additions to the system similar to HyperThreading.
\end{description}
Unfortunately, there is actually no such thing as "The MIPS Calling Convention". Many possible conventions are used
by many different environments such as \emph{O32}\cite{MIPSo32}, \emph{O64}\cite{MIPSo64}, \emph{N32}\cite{MIPSn32/n64}, \emph{N64}\cite{MIPSn32/n64}, \emph{EABI}\cite{MIPSeabi} and \emph{NUBI}\cite{MIPSnubi}.\\
\paragraph{\product{dyncall} support}
Currently, dyncall supports for MIPS 32-bit architectures the widely-used O32 calling convention (for all four combinations of big/little-endian, and soft/hard-float targets),
as well as EABI (little-endian/hard-float, which is used on the Homebrew SDK for the Playstation Portable). \product{dyncall} currently does not support MIPS16e
(contrary to the like-minded ARM-THUMB, which is supported). Both, calls and callbacks are supported.
\clearpage
\subsubsection{MIPS EABI 32-bit Calling Convention}
% This is about hardware floating point targtes, there are also softfloat ones @@@
\paragraph{Register usage}
dyncall/doc/manual/callconvs/callconv_mips64.tex view on Meta::CPAN
uses ILP32 as programming model (32-bit pointers and long integers), whereas
N64 uses LP64 (64-bit pointers and long integers). All registers of a MIPS64
chip are considered to be 64-bit wide, even for the N32 calling convention.\\
The word size is defined to be 32 bits, a dword 64 bits. Note that this is due
to historical reasons (terminology didn't change from MIPS32).\\
Other than that there are correspoding 64-bit versions other MIPS32 ABIs, e.g.
the EABI\cite{MIPSeabi} and O64\cite{MIPSo64}.
\paragraph{\product{dyncall} support}
For MIPS 64-bit machines, dyncall supports the N64 calling conventions for calls and callbacks (for all four combinations of big/little-endian, and soft/hard-float targets).
The N32 calling convention might work - it used to, but hasn't been tested, recently.
\subsubsection{MIPS N64 Calling Convention}
\paragraph{Register usage}
\begin{table}[h]
\begin{tabular*}{0.95\textwidth}{lll}
Name & Alias & Brief description\\
\hline
dyncall/doc/manual/callconvs/callconv_sparc32.tex view on Meta::CPAN
\paragraph{Overview}
The SPARC family of processors is based on the SPARC instruction set architecture, which comes in basically three revisions,
V7, V8\cite{SPARCV8}\cite{SPARCSysV} and V9\cite{SPARCV9}\cite{SPARCV9SysV}. The former two are 32-bit whereas the latter refers to the 64-bit SPARC architecture (see next chapter).
SPARC uses big endian byte order.\\
The word size is defined to be 32 bits.
\paragraph{\product{dyncall} support}
\product{dyncall} fully supports the SPARC 32-bit instruction set (V7 and V8), for calls and callbacks.
\subsubsection{SPARC (32-bit) Calling Convention}
\paragraph{Register usage}
\begin{itemize}
\item 32 single floating point registers (f0-f31, usable as 8 quad precision q0,q4,q8,...,q28, 16 double precision d0,d2,d4,...,d30)
\item 32 32-bit integer/pointer registers out of a bigger (vendor/model dependent) number that are accessible at a time (8 are global ones (g*), whereas the remaining 24 form a register window with 8 input (i*), 8 output (o*) and 8 local (l*) ones)
\item calling a function shifts the register window, the old output registers become the new input registers (old local and input ones are not accessible anymore)
\end{itemize}
dyncall/doc/manual/callconvs/callconv_sparc64.tex view on Meta::CPAN
\paragraph{Overview}
The SPARC family of processors is based on the SPARC instruction set architecture, which comes in basically three revisions,
V7, V8\cite{SPARCV8}\cite{SPARCSysV}\cite{SPARCCD} and V9\cite{SPARCV9}\cite{SPARCV9SysV}\cite{SPARCCD}. The former two are 32-bit (see previous chapter) whereas the latter refers to the 64-bit SPARC architecture.
SPARC uses big endian byte order, however, V9 supports also little endian byte order, but for data access only, not instruction access.\\
\\
There are two proposals, one from Sun and one from Hal, which disagree on how to handle some aspects of this calling convention.\\
\paragraph{\product{dyncall} support}
\product{dyncall} fully supports the SPARC 64-bit instruction set (V9), for calls and callbacks.
\subsubsection{SPARC (64-bit) Calling Convention}
\begin{itemize}
\item 32 double precision floating point registers (d0,d2,d4,...,d62, usable as 16 quad precision ones q0,q4,q8,...q60, and also first half of them are usable as 32 single precision registers f0-f31)
\item 32 64-bit integer/pointer registers out of a bigger (vendor/model dependent) number that are accessible at a time (8 are global ones (g*), whereas the remaining 24 form a register window with 8 input (i*), 8 output (o*) and 8 local (l*) ones)
\item calling a function shifts the register window, the old output registers become the new input registers (old local and input ones are not accessible anymore)
\item stack and frame pointer are offset by a BIAS of 2047 (see official doc for reasons)
\end{itemize}
dyncall/dyncallback/dyncall_thunk.h view on Meta::CPAN
** dyncall thunks
**
** thunks are small-size hybrid code/data objects, created at run-time to
** be used as function pointers with associated data and entry functions.
**
** The header contains code, that does load its address into a designated scratch
** register and will jump to a thunk function.
**
** Thunk entry procedures are compiled functions, that are called as a result of
** a thunk function.
** There is one thunk entry currently for supporting callbacks.
**
** Thunk context register ( ::= an available scratch register in the calling convention):
**
** x86: eax
** x64: rax
** ppc: r2
** arm: r12
** arm64: x9
** mips: t4
**
dyncall/dyncallback/dyncallback.3 view on Meta::CPAN
the
.Ar aggrs
parameter, otherwise pass NULL. This pointer must point to valid data during
callback.
.Pp
.Fn dcbNewCallback
is the same as
.Fn dcbNewCallback2 ,
with an implicit NULL passed via the
.Ar aggrs
parameter, meaning it can only be used for callbacks that do not use any
aggregate by value.
.Pp
.Em NOTE :
C++ non-trivial aggregates (check with the std::is_trivial type trait) do not
use aggregate descriptions, so the respective pointers in the provided array
must be NULL. See
.Xr dyncall 3
for more information on C++ non-trivial aggregates.
.Pp
Use the pointer returned by
dyncall/test/callback_suite/README.txt view on Meta::CPAN
The K_? values are the reference values, which are supposed to be copied to
V_?, and are compared for identity after invocation. The arguments are copied
to V_? in the callback handler, called through "addr".
The reference values stored in K_? are generated once, randomly, at startup.
Specific calling conventions:
Specify 'api' and 'ccprefix' accordingly to generate callbacks for a
specific/custom calling convention:
"__stdcall" "_s"
"__fastcall" "_f" for gcc compiler
"_F" for microsoft compiler
See the dyncall documentation for other/more calling convention prefixes.
lib/Affix.pm view on Meta::CPAN
...would be defined this way:
Union[
c => ArrayRef[Char, 5],
f => Float
];
=head2 C<CodeRef[ ... ]>
A value where C<ref($value)> equals C<CODE>. This would be how callbacks are
defined.
The argument list and return value must be defined. For example,
C<CodeRef[[Int, Int]=>Int]> ~~ C<typedef int (*fuc)(int a, int b);>; that is to
say our function accepts two integers and returns an integer.
CodeRef[[] => Void]; # typedef void (*function)();
CodeRef[[Pointer[Int]] => Int]; # typedef Int (*function)(int * a);
CodeRef[[Str, Int] => Struct[...]]; # typedef struct Person (*function)(chat * name, int age);
t/54_affix_callbacks.t view on Meta::CPAN
BEGIN { chdir '../' if !-d 't'; }
use lib '../lib', 'lib', '../blib/arch', '../blib/lib', 'blib/arch', 'blib/lib', '../../', '.';
use Affix;
use Config;
$|++;
#
use t::lib::nativecall;
#
plan skip_all => 'no support for aggregates by value' unless Affix::Feature::AggrByVal();
#
my $lib = compile_test_lib('54_affix_callbacks');
diag $lib;
#~ {
#~ use Data::Dump;
#~ ddx CodeRef [ [ Pointer [Void], Int, Int ] => Int ];
#~ ddx CodeRef [ [ Double, Str, Bool ] => Bool ];
#~ }
#
is wrap( $lib, 'cb_pii_i', [ CodeRef [ [ Pointer [Void], Int, Int ] => Int ] ] => Int )->(
sub {