[pypy-commit] creflect default: correct call argument types
arigo
noreply at buildbot.pypy.org
Fri Dec 5 15:48:23 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r161:081d71b47603
Date: 2014-12-05 15:43 +0100
http://bitbucket.org/cffi/creflect/changeset/081d71b47603/
Log: correct call argument types
diff --git a/zeffir/cfunc.c b/zeffir/cfunc.c
--- a/zeffir/cfunc.c
+++ b/zeffir/cfunc.c
@@ -5,12 +5,19 @@
int zfs_nargs;
_crx_trampoline0_fn zfs_trampl;
PyMethodDef zfs_md;
- char zfs_funcname[1];
+ size_t zfs_size_args;
+ CTypeDescrObject *zfs_ret;
+ CTypeDescrObject *zfs_args[1];
} ZefFuncSupportObject;
static void zef_func_support_dealloc(ZefFuncSupportObject *zfs)
{
+ int i;
+ for (i = zfs->zfs_nargs - 1; i >= 0; i--)
+ Py_DECREF(zfs->zfs_args[i]);
+ Py_DECREF(zfs->zfs_ret);
+
PyObject_Del(zfs);
}
@@ -37,33 +44,42 @@
Py_TPFLAGS_DEFAULT, /* tp_flags */
};
+#define ROUND_UP(n) (((n) + 7) & ~7)
+
static PyObject *zfs_call(PyObject *self, PyObject *args)
{
ZefFuncSupportObject *zfs = (ZefFuncSupportObject *)self;
int i, nargs = zfs->zfs_nargs;
Py_ssize_t actualnargs;
void *llargs[nargs];
- int llinput[nargs], lloutput; /* temp */
+ char *llbuffer;
+ size_t lloffset;
actualnargs = PyTuple_Size(args);
if (actualnargs != nargs) {
if (!PyErr_Occurred())
PyErr_Format(PyExc_TypeError,
"'%s()' expected %d arguments, but got %zd",
- zfs->zfs_funcname, nargs, actualnargs);
+ zfs->zfs_md.ml_name, nargs, actualnargs);
return NULL;
}
+ llbuffer = alloca(zfs->zfs_size_args);
+ lloffset = zfs->zfs_ret->ct_size;
+
for (i = 0; i < nargs; i++) {
- llinput[i] = PyInt_AsLong(PyTuple_GET_ITEM(args, i));
- if (PyErr_Occurred())
+ CTypeDescrObject *ct = zfs->zfs_args[i];
+ PyObject *x = PyTuple_GET_ITEM(args, i);
+ lloffset = ROUND_UP(lloffset);
+ llargs[i] = llbuffer + lloffset;
+ if (convert_from_object(llbuffer + lloffset, ct, x) < 0)
return NULL;
- llargs[i] = &llinput[i];
+ lloffset += ct->ct_size;
}
- zfs->zfs_trampl(llargs, &lloutput);
+ zfs->zfs_trampl(llargs, llbuffer);
- return PyInt_FromLong(lloutput);
+ return convert_to_object(llbuffer, zfs->zfs_ret);
}
static PyObject *make_builtin_func(PyObject *libname_obj,
@@ -71,7 +87,11 @@
_crx_qual_type args[], int nargs,
_crx_trampoline0_fn trampl)
{
- size_t size = sizeof(ZefFuncSupportObject) + strlen(funcname);
+ int i;
+ char *p;
+ size_t size = (sizeof(ZefFuncSupportObject)
+ + (nargs - 1) * sizeof(CTypeDescrObject *)
+ + strlen(funcname) + 1);
ZefFuncSupportObject *zfs = (ZefFuncSupportObject *)PyObject_Malloc(size);
if (zfs == NULL)
return PyErr_NoMemory();
@@ -79,9 +99,26 @@
zfs->zfs_nargs = nargs;
zfs->zfs_trampl = trampl;
+ zfs->zfs_ret = ret;
+ Py_INCREF(ret);
+
+ assert(ret->ct_size >= 0);
+ size = ret->ct_size;
+
+ for (i = 0; i < nargs; i++) {
+ CTypeDescrObject *ct = args[i].type;
+ if (ct->ct_flags & CT_ARRAY)
+ ct = (CTypeDescrObject *)ct->ct_stuff; /* array -> pointer */
+ Py_INCREF(ct);
+ zfs->zfs_args[i] = ct;
+ assert(ct->ct_size >= 0);
+ size = ROUND_UP(size) + ct->ct_size;
+ }
+ zfs->zfs_size_args = size;
+ p = (char *)(zfs->zfs_args + nargs);
memset(&zfs->zfs_md, 0, sizeof(PyMethodDef));
- zfs->zfs_md.ml_name = strcpy(zfs->zfs_funcname, funcname);
+ zfs->zfs_md.ml_name = strcpy(p, funcname);
zfs->zfs_md.ml_meth = &zfs_call;
zfs->zfs_md.ml_flags = METH_VARARGS;
/*zfs->zfs_md.ml_doc = ... */
diff --git a/zeffir/test/test_function.py b/zeffir/test/test_function.py
--- a/zeffir/test/test_function.py
+++ b/zeffir/test/test_function.py
@@ -9,7 +9,6 @@
assert res == 43
def test_function_with_pointer_arg():
- py.test.skip("in-progress")
ffi, lib = support.compile_and_open('function')
p = ffi.new("int[]", [30, 2, 10])
res = lib.add_from_array(p, 3)
More information about the pypy-commit
mailing list