mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
Fixed bpo-29565: Corrected ctypes passing of large structs by value on Windows AMD64. (#168)
* Fixed bpo-29565: Corrected ctypes passing of large structs by value. Added code and test to check that when a structure passed by value is large enough to need to be passed by reference, a copy of the original structure is passed. The callee updates the passed-in value, and the test verifies that the caller's copy is unchanged. A similar change was also added to the test added for bpo-20160 (that test was passing, but the changes should guard against regressions). * Reverted unintended whitespace changes.
This commit is contained in:
parent
3eea8c67fa
commit
a86339b83f
4 changed files with 57 additions and 0 deletions
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue