Backported PyCapsule from 3.1, and converted most uses of

CObject to PyCapsule.
This commit is contained in:
Larry Hastings 2010-03-25 00:54:54 +00:00
parent 53ff86ea5f
commit 402b73fb8d
40 changed files with 1048 additions and 127 deletions

View file

@ -181,6 +181,8 @@ static int compiler_with(struct compiler *, stmt_ty);
static PyCodeObject *assemble(struct compiler *, int addNone);
static PyObject *__doc__;
#define COMPILER_CAPSULE_NAME_COMPILER_UNIT "compile.c compiler unit"
PyObject *
_Py_Mangle(PyObject *privateobj, PyObject *ident)
{
@ -490,13 +492,13 @@ compiler_enter_scope(struct compiler *c, identifier name, void *key,
/* Push the old compiler_unit on the stack. */
if (c->u) {
PyObject *wrapper = PyCObject_FromVoidPtr(c->u, NULL);
if (!wrapper || PyList_Append(c->c_stack, wrapper) < 0) {
Py_XDECREF(wrapper);
PyObject *capsule = PyCapsule_New(c->u, COMPILER_CAPSULE_NAME_COMPILER_UNIT, NULL);
if (!capsule || PyList_Append(c->c_stack, capsule) < 0) {
Py_XDECREF(capsule);
compiler_unit_free(u);
return 0;
}
Py_DECREF(wrapper);
Py_DECREF(capsule);
u->u_private = c->u->u_private;
Py_XINCREF(u->u_private);
}
@ -513,15 +515,15 @@ static void
compiler_exit_scope(struct compiler *c)
{
int n;
PyObject *wrapper;
PyObject *capsule;
c->c_nestlevel--;
compiler_unit_free(c->u);
/* Restore c->u to the parent unit. */
n = PyList_GET_SIZE(c->c_stack) - 1;
if (n >= 0) {
wrapper = PyList_GET_ITEM(c->c_stack, n);
c->u = (struct compiler_unit *)PyCObject_AsVoidPtr(wrapper);
capsule = PyList_GET_ITEM(c->c_stack, n);
c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT);
assert(c->u);
/* we are deleting from a list so this really shouldn't fail */
if (PySequence_DelItem(c->c_stack, n) < 0)

View file

@ -139,22 +139,33 @@ _PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
/* Handle cleanup of allocated memory in case of exception */
#define GETARGS_CAPSULE_NAME_CLEANUP_PTR "getargs.cleanup_ptr"
#define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"
static void
cleanup_ptr(void *ptr)
cleanup_ptr(PyObject *self)
{
PyMem_FREE(ptr);
void *ptr = PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_PTR);
if (ptr) {
PyMem_FREE(ptr);
}
}
static void
cleanup_buffer(void *ptr)
cleanup_buffer(PyObject *self)
{
PyBuffer_Release((Py_buffer *) ptr);
Py_buffer *ptr = (Py_buffer *)PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_BUFFER);
if (ptr) {
PyBuffer_Release(ptr);
}
}
static int
addcleanup(void *ptr, PyObject **freelist, void (*destr)(void *))
addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
{
PyObject *cobj;
const char *name;
if (!*freelist) {
*freelist = PyList_New(0);
if (!*freelist) {
@ -162,7 +173,15 @@ addcleanup(void *ptr, PyObject **freelist, void (*destr)(void *))
return -1;
}
}
cobj = PyCObject_FromVoidPtr(ptr, destr);
if (destr == cleanup_ptr) {
name = GETARGS_CAPSULE_NAME_CLEANUP_PTR;
} else if (destr == cleanup_buffer) {
name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER;
} else {
return -1;
}
cobj = PyCapsule_New(ptr, name, destr);
if (!cobj) {
destr(ptr);
return -1;
@ -183,8 +202,7 @@ cleanreturn(int retval, PyObject *freelist)
don't get called. */
Py_ssize_t len = PyList_GET_SIZE(freelist), i;
for (i = 0; i < len; i++)
((PyCObject *) PyList_GET_ITEM(freelist, i))
->destructor = NULL;
PyCapsule_SetDestructor(PyList_GET_ITEM(freelist, i), NULL);
}
Py_XDECREF(freelist);
return retval;