@@ -499,7 +499,7 @@ PyLong_FromDouble(double dval)
499499#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)
500500
501501static inline unsigned long
502- _unroll_digits (PyLongObject * v , Py_ssize_t * i )
502+ unroll_digits_ulong (PyLongObject * v , Py_ssize_t * i )
503503{
504504 digit * digits = v -> long_value .ob_digit ;
505505 assert (* i >= 2 );
@@ -518,6 +518,26 @@ _unroll_digits(PyLongObject *v, Py_ssize_t *i)
518518 return x ;
519519}
520520
521+ static inline size_t
522+ unroll_digits_size_t (PyLongObject * v , Py_ssize_t * i )
523+ {
524+ digit * digits = v -> long_value .ob_digit ;
525+ assert (* i >= 2 );
526+ /* unroll 1 digit */
527+ -- (* i );
528+ assert (SIZE_MAX >= ((1UL << PyLong_SHIFT ) - 1 ));
529+ size_t x = digits [* i ];
530+
531+ #if ( (SIZE_MAX >> PyLong_SHIFT ) >= ( ( 1 << PyLong_SHIFT ) - 1 ) )
532+ /* unroll another digit */
533+ x <<= PyLong_SHIFT ;
534+ -- (* i );
535+ x |= digits [* i ];
536+ #endif
537+
538+ return x ;
539+ }
540+
521541/* Get a C long int from an int object or any object that has an __index__
522542 method.
523543
@@ -532,7 +552,6 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
532552{
533553 /* This version originally by Tim Peters */
534554 PyLongObject * v ;
535- unsigned long x ;
536555 long res ;
537556 Py_ssize_t i ;
538557 int sign ;
@@ -576,7 +595,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
576595 i = _PyLong_DigitCount (v );
577596 sign = _PyLong_NonCompactSign (v );
578597
579- x = _unroll_digits (v , & i );
598+ unsigned long x = unroll_digits_ulong (v , & i );
580599 while (-- i >= 0 ) {
581600 if (x > (ULONG_MAX >> PyLong_SHIFT )) {
582601 * overflow = sign ;
@@ -646,7 +665,6 @@ PyLong_AsInt(PyObject *obj)
646665Py_ssize_t
647666PyLong_AsSsize_t (PyObject * vv ) {
648667 PyLongObject * v ;
649- size_t x ;
650668 Py_ssize_t i ;
651669 int sign ;
652670
@@ -666,7 +684,7 @@ PyLong_AsSsize_t(PyObject *vv) {
666684 i = _PyLong_DigitCount (v );
667685 sign = _PyLong_NonCompactSign (v );
668686
669- x = _unroll_digits (v , & i );
687+ size_t x = unroll_digits_size_t (v , & i );
670688 while (-- i >= 0 ) {
671689 if (x > SIZE_MAX >> PyLong_SHIFT ) {
672690 goto overflow ;
@@ -697,7 +715,6 @@ unsigned long
697715PyLong_AsUnsignedLong (PyObject * vv )
698716{
699717 PyLongObject * v ;
700- unsigned long x ;
701718 Py_ssize_t i ;
702719
703720 if (vv == NULL ) {
@@ -729,9 +746,9 @@ PyLong_AsUnsignedLong(PyObject *vv)
729746 }
730747 i = _PyLong_DigitCount (v );
731748
732- x = _unroll_digits (v , & i );
749+ unsigned long x = unroll_digits_ulong (v , & i );
733750 while (-- i >= 0 ) {
734- if (x > SIZE_MAX >> PyLong_SHIFT ) {
751+ if (x > ULONG_MAX >> PyLong_SHIFT ) {
735752 goto overflow ;
736753 }
737754 x = (x << PyLong_SHIFT ) | v -> long_value .ob_digit [i ];
@@ -751,7 +768,6 @@ size_t
751768PyLong_AsSize_t (PyObject * vv )
752769{
753770 PyLongObject * v ;
754- size_t x ;
755771 Py_ssize_t i ;
756772
757773 if (vv == NULL ) {
@@ -774,7 +790,7 @@ PyLong_AsSize_t(PyObject *vv)
774790 }
775791 i = _PyLong_DigitCount (v );
776792
777- x = _unroll_digits (v , & i );
793+ size_t x = unroll_digits_size_t (v , & i );
778794 while (-- i >= 0 ) {
779795 if (x > SIZE_MAX >> PyLong_SHIFT ) {
780796 PyErr_SetString (PyExc_OverflowError ,
@@ -793,7 +809,6 @@ static unsigned long
793809_PyLong_AsUnsignedLongMask (PyObject * vv )
794810{
795811 PyLongObject * v ;
796- unsigned long x ;
797812 Py_ssize_t i ;
798813
799814 if (vv == NULL || !PyLong_Check (vv )) {
@@ -810,7 +825,7 @@ _PyLong_AsUnsignedLongMask(PyObject *vv)
810825 }
811826 i = _PyLong_DigitCount (v );
812827 int sign = _PyLong_NonCompactSign (v );
813- x = _unroll_digits (v , & i );
828+ unsigned long x = unroll_digits_ulong (v , & i );
814829 while (-- i >= 0 ) {
815830 x = (x << PyLong_SHIFT ) | v -> long_value .ob_digit [i ];
816831 }
@@ -1611,7 +1626,6 @@ static unsigned long long
16111626_PyLong_AsUnsignedLongLongMask (PyObject * vv )
16121627{
16131628 PyLongObject * v ;
1614- unsigned long long x ;
16151629 Py_ssize_t i ;
16161630 int sign ;
16171631
@@ -1629,7 +1643,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv)
16291643 }
16301644 i = _PyLong_DigitCount (v );
16311645 sign = _PyLong_NonCompactSign (v );
1632- x = _unroll_digits (v , & i );
1646+ unsigned long long x = unroll_digits_ulong (v , & i );
16331647 while (-- i >= 0 ) {
16341648 x = (x << PyLong_SHIFT ) | v -> long_value .ob_digit [i ];
16351649 }
@@ -1675,7 +1689,6 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
16751689{
16761690 /* This version by Tim Peters */
16771691 PyLongObject * v ;
1678- unsigned long long x , prev ;
16791692 long long res ;
16801693 Py_ssize_t i ;
16811694 int sign ;
@@ -1717,15 +1730,14 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
17171730 else {
17181731 i = _PyLong_DigitCount (v );
17191732 sign = _PyLong_NonCompactSign (v );
1720- x = 0 ;
1733+ unsigned long long x = unroll_digits_ulong ( v , & i ) ;
17211734 while (-- i >= 0 ) {
1722- prev = x ;
1723- x = (x << PyLong_SHIFT ) + v -> long_value .ob_digit [i ];
1724- if ((x >> PyLong_SHIFT ) != prev ) {
1735+ if (x > ULLONG_MAX >> PyLong_SHIFT ) {
17251736 * overflow = sign ;
17261737 res = -1 ;
17271738 goto exit ;
17281739 }
1740+ x = (x << PyLong_SHIFT ) + v -> long_value .ob_digit [i ];
17291741 }
17301742 /* Haven't lost any bits, but casting to long requires extra
17311743 * care (see comment above).
0 commit comments