Index: Modules/_ctypes/_ctypes.c =================================================================== --- Modules/_ctypes/_ctypes.c (revision 83835) +++ Modules/_ctypes/_ctypes.c (working copy) @@ -3463,7 +3463,7 @@ self->callable = callable; self->thunk = thunk; - *(void **)self->b_ptr = (void *)thunk->pcl; + *(void **)self->b_ptr = (void *)thunk->pcl_exec; Py_INCREF((PyObject *)thunk); /* for KeepRef */ if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) { Index: Modules/_ctypes/callbacks.c =================================================================== --- Modules/_ctypes/callbacks.c (revision 83835) +++ Modules/_ctypes/callbacks.c (working copy) @@ -21,8 +21,8 @@ Py_XDECREF(self->converters); Py_XDECREF(self->callable); Py_XDECREF(self->restype); - if (self->pcl) - _ctypes_free_closure(self->pcl); + if (self->pcl_write) + ffi_closure_free(self->pcl_write); PyObject_GC_Del(self); } @@ -391,7 +391,8 @@ return NULL; } - p->pcl = NULL; + p->pcl_exec = NULL; + p->pcl_write = NULL; memset(&p->cif, 0, sizeof(p->cif)); p->converters = NULL; p->callable = NULL; @@ -421,8 +422,9 @@ assert(CThunk_CheckExact(p)); - p->pcl = _ctypes_alloc_closure(); - if (p->pcl == NULL) { + p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure), + &p->pcl_exec); + if (p->pcl_write == NULL) { PyErr_NoMemory(); goto error; } @@ -467,7 +469,9 @@ "ffi_prep_cif failed with %d", result); goto error; } - result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p); + result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn, + p, + p->pcl_exec); if (result != FFI_OK) { PyErr_Format(PyExc_RuntimeError, "ffi_prep_closure failed with %d", result); Index: Modules/_ctypes/ctypes.h =================================================================== --- Modules/_ctypes/ctypes.h (revision 83835) +++ Modules/_ctypes/ctypes.h (working copy) @@ -95,7 +95,8 @@ typedef struct { PyObject_VAR_HEAD - ffi_closure *pcl; /* the C callable */ + ffi_closure *pcl_write; /* the C callable, writeable */ + void *pcl_exec; /* the C callable, executable */ ffi_cif cif; int flags; PyObject *converters; @@ -428,9 +429,6 @@ #endif #endif -extern void _ctypes_free_closure(void *); -extern void *_ctypes_alloc_closure(void); - extern void _ctypes_add_traceback(char *, char *, int); extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); Index: Modules/_ctypes/libffi/fficonfig.py.in =================================================================== --- Modules/_ctypes/libffi/fficonfig.py.in (revision 83835) +++ Modules/_ctypes/libffi/fficonfig.py.in (working copy) @@ -1,5 +1,7 @@ ffi_sources = """ src/prep_cif.c +src/closures.c +src/dlmalloc.c """.split() ffi_platforms = { Index: Modules/_ctypes/libffi_msvc/ffi.c =================================================================== --- Modules/_ctypes/libffi_msvc/ffi.c (revision 83835) +++ Modules/_ctypes/libffi_msvc/ffi.c (working copy) @@ -371,10 +371,11 @@ extern void ffi_closure_OUTER(); ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) { short bytes; char *tramp; @@ -452,6 +453,5 @@ closure->cif = cif; closure->user_data = user_data; closure->fun = fun; - return FFI_OK; } Index: Modules/_ctypes/libffi_msvc/ffi.h =================================================================== --- Modules/_ctypes/libffi_msvc/ffi.h (revision 83835) +++ Modules/_ctypes/libffi_msvc/ffi.h (working copy) @@ -221,11 +221,15 @@ void *user_data; } ffi_closure; +void ffi_closure_free(void *); +void *ffi_closure_alloc (size_t size, void **code); + ffi_status -ffi_prep_closure (ffi_closure*, +ffi_prep_closure_loc (ffi_closure*, ffi_cif *, void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data); + void *user_data, + void *codeloc); typedef struct { char tramp[FFI_TRAMPOLINE_SIZE]; Index: Modules/_ctypes/malloc_closure.c =================================================================== --- Modules/_ctypes/malloc_closure.c (revision 83835) +++ Modules/_ctypes/malloc_closure.c (working copy) @@ -93,7 +93,7 @@ /******************************************************************/ /* put the item back into the free list */ -void _ctypes_free_closure(void *p) +void ffi_closure_free(void *p) { ITEM *item = (ITEM *)p; item->next = free_list; @@ -101,7 +101,7 @@ } /* return one item from the free list, allocating more if needed */ -void *_ctypes_alloc_closure(void) +void *ffi_closure_alloc(size_t ignored, void** codeloc) { ITEM *item; if (!free_list) @@ -110,5 +110,7 @@ return NULL; item = free_list; free_list = item->next; - return item; + *codeloc = (void *)item; + return (void *)item; } + Index: setup.py =================================================================== --- setup.py (revision 83835) +++ setup.py (working copy) @@ -1867,8 +1867,7 @@ '_ctypes/callbacks.c', '_ctypes/callproc.c', '_ctypes/stgdict.c', - '_ctypes/cfield.c', - '_ctypes/malloc_closure.c'] + '_ctypes/cfield.c'] depends = ['_ctypes/ctypes.h'] if sys.platform == 'darwin':