Mercurial > pub > dyncall > dyncall
changeset 362:78dfa2f9783a
- added helper function dcGetModeFromCCSigChar() mapping callconv sig chars to respective mode
- added a signature-based syscall to callf testcode
- manual clarification about dcReset usage in combination with dcMode
author | Tassilo Philipp |
---|---|
date | Tue, 14 Apr 2020 16:56:57 +0200 |
parents | 06c9adae114d |
children | 3ff4a4ba7f0e |
files | ChangeLog doc/manual/manual_dyncall_api.tex dyncall/dyncall.3 dyncall/dyncall.h dyncall/dyncall_api.c dyncall/dyncall_callf.c dyncall/dyncall_signature.h test/callf/main.c |
diffstat | 8 files changed, 57 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Apr 13 21:40:28 2020 +0200 +++ b/ChangeLog Tue Apr 14 16:56:57 2020 +0200 @@ -5,6 +5,7 @@ o extended signature with more chars for calling convention switching (only for modes that coexist on a platform with other conventions) o made "formatted" call interface use calling convention signature chars + o added helper function dcGetModeFromCCSigChar() mapping callconv sig chars to respective mode dynload: o fix to build with musl libc doc: @@ -14,7 +15,7 @@ 'Z' conversions to only immutable types and 'p' to mutable types (and handles), bytearray support, support to specify calling convention tests: - o extended callf testcode with to test calling convention mode switch signature chars + o extended callf testcode to test callconv mode switch signature chars (including syscalls) Version 1.1 (2020/01/11) dyncall:
--- a/doc/manual/manual_dyncall_api.tex Mon Apr 13 21:40:28 2020 +0200 +++ b/doc/manual/manual_dyncall_api.tex Tue Apr 14 16:56:57 2020 +0200 @@ -214,11 +214,12 @@ void dcReset(DCCallVM* vm); \end{lstlisting} - -Resets the internal stack of arguments and prepares it for a new call. -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.\\ +Resets the internal stack of arguments and prepares it for a new call. This +function should be called after setting the call mode (using dcMode), but prior +to binding arguments to the CallVM (except for when setting mode +DC\_SIGCHAR\_CC\_ELLIPSIS\_VARARGS, which is used prior to binding varargs of +variadic functions). Use it also when reusing a CallVM, as arguments don't get +flushed automatically after a function call invocation.\\ Note: you should also call this function after initial creation of the a CallVM object, as dcNewCallVM doesn't do this, implicitly.\\
--- a/dyncall/dyncall.3 Mon Apr 13 21:40:28 2020 +0200 +++ b/dyncall/dyncall.3 Tue Apr 14 16:56:57 2020 +0200 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2007-2013 Daniel Adler <dadler AT uni-goettingen DOT de>, +.\" Copyright (c) 2007-2020 Daniel Adler <dadler AT uni-goettingen DOT de>, .\" Tassilo Philipp <tphilipp AT potion-studios DOT com> .\" .\" Permission to use, copy, modify, and distribute this software for any @@ -112,12 +112,14 @@ silently ignored. .Pp .Fn dcReset -resets the internal stack of arguments and prepares it for a new call. -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. -Note: you should also call this function after initial creation of the a CallVM -object, as dcNewCallVM doesn't do this, implicitly. +resets the internal stack of arguments and prepares it for a new call. This +function should be called after setting the call mode (using dcMode), but prior +to binding arguments to the CallVM (except for when setting mode +DC_SIGCHAR_CC_ELLIPSIS_VARARGS, which is used prior to binding varargs of +variadic functions). Use it also when reusing a CallVM, as arguments don't get +flushed automatically after a function call invocation. Note: you should also +call this function after initial creation of the a CallVM object, as +dcNewCallVM doesn't do this, implicitly. .Pp .Fn dcArgBool , .Fn dcArgChar ,
--- a/dyncall/dyncall.h Mon Apr 13 21:40:28 2020 +0200 +++ b/dyncall/dyncall.h Tue Apr 14 16:56:57 2020 +0200 @@ -39,6 +39,7 @@ #define DYNCALL_H #include "dyncall_types.h" +#include "dyncall_signature.h" #ifdef __cplusplus extern "C" { @@ -136,6 +137,12 @@ DC_API DCstruct* dcDefineStruct (const char* signature); +/* helpers */ + +/* returns respective mode for callconv sig char (w/o checking if mode exists */ +/* on current platform), or DC_ERROR_UNSUPPORTED_MODE if char isn't a sigchar */ +DC_API DCint dcGetModeFromCCSigChar(DCsigchar sig_char); + #ifdef __cplusplus } #endif
--- a/dyncall/dyncall_api.c Mon Apr 13 21:40:28 2020 +0200 +++ b/dyncall/dyncall_api.c Tue Apr 14 16:56:57 2020 +0200 @@ -6,7 +6,7 @@ Description: C interface to call vm License: - Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>, + Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, Tassilo Philipp <tphilipp@potion-studios.com> Permission to use, copy, modify, and distribute this software for any @@ -27,7 +27,6 @@ #include "dyncall.h" #include "dyncall_callvm.h" -#include "dyncall_alloc.h" void dcReset(DCCallVM* vm) { @@ -157,14 +156,23 @@ return vm->mError; } -/*@@@ not used, (re)introduce or cleanup -const char* dcGetErrorString(int mode) +DCint dcGetModeFromCCSigChar(DCsigchar sig_char) { - switch(mode) { - case DC_ERROR_NONE: return "none"; - case DC_ERROR_UNSUPPORTED_MODE: return "unsupported mode"; - default: return "(unknown mode id)"; + switch(sig_char) + { + case DC_SIGCHAR_CC_DEFAULT: return DC_CALL_C_DEFAULT; + case DC_SIGCHAR_CC_ELLIPSIS: return DC_CALL_C_ELLIPSIS; + case DC_SIGCHAR_CC_ELLIPSIS_VARARGS: return DC_CALL_C_ELLIPSIS_VARARGS; + case DC_SIGCHAR_CC_CDECL: return DC_CALL_C_X86_CDECL; + case DC_SIGCHAR_CC_STDCALL: return DC_CALL_C_X86_WIN32_STD; + case DC_SIGCHAR_CC_FASTCALL_MS: return DC_CALL_C_X86_WIN32_FAST_MS; + case DC_SIGCHAR_CC_FASTCALL_GNU: return DC_CALL_C_X86_WIN32_FAST_GNU; + case DC_SIGCHAR_CC_THISCALL_MS: return DC_CALL_C_X86_WIN32_THIS_MS; + case DC_SIGCHAR_CC_THISCALL_GNU: return DC_CALL_C_X86_WIN32_THIS_GNU; + case DC_SIGCHAR_CC_ARM_ARM: return DC_CALL_C_ARM_ARM; + case DC_SIGCHAR_CC_ARM_THUMB: return DC_CALL_C_ARM_THUMB; + case DC_SIGCHAR_CC_SYSCALL: return DC_CALL_SYS_DEFAULT; } + return DC_ERROR_UNSUPPORTED_MODE; } -*/
--- a/dyncall/dyncall_callf.c Mon Apr 13 21:40:28 2020 +0200 +++ b/dyncall/dyncall_callf.c Tue Apr 14 16:56:57 2020 +0200 @@ -53,28 +53,12 @@ case DC_SIGCHAR_STRING: dcArgPointer (vm, (DCpointer) va_arg(args, DCpointer )); break; /* calling convention modes */ case DC_SIGCHAR_CC_PREFIX: - { if(*((*sigptr)+1) != '\0') { - switch(*(*sigptr)++) { - case DC_SIGCHAR_CC_DEFAULT: dcMode(vm, DC_CALL_C_DEFAULT ); break; - case DC_SIGCHAR_CC_ELLIPSIS: dcMode(vm, DC_CALL_C_ELLIPSIS ); break; - case DC_SIGCHAR_CC_ELLIPSIS_VARARGS: dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS ); break; -#if defined(DC__Arch_Intel_x86) /* @@@ theoretically not needed, if mode isn't understood the implementations shouldn't attempt ny mode switch */ - case DC_SIGCHAR_CC_CDECL: dcMode(vm, DC_CALL_C_X86_CDECL ); break; - case DC_SIGCHAR_CC_STDCALL: dcMode(vm, DC_CALL_C_X86_WIN32_STD ); break; - case DC_SIGCHAR_CC_FASTCALL_MS: dcMode(vm, DC_CALL_C_X86_WIN32_FAST_MS ); break; - case DC_SIGCHAR_CC_FASTCALL_GNU: dcMode(vm, DC_CALL_C_X86_WIN32_FAST_GNU); break; - case DC_SIGCHAR_CC_THISCALL_MS: dcMode(vm, DC_CALL_C_X86_WIN32_THIS_MS ); break; - case DC_SIGCHAR_CC_THISCALL_GNU: dcMode(vm, DC_CALL_C_X86_WIN32_THIS_GNU); break; -#elif defined(DC__Arch_ARM) /* @@@ theoretically not needed, if mode isn't understood the implementations shouldn't attempt any mode switch */ - case DC_SIGCHAR_CC_ARM_ARM: dcMode(vm, DC_CALL_C_ARM_ARM ); break; - case DC_SIGCHAR_CC_ARM_THUMB: dcMode(vm, DC_CALL_C_ARM_THUMB ); break; -#endif - case DC_SIGCHAR_CC_SYSCALL: dcMode(vm, DC_CALL_SYS_DEFAULT ); break; - } + DCint mode = dcGetModeFromCCSigChar(*(*sigptr)++); + if(mode != DC_ERROR_UNSUPPORTED_MODE) + dcMode(vm, mode); } - } - break; + break; } } }
--- a/dyncall/dyncall_signature.h Mon Apr 13 21:40:28 2020 +0200 +++ b/dyncall/dyncall_signature.h Tue Apr 14 16:56:57 2020 +0200 @@ -6,7 +6,7 @@ Description: Type and calling-convention signature character defines License: - Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>, + Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, Tassilo Philipp <tphilipp@potion-studios.com> Permission to use, copy, modify, and distribute this software for any
--- a/test/callf/main.c Mon Apr 13 21:40:28 2020 +0200 +++ b/test/callf/main.c Tue Apr 14 16:56:57 2020 +0200 @@ -32,6 +32,9 @@ #include "../common/platformInit.c" /* Impl. for functions only used in this translation unit */ #include <stdarg.h> +#if defined(DC_UNIX) +#include <sys/syscall.h> +#endif /* sample void function */ @@ -129,6 +132,14 @@ dcArgF(vm, "ffiffiffi", 1.f, 2.f, 3, 4.f, 5.f, 6, 7.f, 8.f, 9); r = r && dcCallInt(vm, (void*)&vf_ffiffiffi); +#if defined(DC_UNIX) + /* testing syscall using calling convention prefix - not available on all platforms */ + dcReset(vm); + printf("\ncallf _$ipi)i"); + fflush(NULL); /* needed before syscall write as it's immediate, or order might be incorrect */ + dcCallF(vm, &ret, (DCpointer)(ptrdiff_t)SYS_write, "_$ipi)i", 1/*stdout*/, " = syscall: 1", 13); + r = ret.i == 13 && r; +#endif /* free vm */ dcFree(vm);