[pypy-commit] creflect default: fix ffi.addressof(). Also allows ffi.new("struct_type") directly,
arigo
noreply at buildbot.pypy.org
Fri Dec 5 19:38:48 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r176:620bef5903b4
Date: 2014-12-05 19:39 +0100
http://bitbucket.org/cffi/creflect/changeset/620bef5903b4/
Log: fix ffi.addressof(). Also allows ffi.new("struct_type") directly,
as an extension that seems to make sense for now
diff --git a/zeffir/builder.c b/zeffir/builder.c
--- a/zeffir/builder.c
+++ b/zeffir/builder.c
@@ -45,13 +45,18 @@
return result;
}
-static CTypeDescrObject *get_cached_type(_crx_builder_t *cb, PyObject *name_obj)
+static PyObject *get_types_dict(_crx_builder_t *cb)
+{
+ return ((zeffir_builder_t *)cb)->types_dict;
+}
+
+static CTypeDescrObject *get_cached_type(PyObject *types_dict,
+ PyObject *name_obj)
{
/* Look up the type called 'name_obj' and check that it's a type with the
right flags. Returns either the type or NULL, without changing
the reference counts. Never raises an exception.
*/
- PyObject *types_dict = ((zeffir_builder_t *)cb)->types_dict;
PyObject *x;
assert(name_obj != NULL);
@@ -62,13 +67,13 @@
return (CTypeDescrObject *)x;
}
-static void put_cached_type(_crx_builder_t *cb, PyObject *name_obj,
+static int put_cached_type(PyObject *types_dict, PyObject *name_obj,
CTypeDescrObject *ct)
{
- PyObject *types_dict = ((zeffir_builder_t *)cb)->types_dict;
- PyDict_SetItem(types_dict, name_obj, (PyObject *)ct);
+ int err = PyDict_SetItem(types_dict, name_obj, (PyObject *)ct);
Py_DECREF(ct); /* still a reference in the dict,
unless PyDict_SetItem failed */
+ return err;
}
static _crx_type_t *_zef_primitive(_crx_builder_t *cb, Py_ssize_t size,
@@ -84,7 +89,7 @@
if (name_obj == NULL)
return NULL;
- ct = get_cached_type(cb, name_obj);
+ ct = get_cached_type(get_types_dict(cb), name_obj);
if (ct && (ct->ct_flags == flags) && (ct->ct_size == size))
goto done;
@@ -95,7 +100,8 @@
ct->ct_size = size;
ct->ct_flags = flags;
- put_cached_type(cb, name_obj, ct);
+ if (put_cached_type(get_types_dict(cb), name_obj, ct) < 0)
+ ct = NULL;
done:
Py_DECREF(name_obj);
@@ -207,7 +213,7 @@
== extra_len);
}
- ct = get_cached_type(cb, name_obj);
+ ct = get_cached_type(get_types_dict(cb), name_obj);
if (ct && (ct->ct_flags == CT_FUNCTION))
goto done;
@@ -219,7 +225,7 @@
ct->ct_flags = CT_FUNCTION;
/* XXX more... */
- put_cached_type(cb, name_obj, ct);
+ put_cached_type(get_types_dict(cb), name_obj, ct);
done:
Py_DECREF(name_obj);
@@ -241,12 +247,9 @@
return _zef_function(cb, ret, args, nargs, 1);
}
-static _crx_type_t *zef_get_pointer_type(_crx_builder_t *cb,
- _crx_type_t *totype, int toquals)
+static CTypeDescrObject *fetch_pointer_type(PyObject *types_dict,
+ CTypeDescrObject *totype)
{
- if (PyErr_Occurred())
- return NULL;
-
const char *extra;
PyObject *name_obj;
CTypeDescrObject *ct;
@@ -260,7 +263,7 @@
if (name_obj == NULL)
return NULL;
- ct = get_cached_type(cb, name_obj);
+ ct = get_cached_type(types_dict, name_obj);
if (ct && (ct->ct_flags & CT_POINTER))
goto done;
@@ -280,13 +283,22 @@
totype->ct_size == sizeof(char)))
ct->ct_flags |= CT_CAST_ANYTHING; /* 'void *' or 'char *' only */
- put_cached_type(cb, name_obj, ct);
+ put_cached_type(types_dict, name_obj, ct);
done:
Py_DECREF(name_obj);
return ct;
}
+static _crx_type_t *zef_get_pointer_type(_crx_builder_t *cb,
+ _crx_type_t *totype, int toquals)
+{
+ if (PyErr_Occurred())
+ return NULL;
+
+ return fetch_pointer_type(get_types_dict(cb), totype);
+}
+
static _crx_type_t *_zef_array_type(_crx_builder_t *cb, _crx_type_t *ctitem,
size_t len, CTypeDescrObject *ctptr)
{
@@ -318,7 +330,7 @@
return NULL;
if (cb != NULL) {
- ct = get_cached_type(cb, name_obj);
+ ct = get_cached_type(get_types_dict(cb), name_obj);
if (ct && (ct->ct_flags & CT_ARRAY))
goto done;
}
@@ -356,7 +368,7 @@
Py_INCREF(ct);
ctptr->ct_stuff = (PyObject *)ct;
}
- put_cached_type(cb, name_obj, ct);
+ put_cached_type(get_types_dict(cb), name_obj, ct);
}
else {
assert(length < 0);
@@ -400,7 +412,7 @@
if (name_obj == NULL)
return NULL;
- ct = get_cached_type(cb, name_obj);
+ ct = get_cached_type(get_types_dict(cb), name_obj);
if (ct && (ct->ct_flags == flag))
goto done;
@@ -442,7 +454,7 @@
if (name_obj == NULL)
return result;
- result.type = get_cached_type(cb, name_obj);
+ result.type = get_cached_type(get_types_dict(cb), name_obj);
if (result.type == NULL)
PyErr_Format(ZefError, "undefined type: '%s'", name);
return result;
diff --git a/zeffir/cdata.c b/zeffir/cdata.c
--- a/zeffir/cdata.c
+++ b/zeffir/cdata.c
@@ -1207,6 +1207,7 @@
if (ct == NULL)
return NULL;
+ assert(ct->ct_flags & CT_POINTER);
if (ct->ct_stuff == NULL) {
if (fill_array_type(ct) < 0)
return NULL;
diff --git a/zeffir/ffi_obj.c b/zeffir/ffi_obj.c
--- a/zeffir/ffi_obj.c
+++ b/zeffir/ffi_obj.c
@@ -191,9 +191,9 @@
return NULL;
explicitlength = -1;
- if (ct->ct_flags & CT_POINTER) {
+ if (ct->ct_flags & (CT_POINTER | CT_STRUCT | CT_UNION)) {
dataoffset = offsetof(CDataObject_own_nolength, alignment);
- ctitem = ct->ct_itemdescr;
+ ctitem = (ct->ct_flags & CT_POINTER) ? ct->ct_itemdescr : ct;
datasize = ctitem->ct_size;
if (datasize < 0) {
PyErr_Format(PyExc_TypeError,
@@ -395,7 +395,11 @@
if (cf == NULL)
return NULL;
offset = cf->cf_offset;
+ ct = cf->cf_type;
}
+ ct = fetch_pointer_type(self->types_dict, ct);
+ if (ct == NULL)
+ return NULL;
return new_simple_cdata(cd->c_data + offset, ct);
}
else if (ZefLib_Check(obj)) {
diff --git a/zeffir/test/struct.crx b/zeffir/test/struct.crx
--- a/zeffir/test/struct.crx
+++ b/zeffir/test/struct.crx
@@ -3,6 +3,11 @@
long b;
} mystruct_t;
+typedef struct {
+ int foo[5];
+ //int bar[];
+} myarrstr_t;
+
// CREFLECT: start
@@ -10,4 +15,9 @@
int a, b;
} mystruct_t;
+typedef struct {
+ int foo[5];
+ //int bar[];
+} myarrstr_t;
+
// CREFLECT: end
diff --git a/zeffir/test/test_struct.py b/zeffir/test/test_struct.py
--- a/zeffir/test/test_struct.py
+++ b/zeffir/test/test_struct.py
@@ -6,6 +6,7 @@
ffi, lib = support.compile_and_open('struct')
p = ffi.new('mystruct_t *', [-5, 0x600112233])
assert p.a == -5
+ assert p[0].a == -5
assert p.b == 0x600112233
p.b += 1
assert p.b == 0x600112234
@@ -19,10 +20,27 @@
ffi, lib = support.compile_and_open('struct')
p = ffi.new("mystruct_t *")
assert ffi.addressof(p[0]) == p
+ assert ffi.typeof(ffi.addressof(p[0])) == ffi.typeof("mystruct_t *")
assert ffi.addressof(p[0], None) == p
assert ffi.addressof(p[0], "a") == p
+ assert ffi.typeof(ffi.addressof(p[0], "a")) == ffi.typeof("int *")
assert ffi.addressof(p[0], "b") != p
assert ffi.addressof(p[0], "b") == ffi.addressof(p, "b")
+ assert ffi.typeof(ffi.addressof(p[0], "b")) == ffi.typeof("long *")
assert ffi.addressof(p, "a") == p
py.test.raises(TypeError, ffi.addressof, p)
py.test.raises(TypeError, ffi.addressof, p, None)
+ #
+ p = ffi.new("myarrstr_t *")
+ assert ffi.typeof(ffi.addressof(p, "foo")) == ffi.typeof("int(*)[5]")
+ assert ffi.typeof(p.foo) == ffi.typeof("int[5]")
+ #assert ffi.typeof(ffi.addressof(p, "bar")) == ffi.typeof("int(*)[]")
+
+def test_new_nonptr_struct():
+ ffi, lib = support.compile_and_open('struct')
+ s = ffi.new("mystruct_t", [-5, 0x600112233])
+ assert s.a == -5
+ assert s.b == 0x600112233
+ s.b += 1
+ assert s.b == 0x600112234
+ assert ffi.addressof(s)[0] == s
diff --git a/zeffir/zeffir.h b/zeffir/zeffir.h
--- a/zeffir/zeffir.h
+++ b/zeffir/zeffir.h
@@ -21,3 +21,5 @@
static int convert_from_object_bitfield(char *, CFieldObject *, PyObject *);
static int fill_array_type(CTypeDescrObject *ctptr);
+static CTypeDescrObject *fetch_pointer_type(PyObject *types_dict,
+ CTypeDescrObject *totype);
More information about the pypy-commit
mailing list