Skip to content

Commit 60220c0

Browse files
committed
add small int check to _PyLong_ExactDealloc
1 parent 13bc3e9 commit 60220c0

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

Objects/longobject.c

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3615,10 +3615,32 @@ long_richcompare(PyObject *self, PyObject *other, int op)
36153615
Py_RETURN_RICHCOMPARE(result, 0, op);
36163616
}
36173617

3618+
static inline int
3619+
_PyLong_IsSmallInt(PyObject *self)
3620+
{
3621+
PyLongObject *pylong = (PyLongObject *)self;
3622+
assert(_PyLong_IsCompact(pylong));
3623+
stwodigits ival = medium_value(pylong);
3624+
if (IS_SMALL_INT(ival)) {
3625+
PyLongObject *small_pylong = (PyLongObject *)get_small_int((sdigit)ival);
3626+
if (pylong == small_pylong) {
3627+
return 1;
3628+
}
3629+
}
3630+
return 0;
3631+
}
3632+
36183633
void
36193634
_PyLong_ExactDealloc(PyObject *self)
36203635
{
36213636
if (_PyLong_IsCompact((PyLongObject *)self)) {
3637+
#ifndef Py_GIL_DISABLED
3638+
if (_PyLong_IsSmallInt(self)) {
3639+
// See PEP 683, section Accidental De-Immortalizing for details
3640+
_Py_SetImmortal(self);
3641+
return;
3642+
}
3643+
#endif
36223644
_Py_FREELIST_FREE(ints, self, PyObject_Free);
36233645
return;
36243646
}
@@ -3628,23 +3650,17 @@ _PyLong_ExactDealloc(PyObject *self)
36283650
static void
36293651
long_dealloc(PyObject *self)
36303652
{
3631-
PyLongObject *pylong = (PyLongObject*)self;
3632-
assert(pylong);
3633-
3634-
if (_PyLong_IsCompact(pylong)) {
3635-
stwodigits ival = medium_value(pylong);
3636-
if (IS_SMALL_INT(ival)) {
3637-
PyLongObject *small_pylong = (PyLongObject *)get_small_int((sdigit)ival);
3638-
if (pylong == small_pylong) {
3639-
/* This should never get called, but we also don't want to SEGV if
3640-
* we accidentally decref small Ints out of existence. Instead,
3641-
* since small Ints are immortal, re-set the reference count.
3642-
*
3643-
* With a fixed refcount for immortal objects this should not happen
3644-
*/
3645-
_Py_SetImmortal(self);
3646-
return;
3647-
}
3653+
assert(self);
3654+
if (_PyLong_IsCompact((PyLongObject *)self)) {
3655+
if (_PyLong_IsSmallInt(self)) {
3656+
/* This should never get called, but we also don't want to SEGV if
3657+
* we accidentally decref small Ints out of existence. Instead,
3658+
* since small Ints are immortal, re-set the reference count.
3659+
*
3660+
* See PEP 683, section Accidental De-Immortalizing for details
3661+
*/
3662+
_Py_SetImmortal(self);
3663+
return;
36483664
}
36493665
if (PyLong_CheckExact(self)) {
36503666
_Py_FREELIST_FREE(ints, self, PyObject_Free);

0 commit comments

Comments
 (0)