Skip to content

Commit 750c676

Browse files
committed
test
1 parent 401d860 commit 750c676

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

Objects/longobject.c

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ PyLong_FromDouble(double dval)
499499
#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)
500500

501501
static 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)
646665
Py_ssize_t
647666
PyLong_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
697715
PyLong_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
751768
PyLong_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

Comments
 (0)