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