예제 #1
0
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);
}
예제 #2
0
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;
}