[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