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