From c1b1f51cd1632f0b77dacd43092fb44ed5e053a9 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 30 Jan 2023 10:03:04 +0000 Subject: [PATCH] GH-101291: Refactor the `PyLongObject` struct into object header and PyLongValue struct. (GH-101292) --- Include/cpython/longintrepr.h | 9 +- Include/internal/pycore_runtime_init.h | 8 +- ...-01-24-17-13-32.gh-issue-101291.Yr6u_c.rst | 2 + Modules/_decimal/_decimal.c | 10 +- Objects/boolobject.c | 8 +- Objects/listobject.c | 4 +- Objects/longobject.c | 356 +++++++++--------- Python/bltinmodule.c | 4 +- Python/bytecodes.c | 14 +- Python/generated_cases.c.h | 14 +- Python/marshal.c | 10 +- Python/specialize.c | 2 +- Tools/gdb/libpython.py | 2 +- 13 files changed, 226 insertions(+), 217 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-01-24-17-13-32.gh-issue-101291.Yr6u_c.rst diff --git a/Include/cpython/longintrepr.h b/Include/cpython/longintrepr.h index 6d52427508b..810daa83165 100644 --- a/Include/cpython/longintrepr.h +++ b/Include/cpython/longintrepr.h @@ -79,9 +79,14 @@ typedef long stwodigits; /* signed variant of twodigits */ aware that ints abuse ob_size's sign bit. */ -struct _longobject { - PyObject_VAR_HEAD +typedef struct _PyLongValue { + Py_ssize_t ob_size; /* Number of items in variable part */ digit ob_digit[1]; +} _PyLongValue; + +struct _longobject { + PyObject_HEAD + _PyLongValue long_value; }; PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index f10dccc0158..c6a27d076ea 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -149,9 +149,11 @@ extern "C" { #define _PyLong_DIGIT_INIT(val) \ { \ - _PyVarObject_IMMORTAL_INIT(&PyLong_Type, \ - ((val) == 0 ? 0 : ((val) > 0 ? 1 : -1))), \ - .ob_digit = { ((val) >= 0 ? (val) : -(val)) }, \ + .ob_base = _PyObject_IMMORTAL_INIT(&PyLong_Type), \ + .long_value = { \ + ((val) == 0 ? 0 : ((val) > 0 ? 1 : -1)), \ + { ((val) >= 0 ? (val) : -(val)) }, \ + } \ } #define _PyBytes_SIMPLE_INIT(CH, LEN) \ diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-24-17-13-32.gh-issue-101291.Yr6u_c.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-24-17-13-32.gh-issue-101291.Yr6u_c.rst new file mode 100644 index 00000000000..b585ff5a817 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-24-17-13-32.gh-issue-101291.Yr6u_c.rst @@ -0,0 +1,2 @@ +Refactor the ``PyLongObject`` struct into a normal Python object header and +a ``PyLongValue`` struct. diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index bc97615ffb4..5936fbaaf35 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -2171,16 +2171,16 @@ dec_from_long(PyTypeObject *type, PyObject *v, } if (len == 1) { - _dec_settriple(dec, sign, *l->ob_digit, 0); + _dec_settriple(dec, sign, *l->long_value.ob_digit, 0); mpd_qfinalize(MPD(dec), ctx, status); return dec; } #if PYLONG_BITS_IN_DIGIT == 30 - mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, + mpd_qimport_u32(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE, ctx, status); #elif PYLONG_BITS_IN_DIGIT == 15 - mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, + mpd_qimport_u16(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE, ctx, status); #else #error "PYLONG_BITS_IN_DIGIT should be 15 or 30" @@ -3543,11 +3543,11 @@ dec_as_long(PyObject *dec, PyObject *context, int round) return NULL; } - memcpy(pylong->ob_digit, ob_digit, n * sizeof(digit)); + memcpy(pylong->long_value.ob_digit, ob_digit, n * sizeof(digit)); mpd_free(ob_digit); i = n; - while ((i > 0) && (pylong->ob_digit[i-1] == 0)) { + while ((i > 0) && (pylong->long_value.ob_digit[i-1] == 0)) { i--; } diff --git a/Objects/boolobject.c b/Objects/boolobject.c index 18666f88cbd..55b4a4077ab 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -195,11 +195,11 @@ PyTypeObject PyBool_Type = { /* The objects representing bool values False and True */ struct _longobject _Py_FalseStruct = { - PyVarObject_HEAD_INIT(&PyBool_Type, 0) - { 0 } + PyObject_HEAD_INIT(&PyBool_Type) + { 0, { 0 } } }; struct _longobject _Py_TrueStruct = { - PyVarObject_HEAD_INIT(&PyBool_Type, 1) - { 1 } + PyObject_HEAD_INIT(&PyBool_Type) + { 1, { 1 } } }; diff --git a/Objects/listobject.c b/Objects/listobject.c index 6629775604b..ca6b7123113 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2155,8 +2155,8 @@ unsafe_long_compare(PyObject *v, PyObject *w, MergeState *ms) vl = (PyLongObject*)v; wl = (PyLongObject*)w; - v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->ob_digit[0]; - w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->ob_digit[0]; + v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->long_value.ob_digit[0]; + w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->long_value.ob_digit[0]; if (Py_SIZE(vl) < 0) v0 = -v0; diff --git a/Objects/longobject.c b/Objects/longobject.c index 51ac86961c9..65bf15648b0 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -30,7 +30,7 @@ static inline stwodigits medium_value(PyLongObject *x) { assert(IS_MEDIUM_VALUE(x)); - return ((stwodigits)Py_SIZE(x)) * x->ob_digit[0]; + return ((stwodigits)Py_SIZE(x)) * x->long_value.ob_digit[0]; } #define IS_SMALL_INT(ival) (-_PY_NSMALLNEGINTS <= (ival) && (ival) < _PY_NSMALLPOSINTS) @@ -129,7 +129,7 @@ long_normalize(PyLongObject *v) Py_ssize_t j = Py_ABS(Py_SIZE(v)); Py_ssize_t i = j; - while (i > 0 && v->ob_digit[i-1] == 0) + while (i > 0 && v->long_value.ob_digit[i-1] == 0) --i; if (i != j) { Py_SET_SIZE(v, (Py_SIZE(v) < 0) ? -(i) : i); @@ -141,7 +141,7 @@ long_normalize(PyLongObject *v) Return NULL and set exception if we run out of memory. */ #define MAX_LONG_DIGITS \ - ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit)) + ((PY_SSIZE_T_MAX - offsetof(PyLongObject, long_value.ob_digit))/sizeof(digit)) PyLongObject * _PyLong_New(Py_ssize_t size) @@ -160,7 +160,7 @@ _PyLong_New(Py_ssize_t size) sizeof(PyVarObject) instead of the offsetof, but this risks being incorrect in the presence of padding between the PyVarObject header and the digits. */ - result = PyObject_Malloc(offsetof(PyLongObject, ob_digit) + + result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) + ndigits*sizeof(digit)); if (!result) { PyErr_NoMemory(); @@ -190,7 +190,7 @@ _PyLong_Copy(PyLongObject *src) if (result != NULL) { Py_SET_SIZE(result, Py_SIZE(src)); while (--i >= 0) { - result->ob_digit[i] = src->ob_digit[i]; + result->long_value.ob_digit[i] = src->long_value.ob_digit[i]; } } return (PyObject *)result; @@ -210,7 +210,7 @@ _PyLong_FromMedium(sdigit x) Py_ssize_t sign = x < 0 ? -1: 1; digit abs_x = x < 0 ? -x : x; _PyObject_InitVar((PyVarObject*)v, &PyLong_Type, sign); - v->ob_digit[0] = abs_x; + v->long_value.ob_digit[0] = abs_x; return (PyObject*)v; } @@ -241,7 +241,7 @@ _PyLong_FromLarge(stwodigits ival) } PyLongObject *v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; + digit *p = v->long_value.ob_digit; Py_SET_SIZE(v, ndigits * sign); t = abs_ival; while (t) { @@ -285,7 +285,7 @@ _PyLong_AssignValue(PyObject **target, Py_ssize_t value) // Since the primary use-case is iterating over ranges, which // are typically positive, only do this optimization // for positive integers (for now). - ((PyLongObject *)old)->ob_digit[0] = + ((PyLongObject *)old)->long_value.ob_digit[0] = Py_SAFE_DOWNCAST(value, Py_ssize_t, digit); return 0; } @@ -346,7 +346,7 @@ PyLong_FromLong(long ival) /* Construct output value. */ v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; + digit *p = v->long_value.ob_digit; Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); t = abs_ival; while (t) { @@ -373,7 +373,7 @@ PyLong_FromLong(long ival) if (v == NULL) { \ return NULL; \ } \ - digit *p = v->ob_digit; \ + digit *p = v->long_value.ob_digit; \ while ((ival)) { \ *p++ = (digit)((ival) & PyLong_MASK); \ (ival) >>= PyLong_SHIFT; \ @@ -452,7 +452,7 @@ PyLong_FromDouble(double dval) frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1); for (i = ndig; --i >= 0; ) { digit bits = (digit)frac; - v->ob_digit[i] = bits; + v->long_value.ob_digit[i] = bits; frac = frac - (double)bits; frac = ldexp(frac, PyLong_SHIFT); } @@ -516,13 +516,13 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) switch (i) { case -1: - res = -(sdigit)v->ob_digit[0]; + res = -(sdigit)v->long_value.ob_digit[0]; break; case 0: res = 0; break; case 1: - res = v->ob_digit[0]; + res = v->long_value.ob_digit[0]; break; default: sign = 1; @@ -533,7 +533,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *overflow = sign; goto exit; @@ -617,9 +617,9 @@ PyLong_AsSsize_t(PyObject *vv) { v = (PyLongObject *)vv; i = Py_SIZE(v); switch (i) { - case -1: return -(sdigit)v->ob_digit[0]; + case -1: return -(sdigit)v->long_value.ob_digit[0]; case 0: return 0; - case 1: return v->ob_digit[0]; + case 1: return v->long_value.ob_digit[0]; } sign = 1; x = 0; @@ -629,7 +629,7 @@ PyLong_AsSsize_t(PyObject *vv) { } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) goto overflow; } @@ -679,11 +679,11 @@ PyLong_AsUnsignedLong(PyObject *vv) } switch (i) { case 0: return 0; - case 1: return v->ob_digit[0]; + case 1: return v->long_value.ob_digit[0]; } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert " @@ -723,11 +723,11 @@ PyLong_AsSize_t(PyObject *vv) } switch (i) { case 0: return 0; - case 1: return v->ob_digit[0]; + case 1: return v->long_value.ob_digit[0]; } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C size_t"); @@ -756,7 +756,7 @@ _PyLong_AsUnsignedLongMask(PyObject *vv) i = Py_SIZE(v); switch (i) { case 0: return 0; - case 1: return v->ob_digit[0]; + case 1: return v->long_value.ob_digit[0]; } sign = 1; x = 0; @@ -765,7 +765,7 @@ _PyLong_AsUnsignedLongMask(PyObject *vv) i = -i; } while (--i >= 0) { - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; } return x * sign; } @@ -826,9 +826,9 @@ _PyLong_NumBits(PyObject *vv) assert(v != NULL); assert(PyLong_Check(v)); ndigits = Py_ABS(Py_SIZE(v)); - assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + assert(ndigits == 0 || v->long_value.ob_digit[ndigits - 1] != 0); if (ndigits > 0) { - digit msd = v->ob_digit[ndigits - 1]; + digit msd = v->long_value.ob_digit[ndigits - 1]; if ((size_t)(ndigits - 1) > SIZE_MAX / (size_t)PyLong_SHIFT) goto Overflow; result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT; @@ -855,7 +855,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, size_t numsignificantbytes; /* number of bytes that matter */ Py_ssize_t ndigits; /* number of Python int digits */ PyLongObject* v; /* result */ - Py_ssize_t idigit = 0; /* next free index in v->ob_digit */ + Py_ssize_t idigit = 0; /* next free index in v->long_value.ob_digit */ if (n == 0) return PyLong_FromLong(0L); @@ -937,7 +937,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, if (accumbits >= PyLong_SHIFT) { /* There's enough to fill a Python digit. */ assert(idigit < ndigits); - v->ob_digit[idigit] = (digit)(accum & PyLong_MASK); + v->long_value.ob_digit[idigit] = (digit)(accum & PyLong_MASK); ++idigit; accum >>= PyLong_SHIFT; accumbits -= PyLong_SHIFT; @@ -947,7 +947,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, assert(accumbits < PyLong_SHIFT); if (accumbits) { assert(idigit < ndigits); - v->ob_digit[idigit] = (digit)accum; + v->long_value.ob_digit[idigit] = (digit)accum; ++idigit; } } @@ -961,7 +961,7 @@ _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed) { - Py_ssize_t i; /* index into v->ob_digit */ + Py_ssize_t i; /* index into v->long_value.ob_digit */ Py_ssize_t ndigits; /* |v->ob_size| */ twodigits accum; /* sliding register */ unsigned int accumbits; /* # bits in accum */ @@ -1000,13 +1000,13 @@ _PyLong_AsByteArray(PyLongObject* v, It's crucial that every Python digit except for the MSD contribute exactly PyLong_SHIFT bits to the total, so first assert that the int is normalized. */ - assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + assert(ndigits == 0 || v->long_value.ob_digit[ndigits - 1] != 0); j = 0; accum = 0; accumbits = 0; carry = do_twos_comp ? 1 : 0; for (i = 0; i < ndigits; ++i) { - digit thisdigit = v->ob_digit[i]; + digit thisdigit = v->long_value.ob_digit[i]; if (do_twos_comp) { thisdigit = (thisdigit ^ PyLong_MASK) + carry; carry = thisdigit >> PyLong_SHIFT; @@ -1173,7 +1173,7 @@ PyLong_FromLongLong(long long ival) /* Construct output value. */ v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; + digit *p = v->long_value.ob_digit; Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); t = abs_ival; while (t) { @@ -1216,7 +1216,7 @@ PyLong_FromSsize_t(Py_ssize_t ival) } v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; + digit *p = v->long_value.ob_digit; Py_SET_SIZE(v, negative ? -ndigits : ndigits); t = abs_ival; while (t) { @@ -1256,13 +1256,13 @@ PyLong_AsLongLong(PyObject *vv) res = 0; switch(Py_SIZE(v)) { case -1: - bytes = -(sdigit)v->ob_digit[0]; + bytes = -(sdigit)v->long_value.ob_digit[0]; break; case 0: bytes = 0; break; case 1: - bytes = v->ob_digit[0]; + bytes = v->long_value.ob_digit[0]; break; default: res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)&bytes, @@ -1301,7 +1301,7 @@ PyLong_AsUnsignedLongLong(PyObject *vv) v = (PyLongObject*)vv; switch(Py_SIZE(v)) { case 0: return 0; - case 1: return v->ob_digit[0]; + case 1: return v->long_value.ob_digit[0]; } res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, @@ -1332,7 +1332,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) v = (PyLongObject *)vv; switch(Py_SIZE(v)) { case 0: return 0; - case 1: return v->ob_digit[0]; + case 1: return v->long_value.ob_digit[0]; } i = Py_SIZE(v); sign = 1; @@ -1342,7 +1342,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) i = -i; } while (--i >= 0) { - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; } return x * sign; } @@ -1413,13 +1413,13 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) switch (i) { case -1: - res = -(sdigit)v->ob_digit[0]; + res = -(sdigit)v->long_value.ob_digit[0]; break; case 0: res = 0; break; case 1: - res = v->ob_digit[0]; + res = v->long_value.ob_digit[0]; break; default: sign = 1; @@ -1430,7 +1430,7 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) + v->ob_digit[i]; + x = (x << PyLong_SHIFT) + v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *overflow = sign; goto exit; @@ -1701,7 +1701,7 @@ divrem1(PyLongObject *a, digit n, digit *prem) z = _PyLong_New(size); if (z == NULL) return NULL; - *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n); + *prem = inplace_divrem1(z->long_value.ob_digit, a->long_value.ob_digit, size, n); return long_normalize(z); } @@ -1730,7 +1730,7 @@ rem1(PyLongObject *a, digit n) assert(n > 0 && n <= PyLong_MASK); return (PyLongObject *)PyLong_FromLong( - (long)inplace_rem1(a->ob_digit, size, n) + (long)inplace_rem1(a->long_value.ob_digit, size, n) ); } @@ -1880,8 +1880,8 @@ long_to_decimal_string_internal(PyObject *aa, /* convert array of base _PyLong_BASE digits in pin to an array of base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP, Volume 2 (3rd edn), section 4.4, Method 1b). */ - pin = a->ob_digit; - pout = scratch->ob_digit; + pin = a->long_value.ob_digit; + pout = scratch->long_value.ob_digit; size = 0; for (i = size_a; --i >= 0; ) { digit hi = pin[i]; @@ -2086,7 +2086,7 @@ long_format_binary(PyObject *aa, int base, int alternate, return -1; } size_a_in_bits = (size_a - 1) * PyLong_SHIFT + - bit_length_digit(a->ob_digit[size_a - 1]); + bit_length_digit(a->long_value.ob_digit[size_a - 1]); /* Allow 1 character for a '-' sign. */ sz = negative + (size_a_in_bits + (bits - 1)) / bits; } @@ -2123,7 +2123,7 @@ long_format_binary(PyObject *aa, int base, int alternate, int accumbits = 0; /* # of bits in accum */ \ Py_ssize_t i; \ for (i = 0; i < size_a; ++i) { \ - accum |= (twodigits)a->ob_digit[i] << accumbits; \ + accum |= (twodigits)a->long_value.ob_digit[i] << accumbits; \ accumbits += PyLong_SHIFT; \ assert(accumbits >= bits); \ do { \ @@ -2321,7 +2321,7 @@ long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int */ accum = 0; bits_in_accum = 0; - pdigit = z->ob_digit; + pdigit = z->long_value.ob_digit; p = end; while (--p >= start) { int k; @@ -2334,7 +2334,7 @@ long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int bits_in_accum += bits_per_char; if (bits_in_accum >= PyLong_SHIFT) { *pdigit++ = (digit)(accum & PyLong_MASK); - assert(pdigit - z->ob_digit <= n); + assert(pdigit - z->long_value.ob_digit <= n); accum >>= PyLong_SHIFT; bits_in_accum -= PyLong_SHIFT; assert(bits_in_accum < PyLong_SHIFT); @@ -2343,9 +2343,9 @@ long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int if (bits_in_accum) { assert(bits_in_accum <= PyLong_SHIFT); *pdigit++ = (digit)accum; - assert(pdigit - z->ob_digit <= n); + assert(pdigit - z->long_value.ob_digit <= n); } - while (pdigit - z->ob_digit < n) + while (pdigit - z->long_value.ob_digit < n) *pdigit++ = 0; *res = z; return 0; @@ -2512,7 +2512,7 @@ long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits, /* Create an int object that can contain the largest possible * integer with this base and length. Note that there's no - * need to initialize z->ob_digit -- no slot is read up before + * need to initialize z->long_value.ob_digit -- no slot is read up before * being stored into. */ double fsize_z = (double)digits * log_base_BASE[base] + 1.0; @@ -2571,7 +2571,7 @@ long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits, } /* Multiply z by convmult, and add c. */ - pz = z->ob_digit; + pz = z->long_value.ob_digit; pzstop = pz + Py_SIZE(z); for (; pz < pzstop; ++pz) { c += (twodigits)*pz * convmult; @@ -2595,11 +2595,11 @@ long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits, *res = NULL; return 0; } - memcpy(tmp->ob_digit, - z->ob_digit, + memcpy(tmp->long_value.ob_digit, + z->long_value.ob_digit, sizeof(digit) * size_z); Py_SETREF(z, tmp); - z->ob_digit[size_z] = (digit)c; + z->long_value.ob_digit[size_z] = (digit)c; ++size_z; } } @@ -2901,7 +2901,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, } if (size_a < size_b || (size_a == size_b && - a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { + a->long_value.ob_digit[size_a-1] < b->long_value.ob_digit[size_b-1])) { /* |a| < |b|. */ *prem = (PyLongObject *)long_long((PyObject *)a); if (*prem == NULL) { @@ -2913,7 +2913,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, } if (size_b == 1) { digit rem = 0; - z = divrem1(a, b->ob_digit[0], &rem); + z = divrem1(a, b->long_value.ob_digit[0], &rem); if (z == NULL) return -1; *prem = (PyLongObject *) PyLong_FromLong((long)rem); @@ -2965,13 +2965,13 @@ long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) } if (size_a < size_b || (size_a == size_b && - a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { + a->long_value.ob_digit[size_a-1] < b->long_value.ob_digit[size_b-1])) { /* |a| < |b|. */ *prem = (PyLongObject *)long_long((PyObject *)a); return -(*prem == NULL); } if (size_b == 1) { - *prem = rem1(a, b->ob_digit[0]); + *prem = rem1(a, b->long_value.ob_digit[0]); if (*prem == NULL) return -1; } @@ -3031,16 +3031,16 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2. shift v1 left by the same amount. Results go into w and v. */ - d = PyLong_SHIFT - bit_length_digit(w1->ob_digit[size_w-1]); - carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d); + d = PyLong_SHIFT - bit_length_digit(w1->long_value.ob_digit[size_w-1]); + carry = v_lshift(w->long_value.ob_digit, w1->long_value.ob_digit, size_w, d); assert(carry == 0); - carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d); - if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) { - v->ob_digit[size_v] = carry; + carry = v_lshift(v->long_value.ob_digit, v1->long_value.ob_digit, size_v, d); + if (carry != 0 || v->long_value.ob_digit[size_v-1] >= w->long_value.ob_digit[size_w-1]) { + v->long_value.ob_digit[size_v] = carry; size_v++; } - /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has + /* Now v->long_value.ob_digit[size_v-1] < w->long_value.ob_digit[size_w-1], so quotient has at most (and usually exactly) k = size_v - size_w digits. */ k = size_v - size_w; assert(k >= 0); @@ -3051,11 +3051,11 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) *prem = NULL; return NULL; } - v0 = v->ob_digit; - w0 = w->ob_digit; + v0 = v->long_value.ob_digit; + w0 = w->long_value.ob_digit; wm1 = w0[size_w-1]; wm2 = w0[size_w-2]; - for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) { + for (vk = v0+k, ak = a->long_value.ob_digit + k; vk-- > v0;) { /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving single-digit quotient q, remainder in vk[0:size_w]. */ @@ -3160,7 +3160,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) *e = 0; return 0.0; } - a_bits = bit_length_digit(a->ob_digit[a_size-1]); + a_bits = bit_length_digit(a->long_value.ob_digit[a_size-1]); /* The following is an overflow-free version of the check "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */ if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && @@ -3198,7 +3198,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT; shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT; x_size = shift_digits; - rem = v_lshift(x_digits + x_size, a->ob_digit, a_size, + rem = v_lshift(x_digits + x_size, a->long_value.ob_digit, a_size, (int)shift_bits); x_size += a_size; x_digits[x_size++] = rem; @@ -3206,7 +3206,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) else { shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT; shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT; - rem = v_rshift(x_digits, a->ob_digit + shift_digits, + rem = v_rshift(x_digits, a->long_value.ob_digit + shift_digits, a_size - shift_digits, (int)shift_bits); x_size = a_size - shift_digits; /* For correct rounding below, we need the least significant @@ -3217,7 +3217,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) x_digits[0] |= 1; else while (shift_digits > 0) - if (a->ob_digit[--shift_digits]) { + if (a->long_value.ob_digit[--shift_digits]) { x_digits[0] |= 1; break; } @@ -3297,7 +3297,7 @@ long_compare(PyLongObject *a, PyLongObject *b) Py_ssize_t i = Py_ABS(Py_SIZE(a)); sdigit diff = 0; while (--i >= 0) { - diff = (sdigit) a->ob_digit[i] - (sdigit) b->ob_digit[i]; + diff = (sdigit) a->long_value.ob_digit[i] - (sdigit) b->long_value.ob_digit[i]; if (diff) { break; } @@ -3328,9 +3328,9 @@ long_hash(PyLongObject *v) i = Py_SIZE(v); switch(i) { - case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0]; + case -1: return v->long_value.ob_digit[0]==1 ? -2 : -(sdigit)v->long_value.ob_digit[0]; case 0: return 0; - case 1: return v->ob_digit[0]; + case 1: return v->long_value.ob_digit[0]; } sign = 1; x = 0; @@ -3340,7 +3340,7 @@ long_hash(PyLongObject *v) } while (--i >= 0) { /* Here x is a quantity in the range [0, _PyHASH_MODULUS); we - want to compute x * 2**PyLong_SHIFT + v->ob_digit[i] modulo + want to compute x * 2**PyLong_SHIFT + v->long_value.ob_digit[i] modulo _PyHASH_MODULUS. The computation of x * 2**PyLong_SHIFT % _PyHASH_MODULUS @@ -3366,7 +3366,7 @@ long_hash(PyLongObject *v) _PyHASH_MODULUS. */ x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) | (x >> (_PyHASH_BITS - PyLong_SHIFT)); - x += v->ob_digit[i]; + x += v->long_value.ob_digit[i]; if (x >= _PyHASH_MODULUS) x -= _PyHASH_MODULUS; } @@ -3398,16 +3398,16 @@ x_add(PyLongObject *a, PyLongObject *b) if (z == NULL) return NULL; for (i = 0; i < size_b; ++i) { - carry += a->ob_digit[i] + b->ob_digit[i]; - z->ob_digit[i] = carry & PyLong_MASK; + carry += a->long_value.ob_digit[i] + b->long_value.ob_digit[i]; + z->long_value.ob_digit[i] = carry & PyLong_MASK; carry >>= PyLong_SHIFT; } for (; i < size_a; ++i) { - carry += a->ob_digit[i]; - z->ob_digit[i] = carry & PyLong_MASK; + carry += a->long_value.ob_digit[i]; + z->long_value.ob_digit[i] = carry & PyLong_MASK; carry >>= PyLong_SHIFT; } - z->ob_digit[i] = carry; + z->long_value.ob_digit[i] = carry; return long_normalize(z); } @@ -3433,11 +3433,11 @@ x_sub(PyLongObject *a, PyLongObject *b) else if (size_a == size_b) { /* Find highest digit where a and b differ: */ i = size_a; - while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) + while (--i >= 0 && a->long_value.ob_digit[i] == b->long_value.ob_digit[i]) ; if (i < 0) return (PyLongObject *)PyLong_FromLong(0); - if (a->ob_digit[i] < b->ob_digit[i]) { + if (a->long_value.ob_digit[i] < b->long_value.ob_digit[i]) { sign = -1; { PyLongObject *temp = a; a = b; b = temp; } } @@ -3449,14 +3449,14 @@ x_sub(PyLongObject *a, PyLongObject *b) for (i = 0; i < size_b; ++i) { /* The following assumes unsigned arithmetic works module 2**N for some N>PyLong_SHIFT. */ - borrow = a->ob_digit[i] - b->ob_digit[i] - borrow; - z->ob_digit[i] = borrow & PyLong_MASK; + borrow = a->long_value.ob_digit[i] - b->long_value.ob_digit[i] - borrow; + z->long_value.ob_digit[i] = borrow & PyLong_MASK; borrow >>= PyLong_SHIFT; borrow &= 1; /* Keep only one sign bit */ } for (; i < size_a; ++i) { - borrow = a->ob_digit[i] - borrow; - z->ob_digit[i] = borrow & PyLong_MASK; + borrow = a->long_value.ob_digit[i] - borrow; + z->long_value.ob_digit[i] = borrow & PyLong_MASK; borrow >>= PyLong_SHIFT; borrow &= 1; /* Keep only one sign bit */ } @@ -3557,7 +3557,7 @@ x_mul(PyLongObject *a, PyLongObject *b) if (z == NULL) return NULL; - memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit)); + memset(z->long_value.ob_digit, 0, Py_SIZE(z) * sizeof(digit)); if (a == b) { /* Efficient squaring per HAC, Algorithm 14.16: * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf @@ -3565,12 +3565,12 @@ x_mul(PyLongObject *a, PyLongObject *b) * via exploiting that each entry in the multiplication * pyramid appears twice (except for the size_a squares). */ - digit *paend = a->ob_digit + size_a; + digit *paend = a->long_value.ob_digit + size_a; for (i = 0; i < size_a; ++i) { twodigits carry; - twodigits f = a->ob_digit[i]; - digit *pz = z->ob_digit + (i << 1); - digit *pa = a->ob_digit + i + 1; + twodigits f = a->long_value.ob_digit[i]; + digit *pz = z->long_value.ob_digit + (i << 1); + digit *pa = a->long_value.ob_digit + i + 1; SIGCHECK({ Py_DECREF(z); @@ -3619,10 +3619,10 @@ x_mul(PyLongObject *a, PyLongObject *b) else { /* a is not the same as b -- gradeschool int mult */ for (i = 0; i < size_a; ++i) { twodigits carry = 0; - twodigits f = a->ob_digit[i]; - digit *pz = z->ob_digit + i; - digit *pb = b->ob_digit; - digit *pbend = b->ob_digit + size_b; + twodigits f = a->long_value.ob_digit[i]; + digit *pz = z->long_value.ob_digit + i; + digit *pb = b->long_value.ob_digit; + digit *pbend = b->long_value.ob_digit + size_b; SIGCHECK({ Py_DECREF(z); @@ -3670,8 +3670,8 @@ kmul_split(PyLongObject *n, return -1; } - memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit)); - memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit)); + memcpy(lo->long_value.ob_digit, n->long_value.ob_digit, size_lo * sizeof(digit)); + memcpy(hi->long_value.ob_digit, n->long_value.ob_digit + size_lo, size_hi * sizeof(digit)); *high = long_normalize(hi); *low = long_normalize(lo); @@ -3769,20 +3769,20 @@ k_mul(PyLongObject *a, PyLongObject *b) if (ret == NULL) goto fail; #ifdef Py_DEBUG /* Fill with trash, to catch reference to uninitialized digits. */ - memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit)); + memset(ret->long_value.ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit)); #endif /* 2. t1 <- ah*bh, and copy into high digits of result. */ if ((t1 = k_mul(ah, bh)) == NULL) goto fail; assert(Py_SIZE(t1) >= 0); assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret)); - memcpy(ret->ob_digit + 2*shift, t1->ob_digit, + memcpy(ret->long_value.ob_digit + 2*shift, t1->long_value.ob_digit, Py_SIZE(t1) * sizeof(digit)); /* Zero-out the digits higher than the ah*bh copy. */ i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1); if (i) - memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0, + memset(ret->long_value.ob_digit + 2*shift + Py_SIZE(t1), 0, i * sizeof(digit)); /* 3. t2 <- al*bl, and copy into the low digits. */ @@ -3792,21 +3792,21 @@ k_mul(PyLongObject *a, PyLongObject *b) } assert(Py_SIZE(t2) >= 0); assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */ - memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit)); + memcpy(ret->long_value.ob_digit, t2->long_value.ob_digit, Py_SIZE(t2) * sizeof(digit)); /* Zero out remaining digits. */ i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */ if (i) - memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit)); + memset(ret->long_value.ob_digit + Py_SIZE(t2), 0, i * sizeof(digit)); /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first * because it's fresher in cache. */ i = Py_SIZE(ret) - shift; /* # digits after shift */ - (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2)); + (void)v_isub(ret->long_value.ob_digit + shift, i, t2->long_value.ob_digit, Py_SIZE(t2)); _Py_DECREF_INT(t2); - (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1)); + (void)v_isub(ret->long_value.ob_digit + shift, i, t1->long_value.ob_digit, Py_SIZE(t1)); _Py_DECREF_INT(t1); /* 6. t3 <- (ah+al)(bh+bl), and add into result. */ @@ -3835,7 +3835,7 @@ k_mul(PyLongObject *a, PyLongObject *b) /* Add t3. It's not obvious why we can't run out of room here. * See the (*) comment after this function. */ - (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3)); + (void)v_iadd(ret->long_value.ob_digit + shift, i, t3->long_value.ob_digit, Py_SIZE(t3)); _Py_DECREF_INT(t3); return long_normalize(ret); @@ -3918,7 +3918,7 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) ret = _PyLong_New(asize + bsize); if (ret == NULL) return NULL; - memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit)); + memset(ret->long_value.ob_digit, 0, Py_SIZE(ret) * sizeof(digit)); /* Successive slices of b are copied into bslice. */ bslice = _PyLong_New(asize); @@ -3931,7 +3931,7 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) const Py_ssize_t nbtouse = Py_MIN(bsize, asize); /* Multiply the next slice of b by a. */ - memcpy(bslice->ob_digit, b->ob_digit + nbdone, + memcpy(bslice->long_value.ob_digit, b->long_value.ob_digit + nbdone, nbtouse * sizeof(digit)); Py_SET_SIZE(bslice, nbtouse); product = k_mul(a, bslice); @@ -3939,8 +3939,8 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) goto fail; /* Add into result. */ - (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone, - product->ob_digit, Py_SIZE(product)); + (void)v_iadd(ret->long_value.ob_digit + nbdone, Py_SIZE(ret) - nbdone, + product->long_value.ob_digit, Py_SIZE(product)); _Py_DECREF_INT(product); bsize -= nbtouse; @@ -3988,8 +3988,8 @@ long_mul(PyLongObject *a, PyLongObject *b) static PyObject * fast_mod(PyLongObject *a, PyLongObject *b) { - sdigit left = a->ob_digit[0]; - sdigit right = b->ob_digit[0]; + sdigit left = a->long_value.ob_digit[0]; + sdigit right = b->long_value.ob_digit[0]; sdigit mod; assert(Py_ABS(Py_SIZE(a)) == 1); @@ -4011,8 +4011,8 @@ fast_mod(PyLongObject *a, PyLongObject *b) static PyObject * fast_floor_div(PyLongObject *a, PyLongObject *b) { - sdigit left = a->ob_digit[0]; - sdigit right = b->ob_digit[0]; + sdigit left = a->long_value.ob_digit[0]; + sdigit right = b->long_value.ob_digit[0]; sdigit div; assert(Py_ABS(Py_SIZE(a)) == 1); @@ -4334,18 +4334,18 @@ long_true_divide(PyObject *v, PyObject *w) the x87 FPU set to 64-bit precision. */ a_is_small = a_size <= MANT_DIG_DIGITS || (a_size == MANT_DIG_DIGITS+1 && - a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + a->long_value.ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); b_is_small = b_size <= MANT_DIG_DIGITS || (b_size == MANT_DIG_DIGITS+1 && - b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + b->long_value.ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); if (a_is_small && b_is_small) { double da, db; - da = a->ob_digit[--a_size]; + da = a->long_value.ob_digit[--a_size]; while (a_size > 0) - da = da * PyLong_BASE + a->ob_digit[--a_size]; - db = b->ob_digit[--b_size]; + da = da * PyLong_BASE + a->long_value.ob_digit[--a_size]; + db = b->long_value.ob_digit[--b_size]; while (b_size > 0) - db = db * PyLong_BASE + b->ob_digit[--b_size]; + db = db * PyLong_BASE + b->long_value.ob_digit[--b_size]; result = da / db; goto success; } @@ -4359,8 +4359,8 @@ long_true_divide(PyObject *v, PyObject *w) /* Extreme underflow */ goto underflow_or_zero; /* Next line is now safe from overflowing a Py_ssize_t */ - diff = diff * PyLong_SHIFT + bit_length_digit(a->ob_digit[a_size - 1]) - - bit_length_digit(b->ob_digit[b_size - 1]); + diff = diff * PyLong_SHIFT + bit_length_digit(a->long_value.ob_digit[a_size - 1]) - + bit_length_digit(b->long_value.ob_digit[b_size - 1]); /* Now diff = a_bits - b_bits. */ if (diff > DBL_MAX_EXP) goto overflow; @@ -4389,10 +4389,10 @@ long_true_divide(PyObject *v, PyObject *w) if (x == NULL) goto error; for (i = 0; i < shift_digits; i++) - x->ob_digit[i] = 0; - rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, + x->long_value.ob_digit[i] = 0; + rem = v_lshift(x->long_value.ob_digit + shift_digits, a->long_value.ob_digit, a_size, -shift % PyLong_SHIFT); - x->ob_digit[a_size + shift_digits] = rem; + x->long_value.ob_digit[a_size + shift_digits] = rem; } else { Py_ssize_t shift_digits = shift / PyLong_SHIFT; @@ -4402,13 +4402,13 @@ long_true_divide(PyObject *v, PyObject *w) x = _PyLong_New(a_size - shift_digits); if (x == NULL) goto error; - rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, + rem = v_rshift(x->long_value.ob_digit, a->long_value.ob_digit + shift_digits, a_size - shift_digits, shift % PyLong_SHIFT); /* set inexact if any of the bits shifted out is nonzero */ if (rem) inexact = 1; while (!inexact && shift_digits > 0) - if (a->ob_digit[--shift_digits]) + if (a->long_value.ob_digit[--shift_digits]) inexact = 1; } long_normalize(x); @@ -4417,8 +4417,8 @@ long_true_divide(PyObject *v, PyObject *w) /* x //= b. If the remainder is nonzero, set inexact. We own the only reference to x, so it's safe to modify it in-place. */ if (b_size == 1) { - digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, - b->ob_digit[0]); + digit rem = inplace_divrem1(x->long_value.ob_digit, x->long_value.ob_digit, x_size, + b->long_value.ob_digit[0]); long_normalize(x); if (rem) inexact = 1; @@ -4435,7 +4435,7 @@ long_true_divide(PyObject *v, PyObject *w) } x_size = Py_ABS(Py_SIZE(x)); assert(x_size > 0); /* result of division is never zero */ - x_bits = (x_size-1)*PyLong_SHIFT+bit_length_digit(x->ob_digit[x_size-1]); + x_bits = (x_size-1)*PyLong_SHIFT+bit_length_digit(x->long_value.ob_digit[x_size-1]); /* The number of extra bits that have to be rounded away. */ extra_bits = Py_MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; @@ -4443,15 +4443,15 @@ long_true_divide(PyObject *v, PyObject *w) /* Round by directly modifying the low digit of x. */ mask = (digit)1 << (extra_bits - 1); - low = x->ob_digit[0] | inexact; + low = x->long_value.ob_digit[0] | inexact; if ((low & mask) && (low & (3U*mask-1U))) low += mask; - x->ob_digit[0] = low & ~(2U*mask-1U); + x->long_value.ob_digit[0] = low & ~(2U*mask-1U); /* Convert x to a double dx; the conversion is exact. */ - dx = x->ob_digit[--x_size]; + dx = x->long_value.ob_digit[--x_size]; while (x_size > 0) - dx = dx * PyLong_BASE + x->ob_digit[--x_size]; + dx = dx * PyLong_BASE + x->long_value.ob_digit[--x_size]; Py_DECREF(x); /* Check whether ldexp result will overflow a double. */ @@ -4672,7 +4672,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* if modulus == 1: return 0 */ - if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) { + if ((Py_SIZE(c) == 1) && (c->long_value.ob_digit[0] == 1)) { z = (PyLongObject *)PyLong_FromLong(0L); goto Done; } @@ -4748,7 +4748,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) } while(0) i = Py_SIZE(b); - digit bi = i ? b->ob_digit[i-1] : 0; + digit bi = i ? b->long_value.ob_digit[i-1] : 0; digit bit; if (i <= 1 && bi <= 3) { /* aim for minimal overhead */ @@ -4794,7 +4794,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) if (--i < 0) { break; } - bi = b->ob_digit[i]; + bi = b->long_value.ob_digit[i]; bit = (digit)1 << (PyLong_SHIFT-1); } } @@ -4840,7 +4840,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) } while(0) for (i = Py_SIZE(b) - 1; i >= 0; --i) { - const digit bi = b->ob_digit[i]; + const digit bi = b->long_value.ob_digit[i]; for (j = PyLong_SHIFT - 1; j >= 0; --j) { const int bit = (bi >> j) & 1; pending = (pending << 1) | bit; @@ -5011,7 +5011,7 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) } hishift = PyLong_SHIFT - remshift; - accum = a->ob_digit[wordshift]; + accum = a->long_value.ob_digit[wordshift]; if (a_negative) { /* For a positive integer a and nonnegative shift, we have: @@ -5028,19 +5028,19 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) digit sticky = 0; for (Py_ssize_t j = 0; j < wordshift; j++) { - sticky |= a->ob_digit[j]; + sticky |= a->long_value.ob_digit[j]; } accum += (PyLong_MASK >> hishift) + (digit)(sticky != 0); } accum >>= remshift; for (Py_ssize_t i = 0, j = wordshift + 1; j < size_a; i++, j++) { - accum += (twodigits)a->ob_digit[j] << hishift; - z->ob_digit[i] = (digit)(accum & PyLong_MASK); + accum += (twodigits)a->long_value.ob_digit[j] << hishift; + z->long_value.ob_digit[i] = (digit)(accum & PyLong_MASK); accum >>= PyLong_SHIFT; } assert(accum <= PyLong_MASK); - z->ob_digit[newsize - 1] = (digit)accum; + z->long_value.ob_digit[newsize - 1] = (digit)accum; z = maybe_small_long(long_normalize(z)); return (PyObject *)z; @@ -5108,15 +5108,15 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) Py_SET_SIZE(z, -Py_SIZE(z)); } for (i = 0; i < wordshift; i++) - z->ob_digit[i] = 0; + z->long_value.ob_digit[i] = 0; accum = 0; for (j = 0; j < oldsize; i++, j++) { - accum |= (twodigits)a->ob_digit[j] << remshift; - z->ob_digit[i] = (digit)(accum & PyLong_MASK); + accum |= (twodigits)a->long_value.ob_digit[j] << remshift; + z->long_value.ob_digit[i] = (digit)(accum & PyLong_MASK); accum >>= PyLong_SHIFT; } if (remshift) - z->ob_digit[newsize-1] = (digit)accum; + z->long_value.ob_digit[newsize-1] = (digit)accum; else assert(!accum); z = long_normalize(z); @@ -5199,7 +5199,7 @@ long_bitwise(PyLongObject *a, z = _PyLong_New(size_a); if (z == NULL) return NULL; - v_complement(z->ob_digit, a->ob_digit, size_a); + v_complement(z->long_value.ob_digit, a->long_value.ob_digit, size_a); a = z; } else @@ -5215,7 +5215,7 @@ long_bitwise(PyLongObject *a, Py_DECREF(a); return NULL; } - v_complement(z->ob_digit, b->ob_digit, size_b); + v_complement(z->long_value.ob_digit, b->long_value.ob_digit, size_b); b = z; } else @@ -5265,15 +5265,15 @@ long_bitwise(PyLongObject *a, switch(op) { case '&': for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i]; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] & b->long_value.ob_digit[i]; break; case '|': for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i]; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] | b->long_value.ob_digit[i]; break; case '^': for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i]; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] ^ b->long_value.ob_digit[i]; break; default: Py_UNREACHABLE(); @@ -5282,16 +5282,16 @@ long_bitwise(PyLongObject *a, /* Copy any remaining digits of a, inverting if necessary. */ if (op == '^' && negb) for (; i < size_z; ++i) - z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] ^ PyLong_MASK; else if (i < size_z) - memcpy(&z->ob_digit[i], &a->ob_digit[i], + memcpy(&z->long_value.ob_digit[i], &a->long_value.ob_digit[i], (size_z-i)*sizeof(digit)); /* Complement result if negative. */ if (negz) { Py_SET_SIZE(z, -(Py_SIZE(z))); - z->ob_digit[size_z] = PyLong_MASK; - v_complement(z->ob_digit, z->ob_digit, size_z+1); + z->long_value.ob_digit[size_z] = PyLong_MASK; + v_complement(z->long_value.ob_digit, z->long_value.ob_digit, size_z+1); } Py_DECREF(a); @@ -5386,7 +5386,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) alloc_b = Py_SIZE(b); /* reduce until a fits into 2 digits */ while ((size_a = Py_SIZE(a)) > 2) { - nbits = bit_length_digit(a->ob_digit[size_a-1]); + nbits = bit_length_digit(a->long_value.ob_digit[size_a-1]); /* extract top 2*PyLong_SHIFT bits of a into x, along with corresponding bits of b into y */ size_b = Py_SIZE(b); @@ -5403,13 +5403,13 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) Py_XDECREF(d); return (PyObject *)r; } - x = (((twodigits)a->ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits)) | - ((twodigits)a->ob_digit[size_a-2] << (PyLong_SHIFT-nbits)) | - (a->ob_digit[size_a-3] >> nbits)); + x = (((twodigits)a->long_value.ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits)) | + ((twodigits)a->long_value.ob_digit[size_a-2] << (PyLong_SHIFT-nbits)) | + (a->long_value.ob_digit[size_a-3] >> nbits)); - y = ((size_b >= size_a - 2 ? b->ob_digit[size_a-3] >> nbits : 0) | - (size_b >= size_a - 1 ? (twodigits)b->ob_digit[size_a-2] << (PyLong_SHIFT-nbits) : 0) | - (size_b >= size_a ? (twodigits)b->ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits) : 0)); + y = ((size_b >= size_a - 2 ? b->long_value.ob_digit[size_a-3] >> nbits : 0) | + (size_b >= size_a - 1 ? (twodigits)b->long_value.ob_digit[size_a-2] << (PyLong_SHIFT-nbits) : 0) | + (size_b >= size_a ? (twodigits)b->long_value.ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits) : 0)); /* inner loop of Lehmer's algorithm; A, B, C, D never grow larger than PyLong_MASK during the algorithm. */ @@ -5471,14 +5471,14 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) if (d == NULL) goto error; } - a_end = a->ob_digit + size_a; - b_end = b->ob_digit + size_b; + a_end = a->long_value.ob_digit + size_a; + b_end = b->long_value.ob_digit + size_b; /* compute new a and new b in parallel */ - a_digit = a->ob_digit; - b_digit = b->ob_digit; - c_digit = c->ob_digit; - d_digit = d->ob_digit; + a_digit = a->long_value.ob_digit; + b_digit = b->long_value.ob_digit; + c_digit = c->long_value.ob_digit; + d_digit = d->long_value.ob_digit; c_carry = 0; d_carry = 0; while (b_digit < b_end) { @@ -5651,7 +5651,7 @@ long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) assert(PyLong_Check(newobj)); Py_SET_SIZE(newobj, Py_SIZE(tmp)); for (i = 0; i < n; i++) { - newobj->ob_digit[i] = tmp->ob_digit[i]; + newobj->long_value.ob_digit[i] = tmp->long_value.ob_digit[i]; } Py_DECREF(tmp); return (PyObject *)newobj; @@ -5763,7 +5763,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b); Py_DECREF(twice_rem); - quo_is_odd = Py_SIZE(quo) != 0 && ((quo->ob_digit[0] & 1) != 0); + quo_is_odd = Py_SIZE(quo) != 0 && ((quo->long_value.ob_digit[0] & 1) != 0); if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { /* fix up quotient */ if (quo_is_neg) @@ -5884,7 +5884,7 @@ int___sizeof___impl(PyObject *self) { Py_ssize_t res; - res = offsetof(PyLongObject, ob_digit) + res = offsetof(PyLongObject, long_value.ob_digit) /* using Py_MAX(..., 1) because we always allocate space for at least one digit, even though the integer zero has a Py_SIZE of 0 */ + Py_MAX(Py_ABS(Py_SIZE(self)), 1)*sizeof(digit); @@ -5918,7 +5918,7 @@ int_bit_length_impl(PyObject *self) if (ndigits == 0) return PyLong_FromLong(0); - msd = ((PyLongObject *)self)->ob_digit[ndigits-1]; + msd = ((PyLongObject *)self)->long_value.ob_digit[ndigits-1]; msd_bits = bit_length_digit(msd); if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) @@ -5991,7 +5991,7 @@ int_bit_count_impl(PyObject *self) Py_ssize_t. */ Py_ssize_t ndigits_fast = Py_MIN(ndigits, PY_SSIZE_T_MAX/PyLong_SHIFT); for (Py_ssize_t i = 0; i < ndigits_fast; i++) { - bit_count += popcount_digit(z->ob_digit[i]); + bit_count += popcount_digit(z->long_value.ob_digit[i]); } PyObject *result = PyLong_FromSsize_t(bit_count); @@ -6001,7 +6001,7 @@ int_bit_count_impl(PyObject *self) /* Use Python integers if bit_count would overflow. */ for (Py_ssize_t i = ndigits_fast; i < ndigits; i++) { - PyObject *x = PyLong_FromLong(popcount_digit(z->ob_digit[i])); + PyObject *x = PyLong_FromLong(popcount_digit(z->long_value.ob_digit[i])); if (x == NULL) { goto error; } @@ -6287,7 +6287,7 @@ static PyNumberMethods long_as_number = { PyTypeObject PyLong_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "int", /* tp_name */ - offsetof(PyLongObject, ob_digit), /* tp_basicsize */ + offsetof(PyLongObject, long_value.ob_digit), /* tp_basicsize */ sizeof(digit), /* tp_itemsize */ 0, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index f97dd67269a..53439ab1604 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2507,10 +2507,10 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) overflow = 0; /* Single digits are common, fast, and cannot overflow on unpacking. */ switch (Py_SIZE(item)) { - case -1: b = -(sdigit) ((PyLongObject*)item)->ob_digit[0]; break; + case -1: b = -(sdigit) ((PyLongObject*)item)->long_value.ob_digit[0]; break; // Note: the continue goes to the top of the "while" loop that iterates over the elements case 0: Py_DECREF(item); continue; - case 1: b = ((PyLongObject*)item)->ob_digit[0]; break; + case 1: b = ((PyLongObject*)item)->long_value.ob_digit[0]; break; default: b = PyLong_AsLongAndOverflow(item, &overflow); break; } if (overflow == 0 && diff --git a/Python/bytecodes.c b/Python/bytecodes.c index fb00b887732..d1e59f7908b 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -357,8 +357,8 @@ dummy_func( // Deopt unless 0 <= sub < PyList_Size(list) DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR); - assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + assert(((PyLongObject *)_PyLong_GetZero())->long_value.ob_digit[0] == 0); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); STAT_INC(BINARY_SUBSCR, hit); res = PyList_GET_ITEM(list, index); @@ -375,8 +375,8 @@ dummy_func( // Deopt unless 0 <= sub < PyTuple_Size(list) DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR); - assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + assert(((PyLongObject *)_PyLong_GetZero())->long_value.ob_digit[0] == 0); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); STAT_INC(BINARY_SUBSCR, hit); res = PyTuple_GET_ITEM(tuple, index); @@ -469,7 +469,7 @@ dummy_func( // Ensure nonnegative, zero-or-one-digit ints. DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; // Ensure index < len(list) DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); STAT_INC(STORE_SUBSCR, hit); @@ -1834,8 +1834,8 @@ dummy_func( DEOPT_IF((size_t)(Py_SIZE(right) + 1) > 2, COMPARE_AND_BRANCH); STAT_INC(COMPARE_AND_BRANCH, hit); assert(Py_ABS(Py_SIZE(left)) <= 1 && Py_ABS(Py_SIZE(right)) <= 1); - Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->ob_digit[0]; - Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->ob_digit[0]; + Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->long_value.ob_digit[0]; + Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->long_value.ob_digit[0]; // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg int sign_ish = COMPARISON_BIT(ileft, iright); _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index b5decf804ca..3ee30ae8df9 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -484,8 +484,8 @@ // Deopt unless 0 <= sub < PyList_Size(list) DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR); - assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + assert(((PyLongObject *)_PyLong_GetZero())->long_value.ob_digit[0] == 0); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); STAT_INC(BINARY_SUBSCR, hit); res = PyList_GET_ITEM(list, index); @@ -509,8 +509,8 @@ // Deopt unless 0 <= sub < PyTuple_Size(list) DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR); - assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + assert(((PyLongObject *)_PyLong_GetZero())->long_value.ob_digit[0] == 0); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); STAT_INC(BINARY_SUBSCR, hit); res = PyTuple_GET_ITEM(tuple, index); @@ -634,7 +634,7 @@ // Ensure nonnegative, zero-or-one-digit ints. DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; // Ensure index < len(list) DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); STAT_INC(STORE_SUBSCR, hit); @@ -2179,8 +2179,8 @@ DEOPT_IF((size_t)(Py_SIZE(right) + 1) > 2, COMPARE_AND_BRANCH); STAT_INC(COMPARE_AND_BRANCH, hit); assert(Py_ABS(Py_SIZE(left)) <= 1 && Py_ABS(Py_SIZE(right)) <= 1); - Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->ob_digit[0]; - Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->ob_digit[0]; + Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->long_value.ob_digit[0]; + Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->long_value.ob_digit[0]; // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg int sign_ish = COMPARISON_BIT(ileft, iright); _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); diff --git a/Python/marshal.c b/Python/marshal.c index 5f392d9e1ec..94e79d4392a 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -240,7 +240,7 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) /* set l to number of base PyLong_MARSHAL_BASE digits */ n = Py_ABS(Py_SIZE(ob)); l = (n-1) * PyLong_MARSHAL_RATIO; - d = ob->ob_digit[n-1]; + d = ob->long_value.ob_digit[n-1]; assert(d != 0); /* a PyLong is always normalized */ do { d >>= PyLong_MARSHAL_SHIFT; @@ -254,14 +254,14 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p); for (i=0; i < n-1; i++) { - d = ob->ob_digit[i]; + d = ob->long_value.ob_digit[i]; for (j=0; j < PyLong_MARSHAL_RATIO; j++) { w_short(d & PyLong_MARSHAL_MASK, p); d >>= PyLong_MARSHAL_SHIFT; } assert (d == 0); } - d = ob->ob_digit[n-1]; + d = ob->long_value.ob_digit[n-1]; do { w_short(d & PyLong_MARSHAL_MASK, p); d >>= PyLong_MARSHAL_SHIFT; @@ -853,7 +853,7 @@ r_PyLong(RFILE *p) goto bad_digit; d += (digit)md << j*PyLong_MARSHAL_SHIFT; } - ob->ob_digit[i] = d; + ob->long_value.ob_digit[i] = d; } d = 0; @@ -880,7 +880,7 @@ r_PyLong(RFILE *p) } /* top digit should be nonzero, else the resulting PyLong won't be normalized */ - ob->ob_digit[size-1] = d; + ob->long_value.ob_digit[size-1] = d; return (PyObject *)ob; bad_digit: Py_DECREF(ob); diff --git a/Python/specialize.c b/Python/specialize.c index 84784b2d149..096687f5fdf 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1411,7 +1411,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { if ((Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) - && ((PyLongObject *)sub)->ob_digit[0] < (size_t)PyList_GET_SIZE(container)) + && ((PyLongObject *)sub)->long_value.ob_digit[0] < (size_t)PyList_GET_SIZE(container)) { _py_set_opcode(instr, STORE_SUBSCR_LIST_INT); goto success; diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 6453dff95df..56d6970b292 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -901,7 +901,7 @@ class PyLongObjectPtr(PyObjectPtr): if ob_size == 0: return 0 - ob_digit = self.field('ob_digit') + ob_digit = self.field('long_value')['ob_digit'] if gdb.lookup_type('digit').sizeof == 2: SHIFT = 15