Skip to content

Commit 588490a

Browse files
committed
refactor
1 parent a38cbfb commit 588490a

1 file changed

Lines changed: 29 additions & 42 deletions

File tree

Objects/longobject.c

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
511530
long
512531
PyLong_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;
747740
overflow:
@@ -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

Comments
 (0)