GH-101291: Rearrange the size bits in PyLongObject (GH-102464)

* Eliminate all remaining uses of Py_SIZE and Py_SET_SIZE on PyLongObject, adding asserts.

* Change layout of size/sign bits in longobject to support future addition of immortal ints and tagged medium ints.

* Add functions to hide some internals of long object, and for setting sign and digit count.

* Replace uses of IS_MEDIUM_VALUE macro with _PyLong_IsCompact().
This commit is contained in:
Mark Shannon 2023-03-22 14:49:51 +00:00 committed by GitHub
parent 713df2c534
commit 7559f5fda9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 982 additions and 898 deletions

View file

@ -836,7 +836,7 @@ long_lcm(PyObject *a, PyObject *b)
{
PyObject *g, *m, *f, *ab;
if (Py_SIZE(a) == 0 || Py_SIZE(b) == 0) {
if (_PyLong_IsZero((PyLongObject *)a) || _PyLong_IsZero((PyLongObject *)b)) {
return PyLong_FromLong(0);
}
g = _PyLong_GCD(a, b);
@ -1726,13 +1726,13 @@ math_isqrt(PyObject *module, PyObject *n)
return NULL;
}
if (_PyLong_Sign(n) < 0) {
if (_PyLong_IsNegative((PyLongObject *)n)) {
PyErr_SetString(
PyExc_ValueError,
"isqrt() argument must be nonnegative");
goto error;
}
if (_PyLong_Sign(n) == 0) {
if (_PyLong_IsZero((PyLongObject *)n)) {
Py_DECREF(n);
return PyLong_FromLong(0);
}
@ -2254,7 +2254,7 @@ loghelper(PyObject* arg, double (*func)(double))
Py_ssize_t e;
/* Negative or zero inputs give a ValueError. */
if (Py_SIZE(arg) <= 0) {
if (!_PyLong_IsPositive((PyLongObject *)arg)) {
PyErr_SetString(PyExc_ValueError,
"math domain error");
return NULL;
@ -3716,12 +3716,12 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k)
}
assert(PyLong_CheckExact(n) && PyLong_CheckExact(k));
if (Py_SIZE(n) < 0) {
if (_PyLong_IsNegative((PyLongObject *)n)) {
PyErr_SetString(PyExc_ValueError,
"n must be a non-negative integer");
goto error;
}
if (Py_SIZE(k) < 0) {
if (_PyLong_IsNegative((PyLongObject *)k)) {
PyErr_SetString(PyExc_ValueError,
"k must be a non-negative integer");
goto error;
@ -3808,12 +3808,12 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k)
}
assert(PyLong_CheckExact(n) && PyLong_CheckExact(k));
if (Py_SIZE(n) < 0) {
if (_PyLong_IsNegative((PyLongObject *)n)) {
PyErr_SetString(PyExc_ValueError,
"n must be a non-negative integer");
goto error;
}
if (Py_SIZE(k) < 0) {
if (_PyLong_IsNegative((PyLongObject *)k)) {
PyErr_SetString(PyExc_ValueError,
"k must be a non-negative integer");
goto error;
@ -3845,7 +3845,8 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k)
if (temp == NULL) {
goto error;
}
if (Py_SIZE(temp) < 0) {
assert(PyLong_Check(temp));
if (_PyLong_IsNegative((PyLongObject *)temp)) {
Py_DECREF(temp);
result = PyLong_FromLong(0);
goto done;