diff options
author | Erik Bray <erik.m.bray@gmail.com> | 2017-06-07 17:42:24 (GMT) |
---|---|---|
committer | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2017-06-07 17:42:24 (GMT) |
commit | 9ba3aa4d02a110d1a1ea464a8aff3be7dd9c63c3 (patch) | |
tree | b9ffda17e8b2462c8a859531b645c79a473055f2 /Modules | |
parent | 897bba75632dfce87c355e3cd4700468357715a7 (diff) | |
download | cpython-9ba3aa4d02a110d1a1ea464a8aff3be7dd9c63c3.zip cpython-9ba3aa4d02a110d1a1ea464a8aff3be7dd9c63c3.tar.gz cpython-9ba3aa4d02a110d1a1ea464a8aff3be7dd9c63c3.tar.bz2 |
bpo-30353: Fix pass by value for structs on 64-bit Cygwin/MinGW (GH-1559)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_ctypes/_ctypes_test.c | 18 | ||||
-rw-r--r-- | Modules/_ctypes/callproc.c | 23 |
2 files changed, 39 insertions, 2 deletions
diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index fe0015c..2255e57 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -57,6 +57,24 @@ _testfunc_large_struct_update_value(Test in) ((volatile Test *)&in)->third = 0x0badf00d; } +typedef struct { + unsigned int first; + unsigned int second; +} TestReg; + + +EXPORT(TestReg) last_tfrsuv_arg; + + +EXPORT(void) +_testfunc_reg_struct_update_value(TestReg in) +{ + last_tfrsuv_arg = in; + ((volatile TestReg *)&in)->first = 0x0badf00d; + ((volatile TestReg *)&in)->second = 0x0badf00d; +} + + EXPORT(void)testfunc_array(int values[4]) { printf("testfunc_array %d %d %d %d\n", diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 0b6faf9..5439b93 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1039,6 +1039,13 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) } #endif +#if (defined(__x86_64__) && (defined(__MINGW64__) || defined(__CYGWIN__))) || \ + defined(__aarch64__) +#define CTYPES_PASS_BY_REF_HACK +#define POW2(x) (((x & ~(x - 1)) == x) ? x : 0) +#define IS_PASS_BY_REF(x) (x > 8 || !POW2(x)) +#endif + /* * Requirements, must be ensured by the caller: * - argtuple is tuple of arguments @@ -1136,8 +1143,20 @@ 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 CTYPES_PASS_BY_REF_HACK + size_t size = atypes[i]->size; + if (IS_PASS_BY_REF(size)) { + void *tmp = alloca(size); + if (atypes[i]->type == FFI_TYPE_STRUCT) + memcpy(tmp, args[i].value.p, size); + else + memcpy(tmp, (void*)&args[i].value, size); + + avalues[i] = tmp; + } + else +#endif + if (atypes[i]->type == FFI_TYPE_STRUCT) avalues[i] = (void *)args[i].value.p; else avalues[i] = (void *)&args[i].value; |