[pypy-commit] cffi default: hg backout 0ed9b03dd40d, f0cdef5768b5, 95c88bfbf9f7.
arigo
noreply at buildbot.pypy.org
Fri Jun 29 10:49:58 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r559:ae0b6ba4b07b
Date: 2012-06-29 09:10 +0200
http://bitbucket.org/cffi/cffi/changeset/ae0b6ba4b07b/
Log: hg backout 0ed9b03dd40d, f0cdef5768b5, 95c88bfbf9f7.
Will redo struct-returning functions slightly differently.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -22,11 +22,6 @@
# define USE__THREAD
#endif
-/* Define CAN_RETURN_STRUCTS if the C compiler supports returning structs */
-#if !defined(MS_WIN32)
-# define CAN_RETURN_STRUCTS
-#endif
-
/************************************************************/
/* base type flag: exactly one of the following: */
@@ -1425,9 +1420,6 @@
return PyObject_GenericSetAttr((PyObject *)cd, attr, value);
}
-static PyObject *
-convert_struct_to_owning_object(char *data, CTypeDescrObject *ct); /*forward*/
-
static cif_description_t *
fb_prepare_cif(PyObject *fargs, CTypeDescrObject *fresult); /* forward */
@@ -1550,9 +1542,6 @@
res = Py_None;
Py_INCREF(res);
}
- else if (fresult->ct_flags & CT_STRUCT) {
- res = convert_struct_to_owning_object(resultdata, fresult);
- }
else {
res = convert_to_object(resultdata, fresult);
}
@@ -1760,46 +1749,10 @@
/************************************************************/
-static CDataObject *allocate_owning_object(Py_ssize_t dataoffset,
- Py_ssize_t datasize,
- CTypeDescrObject *ct)
-{
- CDataObject_own_base *cdb;
- cdb = (CDataObject_own_base *)PyObject_Malloc(dataoffset + datasize);
- if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
- return NULL;
-
- Py_INCREF(ct);
- cdb->head.c_type = ct;
- cdb->head.c_data = ((char *)cdb) + dataoffset;
- cdb->weakreflist = NULL;
- return &cdb->head;
-}
-
-static PyObject *
-convert_struct_to_owning_object(char *data, CTypeDescrObject *ct)
-{
- CDataObject *cd;
- Py_ssize_t dataoffset = offsetof(CDataObject_own_nolength, alignment);
- Py_ssize_t datasize = ct->ct_size;
-
- if ((ct->ct_flags & (CT_STRUCT|CT_IS_OPAQUE)) != CT_STRUCT) {
- PyErr_SetString(PyExc_TypeError,
- "return type is not a struct or is opaque");
- return NULL;
- }
- cd = allocate_owning_object(dataoffset, datasize, ct);
- if (cd == NULL)
- return NULL;
-
- memcpy(cd->c_data, data, datasize);
- return (PyObject *)cd;
-}
-
static PyObject *b_newp(PyObject *self, PyObject *args)
{
CTypeDescrObject *ct, *ctitem;
- CDataObject *cd;
+ CDataObject_own_base *cdb;
PyObject *init = Py_None;
Py_ssize_t dataoffset, datasize, explicitlength;
if (!PyArg_ParseTuple(args, "O!|O:newp", &CTypeDescr_Type, &ct, &init))
@@ -1856,21 +1809,26 @@
return NULL;
}
- cd = allocate_owning_object(dataoffset, datasize, ct);
- if (cd == NULL)
+ cdb = (CDataObject_own_base *)PyObject_Malloc(dataoffset + datasize);
+ if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
return NULL;
+
+ Py_INCREF(ct);
+ cdb->head.c_type = ct;
+ cdb->head.c_data = ((char *)cdb) + dataoffset;
+ cdb->weakreflist = NULL;
if (explicitlength >= 0)
- ((CDataObject_own_length*)cd)->length = explicitlength;
-
- memset(cd->c_data, 0, datasize);
+ ((CDataObject_own_length*)cdb)->length = explicitlength;
+
+ memset(cdb->head.c_data, 0, datasize);
if (init != Py_None) {
- if (convert_from_object(cd->c_data,
+ if (convert_from_object(cdb->head.c_data,
(ct->ct_flags & CT_POINTER) ? ct->ct_itemdescr : ct, init) < 0) {
- Py_DECREF(cd);
+ Py_DECREF(cdb);
return NULL;
}
}
- return (PyObject *)cd;
+ return (PyObject *)cdb;
}
static CDataObject *_new_casted_primitive(CTypeDescrObject *ct)
@@ -2785,14 +2743,11 @@
if (PyErr_Occurred())
return -1;
if (cif_descr != NULL) {
-#ifndef CAN_RETURN_STRUCTS
if (fb->rtype->type == FFI_TYPE_STRUCT) {
PyErr_SetString(PyExc_NotImplementedError,
- "functions returning structs are not supported "
- "on this platform");
+ "functions returning structs are not supported");
return -1;
}
-#endif
/* exchange data size */
/* first, enough room for an array of 'nargs' pointers */
exchange_offset = nargs * sizeof(void*);
@@ -2990,9 +2945,9 @@
&ellipsis))
return NULL;
- if (fresult->ct_flags & CT_UNION) {
+ if (fresult->ct_flags & (CT_STRUCT|CT_UNION)) {
PyErr_SetString(PyExc_NotImplementedError,
- "functions returning a union");
+ "functions returning a struct or a union");
return NULL;
}
if ((fresult->ct_size < 0 && !(fresult->ct_flags & CT_VOID)) ||
@@ -3465,16 +3420,6 @@
return total;
}
-#ifdef CAN_RETURN_STRUCTS
-static struct _testfunc7_s _testfunc10(int n)
-{
- struct _testfunc7_s result;
- result.a1 = n;
- result.a2 = n * n;
- return result;
-}
-#endif
-
static PyObject *b__testfunc(PyObject *self, PyObject *args)
{
/* for testing only */
@@ -3493,9 +3438,6 @@
case 7: f = &_testfunc7; break;
case 8: f = stderr; break;
case 9: f = &_testfunc9; break;
-#ifdef CAN_RETURN_STRUCTS
- case 10: f = &_testfunc10; break;
-#endif
default:
PyErr_SetNone(PyExc_ValueError);
return NULL;
@@ -3648,7 +3590,6 @@
_cffi_from_c_char,
convert_to_object,
convert_from_object,
- convert_struct_to_owning_object,
};
/************************************************************/
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1140,32 +1140,18 @@
p.a1 = ['x', 'y']
assert str(p.a1) == 'xyo'
-def test_invalid_function_result_types():
+def test_no_struct_return_in_func():
BFunc = new_function_type((), new_void_type())
BArray = new_array_type(new_pointer_type(BFunc), 5) # works
new_function_type((), BFunc) # works
new_function_type((), new_primitive_type("int"))
new_function_type((), new_pointer_type(BFunc))
- py.test.raises(NotImplementedError, new_function_type,
- (), new_union_type("foo_u"))
+ py.test.raises(NotImplementedError, new_function_type, (),
+ new_struct_type("foo_s"))
+ py.test.raises(NotImplementedError, new_function_type, (),
+ new_union_type("foo_u"))
py.test.raises(TypeError, new_function_type, (), BArray)
-def test_struct_return_in_func():
- if sys.platform == 'win32':
- py.test.skip("function returning struct")
- BChar = new_primitive_type("char")
- BShort = new_primitive_type("short")
- BInt = new_primitive_type("int")
- BStruct = new_struct_type("foo_s")
- complete_struct_or_union(BStruct, [('a1', BChar, -1),
- ('a2', BShort, -1)])
- BFunc10 = new_function_type((BInt,), BStruct)
- f = cast(BFunc10, _testfunc(10))
- s = f(40)
- assert repr(s) == "<cdata 'struct foo_s' owning 4 bytes>"
- assert s.a1 == chr(40)
- assert s.a2 == 40 * 40
-
def test_cast_with_functionptr():
BFunc = new_function_type((), new_void_type())
BFunc2 = new_function_type((), new_primitive_type("short"))
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -184,9 +184,6 @@
elif isinstance(tp, model.ArrayType):
return '_cffi_from_c_deref((char *)%s, _cffi_type(%d))' % (
var, self.gettypenum(tp))
- elif isinstance(tp, model.StructType):
- return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % (
- var, self.gettypenum(tp))
else:
raise NotImplementedError(tp)
@@ -617,9 +614,7 @@
((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16])
#define _cffi_to_c \
((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[17])
-#define _cffi_from_c_struct \
- ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[18])
-#define _CFFI_NUM_EXPORTS 19
+#define _CFFI_NUM_EXPORTS 18
#if SIZEOF_LONG < SIZEOF_LONG_LONG
# define _cffi_to_c_long_long PyLong_AsLongLong
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -576,27 +576,3 @@
""")
msg = 'cannot pass as a argument a struct that was completed with verify()'
assert msg in str(e.value)
-
-def test_func_returns_struct():
- # only supported via verify(), when GCC is the compiler; and only for
- # regular functions.
- ffi = FFI()
- ffi.cdef("""
- struct foo_s { int aa, bb; };
- struct foo_s foo(int a, int b);
- """)
- lib = ffi.verify("""
- struct foo_s { int aa, bb; };
- struct foo_s foo(int a, int b) {
- struct foo_s r;
- r.aa = a*a;
- r.bb = b*b;
- return r;
- }
- """)
- s = lib.foo(6, 7)
- # It's the only way to have a 'struct foo_s' that owns its memory.
- # With ffi.new() we always get a 'struct foo_s *' that owns the memory.
- assert repr(s) == "<cdata 'struct foo_s' owning 8 bytes>"
- assert s.aa == 36
- assert s.bb == 49
More information about the pypy-commit
mailing list