[Python-checkins] r68896 - in python/branches/release30-maint: Objects/longobject.c

mark.dickinson python-checkins at python.org
Sat Jan 24 16:59:42 CET 2009


Author: mark.dickinson
Date: Sat Jan 24 16:59:38 2009
New Revision: 68896

Log:
Merged revisions 68895 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/branches/py3k

................
  r68895 | mark.dickinson | 2009-01-24 15:56:57 +0000 (Sat, 24 Jan 2009) | 13 lines
  
  Merged revisions 68890 via svnmerge from 
  svn+ssh://pythondev@svn.python.org/python/trunk
  
  ........
    r68890 | mark.dickinson | 2009-01-24 15:27:44 +0000 (Sat, 24 Jan 2009) | 6 lines
    
    Issue #4393: fix 3 classes of potential portability problems in longobject.c:
     - fix some places where counters into ob_digit were declared as
       int instead of Py_ssize_t
     - add (twodigit) casts where necessary
     - fix code in _PyLong_AsByteArray that uses << on negative values
  ........
................


Modified:
   python/branches/release30-maint/   (props changed)
   python/branches/release30-maint/Objects/longobject.c

Modified: python/branches/release30-maint/Objects/longobject.c
==============================================================================
--- python/branches/release30-maint/Objects/longobject.c	(original)
+++ python/branches/release30-maint/Objects/longobject.c	Sat Jan 24 16:59:38 2009
@@ -739,7 +739,7 @@
 			/* Because we're going LSB to MSB, thisbyte is
 			   more significant than what's already in accum,
 			   so needs to be prepended to accum. */
-			accum |= thisbyte << accumbits;
+			accum |= (twodigits)thisbyte << accumbits;
 			accumbits += 8;
 			if (accumbits >= PyLong_SHIFT) {
 				/* There's enough to fill a Python digit. */
@@ -768,7 +768,7 @@
 		    unsigned char* bytes, size_t n,
 		    int little_endian, int is_signed)
 {
-	int i;			/* index into v->ob_digit */
+	Py_ssize_t i;		/* index into v->ob_digit */
 	Py_ssize_t ndigits;		/* |v->ob_size| */
 	twodigits accum;	/* sliding register */
 	unsigned int accumbits; /* # bits in accum */
@@ -813,7 +813,7 @@
 	accumbits = 0;
 	carry = do_twos_comp ? 1 : 0;
 	for (i = 0; i < ndigits; ++i) {
-		twodigits thisdigit = v->ob_digit[i];
+		digit thisdigit = v->ob_digit[i];
 		if (do_twos_comp) {
 			thisdigit = (thisdigit ^ PyLong_MASK) + carry;
 			carry = thisdigit >> PyLong_SHIFT;
@@ -822,26 +822,23 @@
 		/* Because we're going LSB to MSB, thisdigit is more
 		   significant than what's already in accum, so needs to be
 		   prepended to accum. */
-		accum |= thisdigit << accumbits;
-		accumbits += PyLong_SHIFT;
+		accum |= (twodigits)thisdigit << accumbits;
 
 		/* The most-significant digit may be (probably is) at least
 		   partly empty. */
 		if (i == ndigits - 1) {
 			/* Count # of sign bits -- they needn't be stored,
 			 * although for signed conversion we need later to
-			 * make sure at least one sign bit gets stored.
-			 * First shift conceptual sign bit to real sign bit.
-			 */
-			stwodigits s = (stwodigits)(thisdigit <<
-				(8*sizeof(stwodigits) - PyLong_SHIFT));
-			unsigned int nsignbits = 0;
-			while ((s < 0) == do_twos_comp && nsignbits < PyLong_SHIFT) {
-				++nsignbits;
-				s <<= 1;
+			 * make sure at least one sign bit gets stored. */
+			digit s = do_twos_comp ? thisdigit ^ PyLong_MASK :
+				                thisdigit;
+			while (s != 0) {
+				s >>= 1;
+				accumbits++;
 			}
-			accumbits -= nsignbits;
 		}
+		else
+			accumbits += PyLong_SHIFT;
 
 		/* Store as many bytes as possible. */
 		while (accumbits >= 8) {
@@ -1361,7 +1358,7 @@
 static digit
 v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
 {
-	int i;
+	Py_ssize_t i;
 	digit carry = 0;
 
 	assert(m >= n);
@@ -1387,7 +1384,7 @@
 static digit
 v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
 {
-	int i;
+	Py_ssize_t i;
 	digit borrow = 0;
 
 	assert(m >= n);
@@ -1453,7 +1450,7 @@
 		digit hi;
 		rem = (rem << PyLong_SHIFT) + *--pin;
 		*--pout = hi = (digit)(rem / n);
-		rem -= hi * n;
+		rem -= (twodigits)hi * n;
 	}
 	return (digit)rem;
 }
@@ -1712,11 +1709,11 @@
 	while (--p >= start) {
 		int k = _PyLong_DigitValue[Py_CHARMASK(*p)];
 		assert(k >= 0 && k < base);
-		accum |= (twodigits)(k << bits_in_accum);
+		accum |= (twodigits)k << bits_in_accum;
 		bits_in_accum += bits_per_char;
 		if (bits_in_accum >= PyLong_SHIFT) {
 			*pdigit++ = (digit)(accum & PyLong_MASK);
-			assert(pdigit - z->ob_digit <= (int)n);
+			assert(pdigit - z->ob_digit <= n);
 			accum >>= PyLong_SHIFT;
 			bits_in_accum -= PyLong_SHIFT;
 			assert(bits_in_accum < PyLong_SHIFT);
@@ -1725,7 +1722,7 @@
 	if (bits_in_accum) {
 		assert(bits_in_accum <= PyLong_SHIFT);
 		*pdigit++ = (digit)accum;
-		assert(pdigit - z->ob_digit <= (int)n);
+		assert(pdigit - z->ob_digit <= n);
 	}
 	while (pdigit - z->ob_digit < n)
 		*pdigit++ = 0;
@@ -2120,7 +2117,7 @@
 		digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
 		twodigits q;
 		stwodigits carry = 0;
-		int i;
+		Py_ssize_t i;
 
 		SIGCHECK({
 			Py_DECREF(a);
@@ -2322,7 +2319,7 @@
 {
 	Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
 	PyLongObject *z;
-	int i;
+	Py_ssize_t i;
 	digit carry = 0;
 
 	/* Ensure a is the larger of the two: */


More information about the Python-checkins mailing list