[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--