bpo-37812: Convert CHECK_SMALL_INT macro to a function so the return is explicit. (GH-15216)

This commit is contained in:
Greg Price 2019-08-24 10:19:37 -07:00 committed by Raymond Hettinger
parent a50f0a4c2b
commit 5e63ab05f1
2 changed files with 28 additions and 11 deletions

View File

@ -0,0 +1,3 @@
The ``CHECK_SMALL_INT`` macro used inside :file:`Object/longobject.c` has
been replaced with an explicit ``return`` at each call site, conditioned on
a ``static inline`` function ``is_small_int``.

View File

@ -41,6 +41,13 @@ PyObject *_PyLong_One = NULL;
-NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive). -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/ */
static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS]; static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
static inline int
is_small_int(long long ival)
{
return -NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS;
}
#ifdef COUNT_ALLOCS #ifdef COUNT_ALLOCS
Py_ssize_t _Py_quick_int_allocs, _Py_quick_neg_int_allocs; Py_ssize_t _Py_quick_int_allocs, _Py_quick_neg_int_allocs;
#endif #endif
@ -49,7 +56,7 @@ static PyObject *
get_small_int(sdigit ival) get_small_int(sdigit ival)
{ {
PyObject *v; PyObject *v;
assert(-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS); assert(is_small_int(ival));
v = (PyObject *)&small_ints[ival + NSMALLNEGINTS]; v = (PyObject *)&small_ints[ival + NSMALLNEGINTS];
Py_INCREF(v); Py_INCREF(v);
#ifdef COUNT_ALLOCS #ifdef COUNT_ALLOCS
@ -60,17 +67,13 @@ get_small_int(sdigit ival)
#endif #endif
return v; return v;
} }
#define CHECK_SMALL_INT(ival) \
do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \
return get_small_int((sdigit)ival); \
} while(0)
static PyLongObject * static PyLongObject *
maybe_small_long(PyLongObject *v) maybe_small_long(PyLongObject *v)
{ {
if (v && Py_ABS(Py_SIZE(v)) <= 1) { if (v && Py_ABS(Py_SIZE(v)) <= 1) {
sdigit ival = MEDIUM_VALUE(v); sdigit ival = MEDIUM_VALUE(v);
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { if (is_small_int(ival)) {
Py_DECREF(v); Py_DECREF(v);
return (PyLongObject *)get_small_int(ival); return (PyLongObject *)get_small_int(ival);
} }
@ -78,7 +81,8 @@ maybe_small_long(PyLongObject *v)
return v; return v;
} }
#else #else
#define CHECK_SMALL_INT(ival) #define is_small_int(ival) 0
#define get_small_int(ival) (assert(0), NULL)
#define maybe_small_long(val) (val) #define maybe_small_long(val) (val)
#endif #endif
@ -293,7 +297,9 @@ _PyLong_Copy(PyLongObject *src)
i = -(i); i = -(i);
if (i < 2) { if (i < 2) {
sdigit ival = MEDIUM_VALUE(src); sdigit ival = MEDIUM_VALUE(src);
CHECK_SMALL_INT(ival); if (is_small_int(ival)) {
return get_small_int(ival);
}
} }
result = _PyLong_New(i); result = _PyLong_New(i);
if (result != NULL) { if (result != NULL) {
@ -315,7 +321,9 @@ PyLong_FromLong(long ival)
int ndigits = 0; int ndigits = 0;
int sign; int sign;
CHECK_SMALL_INT(ival); if (is_small_int(ival)) {
return get_small_int((sdigit)ival);
}
if (ival < 0) { if (ival < 0) {
/* negate: can't write this as abs_ival = -ival since that /* negate: can't write this as abs_ival = -ival since that
@ -1146,7 +1154,10 @@ PyLong_FromLongLong(long long ival)
int ndigits = 0; int ndigits = 0;
int negative = 0; int negative = 0;
CHECK_SMALL_INT(ival); if (is_small_int(ival)) {
return get_small_int((sdigit)ival);
}
if (ival < 0) { if (ival < 0) {
/* avoid signed overflow on negation; see comments /* avoid signed overflow on negation; see comments
in PyLong_FromLong above. */ in PyLong_FromLong above. */
@ -1218,7 +1229,10 @@ PyLong_FromSsize_t(Py_ssize_t ival)
int ndigits = 0; int ndigits = 0;
int negative = 0; int negative = 0;
CHECK_SMALL_INT(ival); if (is_small_int(ival)) {
return get_small_int((sdigit)ival);
}
if (ival < 0) { if (ival < 0) {
/* avoid signed overflow when ival = SIZE_T_MIN */ /* avoid signed overflow when ival = SIZE_T_MIN */
abs_ival = (size_t)(-1-ival)+1; abs_ival = (size_t)(-1-ival)+1;