changeset 35:75fe1dec0eb4

- added support for signature-based calling convention switch
author Tassilo Philipp
date Mon, 13 Apr 2020 16:07:56 +0200
parents 2682a627168c
children b84064293541
files python/pydc/README.txt python/pydc/pydcext.c
diffstat 2 files changed, 41 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/python/pydc/README.txt	Sun Apr 12 19:37:37 2020 +0200
+++ b/python/pydc/README.txt	Mon Apr 13 16:07:56 2020 +0200
@@ -37,11 +37,13 @@
 SIGNATURE FORMAT
 ================
 
-  is a formated string
+  ignoring calling convention mode switching for simplicity, the signature is
+  a string with the following format (using * as regex-like repetition):
 
-  format: "xxxxx)y"
+    "x*)y"
 
-    x is positional parameter-type charcode, y is result-type charcode
+  where x is positional parameter-type charcode (per argument), y is result-type charcode
+
 
   SIG | FROM PYTHON 2                   | FROM PYTHON 3                   | C/C++                           | TO PYTHON 2                          | TO PYTHON 3
   ----+---------------------------------+---------------------------------+---------------------------------+--------------------------------------+---------------------------------------
@@ -71,20 +73,25 @@
       | -                               | bytes (PyBytes)               ! | const char* (UTF-8 for unicode) | int (PyString)                       | str (PyUnicode)
       | bytearray (PyByteArray)       ! | bytearray (PyByteArray)       ! | const char* (UTF-8 for unicode) | int (PyString)                       | str (PyUnicode)
 
-# converted to 1 if True and 0 otherwise
-@ converted to False if 0 and True otherwise
-% range/length checked
-$ cast to single precision
-^ cast to double precision
-& mutable buffer when passed to C
-! immutable buffer when passed to C, as strings (in any form) are considered objects, not buffers
+  # converted to 1 if True and 0 otherwise
+  @ converted to False if 0 and True otherwise
+  % range/length checked
+  $ cast to single precision
+  ^ cast to double precision
+  & mutable buffer when passed to C
+  ! immutable buffer when passed to C, as strings (in any form) are considered objects, not buffers
+
+
+  also supported are specifying calling convention mode switches using
+  '_'-prefixed signature characters; consult the dyncall docs for a list
+
 
 TODO
 ====
 
-- signature suffixes used to indicate calling conventions are not supported yet!
 - callback support
 
+
 BUGS
 ====
 
--- a/python/pydc/pydcext.c	Sun Apr 12 19:37:37 2020 +0200
+++ b/python/pydc/pydcext.c	Mon Apr 13 16:07:56 2020 +0200
@@ -207,6 +207,29 @@
 
 		switch(ch)
 		{
+			case DC_SIGCHAR_CC_PREFIX:
+			{
+				if(*(ptr+1) != '\0')
+				{
+					// @@@ this is easily going out of sync with dyncall, abstract this sigchar->mode lookup somewhere inside dyncall
+					switch(*++ptr) {
+						case DC_SIGCHAR_CC_DEFAULT:          dcMode(gpCall, DC_CALL_C_DEFAULT           ); break;
+						case DC_SIGCHAR_CC_ELLIPSIS:         dcMode(gpCall, DC_CALL_C_ELLIPSIS          ); break;
+						case DC_SIGCHAR_CC_ELLIPSIS_VARARGS: dcMode(gpCall, DC_CALL_C_ELLIPSIS_VARARGS  ); break;
+						case DC_SIGCHAR_CC_CDECL:            dcMode(gpCall, DC_CALL_C_X86_CDECL         ); break;
+						case DC_SIGCHAR_CC_STDCALL:          dcMode(gpCall, DC_CALL_C_X86_WIN32_STD     ); break;
+						case DC_SIGCHAR_CC_FASTCALL_MS:      dcMode(gpCall, DC_CALL_C_X86_WIN32_FAST_MS ); break;
+						case DC_SIGCHAR_CC_FASTCALL_GNU:     dcMode(gpCall, DC_CALL_C_X86_WIN32_FAST_GNU); break;
+						case DC_SIGCHAR_CC_THISCALL_MS:      dcMode(gpCall, DC_CALL_C_X86_WIN32_THIS_MS ); break;
+						case DC_SIGCHAR_CC_THISCALL_GNU:     dcMode(gpCall, DC_CALL_C_X86_WIN32_THIS_GNU); break;
+						case DC_SIGCHAR_CC_ARM_ARM:          dcMode(gpCall, DC_CALL_C_ARM_ARM           ); break;
+						case DC_SIGCHAR_CC_ARM_THUMB:        dcMode(gpCall, DC_CALL_C_ARM_THUMB         ); break;
+						case DC_SIGCHAR_CC_SYSCALL:          dcMode(gpCall, DC_CALL_SYS_DEFAULT         ); break;
+					}
+				}
+			}
+			break;
+
 			case DC_SIGCHAR_BOOL:
 				if ( !PyBool_Check(po) )
 					return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a bool", pos );