Author: Armin Rigo <ar...@tunes.org> Branch: cffi-1.0 Changeset: r1976:73400152d574 Date: 2015-05-11 17:55 +0200 http://bitbucket.org/cffi/cffi/changeset/73400152d574/
Log: struct/unions diff --git a/_cffi1/cdlopen.c b/_cffi1/cdlopen.c --- a/_cffi1/cdlopen.c +++ b/_cffi1/cdlopen.c @@ -134,8 +134,9 @@ ffi->ctx_is_nonempty = 1; if (types_len > 0) { + /* unpack a string of 4-byte entries into an array of _cffi_opcode_t */ _cffi_opcode_t *ntypes; - Py_ssize_t i, n = types_len / 4; /* 4 bytes entries */ + Py_ssize_t i, n = types_len / 4; building = PyMem_Malloc(n * sizeof(_cffi_opcode_t)); if (building == NULL) @@ -147,29 +148,95 @@ types += 4; } ffi->types_builder.ctx.types = ntypes; + ffi->types_builder.ctx.num_types = n; building = NULL; } if (globals != NULL) { - struct _cffi_global_s *nglob; + /* unpack a tuple of strings, each of which describes one global_s + entry with no specified address or size */ + struct _cffi_global_s *nglobs; Py_ssize_t i, n = PyTuple_GET_SIZE(globals); - building = PyMem_Malloc(n * sizeof(struct _cffi_global_s)); + i = n * sizeof(struct _cffi_global_s); + building = PyMem_Malloc(i); if (building == NULL) goto error; - memset(building, 0, n * sizeof(struct _cffi_global_s)); - nglob = (struct _cffi_global_s *)building; + memset(building, 0, i); + nglobs = (struct _cffi_global_s *)building; for (i = 0; i < n; i++) { char *g = PyString_AS_STRING(PyTuple_GET_ITEM(globals, i)); - nglob[i].type_op = cdl_opcode(g); - nglob[i].name = g + 4; + nglobs[i].type_op = cdl_opcode(g); + nglobs[i].name = g + 4; } - ffi->types_builder.ctx.globals = nglob; + ffi->types_builder.ctx.globals = nglobs; ffi->types_builder.ctx.num_globals = n; building = NULL; } + if (struct_unions != NULL) { + /* unpack a tuple of struct/unions, each described as a sub-tuple; + the item 0 of each sub-tuple describes the struct/union, and + the items 1..N-1 describe the fields, if any */ + struct _cffi_struct_union_s *nstructs; + struct _cffi_field_s *nfields; + Py_ssize_t i, n = PyTuple_GET_SIZE(struct_unions); + Py_ssize_t nf = 0; /* total number of fields */ + + for (i = 0; i < n; i++) { + nf += PyTuple_GET_SIZE(PyTuple_GET_ITEM(struct_unions, i)) - 1; + } + i = (n * sizeof(struct _cffi_struct_union_s) + + nf * sizeof(struct _cffi_field_s)); + building = PyMem_Malloc(i); + if (building == NULL) + goto error; + memset(building, 0, i); + nstructs = (struct _cffi_struct_union_s *)building; + nfields = (struct _cffi_field_s *)(nstructs + n); + nf = 0; + + for (i = 0; i < n; i++) { + /* 'desc' is the tuple of strings (desc_struct, desc_field_1, ..) */ + PyObject *desc = PyTuple_GET_ITEM(struct_unions, i); + Py_ssize_t j, nf1 = PyTuple_GET_SIZE(desc) - 1; + char *s = PyString_AS_STRING(PyTuple_GET_ITEM(desc, 0)); + /* 's' is the first string, describing the struct/union */ + nstructs[i].type_index = cdl_int(s); + nstructs[i].flags = cdl_int(s + 4); + nstructs[i].name = s + 8; + if (nstructs[i].flags & _CFFI_F_OPAQUE) { + nstructs[i].size = (size_t)-1; + nstructs[i].alignment = -1; + nstructs[i].first_field_index = -1; + nstructs[i].num_fields = 0; + assert(nf1 == 0); + } + else { + nstructs[i].size = (size_t)-2; + nstructs[i].alignment = -2; + nstructs[i].first_field_index = nf; + nstructs[i].num_fields = nf1; + } + for (j = 0; j < nf1; j++) { + char *f = PyString_AS_STRING(PyTuple_GET_ITEM(desc, j + 1)); + /* 'f' is one of the other strings beyond the first one, + describing one field each */ + nfields[nf].field_type_op = cdl_opcode(f); + nfields[nf].name = f + 4; + nfields[nf].field_offset = (size_t)-1; + nfields[nf].field_size = (size_t)-1; + /* XXXXXXXXXXX BITFIELD MISSING XXXXXXXXXXXXXXXX */ + nf++; + } + } + ffi->types_builder.ctx.struct_unions = nstructs; + ffi->types_builder.ctx.fields = nfields; + ffi->types_builder.ctx.num_struct_unions = n; + building = NULL; + } + if (consts != NULL) { Py_INCREF(consts); ffi->types_builder.known_constants = consts; diff --git a/_cffi1/ffi_obj.c b/_cffi1/ffi_obj.c --- a/_cffi1/ffi_obj.c +++ b/_cffi1/ffi_obj.c @@ -694,94 +694,6 @@ static PyObject *ffi_dlopen(PyObject *self, PyObject *args); /* forward */ static PyObject *ffi_dlclose(PyObject *self, PyObject *args); /* forward */ -#if 0 -static PyObject *ffi__set_types(FFIObject *self, PyObject *args) -{ - PyObject *lst1, *lst2; - _cffi_opcode_t *types = NULL; - struct _cffi_struct_union_s *struct_unions = NULL; - struct _cffi_typename_s *typenames = NULL; - - if (!PyArg_ParseTuple(args, "O!O!", - &PyList_Type, &lst1, &PyList_Type, &lst2)) - return NULL; - - if (self->ctx_is_static) { - bad_usage: - PyMem_Free(typenames); - PyMem_Free(struct_unions); - PyMem_Free(types); - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_RuntimeError, "internal error"); - return NULL; - } - - cleanup_builder_c(self->types_builder); - - int i; - int lst1_length = PyList_GET_SIZE(lst1) / 2; - int lst2_length = PyList_GET_SIZE(lst2) / 2; - Py_ssize_t newsize0 = sizeof(_cffi_opcode_t) * (lst1_length + lst2_length); - Py_ssize_t newsize1 = sizeof(struct _cffi_struct_union_s) * lst1_length; - Py_ssize_t newsize2 = sizeof(struct _cffi_typename_s) * lst2_length; - types = PyMem_Malloc(newsize0); - struct_unions = PyMem_Malloc(newsize1); - typenames = PyMem_Malloc(newsize2); - if (!types || !struct_unions || !typenames) { - PyErr_NoMemory(); - goto bad_usage; - } - memset(types, 0, newsize0); - memset(struct_unions, 0, newsize1); - memset(typenames, 0, newsize2); - - for (i = 0; i < lst1_length; i++) { - PyObject *x = PyList_GET_ITEM(lst1, i * 2); - if (!PyString_Check(x)) - goto bad_usage; - struct_unions[i].name = PyString_AS_STRING(x); - struct_unions[i].type_index = i; - - x = PyList_GET_ITEM(lst1, i * 2 + 1); - if (!CTypeDescr_Check(x)) - goto bad_usage; - types[i] = x; - struct_unions[i].flags = ((CTypeDescrObject *)x)->ct_flags & CT_UNION ? - _CFFI_F_UNION : 0; - struct_unions[i].size = (size_t)-2; - struct_unions[i].alignment = -2; - } - for (i = 0; i < lst2_length; i++) { - PyObject *x = PyList_GET_ITEM(lst2, i * 2); - if (!PyString_Check(x)) - goto bad_usage; - typenames[i].name = PyString_AS_STRING(x); - typenames[i].type_index = lst1_length + i; - - x = PyList_GET_ITEM(lst2, i * 2 + 1); - if (!CTypeDescr_Check(x)) - goto bad_usage; - types[lst1_length + i] = x; - } - for (i = 0; i < lst1_length + lst2_length; i++) { - PyObject *x = (PyObject *)types[i]; - Py_INCREF(x); - } - - Py_INCREF(args); /* to keep alive the strings in '.name' */ - Py_XDECREF(self->dynamic_types); - self->dynamic_types = args; - self->types_builder.ctx.types = types; - self->types_builder.num_types_imported = lst1_length + lst2_length; - self->types_builder.ctx.struct_unions = struct_unions; - self->types_builder.ctx.num_struct_unions = lst1_length; - self->types_builder.ctx.typenames = typenames; - self->types_builder.ctx.num_typenames = lst2_length; - - Py_INCREF(Py_None); - return Py_None; -} -#endif #define METH_VKW (METH_VARARGS | METH_KEYWORDS) static PyMethodDef ffi_methods[] = { diff --git a/_cffi1/manual2.py b/_cffi1/manual2.py --- a/_cffi1/manual2.py +++ b/_cffi1/manual2.py @@ -2,8 +2,8 @@ ffi = _cffi_backend.FFI(b"manual2", _version = 0x2600, - _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x00\x09\x00\x00\x00\x0B', - _globals = (b'\x00\x00\x00#close',), + _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x00\x09\x00\x00\x00\x0B\x00\x00\x01\x03', + _globals = (b'\x00\x00\x00#close',b'\x00\x00\x05#stdout'), _struct_unions = ((b'\x00\x00\x00\x03\x00\x00\x00\x00point_s',b'\x00\x00\x01\x11x',b'\x00\x00\x01\x11y'),), _enums = (b'\x00\x00\x00\x04\x00\x00\x00\x01myenum_e\x00AA,BB,CC',), _typenames = (b'\x00\x00\x00\x01myint_t',), @@ -17,3 +17,11 @@ assert lib.BB == 1 x = lib.close(-42) assert x == -1 + +print lib.stdout + +print ffi.new("struct point_s *") +print ffi.offsetof("struct point_s", "x") +print ffi.offsetof("struct point_s", "y") + +del ffi diff --git a/_cffi1/realize_c_type.c b/_cffi1/realize_c_type.c --- a/_cffi1/realize_c_type.c +++ b/_cffi1/realize_c_type.c @@ -63,7 +63,7 @@ const void *mem[] = {builder->ctx.types, builder->ctx.globals, builder->ctx.struct_unions, - builder->ctx.fields, + //builder->ctx.fields: allocated with struct_unions builder->ctx.enums, builder->ctx.typenames}; for (i = 0; i < sizeof(mem) / sizeof(*mem); i++) { _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit