[Python-Dev] Get rid of etype struct
Christian Tismer
tismer@tismer.com
Tue, 03 Sep 2002 20:26:01 +0200
This is a multi-part message in MIME format.
--------------080306050703000101060801
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Hi Guido,
I think I have a solution for this one, see the attached diff.
I did what you suggested: Make the adressing of the
members dependant from the metatype.
The etype struct has lost its members[1] field, to make it
easier to extend the structure. Instead, the allocator always
adds one to the size, to have the sentinel in place.
I did not yet publish the etype stucture, since I didn't find
a good name and place for it.
Testing was also not very thorow. I just checked that types
work from Python and that I can add __slots__ to them.
Will re-port this stuff to my Py2.2 Stackless base and try it
out as base type for my own C types.
It took me the whole day to understand how it must work, and
then just an hour to get it to work. This is quite some stuff :-)
Can somebody please have a look, if there are subtle errors?
ciao - chris
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=591586&group_id=5470
--------------080306050703000101060801
Content-Type: text/plain; charset=us-ascii;
name="typeobject.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="typeobject.diff"
cvs -z9 diff -u dist/src/Objects/typeobject.c
Index: dist/src/Objects/typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.179
diff -u -r2.179 typeobject.c
--- dist/src/Objects/typeobject.c 16 Aug 2002 17:01:08 -0000 2.179
+++ dist/src/Objects/typeobject.c 3 Sep 2002 18:04:39 -0000
@@ -20,9 +20,12 @@
see add_operators() below. */
PyBufferProcs as_buffer;
PyObject *name, *slots;
- PyMemberDef members[1];
+ /* here are optional user slots, followed by the members. */
} etype;
+#define GET_MEMBERS(etype) \
+ ((PyMemberDef *)(((char *)etype) + (etype)->type.ob_type->tp_basicsize)-1)
+
static PyMemberDef type_members[] = {
{"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY},
{"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY},
@@ -213,7 +216,8 @@
PyType_GenericAlloc(PyTypeObject *type, int nitems)
{
PyObject *obj;
- const size_t size = _PyObject_VAR_SIZE(type, nitems);
+ const size_t size = _PyObject_VAR_SIZE(type, nitems+1);
+ /* note that we need to add one, for the sentinel */
if (PyType_IS_GC(type))
obj = _PyObject_GC_Malloc(size);
@@ -253,7 +257,7 @@
PyMemberDef *mp;
n = type->ob_size;
- mp = ((etype *)type)->members;
+ mp = GET_MEMBERS((etype *)type);
for (i = 0; i < n; i++, mp++) {
if (mp->type == T_OBJECT_EX) {
char *addr = (char *)self + mp->offset;
@@ -318,7 +322,7 @@
PyMemberDef *mp;
n = type->ob_size;
- mp = ((etype *)type)->members;
+ mp = GET_MEMBERS((etype *)type);
for (i = 0; i < n; i++, mp++) {
if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) {
char *addr = (char *)self + mp->offset;
@@ -1125,7 +1129,8 @@
/* Are slots allowed? */
nslots = PyTuple_GET_SIZE(slots);
- if (nslots > 0 && base->tp_itemsize != 0) {
+ if (nslots > 0 && base->tp_itemsize != 0 && !PyType_Check(base)) {
+ /* for the special case of meta types, allow slots */
PyErr_Format(PyExc_TypeError,
"nonempty __slots__ "
"not supported for subtype of '%s'",
@@ -1334,7 +1339,7 @@
}
/* Add descriptors for custom slots from __slots__, or for __dict__ */
- mp = et->members;
+ mp = GET_MEMBERS(et);
slotoffset = base->tp_basicsize;
if (slots != NULL) {
for (i = 0; i < nslots; i++, mp++) {
@@ -1366,7 +1371,7 @@
}
type->tp_basicsize = slotoffset;
type->tp_itemsize = base->tp_itemsize;
- type->tp_members = et->members;
+ type->tp_members = GET_MEMBERS(et);
type->tp_getset = subtype_getsets;
/* Special case some slots */
*****CVS exited normally with code 1*****
--------------080306050703000101060801--