[pypy-commit] cffi verifier2: Test and fix
arigo
noreply at buildbot.pypy.org
Fri Jul 27 18:55:24 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: verifier2
Changeset: r729:34052d659eac
Date: 2012-07-27 18:47 +0200
http://bitbucket.org/cffi/cffi/changeset/34052d659eac/
Log: Test and fix
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1730,7 +1730,7 @@
#endif
}
if (convert_from_object(data, argtype, obj) < 0) {
- if (CData_Check(obj) && argtype->ct_flags & CT_POINTER &&
+ if (CData_Check(obj) && (argtype->ct_flags & CT_POINTER) &&
argtype->ct_itemdescr == ((CDataObject *)obj)->c_type) {
/* special case to make the life of verifier.py easier:
if the formal argument type is 'struct foo *' but
@@ -3908,6 +3908,11 @@
return result;
}
+static short _testfunc18(struct _testfunc7_s *ptr)
+{
+ return ptr->a1 + ptr->a2;
+}
+
static PyObject *b__testfunc(PyObject *self, PyObject *args)
{
/* for testing only */
@@ -3934,6 +3939,7 @@
case 15: f = &_testfunc15; break;
case 16: f = &_testfunc16; break;
case 17: f = &_testfunc17; break;
+ case 18: f = &_testfunc18; break;
default:
PyErr_SetNone(PyExc_ValueError);
return NULL;
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -786,6 +786,22 @@
res = f(x[0])
assert res == -4042 + ord('A')
+def test_call_function_18():
+ BChar = new_primitive_type("char")
+ BShort = new_primitive_type("short")
+ BStruct = new_struct_type("foo")
+ BStructPtr = new_pointer_type(BStruct)
+ complete_struct_or_union(BStruct, [('a1', BChar, -1),
+ ('a2', BShort, -1)])
+ BFunc18 = new_function_type((BStructPtr,), BShort, False)
+ f = cast(BFunc18, _testfunc(18))
+ x = newp(BStructPtr, {'a1': 'A', 'a2': -4042})
+ # test the exception that allows us to pass a 'struct foo' where the
+ # function really expects a 'struct foo *'.
+ res = f(x[0])
+ assert res == -4042 + ord('A')
+ assert res == f(x)
+
def test_call_function_9():
BInt = new_primitive_type("int")
BFunc9 = new_function_type((BInt,), BInt, True) # vararg
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -227,19 +227,31 @@
if tp.ellipsis:
newfunction = self._load_constant(False, tp, name, module)
else:
+ indirections = []
if any(isinstance(type, model.StructOrUnion) for type in tp.args):
indirect_args = []
for i, type in enumerate(tp.args):
if isinstance(type, model.StructOrUnion):
type = model.PointerType(type)
+ indirections.append((i, type))
indirect_args.append(type)
tp = model.FunctionPtrType(tuple(indirect_args),
tp.result, tp.ellipsis)
BFunc = self.ffi._get_cached_btype(tp)
wrappername = '_cffi_f_%s' % name
newfunction = module.load_function(BFunc, wrappername)
+ for i, type in indirections:
+ newfunction = self._make_struct_wrapper(newfunction, i, type)
setattr(library, name, newfunction)
+ def _make_struct_wrapper(self, oldfunc, i, tp):
+ backend = self.ffi._backend
+ BType = self.ffi._get_cached_btype(tp)
+ def newfunc(*args):
+ args = args[:i] + (backend.newp(BType, args[i]),) + args[i+1:]
+ return oldfunc(*args)
+ return newfunc
+
# ----------
# named structs
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -583,6 +583,7 @@
""")
s = ffi.new("struct foo_s *", [100, 1])
assert lib.foo(s[0]) == 99
+ assert lib.foo([100, 1]) == 99
def test_autofilled_struct_as_argument_dynamic():
ffi = FFI()
More information about the pypy-commit
mailing list