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