Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r156:f5bc966d0d96
Date: 2014-12-05 10:01 +0100
http://bitbucket.org/cffi/creflect/changeset/f5bc966d0d96/

Log:    global vars, starting

diff --git a/zeffir/builder.c b/zeffir/builder.c
--- a/zeffir/builder.c
+++ b/zeffir/builder.c
@@ -413,7 +413,17 @@
 static void zef_define_var(_crx_builder_t *cb, const char *name,
                            _crx_type_t *type, int quals, const void *addr)
 {
-    abort();
+    if (PyErr_Occurred())
+        return;
+
+    PyObject *l_dict = ((zeffir_builder_t *)cb)->l_dict;
+
+    PyObject *x = make_global_var(type, addr);
+    if (x == NULL)
+        return;
+
+    PyDict_SetItemString(l_dict, name, x);
+    Py_DECREF(x);
 }
 
 static void zef_define_func(_crx_builder_t *cb, const char *name,
diff --git a/zeffir/cdata.c b/zeffir/cdata.c
--- a/zeffir/cdata.c
+++ b/zeffir/cdata.c
@@ -1,1 +1,56 @@
 
+struct CDataObject_s {
+    PyObject_HEAD
+    CTypeDescrObject *c_type;
+    char *c_data;
+    PyObject *c_weakreflist;
+};
+
+/*
+#define CData_Check(ob)       (Py_TYPE(ob) == &CData_Type ||            \
+                               Py_TYPE(ob) == &CDataOwning_Type ||      \
+                               Py_TYPE(ob) == &CDataOwningGC_Type)
+#define CDataOwn_Check(ob)    (Py_TYPE(ob) == &CDataOwning_Type ||      \
+                               Py_TYPE(ob) == &CDataOwningGC_Type)
+*/
+
+static void cdata_dealloc(CDataObject *cd)
+{
+    if (cd->c_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) cd);
+
+    Py_DECREF(cd->c_type);
+#ifndef CFFI_MEM_LEAK     /* never release anything, tests only */
+    Py_TYPE(cd)->tp_free((PyObject *)cd);
+#endif
+}
+
+static PyTypeObject CData_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "zeffir.CData",
+    sizeof(CDataObject),
+    0,
+    (destructor)cdata_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    0,//(reprfunc)cdata_repr,                       /* tp_repr */
+    0,//&CData_as_number,                           /* tp_as_number */
+    0,                                          /* tp_as_sequence */
+    0,//&CData_as_mapping,                          /* tp_as_mapping */
+    0,//(hashfunc)cdata_hash,                       /* tp_hash */
+    0,//(ternaryfunc)cdata_call,                    /* tp_call */
+    0,                                          /* tp_str */
+    0,//(getattrofunc)cdata_getattro,               /* tp_getattro */
+    0,//(setattrofunc)cdata_setattro,               /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+    0,                                          /* tp_doc */
+    0,                                          /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,//cdata_richcompare,                          /* tp_richcompare */
+    offsetof(CDataObject, c_weakreflist),       /* tp_weaklistoffset */
+    0,//(getiterfunc)cdata_iter,                    /* tp_iter */
+    0,                                          /* tp_iternext */
+};
diff --git a/zeffir/cfunc.c b/zeffir/cfunc.c
--- a/zeffir/cfunc.c
+++ b/zeffir/cfunc.c
@@ -9,7 +9,7 @@
 
 } ZefFuncSupportObject;
 
-static void zef_builtin_support_dealloc(ZefFuncSupportObject *zfs)
+static void zef_func_support_dealloc(ZefFuncSupportObject *zfs)
 {
     PyObject_Del(zfs);
 }
@@ -19,7 +19,7 @@
     "zeffir.FuncSupport",
     sizeof(ZefFuncSupportObject),
     0,
-    (destructor)zef_builtin_support_dealloc,    /* tp_dealloc */
+    (destructor)zef_func_support_dealloc,       /* tp_dealloc */
     0,                                          /* tp_print */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
diff --git a/zeffir/cglob.c b/zeffir/cglob.c
new file mode 100644
--- /dev/null
+++ b/zeffir/cglob.c
@@ -0,0 +1,53 @@
+
+typedef struct {
+    PyObject_HEAD
+
+    CTypeDescrObject *zgs_type;
+    char             *zgs_data;
+
+} ZefGlobSupportObject;
+
+static void zef_glob_support_dealloc(ZefGlobSupportObject *zgs)
+{
+    Py_DECREF(zgs->zgs_type);
+    PyObject_Del(zgs);
+}
+
+static PyTypeObject ZefGlobSupport_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "zeffir.GlobSupport",
+    sizeof(ZefGlobSupportObject),
+    0,
+    (destructor)zef_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 ZefGlobSupport_Check(ob)  (Py_TYPE(ob) == &ZefGlobSupport_Type)
+
+static PyObject *make_global_var(_crx_type_t *type, const void *addr)
+{
+    ZefGlobSupportObject *zgs =
+        PyObject_New(ZefGlobSupportObject, &ZefGlobSupport_Type);
+    if (zgs == NULL)
+        return NULL;
+
+    Py_INCREF(type);
+    zgs->zgs_type = type;
+    zgs->zgs_data = (char *)addr;
+    assert(addr != NULL);
+    return (PyObject *)zgs;
+}
diff --git a/zeffir/ctype.c b/zeffir/ctype.c
--- a/zeffir/ctype.c
+++ b/zeffir/ctype.c
@@ -49,18 +49,7 @@
     char ct_name[1];        /* string, e.g. "int *" for pointers to ints */
 };
 
-static PyTypeObject CTypeDescr_Type;
-//static PyTypeObject CField_Type;
-//static PyTypeObject CData_Type;
-//static PyTypeObject CDataOwning_Type;
-//static PyTypeObject CDataOwningGC_Type;
-
 #define CTypeDescr_Check(ob)  (Py_TYPE(ob) == &CTypeDescr_Type)
-#define CData_Check(ob)       (Py_TYPE(ob) == &CData_Type ||            \
-                               Py_TYPE(ob) == &CDataOwning_Type ||      \
-                               Py_TYPE(ob) == &CDataOwningGC_Type)
-#define CDataOwn_Check(ob)    (Py_TYPE(ob) == &CDataOwning_Type ||      \
-                               Py_TYPE(ob) == &CDataOwningGC_Type)
 
 /************************************************************/
 
diff --git a/zeffir/lib_obj.c b/zeffir/lib_obj.c
--- a/zeffir/lib_obj.c
+++ b/zeffir/lib_obj.c
@@ -25,8 +25,10 @@
                                lib->l_dl_lib == NULL ? " (closed)" : "");
 }
 
-static PyObject *lib_getattr(ZefLibObject *lib, PyObject *name)
+static PyObject *lib_findattr(ZefLibObject *lib, PyObject *name)
 {
+    /* does not return a new reference! */
+
     if (lib->l_dict == NULL) {
         PyErr_Format(ZefError, "lib '%.200s' was closed", lib->l_libname);
         return NULL;
@@ -39,13 +41,49 @@
                      " global variable or constant '%.200s'",
                      lib->l_libname,
                      PyString_Check(name) ? PyString_AS_STRING(name) : "?");
+        return NULL;
     }
     return x;
 }
 
+static PyObject *lib_getattr(ZefLibObject *lib, PyObject *name)
+{
+    PyObject *x = lib_findattr(lib, name);
+    if (x == NULL)
+        return NULL;
+
+    if (ZefGlobSupport_Check(x)) {
+        // XXX!
+        return PyInt_FromLong(*(int *)(((ZefGlobSupportObject *)x)->zgs_data));
+    }
+    Py_INCREF(x);
+    return x;
+}
+
 static int lib_setattr(ZefLibObject *lib, PyObject *name, PyObject *val)
 {
-    PyErr_SetString(PyExc_AttributeError, "Lib object is read-only");
+    PyObject *x = lib_findattr(lib, name);
+    if (x == NULL)
+        return -1;
+
+    if (val == NULL) {
+        PyErr_SetString(PyExc_AttributeError,
+                        "cannot delete attributes from Lib object");
+        return -1;
+    }
+
+    if (ZefGlobSupport_Check(x)) {
+        // XXX!
+        long y = PyInt_AsLong(val);
+        if (PyErr_Occurred())
+            return -1;
+        *(int *)(((ZefGlobSupportObject *)x)->zgs_data) = y;
+        return 0;
+    }
+
+    PyErr_Format(PyExc_AttributeError,
+                 "cannot write to function or constant '%.200s'",
+                 PyString_Check(name) ? PyString_AS_STRING(name) : "?");
     return -1;
 }
 
diff --git a/zeffir/test/global.crx b/zeffir/test/global.crx
new file mode 100644
--- /dev/null
+++ b/zeffir/test/global.crx
@@ -0,0 +1,8 @@
+short myglob = 42;
+
+
+// CREFLECT: start
+
+short myglob;
+
+// CREFLECT: end
diff --git a/zeffir/test/test_global.py b/zeffir/test/test_global.py
new file mode 100644
--- /dev/null
+++ b/zeffir/test/test_global.py
@@ -0,0 +1,17 @@
+import py
+import support
+
+
+def test_simple_global():
+    ffi, lib = support.compile_and_open('global')
+    res = lib.myglob
+    assert type(res) is int
+    assert res == 42
+    #
+    lib.myglob = -43
+    res = lib.myglob
+    assert type(res) is int
+    assert res == -43
+    #
+    #py.test.raises(OverflowError, setattr, lib, 'myglob', 40000)
+    #py.test.raises(OverflowError, setattr, lib, 'myglob', -40000)
diff --git a/zeffir/zeffir.c b/zeffir/zeffir.c
--- a/zeffir/zeffir.c
+++ b/zeffir/zeffir.c
@@ -12,6 +12,7 @@
 #include "zeffir.h"
 #include "ctype.c"
 #include "cdata.c"
+#include "cglob.c"
 #include "lib_obj.c"
 #include "ffi_obj.c"
 #include "cfunc.c"
@@ -39,13 +40,21 @@
         return;
     if (PyType_Ready(&CTypeDescr_Type) < 0)
         return;
+    if (PyType_Ready(&CData_Type) < 0)
+        return;
     if (PyType_Ready(&ZefFuncSupport_Type) < 0)
         return;
+    if (PyType_Ready(&ZefGlobSupport_Type) < 0)
+        return;
 
     if (PyModule_AddObject(m, "FFI", (PyObject *)&ZefFFI_Type) < 0)
         return;
+    if (PyModule_AddObject(m, "Lib", (PyObject *)&ZefLib_Type) < 0)
+        return;
     if (PyModule_AddObject(m, "CType", (PyObject *)&CTypeDescr_Type) < 0)
         return;
+    if (PyModule_AddObject(m, "CData", (PyObject *)&CData_Type) < 0)
+        return;
 
     ZefError = PyErr_NewException("zeffir.error", NULL, NULL);
     if (ZefError == NULL)
diff --git a/zeffir/zeffir.h b/zeffir/zeffir.h
--- a/zeffir/zeffir.h
+++ b/zeffir/zeffir.h
@@ -1,9 +1,15 @@
 
 typedef struct _crx_type_s CTypeDescrObject;
+typedef struct CDataObject_s CDataObject;
 typedef struct ZefLibObject_s ZefLibObject;
 typedef struct ZefFFIObject_s ZefFFIObject;
 
 static PyTypeObject ZefFFI_Type;
+static PyTypeObject CTypeDescr_Type;
+//static PyTypeObject CField_Type;
+static PyTypeObject CData_Type;
+//static PyTypeObject CDataOwning_Type;
+//static PyTypeObject CDataOwningGC_Type;
 
 static PyObject *ZefError;
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to