changeset 358:30aae7371373

- 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
author Tassilo Philipp
date Mon, 13 Apr 2020 15:12:01 +0200
parents d982a00c2177
children e8a13c880399
files ChangeLog dyncall/dyncall_callf.c dyncall/dyncall_signature.h dyncallback/dyncall_callback_x86.c test/callf/main.c
diffstat 5 files changed, 80 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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:
--- 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;
+        }
+      }
     }
   }
 }
--- 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 */
 
--- 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;
     }
   }
 
--- 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 <stdarg.h>
+
 
 /* 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);