Skip to content

Commit 413e56d

Browse files
committed
_long_is_small_int() -> _PyLong_IsImmortal() helper
1 parent 20e79c6 commit 413e56d

File tree

3 files changed

+16
-15
lines changed

3 files changed

+16
-15
lines changed

Include/internal/pycore_long.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,15 @@ _PyLong_IsPositive(const PyLongObject *op)
231231
return (op->long_value.lv_tag & SIGN_MASK) == 0;
232232
}
233233

234+
static inline bool
235+
_PyLong_IsImmortal(const PyLongObject *op)
236+
{
237+
assert(PyLong_Check(op));
238+
bool is_small_int = (op->long_value.lv_tag & IMMORTALITY_BIT_MASK) != 0;
239+
assert(PyLong_CheckExact(op) || (!is_small_int));
240+
return is_small_int;
241+
}
242+
234243
static inline Py_ssize_t
235244
_PyLong_DigitCount(const PyLongObject *op)
236245
{
@@ -292,7 +301,9 @@ _PyLong_SetDigitCount(PyLongObject *op, Py_ssize_t size)
292301
#define NON_SIZE_MASK ~(uintptr_t)((1 << NON_SIZE_BITS) - 1)
293302

294303
static inline void
295-
_PyLong_FlipSign(PyLongObject *op) {
304+
_PyLong_FlipSign(PyLongObject *op)
305+
{
306+
assert(!_PyLong_IsImmortal(op));
296307
unsigned int flipped_sign = 2 - (op->long_value.lv_tag & SIGN_MASK);
297308
op->long_value.lv_tag &= NON_SIZE_MASK;
298309
op->long_value.lv_tag |= flipped_sign;

Modules/_testcapi/immortal.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ test_immortal_small_ints(PyObject *self, PyObject *Py_UNUSED(ignored))
3131
for (int i = -5; i <= 1024; i++) {
3232
PyObject *obj = PyLong_FromLong(i);
3333
assert(verify_immortality(obj));
34-
int has_int_immortal_bit = ((PyLongObject *)obj)->long_value.lv_tag & IMMORTALITY_BIT_MASK;
34+
int has_int_immortal_bit = _PyLong_IsImmortal((PyLongObject *)obj);
3535
assert(has_int_immortal_bit);
3636
}
3737
for (int i = 1025; i <= 1030; i++) {
3838
PyObject *obj = PyLong_FromLong(i);
3939
assert(obj);
40-
int has_int_immortal_bit = ((PyLongObject *)obj)->long_value.lv_tag & IMMORTALITY_BIT_MASK;
40+
int has_int_immortal_bit = _PyLong_IsImmortal((PyLongObject *)obj);
4141
assert(!has_int_immortal_bit);
4242
Py_DECREF(obj);
4343
}

Objects/longobject.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3622,21 +3622,11 @@ long_richcompare(PyObject *self, PyObject *other, int op)
36223622
Py_RETURN_RICHCOMPARE(result, 0, op);
36233623
}
36243624

3625-
static inline int
3626-
/// Return 1 if the object is one of the immortal small ints
3627-
_long_is_small_int(PyObject *op)
3628-
{
3629-
PyLongObject *long_object = (PyLongObject *)op;
3630-
int is_small_int = (long_object->long_value.lv_tag & IMMORTALITY_BIT_MASK) != 0;
3631-
assert((!is_small_int) || PyLong_CheckExact(op));
3632-
return is_small_int;
3633-
}
3634-
36353625
void
36363626
_PyLong_ExactDealloc(PyObject *self)
36373627
{
36383628
assert(PyLong_CheckExact(self));
3639-
if (_long_is_small_int(self)) {
3629+
if (_PyLong_IsImmortal((PyLongObject *)self)) {
36403630
// See PEP 683, section Accidental De-Immortalizing for details
36413631
_Py_SetImmortal(self);
36423632
return;
@@ -3651,7 +3641,7 @@ _PyLong_ExactDealloc(PyObject *self)
36513641
static void
36523642
long_dealloc(PyObject *self)
36533643
{
3654-
if (_long_is_small_int(self)) {
3644+
if (_PyLong_IsImmortal((PyLongObject *)self)) {
36553645
/* This should never get called, but we also don't want to SEGV if
36563646
* we accidentally decref small Ints out of existence. Instead,
36573647
* since small Ints are immortal, re-set the reference count.

0 commit comments

Comments
 (0)