summaryrefslogtreecommitdiffstats
path: root/Modules/_decimal
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2023-03-22 14:49:51 (GMT)
committerGitHub <noreply@github.com>2023-03-22 14:49:51 (GMT)
commit7559f5fda94ab568a1a910b17683ed81dc3426fb (patch)
treea050bbc075372c6246fe3386560596f2283ae8bb /Modules/_decimal
parent713df2c53489ce8012d0ede10b70950e6b0d8372 (diff)
downloadcpython-7559f5fda94ab568a1a910b17683ed81dc3426fb.zip
cpython-7559f5fda94ab568a1a910b17683ed81dc3426fb.tar.gz
cpython-7559f5fda94ab568a1a910b17683ed81dc3426fb.tar.bz2
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().
Diffstat (limited to 'Modules/_decimal')
-rw-r--r--Modules/_decimal/_decimal.c43
1 files changed, 8 insertions, 35 deletions
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index 5936fba..0e11c87 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -30,6 +30,7 @@
#endif
#include <Python.h>
+#include "pycore_long.h" // _PyLong_IsZero()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "complexobject.h"
#include "mpdecimal.h"
@@ -2146,35 +2147,25 @@ dec_from_long(PyTypeObject *type, PyObject *v,
{
PyObject *dec;
PyLongObject *l = (PyLongObject *)v;
- Py_ssize_t ob_size;
- size_t len;
- uint8_t sign;
dec = PyDecType_New(type);
if (dec == NULL) {
return NULL;
}
- ob_size = Py_SIZE(l);
- if (ob_size == 0) {
+ if (_PyLong_IsZero(l)) {
_dec_settriple(dec, MPD_POS, 0, 0);
return dec;
}
- if (ob_size < 0) {
- len = -ob_size;
- sign = MPD_NEG;
- }
- else {
- len = ob_size;
- sign = MPD_POS;
- }
+ uint8_t sign = _PyLong_IsNegative(l) ? MPD_NEG : MPD_POS;
- if (len == 1) {
- _dec_settriple(dec, sign, *l->long_value.ob_digit, 0);
+ if (_PyLong_IsCompact(l)) {
+ _dec_settriple(dec, sign, l->long_value.ob_digit[0], 0);
mpd_qfinalize(MPD(dec), ctx, status);
return dec;
}
+ size_t len = _PyLong_DigitCount(l);
#if PYLONG_BITS_IN_DIGIT == 30
mpd_qimport_u32(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE,
@@ -3482,7 +3473,6 @@ dec_as_long(PyObject *dec, PyObject *context, int round)
PyLongObject *pylong;
digit *ob_digit;
size_t n;
- Py_ssize_t i;
mpd_t *x;
mpd_context_t workctx;
uint32_t status = 0;
@@ -3536,26 +3526,9 @@ dec_as_long(PyObject *dec, PyObject *context, int round)
}
assert(n > 0);
- pylong = _PyLong_New(n);
- if (pylong == NULL) {
- mpd_free(ob_digit);
- mpd_del(x);
- return NULL;
- }
-
- memcpy(pylong->long_value.ob_digit, ob_digit, n * sizeof(digit));
+ assert(!mpd_iszero(x));
+ pylong = _PyLong_FromDigits(mpd_isnegative(x), n, ob_digit);
mpd_free(ob_digit);
-
- i = n;
- while ((i > 0) && (pylong->long_value.ob_digit[i-1] == 0)) {
- i--;
- }
-
- Py_SET_SIZE(pylong, i);
- if (mpd_isnegative(x) && !mpd_iszero(x)) {
- Py_SET_SIZE(pylong, -i);
- }
-
mpd_del(x);
return (PyObject *) pylong;
}