@@ -498,6 +498,26 @@ PyLong_FromDouble(double dval)
498498#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
499499#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)
500500
501+ static inline unsigned long
502+ _unroll_digits (PyLongObject * v , Py_ssize_t * i )
503+ {
504+ digit * digits = v -> long_value .ob_digit ;
505+ assert (* digit_count >= 2 );
506+ /* unroll 1 digit */
507+ -- (* i );
508+ assert (ULONG_MAX >= ((1UL << PyLong_SHIFT ) - 1 ));
509+ unsigned long x = digits [* i ];
510+
511+ #if ((ULONG_MAX >> PyLong_SHIFT )) >= ((1UL << PyLong_SHIFT ) - 1 )
512+ /* unroll another digit */
513+ x <<= PyLong_SHIFT ;
514+ -- (* i );
515+ x |= digits [* i ];
516+ #endif
517+
518+ return x ;
519+ }
520+
501521/* Get a C long int from an int object or any object that has an __index__
502522 method.
503523
@@ -507,7 +527,6 @@ PyLong_FromDouble(double dval)
507527 For other errors (e.g., TypeError), return -1 and set an error condition.
508528 In this case *overflow will be 0.
509529*/
510-
511530long
512531PyLong_AsLongAndOverflow (PyObject * vv , int * overflow )
513532{
@@ -557,21 +576,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
557576 i = _PyLong_DigitCount (v );
558577 sign = _PyLong_NonCompactSign (v );
559578
560- digit * digits = v -> long_value .ob_digit ;
561- assert (i >= 2 );
562- /* unroll 1 digit */
563- -- i ;
564- assert (ULONG_MAX >= ((1UL << PyLong_SHIFT ) - 1 ));
565- x = digits [i ];
566-
567- #if ((ULONG_MAX >> PyLong_SHIFT )) >= ((1UL << PyLong_SHIFT ) - 1 )
568- /* unroll another digit */
569- x <<= PyLong_SHIFT ;
570- -- i ;
571- x |= digits [i ];
572- #endif
573-
574-
579+ x = _unroll_digits (v , & i );
575580 while (-- i >= 0 ) {
576581 if (x > SIZE_MAX >> PyLong_SHIFT ) {
577582 * overflow = sign ;
@@ -661,18 +666,12 @@ PyLong_AsSsize_t(PyObject *vv) {
661666 i = _PyLong_DigitCount (v );
662667 sign = _PyLong_NonCompactSign (v );
663668
664- digit * digits = v -> long_value .ob_digit ;
665- assert (i >= 2 );
666- /* unroll 1 digit */
667- -- i ;
668- assert (ULONG_MAX >= ((1UL << PyLong_SHIFT ) - 1 ));
669- x = digits [i ];
670-
669+ x = _unroll_digits (v , & i );
671670 while (-- i >= 0 ) {
672671 if (x > SIZE_MAX >> PyLong_SHIFT ) {
673672 goto overflow ;
674673 }
675- x = (x << PyLong_SHIFT ) | digits [i ];
674+ x = (x << PyLong_SHIFT ) | v -> long_value . ob_digit [i ];
676675 }
677676 /* Haven't lost any bits, but casting to a signed type requires
678677 * extra care (see comment above).
@@ -730,18 +729,12 @@ PyLong_AsUnsignedLong(PyObject *vv)
730729 }
731730 i = _PyLong_DigitCount (v );
732731
733- digit * digits = v -> long_value .ob_digit ;
734- assert (i >= 2 );
735- /* unroll 1 digit */
736- -- i ;
737- assert (ULONG_MAX >= ((1UL << PyLong_SHIFT ) - 1 ));
738- x = digits [i ];
739-
732+ x = _unroll_digits (v , & i );
740733 while (-- i >= 0 ) {
741734 if (x > SIZE_MAX >> PyLong_SHIFT ) {
742735 goto overflow ;
743736 }
744- x = (x << PyLong_SHIFT ) | digits [i ];
737+ x = (x << PyLong_SHIFT ) | v -> long_value . ob_digit [i ];
745738 }
746739 return x ;
747740overflow :
@@ -781,20 +774,14 @@ PyLong_AsSize_t(PyObject *vv)
781774 }
782775 i = _PyLong_DigitCount (v );
783776
784- digit * digits = v -> long_value .ob_digit ;
785- assert (i >= 2 );
786- /* unroll 1 digit */
787- -- i ;
788- assert (ULONG_MAX >= ((1UL << PyLong_SHIFT ) - 1 ));
789- x = digits [i ];
790-
777+ x = _unroll_digits (v , & i );
791778 while (-- i >= 0 ) {
792779 if (x > SIZE_MAX >> PyLong_SHIFT ) {
793780 PyErr_SetString (PyExc_OverflowError ,
794781 "Python int too large to convert to C size_t" );
795782 return (size_t ) -1 ;
796783 }
797- x = (x << PyLong_SHIFT ) | digits [i ];
784+ x = (x << PyLong_SHIFT ) | v -> long_value . ob_digit [i ];
798785 }
799786 return x ;
800787}
@@ -823,7 +810,7 @@ _PyLong_AsUnsignedLongMask(PyObject *vv)
823810 }
824811 i = _PyLong_DigitCount (v );
825812 int sign = _PyLong_NonCompactSign (v );
826- x = 0 ;
813+ x = _unroll_digits ( v , & i ) ;
827814 while (-- i >= 0 ) {
828815 x = (x << PyLong_SHIFT ) | v -> long_value .ob_digit [i ];
829816 }
@@ -1642,7 +1629,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv)
16421629 }
16431630 i = _PyLong_DigitCount (v );
16441631 sign = _PyLong_NonCompactSign (v );
1645- x = 0 ;
1632+ x = _unroll_digits ( v , & i ) ;
16461633 while (-- i >= 0 ) {
16471634 x = (x << PyLong_SHIFT ) | v -> long_value .ob_digit [i ];
16481635 }
0 commit comments