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

Guido van Rossum gvanrossum@users.sourceforge.net
2001年8月30日 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;
 

AltStyle によって変換されたページ (->オリジナル) /