Пример #1
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;
}
Пример #2
0
CThunkObject *AllocFunctionCallback(PyObject *callable,
				    PyObject *converters,
				    PyObject *restype,
				    int flags)
{
	int result;
	CThunkObject *p;
	Py_ssize_t nArgs, i;
	ffi_abi cc;

	nArgs = PySequence_Size(converters);
	p = CThunkObject_new(nArgs);
	if (p == NULL)
		return NULL;

	assert(CThunk_CheckExact(p));

	p->pcl = MallocClosure();
	if (p->pcl == NULL) {
		PyErr_NoMemory();
		goto error;
	}

	p->flags = flags;
	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;

	Py_INCREF(restype);
	p->restype = restype;
	if (restype == Py_None) {
		p->setfunc = NULL;
		p->ffi_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->ffi_restype = &dict->ffi_type_pointer;
	}

	cc = FFI_DEFAULT_ABI;
#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
	if ((flags & FUNCFLAG_CDECL) == 0)
		cc = FFI_STDCALL;
#endif
	result = ffi_prep_cif(&p->cif, cc,
			      Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int),
			      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;
	}

	Py_INCREF(converters);
	p->converters = converters;
	Py_INCREF(callable);
	p->callable = callable;
	return p;

  error:
	Py_XDECREF(p);
	return NULL;
}