|
|
|
@ -208,6 +208,19 @@ PyList_Size(PyObject *op) |
|
|
|
return Py_SIZE(op); |
|
|
|
} |
|
|
|
|
|
|
|
static inline int |
|
|
|
valid_index(Py_ssize_t i, Py_ssize_t limit) |
|
|
|
{ |
|
|
|
/* The cast to size_t lets us use just a single comparison |
|
|
|
to check whether i is in the range: 0 <= i < limit. |
|
|
|
|
|
|
|
See: Section 14.2 "Bounds Checking" in the Agner Fog |
|
|
|
optimization manual found at: |
|
|
|
https://www.agner.org/optimize/optimizing_cpp.pdf |
|
|
|
*/ |
|
|
|
return (size_t) i < (size_t) limit; |
|
|
|
} |
|
|
|
|
|
|
|
static PyObject *indexerr = NULL; |
|
|
|
|
|
|
|
PyObject * |
|
|
|
@ -217,7 +230,7 @@ PyList_GetItem(PyObject *op, Py_ssize_t i) |
|
|
|
PyErr_BadInternalCall(); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
if (i < 0 || i >= Py_SIZE(op)) { |
|
|
|
if (!valid_index(i, Py_SIZE(op))) { |
|
|
|
if (indexerr == NULL) { |
|
|
|
indexerr = PyUnicode_FromString( |
|
|
|
"list index out of range"); |
|
|
|
@ -240,7 +253,7 @@ PyList_SetItem(PyObject *op, Py_ssize_t i, |
|
|
|
PyErr_BadInternalCall(); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if (i < 0 || i >= Py_SIZE(op)) { |
|
|
|
if (!valid_index(i, Py_SIZE(op))) { |
|
|
|
Py_XDECREF(newitem); |
|
|
|
PyErr_SetString(PyExc_IndexError, |
|
|
|
"list assignment index out of range"); |
|
|
|
@ -426,7 +439,7 @@ list_contains(PyListObject *a, PyObject *el) |
|
|
|
static PyObject * |
|
|
|
list_item(PyListObject *a, Py_ssize_t i) |
|
|
|
{ |
|
|
|
if (i < 0 || i >= Py_SIZE(a)) { |
|
|
|
if (!valid_index(i, Py_SIZE(a))) { |
|
|
|
if (indexerr == NULL) { |
|
|
|
indexerr = PyUnicode_FromString( |
|
|
|
"list index out of range"); |
|
|
|
@ -749,7 +762,7 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n) |
|
|
|
static int |
|
|
|
list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v) |
|
|
|
{ |
|
|
|
if (i < 0 || i >= Py_SIZE(a)) { |
|
|
|
if (!valid_index(i, Py_SIZE(a))) { |
|
|
|
PyErr_SetString(PyExc_IndexError, |
|
|
|
"list assignment index out of range"); |
|
|
|
return -1; |
|
|
|
@ -996,7 +1009,7 @@ list_pop_impl(PyListObject *self, Py_ssize_t index) |
|
|
|
} |
|
|
|
if (index < 0) |
|
|
|
index += Py_SIZE(self); |
|
|
|
if (index < 0 || index >= Py_SIZE(self)) { |
|
|
|
if (!valid_index(index, Py_SIZE(self))) { |
|
|
|
PyErr_SetString(PyExc_IndexError, "pop index out of range"); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|