[Python-checkins] python/dist/src/Objects typeobject.c,2.214,2.215

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Fri, 07 Mar 2003 07:13:52 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv3464/Objects

Modified Files:
	typeobject.c 
Log Message:
- The extended type structure used for heap types (new-style
  classes defined by Python code using a class statement) is now
  exported from object.h as PyHeapTypeObject.  (SF patch #696193.)


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.214
retrieving revision 2.215
diff -C2 -d -r2.214 -r2.215
*** typeobject.c	21 Feb 2003 22:02:54 -0000	2.214
--- typeobject.c	7 Mar 2003 15:13:17 -0000	2.215
***************
*** 6,27 ****
  #include <ctype.h>
  
- /* The *real* layout of a type object when allocated on the heap */
- /* XXX Should we publish this in a header file? */
- typedef struct {
- 	/* Note: there's a dependency on the order of these members
- 	   in slotptr() below. */
- 	PyTypeObject type;
- 	PyNumberMethods as_number;
- 	PyMappingMethods as_mapping;
- 	PySequenceMethods as_sequence; /* as_sequence comes after as_mapping,
- 					  so that the mapping wins when both
- 					  the mapping and the sequence define
- 					  a given operator (e.g. __getitem__).
- 					  see add_operators() below. */
- 	PyBufferProcs as_buffer;
- 	PyObject *name, *slots;
- 	PyMemberDef members[1];
- } etype;
- 
  static PyMemberDef type_members[] = {
  	{"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY},
--- 6,9 ----
***************
*** 43,47 ****
  
  	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
! 		etype* et = (etype*)type;
  
  		Py_INCREF(et->name);
--- 25,29 ----
  
  	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
! 		PyHeapTypeObject* et = (PyHeapTypeObject*)type;
  
  		Py_INCREF(et->name);
***************
*** 61,65 ****
  type_set_name(PyTypeObject *type, PyObject *value, void *context)
  {
! 	etype* et;
  
  	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
--- 43,47 ----
  type_set_name(PyTypeObject *type, PyObject *value, void *context)
  {
! 	PyHeapTypeObject* et;
  
  	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
***************
*** 86,90 ****
  	}
  
! 	et = (etype*)type;
  
  	Py_INCREF(value);
--- 68,72 ----
  	}
  
! 	et = (PyHeapTypeObject*)type;
  
  	Py_INCREF(value);
***************
*** 450,454 ****
  {
  	PyObject *obj;
! 	const size_t size = _PyObject_VAR_SIZE(type, nitems);
  
  	if (PyType_IS_GC(type))
--- 432,437 ----
  {
  	PyObject *obj;
! 	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))
***************
*** 490,494 ****
  
  	n = type->ob_size;
! 	mp = ((etype *)type)->members;
  	for (i = 0; i < n; i++, mp++) {
  		if (mp->type == T_OBJECT_EX) {
--- 473,477 ----
  
  	n = type->ob_size;
! 	mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
  	for (i = 0; i < n; i++, mp++) {
  		if (mp->type == T_OBJECT_EX) {
***************
*** 555,559 ****
  
  	n = type->ob_size;
! 	mp = ((etype *)type)->members;
  	for (i = 0; i < n; i++, mp++) {
  		if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) {
--- 538,542 ----
  
  	n = type->ob_size;
! 	mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
  	for (i = 0; i < n; i++, mp++) {
  		if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) {
***************
*** 1535,1539 ****
  	PyObject *slots, *tmp, *newslots;
  	PyTypeObject *type, *base, *tmptype, *winner;
! 	etype *et;
  	PyMemberDef *mp;
  	int i, nbases, nslots, slotoffset, add_dict, add_weak;
--- 1518,1522 ----
  	PyObject *slots, *tmp, *newslots;
  	PyTypeObject *type, *base, *tmptype, *winner;
! 	PyHeapTypeObject *et;
  	PyMemberDef *mp;
  	int i, nbases, nslots, slotoffset, add_dict, add_weak;
***************
*** 1650,1654 ****
  		/* Are slots allowed? */
  		nslots = PyTuple_GET_SIZE(slots);
! 		if (nslots > 0 && base->tp_itemsize != 0) {
  			PyErr_Format(PyExc_TypeError,
  				     "nonempty __slots__ "
--- 1633,1638 ----
  		/* Are slots allowed? */
  		nslots = PyTuple_GET_SIZE(slots);
! 		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__ "
***************
*** 1771,1775 ****
  
  	/* Keep name and slots alive in the extended type object */
! 	et = (etype *)type;
  	Py_INCREF(name);
  	et->name = name;
--- 1755,1759 ----
  
  	/* Keep name and slots alive in the extended type object */
! 	et = (PyHeapTypeObject *)type;
  	Py_INCREF(name);
  	et->name = name;
***************
*** 1851,1855 ****
  
  	/* Add descriptors for custom slots from __slots__, or for __dict__ */
! 	mp = et->members;
  	slotoffset = base->tp_basicsize;
  	if (slots != NULL) {
--- 1835,1839 ----
  
  	/* Add descriptors for custom slots from __slots__, or for __dict__ */
! 	mp = PyHeapType_GET_MEMBERS(et);
  	slotoffset = base->tp_basicsize;
  	if (slots != NULL) {
***************
*** 1883,1887 ****
  	type->tp_basicsize = slotoffset;
  	type->tp_itemsize = base->tp_itemsize;
! 	type->tp_members = et->members;
  
  	if (type->tp_weaklistoffset && type->tp_dictoffset)
--- 1867,1871 ----
  	type->tp_basicsize = slotoffset;
  	type->tp_itemsize = base->tp_itemsize;
! 	type->tp_members = PyHeapType_GET_MEMBERS(et);
  
  	if (type->tp_weaklistoffset && type->tp_dictoffset)
***************
*** 2053,2057 ****
  type_dealloc(PyTypeObject *type)
  {
! 	etype *et;
  
  	/* Assert this is a heap-allocated type object */
--- 2037,2041 ----
  type_dealloc(PyTypeObject *type)
  {
! 	PyHeapTypeObject *et;
  
  	/* Assert this is a heap-allocated type object */
***************
*** 2059,2063 ****
  	_PyObject_GC_UNTRACK(type);
  	PyObject_ClearWeakRefs((PyObject *)type);
! 	et = (etype *)type;
  	Py_XDECREF(type->tp_base);
  	Py_XDECREF(type->tp_dict);
--- 2043,2047 ----
  	_PyObject_GC_UNTRACK(type);
  	PyObject_ClearWeakRefs((PyObject *)type);
! 	et = (PyHeapTypeObject *)type;
  	Py_XDECREF(type->tp_base);
  	Py_XDECREF(type->tp_dict);
***************
*** 2135,2139 ****
  
  	/* There's no need to visit type->tp_subclasses or
! 	   ((etype *)type)->slots, because they can't be involved
  	   in cycles; tp_subclasses is a list of weak references,
  	   and slots is a tuple of strings. */
--- 2119,2123 ----
  
  	/* There's no need to visit type->tp_subclasses or
! 	   ((PyHeapTypeObject *)type)->slots, because they can't be involved
  	   in cycles; tp_subclasses is a list of weak references,
  	   and slots is a tuple of strings. */
***************
*** 2181,2185 ****
  	       lists have their own tp_clear.
  
! 	   slots (in etype):
  	       A tuple of strings can't be part of a cycle.
  	*/
--- 2165,2169 ----
  	       lists have their own tp_clear.
  
! 	   slots (in PyHeapTypeObject):
  	       A tuple of strings can't be part of a cycle.
  	*/
***************
*** 2202,2206 ****
  	0,					/* ob_size */
  	"type",					/* tp_name */
! 	sizeof(etype),				/* tp_basicsize */
  	sizeof(PyMemberDef),			/* tp_itemsize */
  	(destructor)type_dealloc,		/* tp_dealloc */
--- 2186,2190 ----
  	0,					/* ob_size */
  	"type",					/* tp_name */
! 	sizeof(PyHeapTypeObject),		/* tp_basicsize */
  	sizeof(PyMemberDef),			/* tp_itemsize */
  	(destructor)type_dealloc,		/* tp_dealloc */
***************
*** 4687,4693 ****
  
  /* Table mapping __foo__ names to tp_foo offsets and slot_tp_foo wrapper
!    functions.  The offsets here are relative to the 'etype' structure, which
!    incorporates the additional structures used for numbers, sequences and
!    mappings.  Note that multiple names may map to the same slot (e.g. __eq__,
     __ne__ etc. all map to tp_richcompare) and one name may map to multiple
     slots (e.g. __str__ affects tp_str as well as tp_repr). The table is
--- 4671,4678 ----
  
  /* Table mapping __foo__ names to tp_foo offsets and slot_tp_foo wrapper
!    functions.  The offsets here are relative to the 'PyHeapTypeObject' 
!    structure, which incorporates the additional structures used for numbers,
!    sequences and mappings.
!    Note that multiple names may map to the same slot (e.g. __eq__,
     __ne__ etc. all map to tp_richcompare) and one name may map to multiple
     slots (e.g. __str__ affects tp_str as well as tp_repr). The table is
***************
*** 4715,4719 ****
  	 PyDoc_STR(DOC), FLAGS}
  #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
! 	{NAME, offsetof(etype, SLOT), (void *)(FUNCTION), WRAPPER, \
  	 PyDoc_STR(DOC)}
  #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
--- 4700,4704 ----
  	 PyDoc_STR(DOC), FLAGS}
  #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
! 	{NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
  	 PyDoc_STR(DOC)}
  #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
***************
*** 4929,4946 ****
  	char *ptr;
  
! 	/* Note: this depends on the order of the members of etype! */
  	assert(offset >= 0);
! 	assert(offset < offsetof(etype, as_buffer));
! 	if (offset >= offsetof(etype, as_sequence)) {
  		ptr = (void *)type->tp_as_sequence;
! 		offset -= offsetof(etype, as_sequence);
  	}
! 	else if (offset >= offsetof(etype, as_mapping)) {
  		ptr = (void *)type->tp_as_mapping;
! 		offset -= offsetof(etype, as_mapping);
  	}
! 	else if (offset >= offsetof(etype, as_number)) {
  		ptr = (void *)type->tp_as_number;
! 		offset -= offsetof(etype, as_number);
  	}
  	else {
--- 4914,4931 ----
  	char *ptr;
  
! 	/* Note: this depends on the order of the members of PyHeapTypeObject! */
  	assert(offset >= 0);
! 	assert(offset < offsetof(PyHeapTypeObject, as_buffer));
! 	if (offset >= offsetof(PyHeapTypeObject, as_sequence)) {
  		ptr = (void *)type->tp_as_sequence;
! 		offset -= offsetof(PyHeapTypeObject, as_sequence);
  	}
! 	else if (offset >= offsetof(PyHeapTypeObject, as_mapping)) {
  		ptr = (void *)type->tp_as_mapping;
! 		offset -= offsetof(PyHeapTypeObject, as_mapping);
  	}
! 	else if (offset >= offsetof(PyHeapTypeObject, as_number)) {
  		ptr = (void *)type->tp_as_number;
! 		offset -= offsetof(PyHeapTypeObject, as_number);
  	}
  	else {
***************
*** 5217,5223 ****
  
     In the latter case, the first slotdef entry encoutered wins.  Since
!    slotdef entries are sorted by the offset of the slot in the etype
!    struct, this gives us some control over disambiguating between
!    competing slots: the members of struct etype are listed from most
     general to least general, so the most general slot is preferred.  In
     particular, because as_mapping comes before as_sequence, for a type
--- 5202,5208 ----
  
     In the latter case, the first slotdef entry encoutered wins.  Since
!    slotdef entries are sorted by the offset of the slot in the 
!    PyHeapTypeObject, this gives us some control over disambiguating
!    between competing slots: the members of PyHeapTypeObject are listed from most
     general to least general, so the most general slot is preferred.  In
     particular, because as_mapping comes before as_sequence, for a type