Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r1705:e725f4ea7673
Date: 2015-04-14 18:19 +0200
http://bitbucket.org/cffi/cffi/changeset/e725f4ea7673/

Log:    in-progress: decoding function types while only having a
        CT_FUNCTIONPTR...

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1902,7 +1902,7 @@
     return cd->c_data + i * cd->c_type->ct_itemdescr->ct_size;
 }
 
-static CTypeDescrObject *
+static PyObject *
 new_array_type(CTypeDescrObject *ctptr, Py_ssize_t length);   /* forward */
 
 static CTypeDescrObject *
@@ -1968,7 +1968,7 @@
         return NULL;
 
     if (ct->ct_stuff == NULL) {
-        ct->ct_stuff = (PyObject *)new_array_type(ct, -1);
+        ct->ct_stuff = new_array_type(ct, -1);
         if (ct->ct_stuff == NULL)
             return NULL;
     }
@@ -2269,18 +2269,13 @@
 static cif_description_t *
 fb_prepare_cif(PyObject *fargs, CTypeDescrObject *, ffi_abi);      /*forward*/
 
-static PyObject *
-b_new_primitive_type(PyObject *self, PyObject *args);              /*forward*/
+static PyObject *new_primitive_type(const char *name);             /*forward*/
 
 static CTypeDescrObject *_get_ct_int(void)
 {
     static CTypeDescrObject *ct_int = NULL;
     if (ct_int == NULL) {
-        PyObject *args = Py_BuildValue("(s)", "int");
-        if (args == NULL)
-            return NULL;
-        ct_int = (CTypeDescrObject *)b_new_primitive_type(NULL, args);
-        Py_DECREF(args);
+        ct_int = (CTypeDescrObject *)new_primitive_type("int");
     }
     return ct_int;
 }
@@ -3338,7 +3333,7 @@
 
 /************************************************************/
 
-static CTypeDescrObject *new_primitive_type(const char *name)
+static PyObject *new_primitive_type(const char *name)
 {
 #define ENUM_PRIMITIVE_TYPES                                    \
        EPTYPE(c, char, CT_PRIMITIVE_CHAR)                       \
@@ -3483,7 +3478,7 @@
             td->ct_flags |= CT_PRIMITIVE_FITS_LONG;
     }
     td->ct_name_position = strlen(td->ct_name);
-    return td;
+    return (PyObject *)td;
 
  bad_ffi_type:
     PyErr_Format(PyExc_NotImplementedError,
@@ -3498,10 +3493,10 @@
     char *name;
     if (!PyArg_ParseTuple(args, "s:new_primitive_type", &name))
         return NULL;
-    return (PyObject *)new_primitive_type(name);
-}
-
-static CTypeDescrObject *new_pointer_type(CTypeDescrObject *ctitem)
+    return new_primitive_type(name);
+}
+
+static PyObject *new_pointer_type(CTypeDescrObject *ctitem)
 {
     CTypeDescrObject *td;
     const char *extra;
@@ -3525,7 +3520,7 @@
         ((ctitem->ct_flags & CT_PRIMITIVE_CHAR) &&
          ctitem->ct_size == sizeof(char)))
         td->ct_flags |= CT_CAST_ANYTHING;   /* 'void *' or 'char *' only */
-    return td;
+    return (PyObject *)td;
 }
 
 static PyObject *b_new_pointer_type(PyObject *self, PyObject *args)
@@ -3534,7 +3529,7 @@
     if (!PyArg_ParseTuple(args, "O!:new_pointer_type",
                           &CTypeDescr_Type, &ctitem))
         return NULL;
-    return (PyObject *)new_pointer_type(ctitem);
+    return new_pointer_type(ctitem);
 }
 
 static PyObject *b_new_array_type(PyObject *self, PyObject *args)
@@ -3558,10 +3553,10 @@
             return NULL;
         }
     }
-    return (PyObject *)new_array_type(ctptr, length);
-}
-
-static CTypeDescrObject *
+    return new_array_type(ctptr, length);
+}
+
+static PyObject *
 new_array_type(CTypeDescrObject *ctptr, Py_ssize_t length)
 {
     CTypeDescrObject *td, *ctitem;
@@ -3606,10 +3601,10 @@
     td->ct_size = arraysize;
     td->ct_length = length;
     td->ct_flags = flags;
-    return td;
-}
-
-static CTypeDescrObject *new_void_type(void)
+    return (PyObject *)td;
+}
+
+static PyObject *new_void_type(void)
 {
     int name_size = strlen("void") + 1;
     CTypeDescrObject *td = ctypedescr_new(name_size);
@@ -3620,12 +3615,12 @@
     td->ct_size = -1;
     td->ct_flags = CT_VOID | CT_IS_OPAQUE;
     td->ct_name_position = strlen("void");
-    return td;
+    return (PyObject *)td;
 }
 
 static PyObject *b_new_void_type(PyObject *self, PyObject *args)
 {
-    return (PyObject *)new_void_type();
+    return new_void_type();
 }
 
 static PyObject *_b_struct_or_union_type(const char *name, int flag)
@@ -4389,22 +4384,15 @@
     return NULL;
 }
 
-static PyObject *b_new_function_type(PyObject *self, PyObject *args)
-{
-    PyObject *fargs, *fabiobj;
-    CTypeDescrObject *fresult;
+static PyObject *new_function_type(PyObject *fargs,   /* tuple */
+                                   CTypeDescrObject *fresult,
+                                   int ellipsis, int fabi)
+{
+    PyObject *fabiobj;
     CTypeDescrObject *fct;
-    int ellipsis = 0, fabi = FFI_DEFAULT_ABI;
     struct funcbuilder_s funcbuilder;
     Py_ssize_t i;
 
-    if (!PyArg_ParseTuple(args, "O!O!|ii:new_function_type",
-                          &PyTuple_Type, &fargs,
-                          &CTypeDescr_Type, &fresult,
-                          &ellipsis,
-                          &fabi))
-        return NULL;
-
     if ((fresult->ct_size < 0 && !(fresult->ct_flags & CT_VOID)) ||
         (fresult->ct_flags & CT_ARRAY)) {
         char *msg;
@@ -4468,6 +4456,22 @@
     return NULL;
 }
 
+static PyObject *b_new_function_type(PyObject *self, PyObject *args)
+{
+    PyObject *fargs;
+    CTypeDescrObject *fresult;
+    int ellipsis = 0, fabi = FFI_DEFAULT_ABI;
+
+    if (!PyArg_ParseTuple(args, "O!O!|ii:new_function_type",
+                          &PyTuple_Type, &fargs,
+                          &CTypeDescr_Type, &fresult,
+                          &ellipsis,
+                          &fabi))
+        return NULL;
+
+    return new_function_type(fargs, fresult, ellipsis, fabi);
+}
+
 static int convert_from_object_fficallback(char *result,
                                            CTypeDescrObject *ctype,
                                            PyObject *pyobj)
diff --git a/new/ffi_obj.c b/new/ffi_obj.c
--- a/new/ffi_obj.c
+++ b/new/ffi_obj.c
@@ -101,19 +101,23 @@
                          input_text, spaces);
             return NULL;
         }
-        CTypeDescrObject *ct = realize_c_type(ffi->info.ctx,
-                                              ffi->info.output, index);
+        PyObject *ct = realize_c_type(ffi->info.ctx,
+                                      ffi->info.output, index);
         if (ct == NULL)
             return NULL;
-        x = PyDict_GetItemString(ffi->types_dict, ct->ct_name);
-        if (x != NULL) {
+
+        char *normalized_text = ((CTypeDescrObject *)ct)->ct_name;
+        x = PyDict_GetItemString(ffi->types_dict, normalized_text);
+        if (x == NULL) {
+            PyDict_SetItemString(ffi->types_dict, normalized_text, ct);
+        }
+        else {
             Py_INCREF(x);
             Py_DECREF(ct);
-            ct = (CTypeDescrObject *)x;
+            ct = x;
         }
-        PyDict_SetItemString(ffi->types_dict, ct->ct_name, (PyObject *)ct);
-        PyDict_SetItem(ffi->types_dict, arg, (PyObject *)ct);
-        return ct;
+        PyDict_SetItem(ffi->types_dict, arg, ct);
+        return (CTypeDescrObject *)ct;
     }
     else if ((accept & ACCEPT_CTYPE) && CTypeDescr_Check(arg)) {
         return (CTypeDescrObject *)arg;
diff --git a/new/lib_obj.c b/new/lib_obj.c
--- a/new/lib_obj.c
+++ b/new/lib_obj.c
@@ -66,7 +66,7 @@
 
     xfunc->md.ml_meth = (PyCFunction)g->address;
     xfunc->md.ml_flags = flags;
-    xfunc->md.ml_name = strdup(s);
+    xfunc->md.ml_name = g->name;
     /*xfunc->md.ml_doc = ... */
     if (xfunc->md.ml_name == NULL)
         goto no_memory;
diff --git a/new/realize_c_type.c b/new/realize_c_type.c
--- a/new/realize_c_type.c
+++ b/new/realize_c_type.c
@@ -1,10 +1,10 @@
 
-static CTypeDescrObject *all_primitives[_CFFI__NUM_PRIM];
+static PyObject *all_primitives[_CFFI__NUM_PRIM];
 
 
-CTypeDescrObject *build_primitive_type(int num)
+PyObject *build_primitive_type(int num)
 {
-    CTypeDescrObject *x;
+    PyObject *x;
 
     switch (num) {
 
@@ -30,22 +30,39 @@
 }
 
 
+static PyObject *
+_realize_c_type(const struct _cffi_type_context_s *ctx,
+                _cffi_opcode_t opcodes[], int index);  /* forward */
+
+
 /* Interpret an opcodes[] array.  If opcodes == ctx->types, store all
    the intermediate types back in the opcodes[].  Returns a new
    reference.
 */
-CTypeDescrObject *realize_c_type(const struct _cffi_type_context_s *ctx,
-                                 _cffi_opcode_t opcodes[], int index)
+static PyObject *
+realize_c_type(const struct _cffi_type_context_s *ctx,
+               _cffi_opcode_t opcodes[], int index)
 {
-    CTypeDescrObject *ct;
-    CTypeDescrObject *x, *y, *z;
+    PyObject *x = _realize_c_type(ctx, opcodes, index);
+    if (x != NULL && !CTypeDescr_Check(x)) {
+        PyErr_SetString(PyExc_NotImplementedError, "unexpected type");
+        x = NULL;
+    }
+    return x;
+}
+
+static PyObject *
+_realize_c_type(const struct _cffi_type_context_s *ctx,
+                _cffi_opcode_t opcodes[], int index)
+{
+    PyObject *x, *y, *z;
     _cffi_opcode_t op = opcodes[index];
     Py_ssize_t length = -1;
 
     if ((((uintptr_t)op) & 1) == 0) {
-        ct = (CTypeDescrObject *)op;
-        Py_INCREF(ct);
-        return ct;
+        x = (PyObject *)op;
+        Py_INCREF(x);
+        return x;
     }
 
     switch (_CFFI_GETOP(op)) {
@@ -58,10 +75,17 @@
         break;
 
     case _CFFI_OP_POINTER:
-        y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+        y = _realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
         if (y == NULL)
             return NULL;
-        x = new_pointer_type(y);
+        if (CTypeDescr_Check(y)) {
+            x = new_pointer_type((CTypeDescrObject *)y);
+        }
+        else {
+            assert(PyTuple_Check(y));   /* from _CFFI_OP_FUNCTION */
+            x = PyTuple_GET_ITEM(y, 0);
+            Py_INCREF(x);
+        }
         Py_DECREF(y);
         break;
 
@@ -72,16 +96,36 @@
         y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
         if (y == NULL)
             return NULL;
-        z = new_pointer_type(y);
+        z = new_pointer_type((CTypeDescrObject *)y);
         Py_DECREF(y);
         if (z == NULL)
             return NULL;
-        x = new_array_type(z, length);
+        x = new_array_type((CTypeDescrObject *)z, length);
         Py_DECREF(z);
         break;
 
+    case _CFFI_OP_FUNCTION:
+    {
+        PyObject *fargs;
+
+        y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+        if (y == NULL)
+            return NULL;
+        fargs = PyTuple_New(0);  // XXX NULL
+        z = new_function_type(fargs, (CTypeDescrObject *)y, 0, 
FFI_DEFAULT_ABI);
+        Py_DECREF(fargs);
+        Py_DECREF(y);
+        if (z == NULL)
+            return NULL;
+
+        x = PyTuple_Pack(1, z);   /* hack: hide the CT_FUNCTIONPTR.  it will
+                                     be revealed again by the OP_POINTER */
+        Py_DECREF(z);
+        break;
+    }
+
     case _CFFI_OP_NOOP:
-        x = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+        x = _realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
         break;
 
     default:
diff --git a/new/test_realize_c_type.py b/new/test_realize_c_type.py
--- a/new/test_realize_c_type.py
+++ b/new/test_realize_c_type.py
@@ -23,3 +23,6 @@
 
 def test_array():
     check("int[5]")
+
+def test_funcptr():
+    check("int(*)(long)")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to