[Python-checkins] CVS: python/dist/src/Objects object.c,2.124.4.11,2.124.4.12

Guido van Rossum gvanrossum@users.sourceforge.net
Wed, 06 Jun 2001 07:34:15 -0700


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

Modified Files:
      Tag: descr-branch
	object.c 
Log Message:
Add _PyObject_GetDictPtr() -- an internal API to get a pointer to
where __dict__ is stored in an object.  The simplest case is to add
tp_dictoffset to the start of the object, but there are comlications:
tp_flags may tell us that tp_dictoffset is not defined, or the offset
may be negative: indexing from the end of the object, where
tp_itemsize may have to be taken into account.


Index: object.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v
retrieving revision 2.124.4.11
retrieving revision 2.124.4.12
diff -C2 -r2.124.4.11 -r2.124.4.12
*** object.c	2001/06/06 14:27:54	2.124.4.11
--- object.c	2001/06/06 14:34:13	2.124.4.12
***************
*** 1074,1077 ****
--- 1074,1111 ----
  }
  
+ /* Helper to get a pointer to an object's __dict__ slot, if any */
+ 
+ PyObject **
+ _PyObject_GetDictPtr(PyObject *obj)
+ {
+ #define PTRSIZE (sizeof(PyObject *))
+ 
+ 	long dictoffset;
+ 	PyTypeObject *tp = obj->ob_type;
+ 
+ 	if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
+ 		return NULL;
+ 	dictoffset = tp->tp_dictoffset;
+ 	if (dictoffset == 0)
+ 		return NULL;
+ 	if (dictoffset < 0) {
+ 		dictoffset += tp->tp_basicsize;
+ 		assert(dictoffset > 0); /* Sanity check */
+ 		if (tp->tp_itemsize > 0) {
+ 			int n = ((PyVarObject *)obj)->ob_size;
+ 			if (n > 0) {
+ 				dictoffset += tp->tp_itemsize * n;
+ 				/* Round up, if necessary */
+ 				if (tp->tp_itemsize % PTRSIZE != 0) {
+ 					dictoffset += PTRSIZE - 1;
+ 					dictoffset /= PTRSIZE;
+ 					dictoffset *= PTRSIZE;
+ 				}
+ 			}
+ 		}
+ 	}
+ 	return (PyObject **) ((char *)obj + dictoffset);
+ }
+ 
  /* Generic GetAttr functions - put these in your tp_[gs]etattro slot */
  
***************
*** 1082,1086 ****
  	PyObject *descr;
  	descrgetfunc f;
! 	int dictoffset;
  
  	if (tp->tp_dict == NULL) {
--- 1116,1120 ----
  	PyObject *descr;
  	descrgetfunc f;
! 	PyObject **dictptr;
  
  	if (tp->tp_dict == NULL) {
***************
*** 1097,1103 ****
  	}
  
! 	dictoffset = tp->tp_dictoffset;
! 	if (dictoffset != 0) {
! 		PyObject *dict = * (PyObject **) ((char *)obj + dictoffset);
  		if (dict != NULL) {
  			PyObject *res = PyDict_GetItem(dict, name);
--- 1131,1137 ----
  	}
  
! 	dictptr = _PyObject_GetDictPtr(obj);
! 	if (dictptr != NULL) {
! 		PyObject *dict = *dictptr;
  		if (dict != NULL) {
  			PyObject *res = PyDict_GetItem(dict, name);
***************
*** 1129,1133 ****
  	PyObject *descr;
  	descrsetfunc f;
! 	int dictoffset;
  
  	if (tp->tp_dict == NULL) {
--- 1163,1167 ----
  	PyObject *descr;
  	descrsetfunc f;
! 	PyObject **dictptr;
  
  	if (tp->tp_dict == NULL) {
***************
*** 1143,1149 ****
  	}
  
! 	dictoffset = tp->tp_dictoffset;
! 	if (dictoffset != 0) {
! 		PyObject **dictptr = (PyObject **) ((char *)obj + dictoffset);
  		PyObject *dict = *dictptr;
  		if (dict == NULL && value != NULL) {
--- 1177,1182 ----
  	}
  
! 	dictptr = _PyObject_GetDictPtr(obj);
! 	if (dictptr != NULL) {
  		PyObject *dict = *dictptr;
  		if (dict == NULL && value != NULL) {