diff --git a/mypyc/lib-rt/CPy.h b/mypyc/lib-rt/CPy.h index 458db90efd530..f8d4acef08152 100644 --- a/mypyc/lib-rt/CPy.h +++ b/mypyc/lib-rt/CPy.h @@ -862,11 +862,37 @@ bool CPySet_Remove(PyObject *set, PyObject *key); // Tuple operations - -PyObject *CPySequenceTuple_GetItem(PyObject *tuple, CPyTagged index); PyObject *CPySequenceTuple_GetSlice(PyObject *obj, CPyTagged start, CPyTagged end); -PyObject *CPySequenceTuple_GetItemUnsafe(PyObject *tuple, Py_ssize_t index); -void CPySequenceTuple_SetItemUnsafe(PyObject *tuple, Py_ssize_t index, PyObject *value); +PyObject *CPySequenceTuple_GetItem_(PyObject *tuple, CPyTagged index); + +static inline PyObject *CPySequenceTuple_GetItem(PyObject *tuple, CPyTagged index) +{ + if (likely(CPyTagged_CheckShort(index) && !CPyTagged_IsNegative(index))) { + Py_ssize_t n = CPyTagged_ShortAsSsize_t(index); + Py_ssize_t size = PyTuple_GET_SIZE(tuple); + if (unlikely(n >= size)) { + PyErr_SetString(PyExc_IndexError, "tuple index out of range"); + return NULL; + } + PyObject *result = PyTuple_GET_ITEM(tuple, n); + Py_INCREF(result); + return result; + } else { + return CPySequenceTuple_GetItem_(tuple, index); + } +} + +static inline PyObject *CPySequenceTuple_GetItemUnsafe(PyObject *tuple, Py_ssize_t index) +{ + PyObject *result = PyTuple_GET_ITEM(tuple, index); + Py_INCREF(result); + return result; +} + +static inline void CPySequenceTuple_SetItemUnsafe(PyObject *tuple, Py_ssize_t index, PyObject *value) +{ + PyTuple_SET_ITEM(tuple, index, value); +} // Exception operations diff --git a/mypyc/lib-rt/tuple_ops.c b/mypyc/lib-rt/tuple_ops.c index 1df73f1907e2f..3d4442e61b1b0 100644 --- a/mypyc/lib-rt/tuple_ops.c +++ b/mypyc/lib-rt/tuple_ops.c @@ -5,21 +5,16 @@ #include #include "CPy.h" -PyObject *CPySequenceTuple_GetItem(PyObject *tuple, CPyTagged index) { +PyObject *CPySequenceTuple_GetItem_(PyObject *tuple, CPyTagged index) { if (CPyTagged_CheckShort(index)) { Py_ssize_t n = CPyTagged_ShortAsSsize_t(index); Py_ssize_t size = PyTuple_GET_SIZE(tuple); - if (n >= 0) { - if (n >= size) { - PyErr_SetString(PyExc_IndexError, "tuple index out of range"); - return NULL; - } - } else { + if (n < 0) { n += size; - if (n < 0) { - PyErr_SetString(PyExc_IndexError, "tuple index out of range"); - return NULL; - } + } + if (n < 0 || n >= size) { + PyErr_SetString(PyExc_IndexError, "tuple index out of range"); + return NULL; } PyObject *result = PyTuple_GET_ITEM(tuple, n); Py_INCREF(result); @@ -45,18 +40,3 @@ PyObject *CPySequenceTuple_GetSlice(PyObject *obj, CPyTagged start, CPyTagged en } return CPyObject_GetSlice(obj, start, end); } - -// No error checking -PyObject *CPySequenceTuple_GetItemUnsafe(PyObject *tuple, Py_ssize_t index) -{ - PyObject *result = PyTuple_GET_ITEM(tuple, index); - Py_INCREF(result); - return result; -} - -// PyTuple_SET_ITEM does no error checking, -// and should only be used to fill in brand new tuples. -void CPySequenceTuple_SetItemUnsafe(PyObject *tuple, Py_ssize_t index, PyObject *value) -{ - PyTuple_SET_ITEM(tuple, index, value); -}