changeset 466:ddfb9577a00e

introduced platform-native thiscall mode (DC_CALL_C_DEFAULT_THIS), as needed for upcoming aggregate support (until now only x86 platforms allowed for specifically selecting thiscall mode, given the different conventions on the same platform); also added respective DC_SIGCHAR_CC_THISCALL ('*')
author Tassilo Philipp
date Wed, 02 Feb 2022 18:30:44 +0100
parents e2899b4ff713
children b47168dacba6
files dyncall/dyncall.h dyncall/dyncall_api.c dyncall/dyncall_callvm_arm32_arm.c dyncall/dyncall_callvm_arm32_arm_armhf.c dyncall/dyncall_callvm_arm32_thumb.c dyncall/dyncall_callvm_arm64.c dyncall/dyncall_callvm_arm64_apple.c dyncall/dyncall_callvm_mips_eabi.c dyncall/dyncall_callvm_mips_n32.c dyncall/dyncall_callvm_mips_n64.c dyncall/dyncall_callvm_mips_o32.c dyncall/dyncall_callvm_ppc32.c dyncall/dyncall_callvm_ppc64.c dyncall/dyncall_callvm_sparc.c dyncall/dyncall_callvm_sparc64.c dyncall/dyncall_callvm_x64.c dyncall/dyncall_callvm_x86.c dyncall/dyncall_signature.h dyncallback/dyncall_callback_x86.c test/plain_c++/test_main.cc
diffstat 20 files changed, 330 insertions(+), 325 deletions(-) [+]
line wrap: on
line diff
--- a/dyncall/dyncall.h	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall.h	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: public header for library dyncall
  License:
 
-   Copyright (c) 2007-2020 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
@@ -24,17 +24,6 @@
 */
 
 
-/*
-
-  dyncall C API
-
-  REVISION
-  2015/07/08 added SYS_PPC64 system call
-  2015/01/16 added SYS_PPC32 system call
-  2007/12/11 initial
-  
-*/
-
 #ifndef DYNCALL_H
 #define DYNCALL_H
 
@@ -43,7 +32,7 @@
 
 #ifdef __cplusplus
 extern "C" {
-#endif 
+#endif
 
 typedef struct DCCallVM_    DCCallVM;
 typedef struct DCstruct_    DCstruct;
@@ -51,6 +40,7 @@
 /* Supported Calling Convention Modes */
 
 #define DC_CALL_C_DEFAULT               0
+#define DC_CALL_C_DEFAULT_THIS         99
 #define DC_CALL_C_ELLIPSIS            100
 #define DC_CALL_C_ELLIPSIS_VARARGS    101
 #define DC_CALL_C_X86_CDECL             1
@@ -60,7 +50,9 @@
 #define DC_CALL_C_X86_WIN32_THIS_MS     5
 #define DC_CALL_C_X86_WIN32_THIS_GNU    DC_CALL_C_X86_CDECL /* alias - identical to cdecl (w/ this-ptr as 1st arg) */
 #define DC_CALL_C_X64_WIN64             7
+#define DC_CALL_C_X64_WIN64_THIS       70   /* only needed when using aggregate by value as return type    @@@STRUCT implement */
 #define DC_CALL_C_X64_SYSV              8
+#define DC_CALL_C_X64_SYSV_THIS         DC_CALL_C_X64_SYSV  /* alias */
 #define DC_CALL_C_PPC32_DARWIN          9
 #define DC_CALL_C_PPC32_OSX            DC_CALL_C_PPC32_DARWIN /* alias */
 #define DC_CALL_C_ARM_ARM_EABI         10
@@ -93,45 +85,45 @@
 #define DC_ERROR_NONE                0
 #define DC_ERROR_UNSUPPORTED_MODE   -1
 
-DC_API DCCallVM*  dcNewCallVM     (DCsize size);
-DC_API void       dcFree          (DCCallVM* vm);
-DC_API void       dcReset         (DCCallVM* vm);
+DC_API DCCallVM*  dcNewCallVM       (DCsize size);
+DC_API void       dcFree            (DCCallVM* vm);
+DC_API void       dcReset           (DCCallVM* vm);
 
-DC_API void       dcMode          (DCCallVM* vm, DCint mode);
+DC_API void       dcMode            (DCCallVM* vm, DCint mode);
 
-DC_API void       dcArgBool       (DCCallVM* vm, DCbool     value);
-DC_API void       dcArgChar       (DCCallVM* vm, DCchar     value);
-DC_API void       dcArgShort      (DCCallVM* vm, DCshort    value);
-DC_API void       dcArgInt        (DCCallVM* vm, DCint      value);
-DC_API void       dcArgLong       (DCCallVM* vm, DClong     value);
-DC_API void       dcArgLongLong   (DCCallVM* vm, DClonglong value);
-DC_API void       dcArgFloat      (DCCallVM* vm, DCfloat    value);
-DC_API void       dcArgDouble     (DCCallVM* vm, DCdouble   value);
-DC_API void       dcArgPointer    (DCCallVM* vm, DCpointer  value);
+DC_API void       dcArgBool         (DCCallVM* vm, DCbool     value);
+DC_API void       dcArgChar         (DCCallVM* vm, DCchar     value);
+DC_API void       dcArgShort        (DCCallVM* vm, DCshort    value);
+DC_API void       dcArgInt          (DCCallVM* vm, DCint      value);
+DC_API void       dcArgLong         (DCCallVM* vm, DClong     value);
+DC_API void       dcArgLongLong     (DCCallVM* vm, DClonglong value);
+DC_API void       dcArgFloat        (DCCallVM* vm, DCfloat    value);
+DC_API void       dcArgDouble       (DCCallVM* vm, DCdouble   value);
+DC_API void       dcArgPointer      (DCCallVM* vm, DCpointer  value);
 DC_API void       dcArgStruct     (DCCallVM* vm, DCstruct* s, DCpointer value);
 
-DC_API void       dcCallVoid      (DCCallVM* vm, DCpointer funcptr);
-DC_API DCbool     dcCallBool      (DCCallVM* vm, DCpointer funcptr);
-DC_API DCchar     dcCallChar      (DCCallVM* vm, DCpointer funcptr);
-DC_API DCshort    dcCallShort     (DCCallVM* vm, DCpointer funcptr);
-DC_API DCint      dcCallInt       (DCCallVM* vm, DCpointer funcptr);
-DC_API DClong     dcCallLong      (DCCallVM* vm, DCpointer funcptr);
-DC_API DClonglong dcCallLongLong  (DCCallVM* vm, DCpointer funcptr);
-DC_API DCfloat    dcCallFloat     (DCCallVM* vm, DCpointer funcptr);
-DC_API DCdouble   dcCallDouble    (DCCallVM* vm, DCpointer funcptr);
-DC_API DCpointer  dcCallPointer   (DCCallVM* vm, DCpointer funcptr);
+DC_API void       dcCallVoid        (DCCallVM* vm, DCpointer funcptr);
+DC_API DCbool     dcCallBool        (DCCallVM* vm, DCpointer funcptr);
+DC_API DCchar     dcCallChar        (DCCallVM* vm, DCpointer funcptr);
+DC_API DCshort    dcCallShort       (DCCallVM* vm, DCpointer funcptr);
+DC_API DCint      dcCallInt         (DCCallVM* vm, DCpointer funcptr);
+DC_API DClong     dcCallLong        (DCCallVM* vm, DCpointer funcptr);
+DC_API DClonglong dcCallLongLong    (DCCallVM* vm, DCpointer funcptr);
+DC_API DCfloat    dcCallFloat       (DCCallVM* vm, DCpointer funcptr);
+DC_API DCdouble   dcCallDouble      (DCCallVM* vm, DCpointer funcptr);
+DC_API DCpointer  dcCallPointer     (DCCallVM* vm, DCpointer funcptr);
 DC_API void       dcCallStruct    (DCCallVM* vm, DCpointer funcptr, DCstruct* s, DCpointer returnValue);
 
-DC_API DCint      dcGetError      (DCCallVM* vm);
+DC_API DCint      dcGetError        (DCCallVM* vm);
 
 #define DEFAULT_ALIGNMENT 0
 DC_API DCstruct*  dcNewStruct      (DCsize fieldCount, DCint alignment);
 DC_API void       dcStructField    (DCstruct* s, DCint type, DCint alignment, DCsize arrayLength);
-DC_API void       dcSubStruct      (DCstruct* s, DCsize fieldCount, DCint alignment, DCsize arrayLength);  	
+DC_API void       dcSubStruct      (DCstruct* s, DCsize fieldCount, DCint alignment, DCsize arrayLength);
 /* Each dcNewStruct or dcSubStruct call must be paired with a dcCloseStruct. */
-DC_API void       dcCloseStruct    (DCstruct* s);  	
-DC_API DCsize     dcStructSize     (DCstruct* s);  	
-DC_API DCsize     dcStructAlignment(DCstruct* s);  	
+DC_API void       dcCloseStruct    (DCstruct* s);
+DC_API DCsize     dcStructSize     (DCstruct* s);
+DC_API DCsize     dcStructAlignment(DCstruct* s);
 DC_API void       dcFreeStruct     (DCstruct* s);
 
 DC_API DCstruct*  dcDefineStruct  (const char* signature);
--- a/dyncall/dyncall_api.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_api.c	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: C interface to call vm
  License:
 
-   Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, 
+   Copyright (c) 2007-2022 Daniel Adler <dadler@uni-goettingen.de>,
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -29,124 +29,124 @@
 #include "dyncall_callvm.h"
 
 void dcReset(DCCallVM* vm)
-{ 
-  vm->mVTpointer->reset(vm); 
+{
+  vm->mVTpointer->reset(vm);
 }
 
-void dcFree(DCCallVM* vm) 
-{ 
-  vm->mVTpointer->free(vm); 
+void dcFree(DCCallVM* vm)
+{
+  vm->mVTpointer->free(vm);
 }
 
-void dcMode(DCCallVM* vm,DCint mode) 
-{ 
+void dcMode(DCCallVM* vm,DCint mode)
+{
   vm->mVTpointer->mode(vm,mode);
 }
 
-void dcArgBool(DCCallVM* vm,DCbool x) 
-{ 
-  vm->mVTpointer->argBool(vm, x); 
+void dcArgBool(DCCallVM* vm,DCbool x)
+{
+  vm->mVTpointer->argBool(vm, x);
 }
 
 void dcArgChar(DCCallVM* vm,DCchar x)
-{ 
-  vm->mVTpointer->argChar(vm, x); 
+{
+  vm->mVTpointer->argChar(vm, x);
 }
 
-void dcArgShort(DCCallVM* vm,DCshort x) 
-{ 
-  vm->mVTpointer->argShort(vm, x); 
+void dcArgShort(DCCallVM* vm,DCshort x)
+{
+  vm->mVTpointer->argShort(vm, x);
 }
 
-void dcArgInt(DCCallVM* vm,DCint x) 
-{ 
-  vm->mVTpointer->argInt(vm, x); 
+void dcArgInt(DCCallVM* vm,DCint x)
+{
+  vm->mVTpointer->argInt(vm, x);
 }
 
-void dcArgLong(DCCallVM* vm,DClong x) 
-{ 
-  vm->mVTpointer->argLong(vm, x); 
+void dcArgLong(DCCallVM* vm,DClong x)
+{
+  vm->mVTpointer->argLong(vm, x);
 }
 
-void dcArgLongLong(DCCallVM* vm, DClonglong x) 
-{ 
-  vm->mVTpointer->argLongLong(vm, x); 
+void dcArgLongLong(DCCallVM* vm, DClonglong x)
+{
+  vm->mVTpointer->argLongLong(vm, x);
 }
 
-void dcArgFloat(DCCallVM* vm, DCfloat x) 
-{ 
-  vm->mVTpointer->argFloat(vm, x); 
+void dcArgFloat(DCCallVM* vm, DCfloat x)
+{
+  vm->mVTpointer->argFloat(vm, x);
 }
 
-void dcArgDouble(DCCallVM* vm, DCdouble x) 
-{ 
-  vm->mVTpointer->argDouble(vm, x); 
+void dcArgDouble(DCCallVM* vm, DCdouble x)
+{
+  vm->mVTpointer->argDouble(vm, x);
 }
 
-void dcArgPointer(DCCallVM* vm, DCpointer x) 
-{ 
-  vm->mVTpointer->argPointer(vm, x); 
+void dcArgPointer(DCCallVM* vm, DCpointer x)
+{
+  vm->mVTpointer->argPointer(vm, x);
 }
 
-void dcArgStruct(DCCallVM* vm, DCstruct* s, DCpointer x) 
-{ 
-  vm->mVTpointer->argStruct(vm, s, x); 
+void dcArgStruct(DCCallVM* vm, DCstruct* s, DCpointer x)
+{
+  vm->mVTpointer->argStruct(vm, s, x);
 }
 
 
-void dcCallVoid(DCCallVM* vm, DCpointer funcptr) 
-{        
-  vm->mVTpointer->callVoid(vm, funcptr); 
+void dcCallVoid(DCCallVM* vm, DCpointer funcptr)
+{
+  vm->mVTpointer->callVoid(vm, funcptr);
 }
 
-DCchar dcCallChar(DCCallVM* vm, DCpointer funcptr) 
-{ 
-  return vm->mVTpointer->callChar(vm, funcptr); 
+DCchar dcCallChar(DCCallVM* vm, DCpointer funcptr)
+{
+  return vm->mVTpointer->callChar(vm, funcptr);
 }
 
-DCbool dcCallBool(DCCallVM* vm, DCpointer funcptr) 
-{ 
-  return vm->mVTpointer->callBool(vm, funcptr); 
+DCbool dcCallBool(DCCallVM* vm, DCpointer funcptr)
+{
+  return vm->mVTpointer->callBool(vm, funcptr);
 }
 
-DCshort dcCallShort(DCCallVM* vm, DCpointer funcptr) 
-{ 
-  return vm->mVTpointer->callShort(vm, funcptr); 
+DCshort dcCallShort(DCCallVM* vm, DCpointer funcptr)
+{
+  return vm->mVTpointer->callShort(vm, funcptr);
 }
 
-DCint dcCallInt(DCCallVM* vm, DCpointer funcptr) 
-{ 
-  return vm->mVTpointer->callInt(vm, funcptr); 
+DCint dcCallInt(DCCallVM* vm, DCpointer funcptr)
+{
+  return vm->mVTpointer->callInt(vm, funcptr);
 }
 
-DClong dcCallLong(DCCallVM* vm, DCpointer funcptr) 
-{ 
-  return vm->mVTpointer->callLong(vm, funcptr); 
+DClong dcCallLong(DCCallVM* vm, DCpointer funcptr)
+{
+  return vm->mVTpointer->callLong(vm, funcptr);
 }
 
-DClonglong dcCallLongLong(DCCallVM* vm, DCpointer funcptr) 
-{ 
-  return vm->mVTpointer->callLongLong(vm, funcptr); 
+DClonglong dcCallLongLong(DCCallVM* vm, DCpointer funcptr)
+{
+  return vm->mVTpointer->callLongLong(vm, funcptr);
 }
 
-DCfloat dcCallFloat(DCCallVM* vm, DCpointer funcptr) 
-{ 
-  return vm->mVTpointer->callFloat(vm, funcptr); 
+DCfloat dcCallFloat(DCCallVM* vm, DCpointer funcptr)
+{
+  return vm->mVTpointer->callFloat(vm, funcptr);
 }
 
-DCdouble dcCallDouble(DCCallVM* vm, DCpointer funcptr) 
-{ 
-  return vm->mVTpointer->callDouble(vm, funcptr); 
+DCdouble dcCallDouble(DCCallVM* vm, DCpointer funcptr)
+{
+  return vm->mVTpointer->callDouble(vm, funcptr);
 }
 
-DCpointer dcCallPointer(DCCallVM* vm, DCpointer funcptr) 
-{ 
-  return vm->mVTpointer->callPointer(vm, funcptr); 
+DCpointer dcCallPointer(DCCallVM* vm, DCpointer funcptr)
+{
+  return vm->mVTpointer->callPointer(vm, funcptr);
 }
 
-void dcCallStruct(DCCallVM* vm, DCpointer funcptr, DCstruct* s, DCpointer x) 
-{ 
-  vm->mVTpointer->callStruct(vm, funcptr, s, x); 
+void dcCallStruct(DCCallVM* vm, DCpointer funcptr, DCstruct* s, DCpointer x)
+{
+  vm->mVTpointer->callStruct(vm, funcptr, s, x);
 }
 
 DCint dcGetError(DCCallVM *vm)
@@ -159,6 +159,7 @@
   switch(sig_char)
   {
     case DC_SIGCHAR_CC_DEFAULT:          return DC_CALL_C_DEFAULT;
+    case DC_SIGCHAR_CC_THISCALL:         return DC_CALL_C_DEFAULT_THIS;
     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;
--- a/dyncall/dyncall_callvm_arm32_arm.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_arm32_arm.c	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: ARM 32-bit "arm" ABI callvm implementation
  License:
 
-   Copyright (c) 2007-2020 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
@@ -42,8 +42,8 @@
 #include "dyncall_alloc.h"
 
 
-/* 
-** arm32 arm mode calling convention calls 
+/*
+** arm32 arm mode calling convention calls
 **
 ** - hybrid return-type call (bool ... pointer)
 **
@@ -165,7 +165,7 @@
 , &dc_callvm_mode_arm32_arm
 , &dc_callvm_argBool_arm32_arm
 , &dc_callvm_argChar_arm32_arm
-, &dc_callvm_argShort_arm32_arm 
+, &dc_callvm_argShort_arm32_arm
 , &dc_callvm_argInt_arm32_arm
 , &dc_callvm_argLong_arm32_arm
 , &dc_callvm_argLongLong_arm32_arm
@@ -193,7 +193,7 @@
 , &dc_callvm_mode_arm32_arm
 , &dc_callvm_argBool_arm32_arm
 , &dc_callvm_argChar_arm32_arm
-, &dc_callvm_argShort_arm32_arm 
+, &dc_callvm_argShort_arm32_arm
 , &dc_callvm_argInt_arm32_arm
 , &dc_callvm_argLong_arm32_arm
 , &dc_callvm_argLongLong_arm32_arm_eabi
@@ -224,14 +224,16 @@
     case DC_CALL_C_ELLIPSIS_VARARGS:
 /* Check OS if we need EABI as default. */
 #if defined(DC__ABI_ARM_EABI)
-    case DC_CALL_C_DEFAULT:       vt = &gVT_arm32_arm_eabi; break;
+    case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:  vt = &gVT_arm32_arm_eabi; break;
 #else
-    case DC_CALL_C_DEFAULT:       vt = &gVT_arm32_arm;      break;
+    case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:  vt = &gVT_arm32_arm;      break;
 #endif
     case DC_CALL_C_ARM_ARM:       vt = &gVT_arm32_arm;      break;
     case DC_CALL_C_ARM_ARM_EABI:  vt = &gVT_arm32_arm_eabi; break;
-    default: 
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
   dc_callvm_base_init(&self->mInterface, vt);
--- a/dyncall/dyncall_callvm_arm32_arm_armhf.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_arm32_arm_armhf.c	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: ARM 'armhf' ABI implementation
  License:
 
-   Copyright (c) 2007-2020 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
@@ -28,8 +28,8 @@
 #include "dyncall_alloc.h"
 
 
-/* 
-** arm32 armhf mode calling convention calls 
+/*
+** arm32 armhf mode calling convention calls
 **
 ** - hybrid return-type call (bool ... pointer)
 **
@@ -211,6 +211,7 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_ARM_ARMHF:
       vt = &vt_armhf;
       break;
@@ -219,7 +220,7 @@
       vt = &vt_armhf_ellipsis;
       break;
     default:
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
   dc_callvm_base_init(&self->mInterface, vt);
--- a/dyncall/dyncall_callvm_arm32_thumb.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_arm32_thumb.c	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: ARM 32-bit "thumb" ABI callvm implementation
  License:
 
-   Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>, 
+   Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -41,8 +41,8 @@
 #include "dyncall_callvm_arm32_thumb.h"
 #include "dyncall_alloc.h"
 
-/* 
-** arm32 thumb mode calling convention calls 
+/*
+** arm32 thumb mode calling convention calls
 **
 ** - hybrid return-type call (bool ... pointer)
 **
@@ -164,7 +164,7 @@
 , &dc_callvm_mode_arm32_thumb
 , &dc_callvm_argBool_arm32_thumb
 , &dc_callvm_argChar_arm32_thumb
-, &dc_callvm_argShort_arm32_thumb 
+, &dc_callvm_argShort_arm32_thumb
 , &dc_callvm_argInt_arm32_thumb
 , &dc_callvm_argLong_arm32_thumb
 , &dc_callvm_argLongLong_arm32_thumb
@@ -192,7 +192,7 @@
 , &dc_callvm_mode_arm32_thumb
 , &dc_callvm_argBool_arm32_thumb
 , &dc_callvm_argChar_arm32_thumb
-, &dc_callvm_argShort_arm32_thumb 
+, &dc_callvm_argShort_arm32_thumb
 , &dc_callvm_argInt_arm32_thumb
 , &dc_callvm_argLong_arm32_thumb
 , &dc_callvm_argLongLong_arm32_thumb_eabi
@@ -221,6 +221,7 @@
   switch(mode) {
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
+    case DC_CALL_C_DEFAULT_THIS:
 /* Check OS if we need EABI as default. */
 #if defined(DC__ABI_ARM_EABI)
     case DC_CALL_C_DEFAULT:        vt = &gVT_arm32_thumb_eabi; break;
@@ -230,7 +231,7 @@
     case DC_CALL_C_ARM_THUMB:      vt = &gVT_arm32_thumb;      break;
     case DC_CALL_C_ARM_THUMB_EABI: vt = &gVT_arm32_thumb_eabi; break;
     default:
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
   dc_callvm_base_init(&self->mInterface, vt);
--- a/dyncall/dyncall_callvm_arm64.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_arm64.c	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: ARM 64-bit ABI implementation
  License:
 
-   Copyright (c) 2015-2020 Daniel Adler <dadler@uni-goettingen.de>, 
+   Copyright (c) 2015-2020 Daniel Adler <dadler@uni-goettingen.de>,
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -84,7 +84,7 @@
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
   if (p->f < 8) {
     p->u.D[ p->f ] = x;
-    p->f++; 
+    p->f++;
   } else {
     dcVecAppend(&p->mVecHead, &x, sizeof(DCdouble));
   }
@@ -93,11 +93,11 @@
 void call(DCCallVM* in_p, DCpointer target)
 {
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
-  
+
   /*
   ** copy 'size' argument is given in number of 16-byte 'pair' blocks.
   */
-  
+
   dcCall_arm64(target, dcVecData(&p->mVecHead), ( dcVecSize(&p->mVecHead) + 15 ) & -16, &p->u.S[0]);
 }
 
@@ -110,7 +110,7 @@
 , &mode
 , &a_bool
 , &a_char
-, &a_short 
+, &a_short
 , &a_int
 , &a_long
 , &a_i64
@@ -180,19 +180,20 @@
       vt = &vt_arm64_win_varargs;
       break;
 #endif /* if not win64, use below */
-    case DC_CALL_C_DEFAULT:        
-    case DC_CALL_C_ARM64:        
+    case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
+    case DC_CALL_C_ARM64:
       vt = &vt_arm64;
       break;
-    default: 
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
   dc_callvm_base_init(&self->mInterface, vt);
 }
 
 /* Public API. */
-DCCallVM* dcNewCallVM(DCsize size) 
+DCCallVM* dcNewCallVM(DCsize size)
 {
   DCCallVM_arm64* p = (DCCallVM_arm64*)dcAllocMem(sizeof(DCCallVM_arm64)+size);
 
--- a/dyncall/dyncall_callvm_arm64_apple.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_arm64_apple.c	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: ARM 64-bit Apple ABI implementation
  License:
 
-   Copyright (c) 2015-2020 Daniel Adler <dadler@uni-goettingen.de>, 
+   Copyright (c) 2015-2020 Daniel Adler <dadler@uni-goettingen.de>,
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -59,8 +59,8 @@
   }
 }
 
-static void var_i64     (DCCallVM* in_p, DClonglong  x) 
-{ 
+static void var_i64     (DCCallVM* in_p, DClonglong  x)
+{
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
   dcVecAlign(&p->mVecHead, sizeof(DClonglong));
   dcVecAppend(&p->mVecHead, &x, sizeof(DClonglong));
@@ -73,17 +73,17 @@
 static void var_double  (DCCallVM* in_p, DCdouble x) {
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
   dcVecAlign(&p->mVecHead, sizeof(DCdouble));
-  dcVecAppend(&p->mVecHead, &x, sizeof(DCdouble)); 
-}   
-static void var_float   (DCCallVM* in_p, DCfloat x) {   
+  dcVecAppend(&p->mVecHead, &x, sizeof(DCdouble));
+}
+static void var_float   (DCCallVM* in_p, DCfloat x) {
   var_double( in_p, (DCdouble) x );
 }
 static void var_pointer (DCCallVM* in_p, DCpointer x) {
   var_i64(in_p, (DClonglong) x );
 }
 
-static void a_bool    (DCCallVM* in_p, DCbool  x)   
-{ 
+static void a_bool    (DCCallVM* in_p, DCbool  x)
+{
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
   if (p->i < 8) {
     p->I[p->i] = (DClonglong) x;
@@ -94,7 +94,7 @@
   }
 }
 static void a_char    (DCCallVM* in_p, DCchar  x)
-{ 
+{
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
   if (p->i < 8) {
     p->I[p->i] = (DClonglong) x;
@@ -103,8 +103,8 @@
     dcVecAppend(&p->mVecHead, &x, sizeof(DCchar));
   }
 }
-static void a_short   (DCCallVM* in_p, DCshort x)   
-{ 
+static void a_short   (DCCallVM* in_p, DCshort x)
+{
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
   if (p->i < 8) {
     p->I[p->i] = (DClonglong) x;
@@ -114,8 +114,8 @@
     dcVecAppend(&p->mVecHead, &x, sizeof(DCshort));
   }
 }
-static void a_int     (DCCallVM* in_p, DCint x)     
-{ 
+static void a_int     (DCCallVM* in_p, DCint x)
+{
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
   if (p->i < 8) {
     p->I[p->i] = (DClonglong) x;
@@ -125,8 +125,8 @@
     dcVecAppend(&p->mVecHead, &x, sizeof(DCint));
   }
 }
-static void a_long    (DCCallVM* in_p, DClong  x)   
-{ 
+static void a_long    (DCCallVM* in_p, DClong  x)
+{
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
   if (p->i < 8) {
     p->I[p->i] = (DClonglong) x;
@@ -156,7 +156,7 @@
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
   if (p->f < 8) {
     p->u.D[ p->f ] = x;
-    p->f++; 
+    p->f++;
   } else {
     dcVecAlign(&p->mVecHead, sizeof(DCdouble));
     dcVecAppend(&p->mVecHead, &x, sizeof(DCdouble));
@@ -166,11 +166,11 @@
 void call(DCCallVM* in_p, DCpointer target)
 {
   DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
-  
+
   /*
   ** copy 'size' argument is given in number of 16-byte 'pair' blocks.
   */
-  
+
   dcCall_arm64(target, dcVecData(&p->mVecHead), ( dcVecSize(&p->mVecHead) + 15 ) & -16, &p->u.S[0]);
 }
 
@@ -183,7 +183,7 @@
 , &mode
 , &a_bool
 , &a_char
-, &a_short 
+, &a_short
 , &a_int
 , &a_long
 , &a_i64
@@ -211,7 +211,7 @@
 , &mode
 , &var_bool
 , &var_char
-, &var_short 
+, &var_short
 , &var_int
 , &var_long
 , &var_i64
@@ -238,7 +238,8 @@
   DCCallVM_vt* vt;
 
   switch(mode) {
-    case DC_CALL_C_DEFAULT:        
+    case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_ARM64:
     case DC_CALL_C_ELLIPSIS:
       vt = &vt_arm64;
@@ -246,15 +247,15 @@
     case DC_CALL_C_ELLIPSIS_VARARGS:
       vt = &vt_arm64_variadic;
       break;
-    default: 
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
   dc_callvm_base_init(&self->mInterface, vt);
 }
 
 /* Public API. */
-DCCallVM* dcNewCallVM(DCsize size) 
+DCCallVM* dcNewCallVM(DCsize size)
 {
   DCCallVM_arm64* p = (DCCallVM_arm64*)dcAllocMem(sizeof(DCCallVM_arm64)+size);
 
--- a/dyncall/dyncall_callvm_mips_eabi.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_mips_eabi.c	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: Implementation of Call VM for mips "eabi" abi.
  License:
 
-   Copyright (c) 2007-2020 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
@@ -132,7 +132,7 @@
 , &dc_callvm_mode_mips_eabi
 , &dc_callvm_argBool_mips_eabi
 , &dc_callvm_argChar_mips_eabi
-, &dc_callvm_argShort_mips_eabi 
+, &dc_callvm_argShort_mips_eabi
 , &dc_callvm_argInt_mips_eabi
 , &dc_callvm_argLong_mips_eabi
 , &dc_callvm_argLongLong_mips_eabi
@@ -161,13 +161,14 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_MIPS32_EABI:
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
       vt = &gVT_mips_eabi;
       break;
     default:
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
   dc_callvm_base_init(&self->mInterface, vt);
--- a/dyncall/dyncall_callvm_mips_n32.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_mips_n32.c	Wed Feb 02 18:30:44 2022 +0100
@@ -238,6 +238,7 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_MIPS64_N32:
     case DC_CALL_C_ELLIPSIS:
       vt = &gVT_mips_n32;
--- a/dyncall/dyncall_callvm_mips_n64.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_mips_n64.c	Wed Feb 02 18:30:44 2022 +0100
@@ -255,6 +255,7 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_MIPS64_N64:
     case DC_CALL_C_ELLIPSIS:
       vt = &gVT_mips_n64;
--- a/dyncall/dyncall_callvm_mips_o32.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_mips_o32.c	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: mips "o32" ABI callvm implementation
  License:
 
-   Copyright (c) 2007-2020 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
@@ -130,16 +130,16 @@
 # if 0
     self->mRegData.u[self->mArgCount].f[1] = x;
    call kernel
-        
+
 	mips:
 	lwc1  $f12,  4($5)    <--- byte offset 4
 	lwc1  $f13,  0($5)
-	lwc1  $f14, 12($5)    <--- byte offset 12 
+	lwc1  $f14, 12($5)    <--- byte offset 12
 	lwc1  $f15,  8($5)
 	mipsel:
 	lwc1  $f12,  0($5)    <--- byte offset 4
 	lwc1  $f13,  4($5)
-	lwc1  $f14,  8($5)    <--- byte offset 12 
+	lwc1  $f14,  8($5)    <--- byte offset 12
 	lwc1  $f15, 12($5)
 
 #  if defined(DC__Endian_LITTLE)
@@ -192,7 +192,7 @@
 , &dc_callvm_mode_mips_o32
 , &dc_callvm_argBool_mips_o32
 , &dc_callvm_argChar_mips_o32
-, &dc_callvm_argShort_mips_o32 
+, &dc_callvm_argShort_mips_o32
 , &dc_callvm_argInt_mips_o32
 , &dc_callvm_argLong_mips_o32
 , &dc_callvm_argLongLong_mips_o32
@@ -221,13 +221,14 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_MIPS32_O32:
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
       vt = &gVT_mips_o32;
       break;
     default:
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
   dc_callvm_base_init(&self->mInterface, vt);
--- a/dyncall/dyncall_callvm_ppc32.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_ppc32.c	Wed Feb 02 18:30:44 2022 +0100
@@ -3,10 +3,10 @@
  Package: dyncall
  Library: dyncall
  File: dyncall/dyncall_callvm_ppc32.c
- Description: 
+ Description:
  License:
 
-   Copyright (c) 2007-2020 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
@@ -30,9 +30,9 @@
   dyncall callvm for ppc32 architectures
 
   SUPPORTED CALLING CONVENTIONS
-  ppc32/osx 
+  ppc32/osx
   ppc32/linux (sysv abi)
-  ppc32/syscall 
+  ppc32/syscall
 
   REVISION
   2015/01/15 added syscall (tested on Linux)
@@ -48,7 +48,7 @@
 #include "dyncall_utils.h"
 
 
-/* 
+/*
 ** PowerPC 32-bit calling convention call
 **
 ** - hybrid return-type call (bool ... pointer)
@@ -108,7 +108,7 @@
   if (self->mIntRegs < 8)
     self->mRegData.mIntData[self->mIntRegs++] = i;
   /* OR push onto stack */
-  else 
+  else
     dcVecAppend(&self->mVecHead,&i,sizeof(DCint));
 }
 
@@ -122,9 +122,9 @@
   if (self->mFloatRegs < 13) {
     self->mRegData.mFloatData[self->mFloatRegs++] = d;
     /* skip two integer register file entries */
-    if (self->mIntRegs < 8) 
+    if (self->mIntRegs < 8)
       self->mRegData.mIntData[self->mIntRegs++] = ( (DCint*) &d )[0];
-    if (self->mIntRegs < 8) 
+    if (self->mIntRegs < 8)
       self->mRegData.mIntData[self->mIntRegs++] = ( (DCint*) &d )[1];
   }
   /* push on stack */
@@ -138,9 +138,9 @@
   if (self->mFloatRegs < 8) {
     self->mRegData.mFloatData[self->mFloatRegs++] = d;
     /* skip two integer register file entries */
-    if (self->mIntRegs < 8) 
+    if (self->mIntRegs < 8)
       self->mRegData.mIntData[self->mIntRegs++] = ( (DCint*) &d )[0];
-    if (self->mIntRegs < 8) 
+    if (self->mIntRegs < 8)
       self->mRegData.mIntData[self->mIntRegs++] = ( (DCint*) &d )[1];
   }
   /* push on stack */
@@ -150,24 +150,24 @@
 static void dc_callvm_argDouble_ppc32_sysv(DCCallVM* in_self, DCdouble d)
 {
   DCCallVM_ppc32* self = (DCCallVM_ppc32*)in_self;
-  if (self->mFloatRegs < 8) 
+  if (self->mFloatRegs < 8)
     self->mRegData.mFloatData[self->mFloatRegs++] = d;
   else /* OR push data on stack */
   {
     /* align stack to 8 byte boundary */
-  dcVecResize(&self->mVecHead , ( dcVecSize(&self->mVecHead) + 7UL ) & -8UL ); 
+  dcVecResize(&self->mVecHead , ( dcVecSize(&self->mVecHead) + 7UL ) & -8UL );
     /* AND push data */
     dcVecAppend(&self->mVecHead,(DCpointer) &d,sizeof(DCdouble));
   }
 }
 
 /* Floating-point */
-  
-  
+
+
 /* darwin:
- * - skip one integer register file entry (write in - for ellipsis calls) 
+ * - skip one integer register file entry (write in - for ellipsis calls)
  * sysv:
- * - 
+ * -
  */
 
 static void dc_callvm_argFloat_ppc32_darwin(DCCallVM* in_self, DCfloat f)
@@ -176,14 +176,14 @@
   if (self->mFloatRegs < 13) {
     self->mRegData.mFloatData[self->mFloatRegs++] = (DCdouble) (f);
   }
-  
+
   /* AND skip one integer register file entry (write in - for ellipsis calls) */
-  
-  if (self->mIntRegs < 8) 
+
+  if (self->mIntRegs < 8)
     self->mRegData.mIntData[self->mIntRegs++] = *( (DCint*) &f );
-  
+
   /* AND push on stack */
-  
+
   dcVecAppend(&self->mVecHead, &f, sizeof(DCfloat));
 }
 
@@ -195,7 +195,7 @@
 
   if (self->mFloatRegs < 8)
     self->mRegData.mFloatData[self->mFloatRegs++] = (DCdouble) (f);
-  
+
   else /* OR put float on stack */
     dcVecAppend(&self->mVecHead, &f, sizeof(DCfloat));
 }
@@ -224,7 +224,7 @@
     self->mRegData.mIntData[self->mIntRegs++] = p[1];
   }
   /* OR push onto stack */
-  else  
+  else
   {
     /* in case, mIntRegs == 7, set it to 8 */
     self->mIntRegs = 8;
@@ -273,9 +273,9 @@
 void dc_callvm_call_ppc32_darwin(DCCallVM* in_self, DCpointer target)
 {
   DCCallVM_ppc32* self = (DCCallVM_ppc32*)in_self;
-  dcCall_ppc32_darwin( 
-    target, 
-    &self->mRegData, 
+  dcCall_ppc32_darwin(
+    target,
+    &self->mRegData,
     DC_MAX(dcVecSize(&self->mVecHead), 8*4),
     dcVecData(&self->mVecHead)
   );
@@ -302,7 +302,7 @@
 , &dc_callvm_mode_ppc32
 , &dc_callvm_argBool_ppc32
 , &dc_callvm_argChar_ppc32
-, &dc_callvm_argShort_ppc32 
+, &dc_callvm_argShort_ppc32
 , &dc_callvm_argInt_ppc32_darwin
 , &dc_callvm_argLong_ppc32
 , &dc_callvm_argLongLong_ppc32_darwin
@@ -330,7 +330,7 @@
 , &dc_callvm_mode_ppc32
 , &dc_callvm_argBool_ppc32
 , &dc_callvm_argChar_ppc32
-, &dc_callvm_argShort_ppc32 
+, &dc_callvm_argShort_ppc32
 , &dc_callvm_argInt_ppc32_sysv
 , &dc_callvm_argLong_ppc32
 , &dc_callvm_argLongLong_ppc32_sysv
@@ -358,7 +358,7 @@
 , &dc_callvm_mode_ppc32
 , &dc_callvm_argBool_ppc32
 , &dc_callvm_argChar_ppc32
-, &dc_callvm_argShort_ppc32 
+, &dc_callvm_argShort_ppc32
 , &dc_callvm_argInt_ppc32_sysv
 , &dc_callvm_argLong_ppc32
 , &dc_callvm_argLongLong_ppc32_sysv
@@ -389,19 +389,21 @@
 
 #if defined(DC__ABI_Darwin)
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
 #endif
-    case DC_CALL_C_PPC32_OSX:  
-      vt = &gVT_ppc32_darwin; 
+    case DC_CALL_C_PPC32_OSX:
+      vt = &gVT_ppc32_darwin;
       break;
 
 #if defined(DC__ABI_SysV)
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
 #endif
-    case DC_CALL_C_PPC32_SYSV: 
+    case DC_CALL_C_PPC32_SYSV:
       vt = &gVT_ppc32_sysv;
       break;
 
@@ -410,8 +412,8 @@
       vt = &gVT_ppc32_syscall;
       break;
 
-    default: 
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
 
--- a/dyncall/dyncall_callvm_ppc64.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_ppc64.c	Wed Feb 02 18:30:44 2022 +0100
@@ -3,12 +3,12 @@
  Package: dyncall
  Library: dyncall
  File: dyncall/dyncall_callvm_ppc64.c
- Description: 
+ Description:
  License:
 
    Copyright (c) 2014-2015 Masanori Mitsugi <mitsugi@linux.vnet.ibm.com>
                       2020 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
@@ -45,7 +45,7 @@
 #include "dyncall_types.h"
 
 
-/* 
+/*
 ** PowerPC 64-bit calling convention call
 **
 ** - hybrid return-type call (bool ... pointer)
@@ -204,10 +204,10 @@
 {
   DCCallVM_ppc64* self = (DCCallVM_ppc64*)in_self;
 
-  if (dcVecSize(&self->mVecHead) == 0) 
+  if (dcVecSize(&self->mVecHead) == 0)
     dcVecSkip(&self->mVecHead,(sizeof(DClonglong))*(self->mIntRegs));
 
-  if (self->mIntRegs < 8) 
+  if (self->mIntRegs < 8)
     self->mRegData.mIntData[self->mIntRegs++] = L;
 
   /* push on stack */
@@ -259,7 +259,7 @@
   if (size < 64) {
 	dcVecSkip(&self->mVecHead, 64-size);
   }
-  
+
   dcCall_ppc64( target, &self->mRegData, dcVecSize(&self->mVecHead) , dcVecData(&self->mVecHead));
 }
 
@@ -364,7 +364,8 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
-    case DC_CALL_C_PPC64: 
+    case DC_CALL_C_DEFAULT_THIS:
+    case DC_CALL_C_PPC64:
     case DC_CALL_C_ELLIPSIS:
 #if DC__ABI_PPC64_ELF_V == 2
       vt = &gVT_ppc64;
@@ -383,11 +384,11 @@
       vt = &gVT_ppc64_syscall;
       break;
 
-    default: 
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
-  
+
   dc_callvm_base_init(&self->mInterface, vt);
 }
 
--- a/dyncall/dyncall_callvm_sparc.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_sparc.c	Wed Feb 02 18:30:44 2022 +0100
@@ -61,14 +61,14 @@
 
 /* handle others Pointer, Long, LongLong, Float and Double as-is. */
 
-static void dc_callvm_argPointer_sparc(DCCallVM* in_self, DCpointer x) 
-{ 
+static void dc_callvm_argPointer_sparc(DCCallVM* in_self, DCpointer x)
+{
   DCCallVM_sparc* self = (DCCallVM_sparc*)in_self;
   dcVecAppend(&self->mVecHead, &x, sizeof(DCpointer));
 }
 
-static void dc_callvm_argLong_sparc(DCCallVM* in_self, DClong x) 
-{ 
+static void dc_callvm_argLong_sparc(DCCallVM* in_self, DClong x)
+{
   DCCallVM_sparc* self = (DCCallVM_sparc*)in_self;
   dcVecAppend(&self->mVecHead, &x, sizeof(DClong));
 }
@@ -87,7 +87,7 @@
   DCCallVM_sparc* self = (DCCallVM_sparc*)in_self;
   dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
 }
-  
+
 /* we call directly with 'RTYPE dcCall(DCCallVM* in_self, DCpointer target)' */
 #if 0
 /* call: delegate to default call kernel */
@@ -103,28 +103,28 @@
 /* CallVM virtual table. */
 DCCallVM_vt gVT_sparc =
 {
-  &dc_callvm_free_sparc, 
-  &dc_callvm_reset_sparc, 
-  &dc_callvm_mode_sparc, 
-  &dc_callvm_argBool_sparc, 
-  &dc_callvm_argChar_sparc, 
-  &dc_callvm_argShort_sparc, 
-  &dc_callvm_argInt_sparc, 
-  &dc_callvm_argLong_sparc, 
-  &dc_callvm_argLongLong_sparc, 
-  &dc_callvm_argFloat_sparc, 
-  &dc_callvm_argDouble_sparc, 
-  &dc_callvm_argPointer_sparc, 
-  NULL /* argStruct */, 
-  (DCvoidvmfunc*)       &dcCall_sparc,  
-  (DCboolvmfunc*)       &dcCall_sparc,  
-  (DCcharvmfunc*)       &dcCall_sparc,  
-  (DCshortvmfunc*)      &dcCall_sparc,  
-  (DCintvmfunc*)        &dcCall_sparc, 
-  (DClongvmfunc*)       &dcCall_sparc, 
-  (DClonglongvmfunc*)   &dcCall_sparc,  
-  (DCfloatvmfunc*)      &dcCall_sparc,  
-  (DCdoublevmfunc*)     &dcCall_sparc,  
+  &dc_callvm_free_sparc,
+  &dc_callvm_reset_sparc,
+  &dc_callvm_mode_sparc,
+  &dc_callvm_argBool_sparc,
+  &dc_callvm_argChar_sparc,
+  &dc_callvm_argShort_sparc,
+  &dc_callvm_argInt_sparc,
+  &dc_callvm_argLong_sparc,
+  &dc_callvm_argLongLong_sparc,
+  &dc_callvm_argFloat_sparc,
+  &dc_callvm_argDouble_sparc,
+  &dc_callvm_argPointer_sparc,
+  NULL /* argStruct */,
+  (DCvoidvmfunc*)       &dcCall_sparc,
+  (DCboolvmfunc*)       &dcCall_sparc,
+  (DCcharvmfunc*)       &dcCall_sparc,
+  (DCshortvmfunc*)      &dcCall_sparc,
+  (DCintvmfunc*)        &dcCall_sparc,
+  (DClongvmfunc*)       &dcCall_sparc,
+  (DClonglongvmfunc*)   &dcCall_sparc,
+  (DCfloatvmfunc*)      &dcCall_sparc,
+  (DCdoublevmfunc*)     &dcCall_sparc,
   (DCpointervmfunc*)    &dcCall_sparc,
   NULL /* callStruct */
 };
@@ -137,13 +137,14 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_SPARC32:
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
       vt = &gVT_sparc;
       break;
     default:
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
   dc_callvm_base_init(&self->mInterface, vt);
--- a/dyncall/dyncall_callvm_sparc64.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_sparc64.c	Wed Feb 02 18:30:44 2022 +0100
@@ -92,60 +92,60 @@
 
 static void dc_callvm_mode_v9(DCCallVM* in_self, DCint mode);
 
-DCCallVM_vt gVT_v9_ellipsis = 
+DCCallVM_vt gVT_v9_ellipsis =
 {
-  &dc_callvm_free_v9, 
-  &dc_callvm_reset_v9, 
-  &dc_callvm_mode_v9, 
-  &dc_callvm_argBool_v9, 
-  &dc_callvm_argChar_v9, 
-  &dc_callvm_argShort_v9, 
-  &dc_callvm_argInt_v9, 
-  &dc_callvm_argLong_v9, 
-  &dc_callvm_argLongLong_v9, 
-  &dc_callvm_argFloat_v9_ellipsis, 
-  &dc_callvm_argDouble_v9_ellipsis, 
-  &dc_callvm_argPointer_v9, 
-  NULL /* argStruct */, 
-  (DCvoidvmfunc*)       &dcCall_v9, 
-  (DCboolvmfunc*)       &dcCall_v9, 
-  (DCcharvmfunc*)       &dcCall_v9, 
-  (DCshortvmfunc*)      &dcCall_v9, 
-  (DCintvmfunc*)        &dcCall_v9, 
-  (DClongvmfunc*)       &dcCall_v9, 
-  (DClonglongvmfunc*)   &dcCall_v9, 
-  (DCfloatvmfunc*)      &dcCall_v9, 
-  (DCdoublevmfunc*)     &dcCall_v9, 
-  (DCpointervmfunc*)    &dcCall_v9, 
+  &dc_callvm_free_v9,
+  &dc_callvm_reset_v9,
+  &dc_callvm_mode_v9,
+  &dc_callvm_argBool_v9,
+  &dc_callvm_argChar_v9,
+  &dc_callvm_argShort_v9,
+  &dc_callvm_argInt_v9,
+  &dc_callvm_argLong_v9,
+  &dc_callvm_argLongLong_v9,
+  &dc_callvm_argFloat_v9_ellipsis,
+  &dc_callvm_argDouble_v9_ellipsis,
+  &dc_callvm_argPointer_v9,
+  NULL /* argStruct */,
+  (DCvoidvmfunc*)       &dcCall_v9,
+  (DCboolvmfunc*)       &dcCall_v9,
+  (DCcharvmfunc*)       &dcCall_v9,
+  (DCshortvmfunc*)      &dcCall_v9,
+  (DCintvmfunc*)        &dcCall_v9,
+  (DClongvmfunc*)       &dcCall_v9,
+  (DClonglongvmfunc*)   &dcCall_v9,
+  (DCfloatvmfunc*)      &dcCall_v9,
+  (DCdoublevmfunc*)     &dcCall_v9,
+  (DCpointervmfunc*)    &dcCall_v9,
   NULL /* callStruct */
 };
 
 /* CallVM virtual table. */
 DCCallVM_vt gVT_v9 =
 {
-  &dc_callvm_free_v9, 
-  &dc_callvm_reset_v9, 
-  &dc_callvm_mode_v9, 
-  &dc_callvm_argBool_v9, 
-  &dc_callvm_argChar_v9, 
-  &dc_callvm_argShort_v9, 
-  &dc_callvm_argInt_v9, 
-  &dc_callvm_argLong_v9, 
-  &dc_callvm_argLongLong_v9, 
-  &dc_callvm_argFloat_v9, 
-  &dc_callvm_argDouble_v9, 
-  &dc_callvm_argPointer_v9, 
-  NULL /* argStruct */, 
-  (DCvoidvmfunc*)       &dcCall_v9, 
-  (DCboolvmfunc*)       &dcCall_v9, 
-  (DCcharvmfunc*)       &dcCall_v9, 
-  (DCshortvmfunc*)      &dcCall_v9, 
-  (DCintvmfunc*)        &dcCall_v9, 
-  (DClongvmfunc*)       &dcCall_v9, 
-  (DClonglongvmfunc*)   &dcCall_v9, 
-  (DCfloatvmfunc*)      &dcCall_v9, 
-  (DCdoublevmfunc*)     &dcCall_v9, 
-  (DCpointervmfunc*)    &dcCall_v9, 
+  &dc_callvm_free_v9,
+  &dc_callvm_reset_v9,
+  &dc_callvm_mode_v9,
+  &dc_callvm_argBool_v9,
+  &dc_callvm_argChar_v9,
+  &dc_callvm_argShort_v9,
+  &dc_callvm_argInt_v9,
+  &dc_callvm_argLong_v9,
+  &dc_callvm_argLongLong_v9,
+  &dc_callvm_argFloat_v9,
+  &dc_callvm_argDouble_v9,
+  &dc_callvm_argPointer_v9,
+  NULL /* argStruct */,
+  (DCvoidvmfunc*)       &dcCall_v9,
+  (DCboolvmfunc*)       &dcCall_v9,
+  (DCcharvmfunc*)       &dcCall_v9,
+  (DCshortvmfunc*)      &dcCall_v9,
+  (DCintvmfunc*)        &dcCall_v9,
+  (DClongvmfunc*)       &dcCall_v9,
+  (DClonglongvmfunc*)   &dcCall_v9,
+  (DCfloatvmfunc*)      &dcCall_v9,
+  (DCdoublevmfunc*)     &dcCall_v9,
+  (DCpointervmfunc*)    &dcCall_v9,
   NULL /* callStruct */
 };
 
@@ -157,6 +157,7 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_DEFAULT_THIS:
     case DC_CALL_C_SPARC64:
     case DC_CALL_C_ELLIPSIS:
       vt = &gVT_v9;
@@ -165,8 +166,8 @@
       vt = &gVT_v9_ellipsis;
       break;
     default:
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
-      return; 
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
+      return;
   }
   dc_callvm_base_init(&self->mInterface, vt);
 }
--- a/dyncall/dyncall_callvm_x64.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_x64.c	Wed Feb 02 18:30:44 2022 +0100
@@ -255,6 +255,7 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+	case DC_CALL_C_DEFAULT_THIS:
 #if defined(DC_UNIX)
     case DC_CALL_C_X64_SYSV:
 #else
@@ -265,12 +266,12 @@
       vt = &gVT_x64;
       break;
     case DC_CALL_SYS_DEFAULT:
-# if defined DC_UNIX
+#if defined(DC_UNIX)
     case DC_CALL_SYS_X64_SYSCALL_SYSV:
       vt = &gVT_x64_syscall_sysv; break;
-# else
+#else
       self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return;
-# endif
+#endif
     default:
       self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
       return;
--- a/dyncall/dyncall_callvm_x86.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_callvm_x86.c	Wed Feb 02 18:30:44 2022 +0100
@@ -6,7 +6,7 @@
  Description: Call VM for x86 architecture implementation
  License:
 
-   Copyright (c) 2007-2020 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
@@ -29,8 +29,8 @@
 #include "dyncall_alloc.h"
 
 
-/* 
-** x86 calling convention calls 
+/*
+** x86 calling convention calls
 **
 ** - hybrid return-type call (bool ... pointer)
 **
@@ -171,7 +171,7 @@
 , &dc_callvm_mode_x86
 , &dc_callvm_argBool_x86
 , &dc_callvm_argChar_x86
-, &dc_callvm_argShort_x86 
+, &dc_callvm_argShort_x86
 , &dc_callvm_argInt_x86
 , &dc_callvm_argLong_x86
 , &dc_callvm_argLongLong_x86
@@ -211,7 +211,7 @@
 , &dc_callvm_mode_x86
 , &dc_callvm_argBool_x86
 , &dc_callvm_argChar_x86
-, &dc_callvm_argShort_x86 
+, &dc_callvm_argShort_x86
 , &dc_callvm_argInt_x86
 , &dc_callvm_argLong_x86
 , &dc_callvm_argLongLong_x86
@@ -599,6 +599,9 @@
 
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+#if !defined(DC__C_MSVC)
+    case DC_CALL_C_DEFAULT_THIS:
+#endif
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
 /* Plan9 (and forks) have their own calling convention (and no support for foreign ones). */
@@ -608,6 +611,9 @@
     case DC_CALL_C_X86_CDECL:          vt = &gVT_x86_cdecl;          break; /* also handles DC_CALL_C_X86_WIN32_THIS_GNU */
     case DC_CALL_C_X86_WIN32_STD:      vt = &gVT_x86_win32_std;      break;
     case DC_CALL_C_X86_WIN32_FAST_MS:  vt = &gVT_x86_win32_fast_ms;  break;
+#if defined(DC__C_MSVC)
+    case DC_CALL_C_DEFAULT_THIS:
+#endif
     case DC_CALL_C_X86_WIN32_THIS_MS:  vt = &gVT_x86_win32_this_ms;  break;
     case DC_CALL_C_X86_WIN32_FAST_GNU: vt = &gVT_x86_win32_fast_gnu; break;
     case DC_CALL_SYS_DEFAULT:
@@ -623,7 +629,7 @@
     case DC_CALL_SYS_X86_INT80H_LINUX: vt = &gVT_x86_syscall_int80h_linux; break;
     case DC_CALL_SYS_X86_INT80H_BSD:   vt = &gVT_x86_syscall_int80h_bsd;   break;
 #endif
-    default: 
+    default:
       self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
--- a/dyncall/dyncall_signature.h	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncall/dyncall_signature.h	Wed Feb 02 18:30:44 2022 +0100
@@ -62,15 +62,16 @@
 /* calling convention / mode signatures */
 
 #define DC_SIGCHAR_CC_PREFIX           '_'
-#define DC_SIGCHAR_CC_DEFAULT          ':'
+#define DC_SIGCHAR_CC_DEFAULT          ':' /* default calling conv (platform native) */
+#define DC_SIGCHAR_CC_THISCALL         '*' /* C++ this calls (platform native) */
 #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     '#' /* GNU thiscalls are cdecl, but keep specific sig char for clarity */
+#define DC_SIGCHAR_CC_CDECL            'c' /* x86 specific */
+#define DC_SIGCHAR_CC_STDCALL          's' /* x86 specific */
+#define DC_SIGCHAR_CC_FASTCALL_MS      'F' /* x86 specific */
+#define DC_SIGCHAR_CC_FASTCALL_GNU     'f' /* x86 specific */
+#define DC_SIGCHAR_CC_THISCALL_MS      '+' /* x86 specific, MS C++ this calls */
+#define DC_SIGCHAR_CC_THISCALL_GNU     '#' /* x86 specific, GNU C++ this calls are cdecl, but keep specific sig char for clarity */
 #define DC_SIGCHAR_CC_ARM_ARM          'A'
 #define DC_SIGCHAR_CC_ARM_THUMB        'a'
 #define DC_SIGCHAR_CC_SYSCALL          '$'
--- a/dyncallback/dyncall_callback_x86.c	Wed Feb 02 12:55:23 2022 +0100
+++ b/dyncallback/dyncall_callback_x86.c	Wed Feb 02 18:30:44 2022 +0100
@@ -186,31 +186,20 @@
 void dcbInitCallback(DCCallback* pcb, const char* signature, DCCallbackHandler* handler, void* userdata)
 {
   const char* ptr;
-  char  ch;
   int mode;
   pcb->handler = handler;
   pcb->userdata = userdata;
 
   ptr = signature;
-  ch = *ptr;
 
   /* x86 hints: */
 
   mode = DC_CALL_C_X86_CDECL;
 
-  if(ch == DC_SIGCHAR_CC_PREFIX)
+  if(*ptr == DC_SIGCHAR_CC_PREFIX)
   {
-    ptr++;
-    ch = *ptr++;
-    switch(ch) {
-      case DC_SIGCHAR_CC_DEFAULT:      mode = DC_CALL_C_DEFAULT;            break;
-      case DC_SIGCHAR_CC_THISCALL_GNU: // == cdecl
-      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;
-    }
+    mode = dcGetModeFromCCSigChar(ptr[1]);
+    ptr += 2;
   }
 
   /* x86 configuration: */
@@ -262,7 +251,6 @@
 /*
  * callback constructor
  */
-
 DCCallback* dcbNewCallback(const char* signature, DCCallbackHandler* handler, void* userdata)
 {
   int err;
--- a/test/plain_c++/test_main.cc	Wed Feb 02 12:55:23 2022 +0100
+++ b/test/plain_c++/test_main.cc	Wed Feb 02 18:30:44 2022 +0100
@@ -290,6 +290,7 @@
 {
   bool r = false;
   DCCallVM* pc = dcNewCallVM(4096);
+  dcMode(pc, DC_CALL_C_DEFAULT_THIS);
   dcReset(pc);
   if(setjmp(jbuf) != 0)
     printf("sigsegv\n");