summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLawrence D'Anna <lawrence_danna@apple.com>2020-07-09 18:39:23 -0700
committerLawrence D'Anna <lawrence_danna@apple.com>2020-07-09 18:39:23 -0700
commit6684336eafc9aafebbccb8f48c3b82cc913b3aa8 (patch)
tree3a8c0bb1bea225de15c2e3724b79c9465c723a92
parentfc9349e8aa5a533ff51f5ec6c592e8024f2d727e (diff)
downloadcffi-6684336eafc9aafebbccb8f48c3b82cc913b3aa8.tar.gz
MacOS 11, arm64, ffi_prep_cif_var
On Apple arm64, theABI for a variardic function is different than the ABI for a fixed-arg function, even of the same arg types. In order to account for this, CFFI must call ffi_prep_cif_var for variardic calls. see: https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html
-rw-r--r--c/_cffi_backend.c27
-rw-r--r--setup.py3
2 files changed, 24 insertions, 6 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
index 19801f0..6a8bccb 100644
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -2892,7 +2892,7 @@ static PyObject *
convert_struct_to_owning_object(char *data, CTypeDescrObject *ct); /*forward*/
static cif_description_t *
-fb_prepare_cif(PyObject *fargs, CTypeDescrObject *, ffi_abi); /*forward*/
+fb_prepare_cif(PyObject *fargs, CTypeDescrObject *, Py_ssize_t, int, ffi_abi); /*forward*/
static PyObject *new_primitive_type(const char *name); /*forward*/
@@ -3085,7 +3085,7 @@ cdata_call(CDataObject *cd, PyObject *args, PyObject *kwds)
#else
fabi = PyLong_AS_LONG(PyTuple_GET_ITEM(signature, 0));
#endif
- cif_descr = fb_prepare_cif(fvarargs, fresult, fabi);
+ cif_descr = fb_prepare_cif(fvarargs, fresult, nargs_declared, true, fabi);
if (cif_descr == NULL)
goto error;
}
@@ -5810,7 +5810,10 @@ static CTypeDescrObject *fb_prepare_ctype(struct funcbuilder_s *fb,
static cif_description_t *fb_prepare_cif(PyObject *fargs,
CTypeDescrObject *fresult,
+ Py_ssize_t nargs_declared,
+ int ellipsis,
ffi_abi fabi)
+
{
char *buffer;
cif_description_t *cif_descr;
@@ -5837,8 +5840,22 @@ static cif_description_t *fb_prepare_cif(PyObject *fargs,
assert(funcbuffer.bufferp == buffer + funcbuffer.nb_bytes);
cif_descr = (cif_description_t *)buffer;
- if (ffi_prep_cif(&cif_descr->cif, fabi, funcbuffer.nargs,
- funcbuffer.rtype, funcbuffer.atypes) != FFI_OK) {
+ ffi_status status;
+#if HAVE_FFI_PREP_CIF_VAR
+ if (ellipsis) {
+ status = ffi_prep_cif_var(&cif_descr->cif, fabi,
+ nargs_declared, funcbuffer.nargs,
+ funcbuffer.rtype, funcbuffer.atypes);
+ } else
+#endif
+#if !HAVE_FFI_PREP_CIF_VAR && defined(__arm64__) && defined(__APPLE__)
+#error Apple Arm64 ABI requires ffi_prep_cif_var
+#endif
+ {
+ status = ffi_prep_cif(&cif_descr->cif, fabi, funcbuffer.nargs,
+ funcbuffer.rtype, funcbuffer.atypes);
+ }
+ if (status != FFI_OK) {
PyErr_SetString(PyExc_SystemError,
"libffi failed to build this function type");
goto error;
@@ -5882,7 +5899,7 @@ static PyObject *new_function_type(PyObject *fargs, /* tuple */
is computed here. */
cif_description_t *cif_descr;
- cif_descr = fb_prepare_cif(fargs, fresult, fabi);
+ cif_descr = fb_prepare_cif(fargs, fresult, 0, ellipsis, fabi);
if (cif_descr == NULL) {
if (PyErr_ExceptionMatches(PyExc_NotImplementedError)) {
PyErr_Clear(); /* will get the exception if we see an
diff --git a/setup.py b/setup.py
index c28147e..fc8d705 100644
--- a/setup.py
+++ b/setup.py
@@ -152,7 +152,8 @@ else:
if 'darwin' in sys.platform and macosx_deployment_target() >= (10, 15):
# use libffi from Mac OS SDK
extra_compile_args += ['-iwithsysroot/usr/include/ffi']
- define_macros += [('CFFI_TRUST_LIBFFI', '1')]
+ define_macros += [('CFFI_TRUST_LIBFFI', '1'),
+ ('HAVE_FFI_PREP_CIF_VAR', '1')]
libraries += ['ffi']
else:
use_pkg_config()