[pypy-commit] cffi cffi-1.0: Take cglob.c from zeffir, and fix a few bugs

arigo noreply at buildbot.pypy.org
Thu Apr 16 09:36:47 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1723:e3ed1d0463a1
Date: 2015-04-16 09:37 +0200
http://bitbucket.org/cffi/cffi/changeset/e3ed1d0463a1/

Log:	Take cglob.c from zeffir, and fix a few bugs

diff --git a/new/cffi1_module.c b/new/cffi1_module.c
--- a/new/cffi1_module.c
+++ b/new/cffi1_module.c
@@ -10,6 +10,7 @@
 static PyTypeObject Lib_Type;   /* forward */
 
 #include "ffi_obj.c"
+#include "cglob.c"
 #include "lib_obj.c"
 
 
diff --git a/new/cglob.c b/new/cglob.c
new file mode 100644
--- /dev/null
+++ b/new/cglob.c
@@ -0,0 +1,68 @@
+
+typedef struct {
+    PyObject_HEAD
+
+    CTypeDescrObject *gs_type;
+    char             *gs_data;
+
+} GlobSupportObject;
+
+static void glob_support_dealloc(GlobSupportObject *gs)
+{
+    Py_DECREF(gs->gs_type);
+    PyObject_Del(gs);
+}
+
+static PyTypeObject GlobSupport_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "cffi.GlobSupport",
+    sizeof(GlobSupportObject),
+    0,
+    (destructor)glob_support_dealloc,           /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    0,                                          /* tp_repr */
+    0,                                          /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
+};
+
+#define GlobSupport_Check(ob)  (Py_TYPE(ob) == &GlobSupport_Type)
+
+static PyObject *make_global_var(CTypeDescrObject *type, char *addr)
+{
+    GlobSupportObject *gs = PyObject_New(GlobSupportObject, &GlobSupport_Type);
+    if (gs == NULL)
+        return NULL;
+
+    Py_INCREF(type);
+    gs->gs_type = type;
+    gs->gs_data = addr;
+    return (PyObject *)gs;
+}
+
+static PyObject *read_global_var(GlobSupportObject *gs)
+{
+    return convert_to_object(gs->gs_data, gs->gs_type);
+}
+
+#if 0
+static int write_global_var(GlobSupportObject *gs, PyObject *obj)
+{
+    return convert_from_object(gs->gs_data, gs->gs_type, obj);
+}
+
+static PyObject *addressof_global_var(GlobSupportObject *gs)
+{
+    return new_simple_cdata(gs->gs_data, gs->gs_type);
+}
+#endif
diff --git a/new/ffi_obj.c b/new/ffi_obj.c
--- a/new/ffi_obj.c
+++ b/new/ffi_obj.c
@@ -144,23 +144,24 @@
                          input_text, spaces);
             return NULL;
         }
-        PyObject *ct = realize_c_type(ffi->info.ctx,
-                                      ffi->info.output, index);
+        CTypeDescrObject *ct = realize_c_type(ffi->info.ctx,
+                                              ffi->info.output, index);
         if (ct == NULL)
             return NULL;
 
-        char *normalized_text = ((CTypeDescrObject *)ct)->ct_name;
+        char *normalized_text = ct->ct_name;
         x = PyDict_GetItemString(ffi->types_dict, normalized_text);
         if (x == NULL) {
-            PyDict_SetItemString(ffi->types_dict, normalized_text, ct);
+            PyDict_SetItemString(ffi->types_dict, normalized_text,
+                                 (PyObject *)ct);
         }
         else {
             Py_INCREF(x);
             Py_DECREF(ct);
-            ct = x;
+            ct = (CTypeDescrObject *)x;
         }
-        PyDict_SetItem(ffi->types_dict, arg, ct);
-        return (CTypeDescrObject *)ct;
+        PyDict_SetItem(ffi->types_dict, arg, (PyObject *)ct);
+        return 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
@@ -95,6 +95,7 @@
 
     const struct _cffi_global_s *g = &lib->l_ctx->globals[index];
     PyObject *x;
+    CTypeDescrObject *ct;
 
     switch (_CFFI_GETOP(g->type_op)) {
 
@@ -110,6 +111,17 @@
         x = lib_build_cpython_func(lib, g, s, METH_O);
         break;
 
+    case _CFFI_OP_NOOP:
+        /* this is used for global variables, of the exact type specified
+           here */
+        ct = realize_c_type(lib->l_ctx, lib->l_ctx->types,
+                            _CFFI_GETARG(g->type_op));
+        if (ct == NULL)
+            return NULL;
+        x = make_global_var(ct, g->address);
+        Py_DECREF(ct);
+        break;
+
     default:
         PyErr_SetString(PyExc_NotImplementedError, "in lib_build_attr");
         return NULL;
@@ -130,9 +142,9 @@
     if (x == NULL)
         x = lib_build_and_cache_attr(lib, name);
 
-    //if (ZefGlobSupport_Check(x)) {
-    //    return read_global_var((ZefGlobSupportObject *)x);
-    //}
+    if (GlobSupport_Check(x)) {
+        return read_global_var((GlobSupportObject *)x);
+    }
     return x;
 }
 
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
@@ -66,13 +66,13 @@
    the intermediate types back in the opcodes[].  Returns a new
    reference.
 */
-static PyObject *
+static CTypeDescrObject *
 realize_c_type(const struct _cffi_type_context_s *ctx,
                _cffi_opcode_t opcodes[], int index)
 {
     PyObject *x = _realize_c_type_or_func(ctx, opcodes, index);
     if (x == NULL || CTypeDescr_Check(x)) {
-        return x;
+        return (CTypeDescrObject *)x;
     }
     else {
         PyObject *y;
@@ -129,10 +129,10 @@
         break;
 
     case _CFFI_OP_ARRAY:
-        length = (Py_ssize_t)opcodes[_CFFI_GETARG(op) + 1];
+        length = (Py_ssize_t)opcodes[index + 1];
         /* fall-through */
     case _CFFI_OP_OPEN_ARRAY:
-        y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+        y = (PyObject *)realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
         if (y == NULL)
             return NULL;
         z = new_pointer_type((CTypeDescrObject *)y);
@@ -148,7 +148,7 @@
         PyObject *fargs;
         int i, base_index, num_args;
 
-        y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+        y = (PyObject *)realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
         if (y == NULL)
             return NULL;
 
@@ -165,7 +165,7 @@
         }
 
         for (i = 0; i < num_args; i++) {
-            z = realize_c_type(ctx, opcodes, base_index + i);
+            z = (PyObject *)realize_c_type(ctx, opcodes, base_index + i);
             if (z == NULL) {
                 Py_DECREF(fargs);
                 Py_DECREF(y);
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
@@ -28,7 +28,7 @@
     check("int(*)", "int *")
 
 def test_array():
-    check("int[5]")
+    check("int[6]")
 
 def test_funcptr():
     check("int(*)(long)")
diff --git a/new/test_recompiler.py b/new/test_recompiler.py
--- a/new/test_recompiler.py
+++ b/new/test_recompiler.py
@@ -71,9 +71,9 @@
     ffi = FFI()
     ffi.cdef("int a[100];")
     lib = verify(ffi, 'test_global_var_array', 'int a[100] = { 9999 };')
-    #lib.a[42] = 123456
-    #assert lib.a[42] == 123456
-    #assert lib.a[0] == 9999
+    lib.a[42] = 123456
+    assert lib.a[42] == 123456
+    assert lib.a[0] == 9999
 
 def test_typedef():
     ffi = FFI()


More information about the pypy-commit mailing list