[Python-checkins] python/dist/src/Objects longobject.c,1.128,1.129

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Mon, 12 Aug 2002 12:30:29 -0700


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

Modified Files:
	longobject.c 
Log Message:
k_mul():  White-box testing turned up that (ah+al)*(bh+bl) can, in rare
cases, overflow the allocated result object by 1 bit.  In such cases,
it would have been brought back into range if we subtracted al*bl and
ah*bh from it first, but I don't want to do that because it hurts cache
behavior.  Instead we just ignore the excess bit when it appears -- in
effect, this is forcing unsigned mod BASE**(asize + bsize) arithmetic
in a case where that doesn't happen all by itself.


Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.128
retrieving revision 1.129
diff -C2 -d -r1.128 -r1.129
*** longobject.c	12 Aug 2002 18:25:43 -0000	1.128
--- longobject.c	12 Aug 2002 19:30:26 -0000	1.129
***************
*** 1664,1668 ****
  
  	/* 1. Allocate result space. */
! 	ret = _PyLong_New(asize + bsize);
  	if (ret == NULL) goto fail;
  #ifdef Py_DEBUG
--- 1664,1668 ----
  
  	/* 1. Allocate result space. */
! 	ret = _PyLong_New(asize + bsize + 1);
  	if (ret == NULL) goto fail;
  #ifdef Py_DEBUG
***************
*** 1728,1732 ****
  	if (t3 == NULL) goto fail;
  
! 	/* Add t3. */
  	(void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, t3->ob_size);
  	Py_DECREF(t3);
--- 1728,1740 ----
  	if (t3 == NULL) goto fail;
  
! 	/* Add t3.  Caution:  t3 can spill one bit beyond the allocated
! 	 * result space; it's t3-al*bl-ah*bh that always fits.  We have
! 	 * to arrange to ignore the hight bit.
! 	 */
! 	if (t3->ob_size > i) {
! 		assert(t3->ob_size == i+1);	/* just one digit over */
! 		assert(t3->ob_digit[t3->ob_size - 1] == 1); /* & just one bit */
! 		--t3->ob_size;	/* ignore the overflow bit */
! 	}
  	(void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, t3->ob_size);
  	Py_DECREF(t3);
***************
*** 1762,1766 ****
  	}
  
! #if 0
  	if (Py_GETENV("KARAT") != NULL)
  		z = k_mul(a, b);
--- 1770,1774 ----
  	}
  
! #if 1
  	if (Py_GETENV("KARAT") != NULL)
  		z = k_mul(a, b);