[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.53,2.54

Guido van Rossum gvanrossum@users.sourceforge.net
Thu, 30 Aug 2001 13:00:09 -0700


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

Modified Files:
	typeobject.c 
Log Message:
Pytype_GenericAlloc(): round up size so we zap all four bytes of the
__dict__ slot for string subtypes.

subtype_dealloc(): properly use _PyObject_GetDictPtr() to get the
(potentially negative) dict offset.  Don't copy things into local
variables that are used only once.

type_new(): properly calculate a negative dict offset when tp_itemsize
is nonzero.  The __dict__ attribute, if present, is now a calculated
attribute rather than a structure member.


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.53
retrieving revision 2.54
diff -C2 -d -r2.53 -r2.54
*** typeobject.c	2001/08/30 04:43:35	2.53
--- typeobject.c	2001/08/30 20:00:07	2.54
***************
*** 167,170 ****
--- 167,172 ----
  PyType_GenericAlloc(PyTypeObject *type, int nitems)
  {
+ #define PTRSIZE (sizeof(PyObject *))
+ 
  	int size;
  	PyObject *obj;
***************
*** 172,175 ****
--- 174,183 ----
  	/* Inline PyObject_New() so we can zero the memory */
  	size = _PyObject_VAR_SIZE(type, nitems);
+ 	/* Round up size, if necessary, so we fully zero out __dict__ */
+ 	if (type->tp_itemsize % PTRSIZE != 0) {
+ 		size += PTRSIZE - 1;
+ 		size /= PTRSIZE;
+ 		size *= PTRSIZE;
+ 	}
  	if (PyType_IS_GC(type)) {
  		obj = _PyObject_GC_Malloc(type, nitems);
***************
*** 203,208 ****
  subtype_dealloc(PyObject *self)
  {
- 	int dictoffset = self->ob_type->tp_dictoffset;
- 	int weaklistoffset = self->ob_type->tp_weaklistoffset;
  	PyTypeObject *type, *base;
  	destructor f;
--- 211,214 ----
***************
*** 219,233 ****
  
  	/* If we added a dict, DECREF it */
! 	if (dictoffset && !base->tp_dictoffset) {
! 		PyObject **dictptr = (PyObject **) ((char *)self + dictoffset);
! 		PyObject *dict = *dictptr;
! 		if (dict != NULL) {
! 			Py_DECREF(dict);
! 			*dictptr = NULL;
  		}
  	}
  
  	/* If we added weaklist, we clear it */
! 	if (weaklistoffset && !base->tp_weaklistoffset)
  		PyObject_ClearWeakRefs(self);
  
--- 225,241 ----
  
  	/* If we added a dict, DECREF it */
! 	if (type->tp_dictoffset && !base->tp_dictoffset) {
! 		PyObject **dictptr = _PyObject_GetDictPtr(self);
! 		if (dictptr != NULL) {
! 			PyObject *dict = *dictptr;
! 			if (dict != NULL) {
! 				Py_DECREF(dict);
! 				*dictptr = NULL;
! 			}
  		}
  	}
  
  	/* If we added weaklist, we clear it */
! 	if (type->tp_weaklistoffset && !base->tp_weaklistoffset)
  		PyObject_ClearWeakRefs(self);
  
***************
*** 581,584 ****
--- 589,619 ----
  
  static PyObject *
+ subtype_dict(PyObject *obj, void *context)
+ {
+ 	PyObject **dictptr = _PyObject_GetDictPtr(obj);
+ 	PyObject *dict;
+ 
+ 	if (dictptr == NULL) {
+ 		PyErr_SetString(PyExc_AttributeError,
+ 				"This object has no __dict__");
+ 		return NULL;
+ 	}
+ 	dict = *dictptr;
+ 	if (dict == NULL) {
+ 		Py_INCREF(Py_None);
+ 		return Py_None;
+ 	}
+ 	else {
+ 		Py_INCREF(dict);
+ 		return dict;
+ 	}
+ }
+ 
+ struct getsetlist subtype_getsets[] = {
+ 	{"__dict__", subtype_dict, NULL, NULL},
+ 	{0},
+ };
+ 
+ static PyObject *
  type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
  {
***************
*** 733,737 ****
  	    (base->tp_setattro == PyObject_GenericSetAttr ||
  	     base->tp_setattro == NULL)) {
- 		nslots++;
  		add_dict++;
  	}
--- 768,771 ----
***************
*** 830,842 ****
  	else {
  		if (add_dict) {
! 			type->tp_dictoffset = slotoffset;
! 			mp->name = "__dict__";
! 			mp->type = T_OBJECT;
! 			mp->offset = slotoffset;
! 			mp->readonly = 1;
! 			mp++;
  			slotoffset += sizeof(PyObject *);
  		}
  		if (add_weak) {
  			type->tp_weaklistoffset = slotoffset;
  			mp->name = "__weakref__";
--- 864,876 ----
  	else {
  		if (add_dict) {
! 			if (base->tp_itemsize)
! 				type->tp_dictoffset = -sizeof(PyObject *);
! 			else
! 				type->tp_dictoffset = slotoffset;
  			slotoffset += sizeof(PyObject *);
+ 			type->tp_getset = subtype_getsets;
  		}
  		if (add_weak) {
+ 			assert(!base->tp_itemsize);
  			type->tp_weaklistoffset = slotoffset;
  			mp->name = "__weakref__";
***************
*** 849,852 ****
--- 883,887 ----
  	}
  	type->tp_basicsize = slotoffset;
+ 	type->tp_itemsize = base->tp_itemsize;
  	type->tp_members = et->members;