[pypy-commit] creflect default: function types
arigo
noreply at buildbot.pypy.org
Thu Dec 4 22:45:28 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r153:bfdb3cb4b9b4
Date: 2014-12-04 22:45 +0100
http://bitbucket.org/cffi/creflect/changeset/bfdb3cb4b9b4/
Log: function types
diff --git a/zeffir/builder.c b/zeffir/builder.c
--- a/zeffir/builder.c
+++ b/zeffir/builder.c
@@ -10,32 +10,38 @@
PyObject *types_dict;
} zeffir_builder_t;
-static PyObject *combine_type_name(_crx_builder_t *cb, CTypeDescrObject *ct,
- const char *extra_text)
+static PyObject *combine_type_name_l(CTypeDescrObject *ct,
+ size_t extra_text_len)
{
- /* 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;
+ size_t base_name_len;
PyObject *result;
char *p;
- 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);
+ base_name_len = strlen(ct->ct_name);
+ result = PyString_FromStringAndSize(NULL, base_name_len + extra_text_len);
if (result == NULL)
return NULL;
p = PyString_AS_STRING(result);
- if (ct != NULL) {
- memcpy(p, ct->ct_name, ct->ct_name_position);
+ memcpy(p, ct->ct_name, ct->ct_name_position);
+ p += ct->ct_name_position;
+ p += extra_text_len;
+ memcpy(p, ct->ct_name + ct->ct_name_position,
+ base_name_len - ct->ct_name_position);
+ return result;
+}
+
+static PyObject *combine_type_name(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 returns NULL. */
+ size_t extra_text_len = strlen(extra_text);
+ PyObject *result = combine_type_name_l(ct, extra_text_len);
+
+ if (result != NULL) {
+ char *p = PyString_AS_STRING(result);
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);
+ memcpy(p, extra_text, extra_text_len);
}
return result;
}
@@ -75,7 +81,7 @@
PyObject *name_obj;
CTypeDescrObject *ct;
- name_obj = combine_type_name(cb, NULL, name);
+ name_obj = PyString_FromString(name);
if (name_obj == NULL)
return NULL;
@@ -151,7 +157,63 @@
_crx_qual_type args[], int nargs,
_crx_trampoline1_fn trampl)
{
- abort();
+ if (PyErr_Occurred())
+ return NULL;
+
+ PyObject *name_obj;
+ CTypeDescrObject *ct;
+ size_t extra_len;
+
+ if (nargs == 0) {
+ name_obj = combine_type_name(ret, "(void)");
+ if (name_obj == NULL)
+ return NULL;
+ }
+ else {
+ char *p;
+ int i;
+ extra_len = 1 + 1; /* "(" ")" */
+ extra_len += (nargs - 1) * 2; /* ", " */
+ for (i = 0; i < nargs; i++) {
+ extra_len += strlen(args[i].type->ct_name);
+ }
+ name_obj = combine_type_name_l(ret, extra_len);
+ if (name_obj == NULL)
+ return NULL;
+ p = PyString_AS_STRING(name_obj);
+ p += ret->ct_name_position;
+ *p++ = '(';
+ for (i = 0; i < nargs; i++) {
+ size_t len = strlen(args[i].type->ct_name);
+ if (i > 0) {
+ *p++ = ',';
+ *p++ = ' ';
+ }
+ memcpy(p, args[i].type->ct_name, len);
+ p += len;
+ }
+ *p++ = ')';
+ assert(p - PyString_AS_STRING(name_obj) - ret->ct_name_position
+ == extra_len);
+ }
+
+ ct = get_cached_type(cb, name_obj);
+ if (ct && (ct->ct_flags == CT_FUNCTION))
+ goto done;
+
+ ct = ctypedescr_new(name_obj, ret->ct_name_position);
+ if (ct == NULL)
+ goto done;
+
+ ct->ct_size = -1;
+ ct->ct_flags = CT_FUNCTION;
+ /* XXX more... */
+
+ put_cached_type(cb, name_obj, ct);
+
+ done:
+ Py_DECREF(name_obj);
+ return ct;
}
static _crx_type_t *zef_get_ellipsis_function_type(_crx_builder_t *cb,
@@ -172,12 +234,12 @@
PyObject *name_obj;
CTypeDescrObject *ct;
- if (totype->ct_flags & CT_ARRAY)
+ if (totype->ct_flags & (CT_ARRAY | CT_FUNCTION))
extra = "(*)";
else
extra = " *";
- name_obj = combine_type_name(cb, totype, extra);
+ name_obj = combine_type_name(totype, extra);
if (name_obj == NULL)
return NULL;
@@ -228,7 +290,7 @@
else
sprintf(extra_text, "[%zd]", length);
- name_obj = combine_type_name(cb, ctitem, extra_text);
+ name_obj = combine_type_name(ctitem, extra_text);
if (name_obj == NULL)
return NULL;
@@ -292,7 +354,7 @@
if (PyErr_Occurred())
return result;
- name_obj = combine_type_name(cb, NULL, name);
+ name_obj = PyString_FromString(name);
if (name_obj == NULL)
return result;
diff --git a/zeffir/ctype.c b/zeffir/ctype.c
--- a/zeffir/ctype.c
+++ b/zeffir/ctype.c
@@ -10,11 +10,11 @@
#define CT_UNION 128 /* union */
#define CT_UNKNOWN 256 /* unknown type */
#define CT_VOID 512 /* void */
+#define CT_FUNCTION 1024 /* function */
/* other flags that may also be set in addition to the base flag: */
-#define CT_CAST_ANYTHING 1024 /* 'char *' and 'void *' only */
-#define CT_PRIMITIVE_FITS_LONG 2048
-//#define CT_IS_OPAQUE 4096 /* == (ct_size < 0) */
+#define CT_CAST_ANYTHING 2048 /* 'char *' and 'void *' only */
+#define CT_PRIMITIVE_FITS_LONG 4096
#define CT_IS_ENUM 8192
#define CT_IS_PTR_TO_OWNED 16384
#define CT_IS_LONGDOUBLE 65536
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
@@ -67,6 +67,13 @@
assert repr(ffi.typeof("int * [ ]")) == "<ctype 'int *[]'>"
assert repr(ffi.typeof("int ( * ) [ ]")) == "<ctype 'int(*)[]'>"
+def test_typeof_function():
+ ffi = support.new_ffi()
+ assert repr(ffi.typeof("int()")) == "<ctype 'int(void)'>"
+ assert repr(ffi.typeof("int*(void*)")) == "<ctype 'int *(void *)'>"
+ assert repr(ffi.typeof("int(long a,short b)"))=="<ctype 'int(long, short)'>"
+ assert repr(ffi.typeof("int(*)(long)"))=="<ctype 'int(*)(long)'>"
+
def test_simple_typedef():
ffi, lib = support.compile_and_open('ctype')
assert ffi.sizeof("foo_t") == ffi.sizeof("long long")
More information about the pypy-commit
mailing list