[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))