static void CThunkObject_dealloc(PyObject *_self) { CThunkObject *self = (CThunkObject *)_self; Py_XDECREF(self->converters); Py_XDECREF(self->callable); Py_XDECREF(self->restype); if (self->pcl) FreeClosure(self->pcl); PyObject_GC_Del(self); }
ffi_info *AllocFunctionCallback(PyObject *callable, PyObject *converters, PyObject *restype, int is_cdecl) { int result; ffi_info *p; int nArgs, i; ffi_abi cc; nArgs = PySequence_Size(converters); p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1)); if (p == NULL) { PyErr_NoMemory(); return NULL; } p->pcl = MallocClosure(); if (p->pcl == NULL) { PyErr_NoMemory(); goto error; } for (i = 0; i < nArgs; ++i) { PyObject *cnv = PySequence_GetItem(converters, i); if (cnv == NULL) goto error; p->atypes[i] = GetType(cnv); Py_DECREF(cnv); } p->atypes[i] = NULL; if (restype == Py_None) { p->setfunc = NULL; p->restype = &ffi_type_void; } else { StgDictObject *dict = PyType_stgdict(restype); if (dict == NULL || dict->setfunc == NULL) { PyErr_SetString(PyExc_TypeError, "invalid result type for callback function"); goto error; } p->setfunc = dict->setfunc; p->restype = &dict->ffi_type_pointer; } cc = FFI_DEFAULT_ABI; #if defined(MS_WIN32) && !defined(_WIN32_WCE) if (is_cdecl == 0) cc = FFI_STDCALL; #endif result = ffi_prep_cif(&p->cif, cc, nArgs, GetType(restype), &p->atypes[0]); if (result != FFI_OK) { PyErr_Format(PyExc_RuntimeError, "ffi_prep_cif failed with %d", result); goto error; } result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p); if (result != FFI_OK) { PyErr_Format(PyExc_RuntimeError, "ffi_prep_closure failed with %d", result); goto error; } p->converters = converters; p->callable = callable; return p; error: if (p) { if (p->pcl) FreeClosure(p->pcl); PyMem_Free(p); } return NULL; }