[Zodb-checkins] CVS: StandaloneZODB/ExtensionClass/src - ExtensionClass.c:1.52

Jeremy Hylton jeremy@zope.com
Mon, 10 Jun 2002 18:30:47 -0400


Update of /cvs-repository/StandaloneZODB/ExtensionClass/src
In directory cvs.zope.org:/tmp/cvs-serv2892/ExtensionClass/src

Modified Files:
	ExtensionClass.c 
Log Message:
Fix ExtensionClass to work with Python debug builds.

When an object is initialized with null bytes, do not overwrite the
PyObject_HEAD or PyObject_VAR_HEAD, which is initialized by Python
core function, e.g. PyObject_NEW().

New function EC_NewObject() is called for all object creations --
replacing four calls to either PyObject_NEW() or PyObject_NEW_VAR().
The new function initializes all the bytes that ExtensionClass is
resposible for and INCREFs the base class.

In ALLOC_FREE() macro, call _Py_NewReference() for objects allocated
from the free list.


=== StandaloneZODB/ExtensionClass/src/ExtensionClass.c 1.51 => 1.52 ===
       self=free ## T; \
       free ## T=(T*)self->self; \
-      self->ob_refcnt=1; \
+      _Py_NewReference((PyObject *)self); \
+      assert(self->ob_refcnt == 1); \
     } \
   else UNLESS(self = PyObject_NEW(T, & T ## Type)) return NULL;
 
@@ -336,7 +337,29 @@
   return retval;
 }
 
+static PyObject *
+EC_NewObject(PyTypeObject *type, int size)
+{
+    PyObject *inst;
+    int len;
 
+    if (type->tp_itemsize) {
+	inst = PyObject_NEW_VAR(PyObject, type, size);
+	if (inst == NULL)
+	    return NULL;
+	((PyVarObject *)inst)->ob_size = size;
+    } 
+    else {
+	assert(size == 0);
+	inst = PyObject_NEW(PyObject, type);
+	if (inst == NULL)
+	    return NULL;
+    }
+    Py_INCREF(type);
+    len = (type->tp_basicsize + type->tp_itemsize * size) - sizeof(PyObject);
+    memset(((char *)inst) + sizeof(PyObject), 0, len);
+    return inst;
+}
 
 static int
 CMethod_issubclass(PyExtensionClass *sub, PyExtensionClass *type)
@@ -1414,7 +1437,7 @@
 basicnew(PyExtensionClass *self, PyObject *args)
 {
   PyObject *inst=0;
-  typedef struct { PyObject_VAR_HEAD } PyVarObject__;
+  int size = 0;
 
   if (! self->tp_dealloc)
     {
@@ -1430,26 +1453,14 @@
     {
       /* We have a variable-sized object, we need to get it's size */
       PyObject *var_size;
-      int size;
       
       UNLESS(var_size=CCL_getattr(self, py__var_size__, 0)) return NULL;
       UNLESS_ASSIGN(var_size,PyObject_CallObject(var_size,NULL)) return NULL;
       size=PyInt_AsLong(var_size);
       if (PyErr_Occurred()) return NULL;
-      UNLESS(inst=PyObject_NEW_VAR(PyObject,(PyTypeObject *)self, size))
-	return NULL;
-      memset(inst,0,self->tp_basicsize+self->tp_itemsize*size);
-      ((PyVarObject__*)inst)->ob_size=size;
     }
-  else
-    {
-      UNLESS(inst=PyObject_NEW(PyObject,(PyTypeObject *)self)) return NULL;
-      memset(inst,0,self->tp_basicsize);
-    }
-
-  inst->ob_refcnt=1;
-  inst->ob_type=(PyTypeObject *)self;
-  Py_INCREF(self);
+  UNLESS(inst=EC_NewObject((PyTypeObject *)self, size))
+    return NULL;
 
   if (ClassHasInstDict(self))
     UNLESS(INSTANCE_DICT(inst)=PyDict_New()) goto err;
@@ -1990,7 +2001,7 @@
 CCL_call(PyExtensionClass *self, PyObject *arg, PyObject *kw)
 {
   PyObject *inst=0, *init=0, *args=0;
-  typedef struct { PyObject_VAR_HEAD } PyVarObject__;
+  int size = 0;
 
   if (! self->tp_dealloc)
     {
@@ -2003,7 +2014,6 @@
     {
       /* We have a variable-sized object, we need to get it's size */
       PyObject *var_size;
-      int size;
       
       if ((var_size=CCL_getattr(self,py__var_size__, 0)))
 	{
@@ -2032,33 +2042,21 @@
 	      return NULL;
 	    }
 	}
-      UNLESS(inst=PyObject_NEW_VAR(PyObject,(PyTypeObject *)self, size))
-	return NULL;
-      memset(inst,0,self->tp_basicsize+self->tp_itemsize*size);
-      ((PyVarObject__*)inst)->ob_size=size;
-    }
-  else
-    {
-      UNLESS(inst=PyObject_NEW(PyObject,(PyTypeObject *)self)) return NULL;
-      memset(inst,0,self->tp_basicsize);
     }
-
-  inst->ob_refcnt=1;
-  inst->ob_type=(PyTypeObject *)self;
-  Py_INCREF(self);
+  UNLESS(inst=EC_NewObject((PyTypeObject *)self, size)) return NULL;
 
   if (ClassHasInstDict(self))
     UNLESS(INSTANCE_DICT(inst)=PyDict_New()) goto err;
 
-  if ((init=CCL_getattr(self,py__init__,0)))
-    {
-      UNLESS(args=Py_BuildValue("(O)",inst)) goto err;
-      if (arg) UNLESS_ASSIGN(args,PySequence_Concat(args,arg)) goto err;
-      UNLESS_ASSIGN(args,PyEval_CallObjectWithKeywords(init,args,kw)) goto err;
-      Py_DECREF(args);
-      Py_DECREF(init);
-    }
-  else PyErr_Clear();
+   if ((init=CCL_getattr(self,py__init__,0)))
+      {
+       UNLESS(args=Py_BuildValue("(O)",inst)) goto err;
+       if (arg) UNLESS_ASSIGN(args,PySequence_Concat(args,arg)) goto err;
+       UNLESS_ASSIGN(args,PyEval_CallObjectWithKeywords(init,args,kw)) goto err;
+       Py_DECREF(args);
+       Py_DECREF(init);
+      }
+   else PyErr_Clear();
 
   if (self->bases && subclass_watcher &&
      ! PyObject_CallMethod(subclass_watcher,"created","O",inst))