[pypy-commit] cffi sirtom67/float_complex: Test explicitly that if we try to call a function in ABI mode with a
arigo
pypy.commits at gmail.com
Mon May 29 13:11:21 EDT 2017
Author: Armin Rigo <arigo at tunes.org>
Branch: sirtom67/float_complex
Changeset: r2937:f0f90cb166e5
Date: 2017-05-29 19:10 +0200
http://bitbucket.org/cffi/cffi/changeset/f0f90cb166e5/
Log: Test explicitly that if we try to call a function in ABI mode with a
complex argument or return value, then we get a clear error message.
Previously, it would still try to call libffi. But libffi doesn't
support complex, on all platforms except a single very obscure one,
I think. So it seems to be a better behaviour for now.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -888,7 +888,7 @@
static Py_complex
read_raw_complex_data(char *target, int size)
{
- Py_complex r = {.real=0, .imag=0};
+ Py_complex r = {0.0, 0.0};
if (size == 2*sizeof(float)) {
float real_part, imag_part;
memcpy(&real_part, target + 0, sizeof(float));
@@ -898,7 +898,7 @@
return r;
}
if (size == 2*sizeof(double)) {
- memcpy(&(r.real), target, 2*sizeof(double));
+ memcpy(&r, target, 2*sizeof(double));
return r;
}
Py_FatalError("read_raw_complex_data: bad float size");
@@ -4224,14 +4224,11 @@
goto bad_ffi_type;
}
else if (ptypes->flags & CT_PRIMITIVE_COMPLEX) {
- // as of March 2017, still no libffi support for complex
- // but it fails silently.
- if (strcmp(ptypes->name, "float _Complex") == 0)
- ffitype = &ffi_type_complex_float;
- else if (strcmp(ptypes->name, "double _Complex") == 0)
- ffitype = &ffi_type_complex_double;
- else
- goto bad_ffi_type;
+ /* As of March 2017, still no libffi support for complex.
+ It fails silently if we try to use ffi_type_complex_float
+ or ffi_type_complex_double. Better not use it at all.
+ */
+ ffitype = NULL;
}
else {
switch (ptypes->size) {
@@ -4925,7 +4922,7 @@
{
const char *place = is_result_type ? "return value" : "argument";
- if (ct->ct_flags & CT_PRIMITIVE_ANY) {
+ if (ct->ct_flags & (CT_PRIMITIVE_ANY & ~CT_PRIMITIVE_COMPLEX)) {
return (ffi_type *)ct->ct_extra;
}
else if (ct->ct_flags & (CT_POINTER|CT_FUNCTIONPTR)) {
@@ -5051,9 +5048,16 @@
return NULL;
}
else {
+ char *extra = "";
+ if (ct->ct_flags & CT_PRIMITIVE_COMPLEX)
+ extra = " (the support for complex types inside libffi "
+ "is mostly missing at this point, so CFFI only "
+ "supports complex types as arguments or return "
+ "value in API-mode functions)";
+
PyErr_Format(PyExc_NotImplementedError,
- "ctype '%s' (size %zd) not supported as %s",
- ct->ct_name, ct->ct_size, place);
+ "ctype '%s' (size %zd) not supported as %s%s",
+ ct->ct_name, ct->ct_size, place, extra);
return NULL;
}
}
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1130,27 +1130,32 @@
assert f(3, cast(BSChar, -3), cast(BUChar, 200), cast(BSShort, -5)) == 192
def test_call_function_24():
- py.test.skip("libffi returning nonsense silently")
BFloat = new_primitive_type("float")
BFloatComplex = new_primitive_type("float _Complex")
BFunc3 = new_function_type((BFloat, BFloat), BFloatComplex, False)
- f = cast(BFunc3, _testfunc(24))
- result = f(1.25, 5.1)
- assert type(result) == complex
- assert result.real == 1.25 # exact
- assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-5) # inexact
+ if 0: # libffi returning nonsense silently, so logic disabled for now
+ f = cast(BFunc3, _testfunc(24))
+ result = f(1.25, 5.1)
+ assert type(result) == complex
+ assert result.real == 1.25 # exact
+ assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-5) # inexact
+ else:
+ f = cast(BFunc3, _testfunc(9))
+ py.test.raises(NotImplementedError, f, 12.3, 34.5)
def test_call_function_25():
- py.test.skip("libffi returning nonsense silently")
BDouble = new_primitive_type("double")
BDoubleComplex = new_primitive_type("double _Complex")
BFunc3 = new_function_type((BDouble, BDouble), BDoubleComplex, False)
- f = cast(BFunc3, _testfunc(25))
- result = f(1.25, 5.1)
- assert type(result) == complex
- assert result.real == 1.25 # exact
- assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-10) # inexact
-
+ if 0: # libffi returning nonsense silently, so logic disabled for now
+ f = cast(BFunc3, _testfunc(25))
+ result = f(1.25, 5.1)
+ assert type(result) == complex
+ assert result.real == 1.25 # exact
+ assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-10) # inexact
+ else:
+ f = cast(BFunc3, _testfunc(9))
+ py.test.raises(NotImplementedError, f, 12.3, 34.5)
def test_cannot_call_with_a_autocompleted_struct():
BSChar = new_primitive_type("signed char")
More information about the pypy-commit
mailing list