summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2014-11-06 13:56:47 (GMT)
committerGeorg Brandl <georg@python.org>2014-11-06 13:56:47 (GMT)
commita6a8a4f5f7e2ef0ca78622649d23acd984047613 (patch)
tree992572eab4cbc5bac90564a80e5545b118260386
parent6246f2a103c6bbe36c885e076437d32144f27f81 (diff)
parent9dcab59b088f0cee1c7a2581f50f227defe2d3a2 (diff)
downloadcpython-a6a8a4f5f7e2ef0ca78622649d23acd984047613.zip
cpython-a6a8a4f5f7e2ef0ca78622649d23acd984047613.tar.gz
cpython-a6a8a4f5f7e2ef0ca78622649d23acd984047613.tar.bz2
merge heads
-rw-r--r--Doc/make.bat2
-rw-r--r--Lib/ctypes/test/test_win32.py26
-rw-r--r--Modules/_ctypes/_ctypes_test.c43
-rw-r--r--Modules/_ctypes/callproc.c6
-rw-r--r--Modules/_ctypes/libffi_msvc/ffi.c29
-rw-r--r--Modules/_ctypes/libffi_msvc/prep_cif.c18
-rw-r--r--Modules/_ctypes/libffi_msvc/types.c2
7 files changed, 107 insertions, 19 deletions
diff --git a/Doc/make.bat b/Doc/make.bat
index c8f6082..1070166 100644
--- a/Doc/make.bat
+++ b/Doc/make.bat
@@ -12,7 +12,7 @@ if DEFINED ProgramFiles(x86) set _PRGMFLS=%ProgramFiles(x86)%
if NOT DEFINED ProgramFiles(x86) set _PRGMFLS=%ProgramFiles%
if "%HTMLHELP%" EQU "" set HTMLHELP=%_PRGMFLS%\HTML Help Workshop\hhc.exe
-if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/patchlevel.py`) do set DISTVERSION=%%v
+if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v
if "%BUILDDIR%" EQU "" set BUILDDIR=build
diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py
index 2dd7b45..ff08386 100644
--- a/Lib/ctypes/test/test_win32.py
+++ b/Lib/ctypes/test/test_win32.py
@@ -90,9 +90,29 @@ class Structures(unittest.TestCase):
dll = CDLL(_ctypes_test.__file__)
- pt = POINT(10, 10)
- rect = RECT(0, 0, 20, 20)
- self.assertEqual(1, dll.PointInRect(byref(rect), pt))
+ pt = POINT(15, 25)
+ left = c_long.in_dll(dll, 'left')
+ top = c_long.in_dll(dll, 'top')
+ right = c_long.in_dll(dll, 'right')
+ bottom = c_long.in_dll(dll, 'bottom')
+ rect = RECT(left, top, right, bottom)
+ PointInRect = dll.PointInRect
+ PointInRect.argtypes = [POINTER(RECT), POINT]
+ self.assertEqual(1, PointInRect(byref(rect), pt))
+
+ ReturnRect = dll.ReturnRect
+ ReturnRect.argtypes = [c_int, RECT, POINTER(RECT), POINT, RECT,
+ POINTER(RECT), POINT, RECT]
+ ReturnRect.restype = RECT
+ for i in range(4):
+ ret = ReturnRect(i, rect, pointer(rect), pt, rect,
+ byref(rect), pt, rect)
+ # the c function will check and modify ret if something is
+ # passed in improperly
+ self.assertEqual(ret.left, left.value)
+ self.assertEqual(ret.right, right.value)
+ self.assertEqual(ret.top, top.value)
+ self.assertEqual(ret.bottom, bottom.value)
if __name__ == '__main__':
unittest.main()
diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c
index 2756187..a52f650 100644
--- a/Modules/_ctypes/_ctypes_test.c
+++ b/Modules/_ctypes/_ctypes_test.c
@@ -540,6 +540,49 @@ EXPORT(int) PointInRect(RECT *prc, POINT pt)
return 1;
}
+EXPORT(long left = 10);
+EXPORT(long top = 20);
+EXPORT(long right = 30);
+EXPORT(long bottom = 40);
+
+EXPORT(RECT) ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr,
+ RECT *er, POINT fp, RECT gr)
+{
+ /*Check input */
+ if (ar.left + br->left + dr.left + er->left + gr.left != left * 5)
+ {
+ ar.left = 100;
+ return ar;
+ }
+ if (ar.right + br->right + dr.right + er->right + gr.right != right * 5)
+ {
+ ar.right = 100;
+ return ar;
+ }
+ if (cp.x != fp.x)
+ {
+ ar.left = -100;
+ }
+ if (cp.y != fp.y)
+ {
+ ar.left = -200;
+ }
+ switch(i)
+ {
+ case 0:
+ return ar;
+ break;
+ case 1:
+ return dr;
+ break;
+ case 2:
+ return gr;
+ break;
+
+ }
+ return ar;
+}
+
typedef struct {
short x;
short y;
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 19f59e0..7007b7c 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -1170,11 +1170,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
}
for (i = 0; i < argcount; ++i) {
atypes[i] = args[i].ffi_type;
- if (atypes[i]->type == FFI_TYPE_STRUCT
-#ifdef _WIN64
- && atypes[i]->size <= sizeof(void *)
-#endif
- )
+ if (atypes[i]->type == FFI_TYPE_STRUCT)
avalues[i] = (void *)args[i].value.p;
else
avalues[i] = (void *)&args[i].value;
diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c
index fb2e45e..ab6b220 100644
--- a/Modules/_ctypes/libffi_msvc/ffi.c
+++ b/Modules/_ctypes/libffi_msvc/ffi.c
@@ -102,6 +102,15 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
FFI_ASSERT(0);
}
}
+#ifdef _WIN64
+ else if (z > 8)
+ {
+ /* On Win64, if a single argument takes more than 8 bytes,
+ then it is always passed by reference. */
+ *(void **)argp = *p_argv;
+ z = 8;
+ }
+#endif
else
{
memcpy(argp, *p_argv, z);
@@ -124,7 +133,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
- case FFI_TYPE_STRUCT:
case FFI_TYPE_SINT64:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
@@ -132,6 +140,18 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = (unsigned) cif->rtype->type;
break;
+ case FFI_TYPE_STRUCT:
+ /* MSVC returns small structures in registers. Put in cif->flags
+ the value FFI_TYPE_STRUCT only if the structure is big enough;
+ otherwise, put the 4- or 8-bytes integer type. */
+ if (cif->rtype->size <= 4)
+ cif->flags = FFI_TYPE_INT;
+ else if (cif->rtype->size <= 8)
+ cif->flags = FFI_TYPE_SINT64;
+ else
+ cif->flags = FFI_TYPE_STRUCT;
+ break;
+
case FFI_TYPE_UINT64:
#ifdef _WIN64
case FFI_TYPE_POINTER:
@@ -201,8 +221,7 @@ ffi_call(/*@dependent@*/ ffi_cif *cif,
#else
case FFI_SYSV:
/*@-usedef@*/
- /* Function call needs at least 40 bytes stack size, on win64 AMD64 */
- return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes ? cif->bytes : 40,
+ return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break;
@@ -227,7 +246,7 @@ void *
#else
static void __fastcall
#endif
-ffi_closure_SYSV (ffi_closure *closure, int *argp)
+ffi_closure_SYSV (ffi_closure *closure, char *argp)
{
// this is our return value storage
long double res;
@@ -237,7 +256,7 @@ ffi_closure_SYSV (ffi_closure *closure, int *argp)
void **arg_area;
unsigned short rtype;
void *resp = (void*)&res;
- void *args = &argp[1];
+ void *args = argp + sizeof(void*);
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
diff --git a/Modules/_ctypes/libffi_msvc/prep_cif.c b/Modules/_ctypes/libffi_msvc/prep_cif.c
index 2650fa0..b28f895 100644
--- a/Modules/_ctypes/libffi_msvc/prep_cif.c
+++ b/Modules/_ctypes/libffi_msvc/prep_cif.c
@@ -116,9 +116,9 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
#if !defined M68K && !defined __x86_64__ && !defined S390
/* Make space for the return structure pointer */
if (cif->rtype->type == FFI_TYPE_STRUCT
- /* MSVC returns small structures in registers. But we have a different
- workaround: pretend int32 or int64 return type, and converting to
- structure afterwards. */
+#ifdef _WIN32
+ && (cif->rtype->size > 8) /* MSVC returns small structs in registers */
+#endif
#ifdef SPARC
&& (cif->abi != FFI_V9 || cif->rtype->size > 32)
#endif
@@ -143,7 +143,11 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
|| ((*ptr)->type == FFI_TYPE_LONGDOUBLE
&& cif->abi != FFI_V9))
- bytes += sizeof(void*);
+ bytes += sizeof(void*);
+ else
+#elif defined (_WIN64)
+ if ((*ptr)->type == FFI_TYPE_STRUCT && ((*ptr)->size > 8))
+ bytes += sizeof(void*);
else
#endif
{
@@ -168,6 +172,12 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
#endif
}
+#ifdef _WIN64
+ /* Function call needs at least 40 bytes stack size, on win64 AMD64 */
+ if (bytes < 40)
+ bytes = 40;
+#endif
+
cif->bytes = bytes;
/* Perform machine dependent cif processing */
diff --git a/Modules/_ctypes/libffi_msvc/types.c b/Modules/_ctypes/libffi_msvc/types.c
index df32190..4433ac2 100644
--- a/Modules/_ctypes/libffi_msvc/types.c
+++ b/Modules/_ctypes/libffi_msvc/types.c
@@ -43,7 +43,7 @@ FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
#if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \
- || defined IA64
+ || defined IA64 || defined _WIN64
FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);