[pypy-commit] creflect default: pointer types
arigo
noreply at buildbot.pypy.org
Wed Dec 3 15:19:52 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r140:dc4373af8fab
Date: 2014-12-03 15:20 +0100
http://bitbucket.org/cffi/creflect/changeset/dc4373af8fab/
Log: pointer types
diff --git a/zeffir/builder.c b/zeffir/builder.c
--- a/zeffir/builder.c
+++ b/zeffir/builder.c
@@ -10,30 +10,63 @@
PyObject *types_dict;
} zeffir_builder_t;
-static CTypeDescrObject *get_cached_type(_crx_builder_t *cb, const char *name,
- int accept_flags)
+static PyObject *combine_type_name(_crx_builder_t *cb, CTypeDescrObject *ct,
+ const char *extra_text)
+{
+ /* Build a PyString with the name given by combining 'ct' and 'extra_text'.
+ 'ct' can be NULL. If an error occurs (or has already occurred),
+ returns NULL. */
+ size_t base_name_len, extra_name_len;
+ PyObject *result;
+ char *p;
+
+ if (PyErr_Occurred())
+ return NULL;
+
+ base_name_len = (ct != NULL ? strlen(ct->ct_name) : 0);
+ extra_name_len = strlen(extra_text);
+ result = PyString_FromStringAndSize(NULL, base_name_len + extra_name_len);
+ if (result == NULL)
+ return NULL;
+
+ p = PyString_AS_STRING(result);
+ if (ct != NULL) {
+ memcpy(p, ct->ct_name, ct->ct_name_position);
+ p += ct->ct_name_position;
+ }
+ memcpy(p, extra_text, extra_name_len);
+ if (ct != NULL) {
+ p += extra_name_len;
+ memcpy(p, ct->ct_name + ct->ct_name_position,
+ base_name_len - ct->ct_name_position);
+ }
+ return result;
+}
+
+static CTypeDescrObject *get_cached_type(_crx_builder_t *cb, 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);
+ x = PyDict_GetItem(types_dict, name_obj);
+ if (x == NULL || !CTypeDescr_Check(x))
+ return NULL;
+ else
+ return (CTypeDescrObject *)x;
+}
+
+static void put_cached_type(_crx_builder_t *cb, PyObject *name_obj,
+ CTypeDescrObject *ct)
{
PyObject *types_dict = ((zeffir_builder_t *)cb)->types_dict;
- PyObject *x = PyDict_GetItemString(types_dict, name);
- CTypeDescrObject *ct;
-
- if (x == NULL || !CTypeDescr_Check(x))
- return NULL;
- ct = (CTypeDescrObject *)x;
- if ((ct->ct_flags & accept_flags) == 0)
- return NULL;
- return ct;
-}
-
-static _crx_type_t *put_cached_type(_crx_builder_t *cb, const char *name,
- CTypeDescrObject *ct)
-{
- PyObject *types_dict = ((zeffir_builder_t *)cb)->types_dict;
- int err = PyDict_SetItemString(types_dict, name, (PyObject *)ct);
- Py_DECREF(ct);
- if (err < 0)
- return NULL;
- return ct; /* still a reference in the dict */
+ PyDict_SetItem(types_dict, name_obj, (PyObject *)ct);
+ Py_DECREF(ct); /* still a reference in the dict,
+ unless PyDict_SetItem failed */
}
static _crx_type_t *zef_get_void_type(_crx_builder_t *cb)
@@ -54,26 +87,33 @@
static _crx_type_t *zef_get_signed_type(_crx_builder_t *cb, size_t sz,
const char *name)
{
- CTypeDescrObject *td = get_cached_type(cb, name, CT_PRIMITIVE_SIGNED);
- if (td != NULL && td->ct_size == sz)
- return td;
+ PyObject *name_obj;
+ CTypeDescrObject *ct;
- size_t name_length = strlen(name);
-
- td = ctypedescr_new(name_length + 1);
- if (td == NULL)
+ name_obj = combine_type_name(cb, NULL, name);
+ if (name_obj == NULL)
return NULL;
- memcpy(td->ct_name, name, name_length + 1);
- td->ct_name_position = name_length;
- td->ct_size = sz;
- //td->ct_length = ptypes->align;
- //td->ct_extra = ffitype;
- td->ct_flags = CT_PRIMITIVE_SIGNED;
- if (td->ct_size <= sizeof(long))
- td->ct_flags |= CT_PRIMITIVE_FITS_LONG;
+ ct = get_cached_type(cb, name_obj);
+ if (ct && (ct->ct_flags & CT_PRIMITIVE_SIGNED) && ct->ct_size == sz)
+ goto done;
- return put_cached_type(cb, name, td);
+ ct = ctypedescr_new(name_obj, PyString_GET_SIZE(name_obj));
+ if (ct == NULL)
+ goto done;
+
+ ct->ct_size = sz;
+ //ct->ct_length = ptypes->align;
+ //ct->ct_extra = ffitype;
+ ct->ct_flags = CT_PRIMITIVE_SIGNED;
+ if (ct->ct_size <= sizeof(long))
+ ct->ct_flags |= CT_PRIMITIVE_FITS_LONG;
+
+ put_cached_type(cb, name_obj, ct);
+
+ done:
+ Py_DECREF(name_obj);
+ return ct;
}
static _crx_type_t *zef_get_unsigned_type(_crx_builder_t *cb, size_t sz,
@@ -106,7 +146,41 @@
static _crx_type_t *zef_get_pointer_type(_crx_builder_t *cb,
_crx_type_t *totype, int toquals)
{
- abort();
+ const char *extra;
+ PyObject *name_obj;
+ CTypeDescrObject *ct;
+
+ if (totype->ct_flags & CT_ARRAY)
+ extra = "(*)";
+ else
+ extra = " *";
+
+ name_obj = combine_type_name(cb, totype, extra);
+ if (name_obj == NULL)
+ return NULL;
+
+ ct = get_cached_type(cb, name_obj);
+ if (ct && (ct->ct_flags & CT_POINTER))
+ goto done;
+
+ ct = ctypedescr_new(name_obj, totype->ct_name_position + 2);
+ if (ct == NULL)
+ goto done;
+
+ ct->ct_size = sizeof(void *);
+ ct->ct_flags = CT_POINTER;
+ if (totype->ct_flags & CT_VOID)
+ ct->ct_flags |= CT_IS_VOID_PTR;
+ if ((totype->ct_flags & CT_VOID) ||
+ ((totype->ct_flags & CT_PRIMITIVE_CHAR) &&
+ totype->ct_size == sizeof(char)))
+ ct->ct_flags |= CT_CAST_ANYTHING; /* 'void *' or 'char *' only */
+
+ put_cached_type(cb, name_obj, ct);
+
+ done:
+ Py_DECREF(name_obj);
+ return ct;
}
static _crx_type_t *zef_get_array_type(_crx_builder_t *cb, _crx_type_t *t,
diff --git a/zeffir/ctype.c b/zeffir/ctype.c
--- a/zeffir/ctype.c
+++ b/zeffir/ctype.c
@@ -45,7 +45,7 @@
Py_ssize_t ct_length; /* length of arrays, or -1 if unknown */
int ct_flags; /* CT_xxx flags */
- int ct_name_position; /* index in ct_name of where to put a var name */
+ size_t ct_name_position;/* index in ct_name of where to put a var name */
char ct_name[1]; /* string, e.g. "int *" for pointers to ints */
};
@@ -64,11 +64,12 @@
/************************************************************/
-static CTypeDescrObject *ctypedescr_new(size_t name_size)
+static CTypeDescrObject *ctypedescr_new(PyObject *name_obj,
+ size_t name_position)
{
CTypeDescrObject *ct = PyObject_GC_NewVar(CTypeDescrObject,
&CTypeDescr_Type,
- name_size);
+ PyString_GET_SIZE(name_obj) + 1);
if (ct == NULL)
return NULL;
@@ -77,6 +78,9 @@
ct->ct_weakreflist = NULL;
ct->ct_size = -1;
ct->ct_length = -1;
+ ct->ct_name_position = name_position;
+ memcpy(ct->ct_name, PyString_AS_STRING(name_obj),
+ PyString_GET_SIZE(name_obj) + 1);
PyObject_GC_Track(ct);
return ct;
}
diff --git a/zeffir/test/test_ctype.py b/zeffir/test/test_ctype.py
--- a/zeffir/test/test_ctype.py
+++ b/zeffir/test/test_ctype.py
@@ -1,8 +1,18 @@
import support
-def test_typeof():
+def test_typeof_primitive():
ffi = support.new_ffi()
- assert repr(ffi.typeof("int")) == "<ctype 'int'>"
- assert repr(ffi.typeof("long int")) == "<ctype 'long'>"
- #assert repr(ffi.typeof("int*")) == "<ctype 'int *'>"
+ ct_int = ffi.typeof("int")
+ assert repr(ct_int) == "<ctype 'int'>"
+ #
+ ct_long = ffi.typeof("long int")
+ assert repr(ct_long) == "<ctype 'long'>"
+ #
+ assert ffi.types == {'int': ct_int,
+ 'long': ct_long,
+ 'long int': ct_long}
+
+def test_typeof_pointer():
+ ffi = support.new_ffi()
+ assert repr(ffi.typeof("int*")) == "<ctype 'int *'>"
More information about the pypy-commit
mailing list