pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/b456cb25a98985bdbce6987a37f01da4e2ed478e

d9af82350aeda.css" /> gh-143050: Add helper _PyLong_InitTag() (#147956) · python/cpython@b456cb2 · GitHub
Skip to content

Commit b456cb2

Browse files
skirpichevvstinner
andauthored
gh-143050: Add helper _PyLong_InitTag() (#147956)
With this we can assume, that _PyLong_SetSignAndDigitCount() and _PyLong_SetDigitCount() operate on non-immortal integers. Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent 4810bed commit b456cb2

File tree

2 files changed

+33
-14
lines changed

2 files changed

+33
-14
lines changed

Include/internal/pycore_long.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,12 @@ _PyLong_IsSmallInt(const PyLongObject *op)
238238
{
239239
assert(PyLong_Check(op));
240240
bool is_small_int = (op->long_value.lv_tag & IMMORTALITY_BIT_MASK) != 0;
241-
assert(PyLong_CheckExact(op) || (!is_small_int));
242-
assert(_Py_IsImmortal(op) || (!is_small_int));
243-
assert((_PyLong_IsCompact(op)
244-
&& _PY_IS_SMALL_INT(_PyLong_CompactValue(op)))
245-
|| (!is_small_int));
241+
if (is_small_int) {
242+
assert(PyLong_CheckExact(op));
243+
assert(_Py_IsImmortal(op));
244+
assert((_PyLong_IsCompact(op)
245+
&& _PY_IS_SMALL_INT(_PyLong_CompactValue(op))));
246+
}
246247
return is_small_int;
247248
}
248249

@@ -285,6 +286,14 @@ _PyLong_SameSign(const PyLongObject *a, const PyLongObject *b)
285286
return (a->long_value.lv_tag & SIGN_MASK) == (b->long_value.lv_tag & SIGN_MASK);
286287
}
287288

289+
/* Initialize the tag of a freshly-allocated int. */
290+
static inline void
291+
_PyLong_InitTag(PyLongObject *op)
292+
{
293+
assert(PyLong_Check(op));
294+
op->long_value.lv_tag = SIGN_ZERO; /* non-immortal zero */
295+
}
296+
288297
#define TAG_FROM_SIGN_AND_SIZE(sign, size) \
289298
((uintptr_t)(1 - (sign)) | ((uintptr_t)(size) << NON_SIZE_BITS))
290299

@@ -294,13 +303,15 @@ _PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size)
294303
assert(size >= 0);
295304
assert(-1 <= sign && sign <= 1);
296305
assert(sign != 0 || size == 0);
306+
assert(!_PyLong_IsSmallInt(op));
297307
op->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(sign, size);
298308
}
299309

300310
static inline void
301311
_PyLong_SetDigitCount(PyLongObject *op, Py_ssize_t size)
302312
{
303313
assert(size >= 0);
314+
assert(!_PyLong_IsSmallInt(op));
304315
op->long_value.lv_tag = (((size_t)size) << NON_SIZE_BITS) | (op->long_value.lv_tag & SIGN_MASK);
305316
}
306317

Objects/longobject.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ long_alloc(Py_ssize_t size)
185185
return NULL;
186186
}
187187
_PyObject_Init((PyObject*)result, &PyLong_Type);
188+
_PyLong_InitTag(result);
188189
}
189190
_PyLong_SetSignAndDigitCount(result, size != 0, size);
190191
/* The digit has to be initialized explicitly to avoid
@@ -258,6 +259,7 @@ _PyLong_FromMedium(sdigit x)
258259
return NULL;
259260
}
260261
_PyObject_Init((PyObject*)v, &PyLong_Type);
262+
_PyLong_InitTag(v);
261263
}
262264
digit abs_x = x < 0 ? -x : x;
263265
_PyLong_SetSignAndDigitCount(v, x<0?-1:1, 1);
@@ -337,6 +339,7 @@ medium_from_stwodigits(stwodigits x)
337339
return PyStackRef_NULL;
338340
}
339341
_PyObject_Init((PyObject*)v, &PyLong_Type);
342+
_PyLong_InitTag(v);
340343
}
341344
digit abs_x = x < 0 ? (digit)(-x) : (digit)x;
342345
_PyLong_SetSignAndDigitCount(v, x<0?-1:1, 1);
@@ -6011,29 +6014,34 @@ static PyObject *
60116014
long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase)
60126015
{
60136016
PyLongObject *tmp, *newobj;
6014-
Py_ssize_t i, n;
6017+
Py_ssize_t size, ndigits;
6018+
int sign;
60156019

60166020
assert(PyType_IsSubtype(type, &PyLong_Type));
60176021
tmp = (PyLongObject *)long_new_impl(&PyLong_Type, x, obase);
60186022
if (tmp == NULL)
60196023
return NULL;
60206024
assert(PyLong_Check(tmp));
6021-
n = _PyLong_DigitCount(tmp);
6025+
size = _PyLong_DigitCount(tmp);
60226026
/* Fast operations for single digit integers (including zero)
60236027
* assume that there is always at least one digit present. */
6024-
if (n == 0) {
6025-
n = 1;
6026-
}
6027-
newobj = (PyLongObject *)type->tp_alloc(type, n);
6028+
ndigits = size ? size : 1;
6029+
newobj = (PyLongObject *)type->tp_alloc(type, ndigits);
60286030
if (newobj == NULL) {
60296031
Py_DECREF(tmp);
60306032
return NULL;
60316033
}
60326034
assert(PyLong_Check(newobj));
6033-
newobj->long_value.lv_tag = tmp->long_value.lv_tag & ~IMMORTALITY_BIT_MASK;
6034-
for (i = 0; i < n; i++) {
6035-
newobj->long_value.ob_digit[i] = tmp->long_value.ob_digit[i];
6035+
if (_PyLong_IsCompact(tmp)) {
6036+
sign = _PyLong_CompactSign(tmp);
6037+
}
6038+
else {
6039+
sign = _PyLong_NonCompactSign(tmp);
60366040
}
6041+
_PyLong_InitTag(newobj);
6042+
_PyLong_SetSignAndDigitCount(newobj, sign, size);
6043+
memcpy(newobj->long_value.ob_digit, tmp->long_value.ob_digit,
6044+
ndigits * sizeof(digit));
60376045
Py_DECREF(tmp);
60386046
return (PyObject *)newobj;
60396047
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy