[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