Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
bpo-41100: ctypes fixes for arm64 Mac OS#21249
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
ff883bc36b35bcbacf128971ef00da3058780f852baeac14b62fe20ae160a59bca75fdFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| setup.py: probe libffi for ffi_closure_alloc and ffi_prep_cif_var |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| #include "Python.h" | ||
| #include "frameobject.h" | ||
| #include <stdbool.h> | ||
| #include <ffi.h> | ||
| #ifdef MS_WIN32 | ||
| #include <windows.h> | ||
| @@ -18,7 +20,7 @@ CThunkObject_dealloc(PyObject *myself) | ||
| Py_XDECREF(self->callable); | ||
| Py_XDECREF(self->restype); | ||
| if (self->pcl_write) | ||
| ffi_closure_free(self->pcl_write); | ||
| Py_ffi_closure_free(self->pcl_write); | ||
| PyObject_GC_Del(self); | ||
| } | ||
| @@ -361,8 +363,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, | ||
| assert(CThunk_CheckExact((PyObject *)p)); | ||
| p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure), | ||
| &p->pcl_exec); | ||
| p->pcl_write = Py_ffi_closure_alloc(sizeof(ffi_closure), &p->pcl_exec); | ||
| if (p->pcl_write == NULL){ | ||
| PyErr_NoMemory(); | ||
| goto error; | ||
| @@ -408,13 +409,33 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, | ||
| "ffi_prep_cif failed with %d", result); | ||
| goto error; | ||
| } | ||
| #if defined(X86_DARWIN) || defined(POWERPC_DARWIN) | ||
| result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p); | ||
| #if HAVE_FFI_PREP_CLOSURE_LOC | ||
| # if USING_APPLE_OS_LIBFFI | ||
| # define HAVE_FFI_PREP_CLOSURE_LOC_RUNTIME __builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *) | ||
| # else | ||
| # define HAVE_FFI_PREP_CLOSURE_LOC_RUNTIME true | ||
| # endif | ||
| if (HAVE_FFI_PREP_CLOSURE_LOC_RUNTIME){ | ||
| result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn, | ||
| p, | ||
| p->pcl_exec); | ||
| } else | ||
| #endif | ||
| { | ||
| #if USING_APPLE_OS_LIBFFI && defined(__arm64__) | ||
| PyErr_Format(PyExc_NotImplementedError, "ffi_prep_closure_loc() is missing"); | ||
| goto error; | ||
| #else | ||
| result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn, | ||
| p, | ||
| p->pcl_exec); | ||
| #if __clang__ | ||
| #pragma clang diagnostic push | ||
| #pragma clang diagnostic ignored "-Wdeprecated-declarations" | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto | ||
| #endif | ||
| result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p); | ||
| #if __clang__ | ||
| #pragma clang diagnostic pop | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto | ||
| #endif | ||
| #endif | ||
| } | ||
| if (result != FFI_OK){ | ||
| PyErr_Format(PyExc_RuntimeError, | ||
| "ffi_prep_closure failed with %d", result); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -57,6 +57,8 @@ | ||
| #include "Python.h" | ||
| #include "structmember.h" // PyMemberDef | ||
| #include <stdbool.h> | ||
| #ifdef MS_WIN32 | ||
| #include <windows.h> | ||
| #include <tchar.h> | ||
| @@ -812,7 +814,8 @@ static int _call_function_pointer(int flags, | ||
| ffi_type **atypes, | ||
| ffi_type *restype, | ||
| void *resmem, | ||
| int argcount) | ||
| int argcount, | ||
| int argtypecount) | ||
| { | ||
| PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */ | ||
| PyObject *error_object = NULL; | ||
| @@ -835,14 +838,63 @@ static int _call_function_pointer(int flags, | ||
| if ((flags & FUNCFLAG_CDECL) == 0) | ||
| cc = FFI_STDCALL; | ||
| #endif | ||
| if (FFI_OK != ffi_prep_cif(&cif, | ||
| cc, | ||
| argcount, | ||
| restype, | ||
| atypes)){ | ||
| PyErr_SetString(PyExc_RuntimeError, | ||
| "ffi_prep_cif failed"); | ||
| return -1; | ||
| # if USING_APPLE_OS_LIBFFI | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Proposed change: #if USING_APPLE_OS_LIBFFI && HAVE_FFI_PREP_CIF_VAR This way the __builtin_available is not used when building on older macOS versions. | ||
| # define HAVE_FFI_PREP_CIF_VAR_RUNTIME __builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *) | ||
| # elif HAVE_FFI_PREP_CIF_VAR | ||
| # define HAVE_FFI_PREP_CIF_VAR_RUNTIME true | ||
| # else | ||
| # define HAVE_FFI_PREP_CIF_VAR_RUNTIME false | ||
| # endif | ||
| /* Even on Apple-arm64 the calling convention for variadic functions conincides | ||
| * with the standard calling convention in the case that the function called | ||
| * only with its fixed arguments. Thus, we do not need a special flag to be | ||
| * set on variadic functions. We treat a function as variadic if it is called | ||
| * with a nonzero number of variadic arguments */ | ||
| bool is_variadic = (argtypecount != 0 && argcount > argtypecount); | ||
| (void) is_variadic; | ||
| #if defined(__APPLE__) && defined(__arm64__) | ||
| if (is_variadic){ | ||
| if (HAVE_FFI_PREP_CIF_VAR_RUNTIME){ | ||
| } else{ | ||
| PyErr_SetString(PyExc_NotImplementedError, "ffi_prep_cif_var() is missing"); | ||
| return -1; | ||
| } | ||
| } | ||
| #endif | ||
| bool called_ffi_prep_cif_var = false; | ||
| #if HAVE_FFI_PREP_CIF_VAR | ||
| if (is_variadic){ | ||
| if (HAVE_FFI_PREP_CIF_VAR_RUNTIME){ | ||
| if (FFI_OK != ffi_prep_cif_var(&cif, | ||
| cc, | ||
| argtypecount, | ||
| argcount, | ||
| restype, | ||
| atypes)){ | ||
| PyErr_SetString(PyExc_RuntimeError, | ||
| "ffi_prep_cif_var failed"); | ||
| return -1; | ||
| } | ||
| called_ffi_prep_cif_var = true; | ||
| } | ||
| } | ||
| #endif | ||
| if (!called_ffi_prep_cif_var){ | ||
| if (FFI_OK != ffi_prep_cif(&cif, | ||
| cc, | ||
| argcount, | ||
| restype, | ||
| atypes)){ | ||
| PyErr_SetString(PyExc_RuntimeError, | ||
| "ffi_prep_cif failed"); | ||
| return -1; | ||
| } | ||
| } | ||
| if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)){ | ||
| @@ -1212,9 +1264,8 @@ PyObject *_ctypes_callproc(PPROC pProc, | ||
| if (-1 == _call_function_pointer(flags, pProc, avalues, atypes, | ||
| rtype, resbuf, | ||
| Py_SAFE_DOWNCAST(argcount, | ||
| Py_ssize_t, | ||
| int))) | ||
| Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int), | ||
| Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int))) | ||
| goto cleanup; | ||
| #ifdef WORDS_BIGENDIAN | ||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should avoid
-Wunknown-pragmaswarnings when building on other platforms.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed