Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-35947: Update windows to the current version of libffi #11797

Merged
merged 35 commits into from
Mar 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
de396d4
Rip out libffi_msvc
zware Sep 7, 2017
e7f43ea
Remove /safeseh, which doesn't seem to exist for ml64
zware Sep 8, 2017
102a098
Fix copy of structures when passed by value.
zooba Sep 8, 2017
374110e
preserve bug fix
Jan 23, 2019
548e488
use libffi 3.3
Jan 23, 2019
bc59c71
add sysv_intel.S for x86
Feb 6, 2019
87a232f
ffi_call no longer returns stack difference from windows 32-bit
Feb 7, 2019
51ccf8a
change libffi-3.3 to libffi
Feb 11, 2019
83da944
add blurb
Feb 11, 2019
369318e
change libffi-3.3 to libffi in python.props
Feb 11, 2019
ec20baa
add configured windows header files
Feb 13, 2019
109ba99
put configured files in libffi_msvc so that they pass patchcheck.py
Feb 13, 2019
55f62c4
move configured files to ctypes-source-dep
Feb 15, 2019
c43cb08
add missing quotes
Feb 19, 2019
c663960
remove reference to libffi_msvc
Feb 19, 2019
ad7d6bf
Update PCbuild/get_externals.bat
zware Feb 19, 2019
f4ccea6
Update PCbuild/python.props
zware Feb 19, 2019
8c3479f
basic script for configuring libffi
Mar 1, 2019
d57ab4c
add cygwin info
Mar 1, 2019
0dc1bd1
add link to appveyor.yml used as a reference
Mar 1, 2019
0ba8113
used per-processor configured files
Mar 1, 2019
2f70852
remove prepare_libffi.bat
Mar 1, 2019
27b9946
generate configured header files for libffi
Mar 4, 2019
c9d8354
improvements found by trying this with ARM
Mar 5, 2019
9b4773b
use prebuilt libffi binaries
Mar 12, 2019
12e69e4
build after installing vs 2019
Mar 12, 2019
1914207
add libffi .dll to layout
Mar 12, 2019
ff0edbc
got libffi tests to run
Mar 14, 2019
9eb7c3c
setting MSBUILD is a better workaround
Mar 15, 2019
814034d
optionally install cygwin with required packages
Mar 18, 2019
d5b71ba
Fixes empty variable checks
zooba Mar 29, 2019
d7a2546
Enable overriding output directory
zooba Mar 29, 2019
ff3ff8a
Ensure VCVARSALL variable is quoted
zooba Mar 29, 2019
8fa8035
build with libffi from cpython-bin-deps
Mar 29, 2019
20d27a3
add libffi to msi definition
Mar 29, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 0 additions & 29 deletions Lib/ctypes/test/test_win32.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,6 @@

import _ctypes_test

# Only windows 32-bit has different calling conventions.
@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
@unittest.skipUnless(sizeof(c_void_p) == sizeof(c_int),
"sizeof c_void_p and c_int differ")
class WindowsTestCase(unittest.TestCase):
def test_callconv_1(self):
# Testing stdcall function

IsWindow = windll.user32.IsWindow
# ValueError: Procedure probably called with not enough arguments
# (4 bytes missing)
self.assertRaises(ValueError, IsWindow)

# This one should succeed...
self.assertEqual(0, IsWindow(0))

# ValueError: Procedure probably called with too many arguments
# (8 bytes in excess)
self.assertRaises(ValueError, IsWindow, 0, 0, 0)

def test_callconv_2(self):
# Calling stdcall function as cdecl

IsWindow = cdll.user32.IsWindow

# ValueError: Procedure called with not enough arguments
# (4 bytes missing) or wrong calling convention
self.assertRaises(ValueError, IsWindow, None)

@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
class FunctionCallTestCase(unittest.TestCase):
@unittest.skipUnless('MSC' in sys.version, "SEH only supported by MSC")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Added current version of libffi to cpython-source-deps.
Change _ctypes to use current version of libffi on Windows.
31 changes: 21 additions & 10 deletions Modules/_ctypes/_ctypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,24 +403,35 @@ static PyCArgObject *
StructUnionType_paramfunc(CDataObject *self)
{
PyCArgObject *parg;
CDataObject *copied_self;
StgDictObject *stgdict;

if (self->b_size > sizeof(void*)) {
void *new_ptr = PyMem_Malloc(self->b_size);
if (new_ptr == NULL)
return NULL;
memcpy(new_ptr, self->b_ptr, self->b_size);
copied_self = (CDataObject *)PyCData_AtAddress(
(PyObject *)Py_TYPE(self), new_ptr);
copied_self->b_needsfree = 1;
} else {
copied_self = self;
Py_INCREF(copied_self);
}

parg = PyCArgObject_new();
if (parg == NULL)
if (parg == NULL) {
Py_DECREF(copied_self);
return NULL;
}

parg->tag = 'V';
stgdict = PyObject_stgdict((PyObject *)self);
stgdict = PyObject_stgdict((PyObject *)copied_self);
assert(stgdict); /* Cannot be NULL for structure/union instances */
parg->pffi_type = &stgdict->ffi_type_pointer;
/* For structure parameters (by value), parg->value doesn't contain the structure
data itself, instead parg->value.p *points* to the structure's data
See also _ctypes.c, function _call_function_pointer().
*/
parg->value.p = self->b_ptr;
parg->size = self->b_size;
Py_INCREF(self);
parg->obj = (PyObject *)self;
parg->value.p = copied_self->b_ptr;
parg->size = copied_self->b_size;
parg->obj = (PyObject *)copied_self;
return parg;
}

Expand Down
52 changes: 18 additions & 34 deletions Modules/_ctypes/callproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,23 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa)
}
}

#if defined(MS_WIN32) && !defined(_WIN32_WCE)
/*
Per: https://msdn.microsoft.com/en-us/library/7572ztz4.aspx
To be returned by value in RAX, user-defined types must have a length
of 1, 2, 4, 8, 16, 32, or 64 bits
*/
int can_return_struct_as_int(size_t s)
{
return s == 1 || s == 2 || s == 4;
}

int can_return_struct_as_sint64(size_t s)
{
return s == 8;
}
#endif


ffi_type *_ctypes_get_ffi_type(PyObject *obj)
{
Expand Down Expand Up @@ -778,12 +795,9 @@ static int _call_function_pointer(int flags,
int *space;
ffi_cif cif;
int cc;
#ifdef MS_WIN32
int delta;
#ifndef DONT_USE_SEH
#if defined(MS_WIN32) && !defined(DONT_USE_SEH)
DWORD dwExceptionCode = 0;
EXCEPTION_RECORD record;
#endif
#endif
/* XXX check before here */
if (restype == NULL) {
Expand Down Expand Up @@ -828,7 +842,6 @@ static int _call_function_pointer(int flags,
#ifndef DONT_USE_SEH
__try {
#endif
delta =
#endif
ffi_call(&cif, (void *)pProc, resmem, avalues);
#ifdef MS_WIN32
Expand Down Expand Up @@ -860,35 +873,6 @@ static int _call_function_pointer(int flags,
return -1;
}
#endif
#ifdef MS_WIN64
if (delta != 0) {
PyErr_Format(PyExc_RuntimeError,
"ffi_call failed with code %d",
delta);
return -1;
}
#else
if (delta < 0) {
if (flags & FUNCFLAG_CDECL)
PyErr_Format(PyExc_ValueError,
"Procedure called with not enough "
"arguments (%d bytes missing) "
"or wrong calling convention",
-delta);
else
PyErr_Format(PyExc_ValueError,
"Procedure probably called with not enough "
"arguments (%d bytes missing)",
-delta);
return -1;
} else if (delta > 0) {
PyErr_Format(PyExc_ValueError,
"Procedure probably called with too many "
"arguments (%d bytes in excess)",
delta);
return -1;
}
#endif
#endif
if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred())
return -1;
Expand Down
20 changes: 0 additions & 20 deletions Modules/_ctypes/libffi_msvc/LICENSE

This file was deleted.

Loading