[Python-checkins] CVS: python/dist/src/Objects abstract.c,2.80,2.81
Guido van Rossum
gvanrossum@users.sourceforge.net
Fri, 28 Sep 2001 18:05:05 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv23611
Modified Files:
abstract.c
Log Message:
The changes to ternary_op could cause a core dump. Fix this, and
rewrite the code a bit to avoid calling the same slot more than once.
Index: abstract.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v
retrieving revision 2.80
retrieving revision 2.81
diff -C2 -d -r2.80 -r2.81
*** abstract.c 2001/09/28 23:49:48 2.80
--- abstract.c 2001/09/29 01:05:03 2.81
***************
*** 395,398 ****
--- 395,400 ----
Calling scheme used for ternary operations:
+ *** In some cases, w.op is called before v.op; see binary_op1. ***
+
v w z Action
-------------------------------------------------------------------
***************
*** 426,485 ****
{
PyNumberMethods *mv, *mw, *mz;
! register PyObject *x = NULL;
! register ternaryfunc *slot;
mv = v->ob_type->tp_as_number;
mw = w->ob_type->tp_as_number;
! if (v->ob_type != w->ob_type && mw && NEW_STYLE_NUMBER(w)) {
! slot = NB_TERNOP(mw, op_slot);
! if (*slot && *slot != *NB_TERNOP(mv, op_slot) &&
! PyType_IsSubtype(w->ob_type, v->ob_type)) {
! x = (*slot)(v, w, z);
! if (x != Py_NotImplemented)
! return x;
! /* Can't do it... fall through */
! Py_DECREF(x);
! }
}
! if (mv != NULL && NEW_STYLE_NUMBER(v)) {
! /* try v.op(v,w,z) */
! slot = NB_TERNOP(mv, op_slot);
! if (*slot) {
! x = (*slot)(v, w, z);
! if (x != Py_NotImplemented)
! return x;
! /* Can't do it... fall through */
! Py_DECREF(x);
! }
! if (v->ob_type == w->ob_type &&
! (z == Py_None || z->ob_type == v->ob_type)) {
! goto ternary_error;
! }
}
! if (mw != NULL && NEW_STYLE_NUMBER(w)) {
! /* try w.op(v,w,z) */
! slot = NB_TERNOP(mw,op_slot);
! if (*slot) {
! x = (*slot)(v, w, z);
! if (x != Py_NotImplemented)
! return x;
! /* Can't do it... fall through */
! Py_DECREF(x);
! }
! if (NEW_STYLE_NUMBER(v) &&
! (z == Py_None || z->ob_type == v->ob_type)) {
! goto ternary_error;
! }
}
mz = z->ob_type->tp_as_number;
if (mz != NULL && NEW_STYLE_NUMBER(z)) {
! /* try: z.op(v,w,z) */
! slot = NB_TERNOP(mz, op_slot);
! if (*slot) {
! x = (*slot)(v, w, z);
if (x != Py_NotImplemented)
return x;
! /* Can't do it... fall through */
! Py_DECREF(x);
}
}
--- 428,475 ----
{
PyNumberMethods *mv, *mw, *mz;
! PyObject *x = NULL;
! ternaryfunc slotv = NULL;
! ternaryfunc slotw = NULL;
! ternaryfunc slotz = NULL;
mv = v->ob_type->tp_as_number;
mw = w->ob_type->tp_as_number;
! if (mv != NULL && NEW_STYLE_NUMBER(v))
! slotv = *NB_TERNOP(mv, op_slot);
! if (w->ob_type != v->ob_type &&
! mv != NULL && NEW_STYLE_NUMBER(w)) {
! slotw = *NB_TERNOP(mw, op_slot);
! if (slotw == slotv)
! slotw = NULL;
}
! if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
! x = slotw(v, w, z);
! if (x != Py_NotImplemented)
! return x;
! Py_DECREF(x); /* can't do it */
! slotw = NULL;
}
! if (slotv) {
! x = slotv(v, w, z);
! if (x != Py_NotImplemented)
! return x;
! Py_DECREF(x); /* can't do it */
! }
! if (slotw) {
! x = slotw(v, w, z);
! if (x != Py_NotImplemented)
! return x;
! Py_DECREF(x); /* can't do it */
}
mz = z->ob_type->tp_as_number;
if (mz != NULL && NEW_STYLE_NUMBER(z)) {
! slotz = *NB_TERNOP(mz, op_slot);
! if (slotz == slotv || slotz == slotw)
! slotz = NULL;
! if (slotz) {
! x = slotz(v, w, z);
if (x != Py_NotImplemented)
return x;
! Py_DECREF(x); /* can't do it */
}
}
***************
*** 499,506 ****
if (z == Py_None) {
if (v->ob_type->tp_as_number) {
! slot = NB_TERNOP(v->ob_type->tp_as_number,
! op_slot);
! if (*slot)
! x = (*slot)(v, w, z);
else
c = -1;
--- 489,496 ----
if (z == Py_None) {
if (v->ob_type->tp_as_number) {
! slotz = *NB_TERNOP(v->ob_type->tp_as_number,
! op_slot);
! if (slotz)
! x = slotz(v, w, z);
else
c = -1;
***************
*** 522,529 ****
if (v1->ob_type->tp_as_number != NULL) {
! slot = NB_TERNOP(v1->ob_type->tp_as_number,
! op_slot);
! if (*slot)
! x = (*slot)(v1, w2, z2);
else
c = -1;
--- 512,519 ----
if (v1->ob_type->tp_as_number != NULL) {
! slotv = *NB_TERNOP(v1->ob_type->tp_as_number,
! op_slot);
! if (slotv)
! x = slotv(v1, w2, z2);
else
c = -1;
***************
*** 545,549 ****
}
- ternary_error:
PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for %s",
op_name);
--- 535,538 ----