# HG changeset patch # User Tassilo Philipp # Date 1586783521 -7200 # Node ID 30aae7371373c22422373a7b2d951ddc340150db # Parent d982a00c2177ffaab473cc0bca919aa5168e475b - extended signature with calling convention mode switches for fastcall (gnu), default, cdecl, stdcall, arm (arm), arm (thumb), syscall - made formatted call (dcV?{Call,Arg}F) interface use those calling convention mode signature specifications to begin with - extended callf testcode with one standard and one vararg call to test those cc mode switches diff -r d982a00c2177 -r 30aae7371373 ChangeLog --- a/ChangeLog Tue Feb 25 18:16:13 2020 +0100 +++ b/ChangeLog Mon Apr 13 15:12:01 2020 +0200 @@ -1,8 +1,14 @@ This file lists bigger/noteworthy changes, only... Version 1.2 (upcoming) +dyncall: + 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 dynload: o fix to build with musl libc +tests: + o extended callf testcode with to test calling convention mode switch signature chars Version 1.1 (2020/01/11) dyncall: diff -r d982a00c2177 -r 30aae7371373 dyncall/dyncall_callf.c --- a/dyncall/dyncall_callf.c Tue Feb 25 18:16:13 2020 +0100 +++ b/dyncall/dyncall_callf.c Mon Apr 13 15:12:01 2020 +0200 @@ -35,6 +35,7 @@ dcReset(vm); while((ch=*(*sigptr)++) != '\0' && ch != DC_SIGCHAR_ENDARG) { switch(ch) { + /* types */ case DC_SIGCHAR_BOOL: dcArgBool (vm, (DCbool) va_arg(args, DCint )); break; case DC_SIGCHAR_CHAR: dcArgChar (vm, (DCchar) va_arg(args, DCint )); break; case DC_SIGCHAR_UCHAR: dcArgChar (vm, (DCchar)(DCuchar) va_arg(args, DCint )); break; @@ -50,6 +51,24 @@ case DC_SIGCHAR_DOUBLE: dcArgDouble (vm, (DCdouble) va_arg(args, DCdouble )); break; case DC_SIGCHAR_POINTER: dcArgPointer (vm, (DCpointer) va_arg(args, DCpointer )); break; case DC_SIGCHAR_STRING: dcArgPointer (vm, (DCpointer) va_arg(args, DCpointer )); break; + /* calling convention modes */ + case DC_SIGCHAR_CC_PREFIX: + { + 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; + 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; + 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; + case DC_SIGCHAR_CC_SYSCALL: dcMode(vm, DC_CALL_SYS_DEFAULT ); break; + } + } } } } diff -r d982a00c2177 -r 30aae7371373 dyncall/dyncall_signature.h --- a/dyncall/dyncall_signature.h Tue Feb 25 18:16:13 2020 +0100 +++ b/dyncall/dyncall_signature.h Mon Apr 13 15:12:01 2020 +0200 @@ -59,14 +59,21 @@ #define DC_SIGCHAR_STRUCT 'T' #define DC_SIGCHAR_ENDARG ')' /* also works for end struct */ -/* callback signatures */ +/* calling convention / mode signatures */ -#define DC_SIGCHAR_CC_PREFIX '_' -#define DC_SIGCHAR_CC_ELLIPSIS 'e' -#define DC_SIGCHAR_CC_STDCALL 's' -#define DC_SIGCHAR_CC_FASTCALL_GNU 'f' -#define DC_SIGCHAR_CC_FASTCALL_MS 'F' -#define DC_SIGCHAR_CC_THISCALL_MS '+' +#define DC_SIGCHAR_CC_PREFIX '_' +#define DC_SIGCHAR_CC_DEFAULT ':' +#define DC_SIGCHAR_CC_ELLIPSIS 'e' +#define DC_SIGCHAR_CC_ELLIPSIS_VARARGS '.' +#define DC_SIGCHAR_CC_CDECL 'c' +#define DC_SIGCHAR_CC_STDCALL 's' +#define DC_SIGCHAR_CC_FASTCALL_MS 'F' +#define DC_SIGCHAR_CC_FASTCALL_GNU 'f' +#define DC_SIGCHAR_CC_THISCALL_MS '+' +#define DC_SIGCHAR_CC_THISCALL_GNU '#' +#define DC_SIGCHAR_CC_ARM_ARM 'A' +#define DC_SIGCHAR_CC_ARM_THUMB 'a' +#define DC_SIGCHAR_CC_SYSCALL '$' #endif /* DYNCALL_SIGNATURE_H */ diff -r d982a00c2177 -r 30aae7371373 dyncallback/dyncall_callback_x86.c --- a/dyncallback/dyncall_callback_x86.c Tue Feb 25 18:16:13 2020 +0100 +++ b/dyncallback/dyncall_callback_x86.c Mon Apr 13 15:12:01 2020 +0200 @@ -203,10 +203,15 @@ ptr++; ch = *ptr++; switch(ch) { + case DC_SIGCHAR_CC_DEFAULT: mode = DC_CALL_C_DEFAULT; break; + /*@@@ add ellipsis?*/ + case DC_SIGCHAR_CC_CDECL: mode = DC_CALL_C_X86_CDECL; break; case DC_SIGCHAR_CC_STDCALL: mode = DC_CALL_C_X86_WIN32_STD; break; + case DC_SIGCHAR_CC_FASTCALL_MS: mode = DC_CALL_C_X86_WIN32_FAST_MS; break; + case DC_SIGCHAR_CC_FASTCALL_GNU: mode = DC_CALL_C_X86_WIN32_FAST_GNU; break; case DC_SIGCHAR_CC_THISCALL_MS: mode = DC_CALL_C_X86_WIN32_THIS_MS; break; - case DC_SIGCHAR_CC_FASTCALL_GNU: mode = DC_CALL_C_X86_WIN32_FAST_GNU; break; - case DC_SIGCHAR_CC_FASTCALL_MS: mode = DC_CALL_C_X86_WIN32_FAST_MS; break; + case DC_SIGCHAR_CC_THISCALL_GNU: mode = DC_CALL_C_X86_WIN32_THIS_GNU; break; + case DC_SIGCHAR_CC_SYSCALL: mode = DC_CALL_SYS_DEFAULT; break; } } diff -r d982a00c2177 -r 30aae7371373 test/callf/main.c --- a/test/callf/main.c Tue Feb 25 18:16:13 2020 +0100 +++ b/test/callf/main.c Mon Apr 13 15:12:01 2020 +0200 @@ -31,6 +31,8 @@ #include "../common/platformInit.h" #include "../common/platformInit.c" /* Impl. for functions only used in this translation unit */ +#include + /* sample void function */ @@ -48,6 +50,27 @@ return r; } +int vf_ffiV(float a, float b, int c, ...) +{ + va_list ap; + double d, e, g, h; + int f, i; + int r; + + va_start(ap, c); + d = va_arg(ap, double); + e = va_arg(ap, double); + f = va_arg(ap, int); + g = va_arg(ap, double); + h = va_arg(ap, double); + i = va_arg(ap, int); + va_end(ap); + + r = (a == 1.f && b == 2.f && c == 3 && d == 4. && e == 5. && f == 6 && g == 7. && h == 8. && i == 9); + printf("%f %f %d %f %f %d %f %f %d: %d", a, b, c, d, e, f, g, h, i, r); + return r; +} + /* main */ int main(int argc, char* argv[]) @@ -73,6 +96,17 @@ dcCallF(vm, &ret, (void*)&vf_ffiffiffi, "ffiffiffi)i", 1.f, 2.f, 3, 4.f, 5.f, 6, 7.f, 8.f, 9); r = ret.i && r; + /* same but with calling convention prefix */ + dcReset(vm); + printf("\ncallf _:ffiffiffi)i: "); + dcCallF(vm, &ret, (void*)&vf_ffiffiffi, "_:ffiffiffi)i", 1.f, 2.f, 3, 4.f, 5.f, 6, 7.f, 8.f, 9); + r = ret.i && r; + + /* vararg call */ + dcReset(vm); + printf("\ncallf _effi_.ddiddi)i: "); + dcCallF(vm, &ret, (void*)&vf_ffiV, "_effi_.ddiddi)i", 1.f, 2.f, 3, 4., 5., 6, 7., 8., 9); + r = ret.i && r; /* arg binding then call using 'formatted' API */ dcReset(vm);