PROT_WRITE and PROT_EXEC.
Library
-------
+- Issue5504 - ctypes should now work with systems where mmap can't be
+ PROT_WRITE and PROT_EXEC.
+
- Fix Issue8280 - urllib2's Request method will remove fragements in the url.
This is how it is supposed to work, wget and curl do the same. Previous
behavior was wrong.
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)) {
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);
}
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;
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;
}
"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);
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;
#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);
ffi_sources = """
src/prep_cif.c
+src/closures.c
+src/dlmalloc.c
""".split()
ffi_platforms = {
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;
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
-
return FFI_OK;
}
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];
/******************************************************************/
/* 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;
}
/* 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)
return NULL;
item = free_list;
free_list = item->next;
- return item;
+ *codeloc = (void *)item;
+ return (void *)item;
}
+
'_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':