Author: Armin Rigo <[email protected]>
Branch:
Changeset: r1034:b22bc0909265
Date: 2012-11-09 17:40 +0100
http://bitbucket.org/cffi/cffi/changeset/b22bc0909265/
Log: Improve the test, which fails now. Fix it.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3358,7 +3358,7 @@
if (ct->ct_flags & CT_PRIMITIVE_ANY) {
return (ffi_type *)ct->ct_extra;
}
- else if (ct->ct_flags & (CT_POINTER|CT_ARRAY|CT_FUNCTIONPTR)) {
+ else if (ct->ct_flags & (CT_POINTER|CT_FUNCTIONPTR)) {
return &ffi_type_pointer;
}
else if ((ct->ct_flags & CT_VOID) && is_result_type) {
@@ -3375,7 +3375,7 @@
if (ct->ct_flags & CT_STRUCT) {
ffi_type *ffistruct, *ffifield;
ffi_type **elements;
- Py_ssize_t i, n;
+ Py_ssize_t i, n, nflat;
CFieldObject *cf;
/* We can't pass a struct that was completed by verify().
@@ -3412,10 +3412,14 @@
#endif
n = PyDict_Size(ct->ct_stuff);
- elements = fb_alloc(fb, (n + 1) * sizeof(ffi_type*));
+ nflat = 0;
+
+ /* walk the fields, expanding arrays into repetitions; first,
+ only count how many flattened fields there are */
cf = (CFieldObject *)ct->ct_extra;
-
for (i=0; i<n; i++) {
+ Py_ssize_t flat;
+ CTypeDescrObject *ct;
assert(cf != NULL);
if (cf->cf_bitshift >= 0) {
PyErr_SetString(PyExc_NotImplementedError,
@@ -3423,16 +3427,41 @@
"a struct with bit fields");
return NULL;
}
- ffifield = fb_fill_type(fb, cf->cf_type, 0);
- if (elements != NULL)
- elements[i] = ffifield;
+ flat = 1;
+ ct = cf->cf_type;
+ while (ct->ct_flags & CT_ARRAY) {
+ flat *= ct->ct_length;
+ ct = ct->ct_itemdescr;
+ }
+ assert(flat >= 0);
+ nflat += flat;
cf = cf->cf_next;
}
assert(cf == NULL);
+ /* next, allocate and fill the flattened list */
+ elements = fb_alloc(fb, (nflat + 1) * sizeof(ffi_type*));
+ nflat = 0;
+ cf = (CFieldObject *)ct->ct_extra;
+ for (i=0; i<n; i++) {
+ Py_ssize_t j, flat = 1;
+ CTypeDescrObject *ct = cf->cf_type;
+ while (ct->ct_flags & CT_ARRAY) {
+ flat *= ct->ct_length;
+ ct = ct->ct_itemdescr;
+ }
+ ffifield = fb_fill_type(fb, ct, 0);
+ if (elements != NULL) {
+ for (j=0; j<flat; j++)
+ elements[nflat++] = ffifield;
+ }
+ cf = cf->cf_next;
+ }
+
+ /* finally, allocate the FFI_TYPE_STRUCT */
ffistruct = fb_alloc(fb, sizeof(ffi_type));
if (ffistruct != NULL) {
- elements[n] = NULL;
+ elements[nflat] = NULL;
ffistruct->size = ct->ct_size;
ffistruct->alignment = ct->ct_length;
ffistruct->type = FFI_TYPE_STRUCT;
@@ -3491,6 +3520,9 @@
ffi_type *atype;
farg = (CTypeDescrObject *)PyTuple_GET_ITEM(fargs, i);
+ /* convert arrays to pointers */
+ if (farg->ct_flags & CT_ARRAY)
+ farg = (CTypeDescrObject *)farg->ct_stuff;
/* ffi buffer: fill in the ffi for the i'th argument */
assert(farg != NULL);
@@ -4490,10 +4522,13 @@
}
struct _testfunc22_s { int a[10]; };
-static struct _testfunc22_s _testfunc22(int n)
+static struct _testfunc22_s _testfunc22(struct _testfunc22_s s1,
+ struct _testfunc22_s s2)
{
struct _testfunc22_s result;
- result.a[5] = n;
+ int i;
+ for (i=0; i<10; i++)
+ result.a[i] = s1.a[i] - s2.a[i];
return result;
}
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -931,11 +931,15 @@
BInt = new_primitive_type("int")
BArray10 = new_array_type(new_pointer_type(BInt), 10)
BStruct = new_struct_type("foo")
+ BStructP = new_pointer_type(BStruct)
complete_struct_or_union(BStruct, [('a', BArray10, -1)])
- BFunc22 = new_function_type((BInt,), BStruct, False)
+ BFunc22 = new_function_type((BStruct, BStruct), BStruct, False)
f = cast(BFunc22, _testfunc(22))
- res = f(5432)
- assert res.a[5] == 5432
+ p1 = newp(BStructP, {'a': range(100, 110)})
+ p2 = newp(BStructP, {'a': range(1000, 1100, 10)})
+ res = f(p1[0], p2[0])
+ for i in range(10):
+ assert res.a[i] == p1.a[i] - p2.a[i]
def test_call_function_9():
BInt = new_primitive_type("int")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit