Author: Armin Rigo <ar...@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() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit