diff options
author | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2017-02-22 06:21:17 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-22 06:21:17 (GMT) |
commit | 3cc5817cfaf5663645f4ee447eaed603d2ad290a (patch) | |
tree | 34797bd494eb8e1a2a77bdee100c682fb8055362 /Modules | |
parent | b067a5eef7fdf69264d3578654996fc3755df4ea (diff) | |
download | cpython-3cc5817cfaf5663645f4ee447eaed603d2ad290a.zip cpython-3cc5817cfaf5663645f4ee447eaed603d2ad290a.tar.gz cpython-3cc5817cfaf5663645f4ee447eaed603d2ad290a.tar.bz2 |
Fixed bpo-29565: Corrected ctypes passing of large structs by value on Windows AMD64. (#168) (#220)
Fixed bpo-29565: Corrected ctypes passing of large structs by value.
(cherry picked from commit a86339b83fbd0932e0529a3c91935e997a234582)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_ctypes/_ctypes_test.c | 13 | ||||
-rw-r--r-- | Modules/_ctypes/libffi_msvc/ffi.c | 10 |
2 files changed, 23 insertions, 0 deletions
diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 629ddf6..59d56d0 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -44,6 +44,19 @@ _testfunc_cbk_large_struct(Test in, void (*func)(Test)) func(in); } +/* + * See issue 29565. Update a structure passed by value; + * the caller should not see any change. + */ + +EXPORT(void) +_testfunc_large_struct_update_value(Test in) +{ + in.first = 0x0badf00d; + in.second = 0x0badf00d; + in.third = 0x0badf00d; +} + EXPORT(void)testfunc_array(int values[4]) { printf("testfunc_array %d %d %d %d\n", diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c index 1d82929..91a27dc 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.c +++ b/Modules/_ctypes/libffi_msvc/ffi.c @@ -239,6 +239,16 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, break; #else case FFI_SYSV: + /* If a single argument takes more than 8 bytes, + then a copy is passed by reference. */ + for (unsigned i = 0; i < cif->nargs; i++) { + size_t z = cif->arg_types[i]->size; + if (z > 8) { + void *temp = alloca(z); + memcpy(temp, avalue[i], z); + avalue[i] = temp; + } + } /*@-usedef@*/ return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); |