Skip to content

Commit 2d86383

Browse files
authored
[mypyc] Inline tuple ops (#21828)
Mypyc tuple ops were not yet inlined. I've left `CPySequenceTuple_GetSlice` un-inlined since it's still kind of heavy.
1 parent b4b8d74 commit 2d86383

2 files changed

Lines changed: 36 additions & 30 deletions

File tree

mypyc/lib-rt/CPy.h

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -862,11 +862,37 @@ bool CPySet_Remove(PyObject *set, PyObject *key);
862862

863863
// Tuple operations
864864

865-
866-
PyObject *CPySequenceTuple_GetItem(PyObject *tuple, CPyTagged index);
867865
PyObject *CPySequenceTuple_GetSlice(PyObject *obj, CPyTagged start, CPyTagged end);
868-
PyObject *CPySequenceTuple_GetItemUnsafe(PyObject *tuple, Py_ssize_t index);
869-
void CPySequenceTuple_SetItemUnsafe(PyObject *tuple, Py_ssize_t index, PyObject *value);
866+
PyObject *CPySequenceTuple_GetItem_(PyObject *tuple, CPyTagged index);
867+
868+
static inline PyObject *CPySequenceTuple_GetItem(PyObject *tuple, CPyTagged index)
869+
{
870+
if (likely(CPyTagged_CheckShort(index) && !CPyTagged_IsNegative(index))) {
871+
Py_ssize_t n = CPyTagged_ShortAsSsize_t(index);
872+
Py_ssize_t size = PyTuple_GET_SIZE(tuple);
873+
if (unlikely(n >= size)) {
874+
PyErr_SetString(PyExc_IndexError, "tuple index out of range");
875+
return NULL;
876+
}
877+
PyObject *result = PyTuple_GET_ITEM(tuple, n);
878+
Py_INCREF(result);
879+
return result;
880+
} else {
881+
return CPySequenceTuple_GetItem_(tuple, index);
882+
}
883+
}
884+
885+
static inline PyObject *CPySequenceTuple_GetItemUnsafe(PyObject *tuple, Py_ssize_t index)
886+
{
887+
PyObject *result = PyTuple_GET_ITEM(tuple, index);
888+
Py_INCREF(result);
889+
return result;
890+
}
891+
892+
static inline void CPySequenceTuple_SetItemUnsafe(PyObject *tuple, Py_ssize_t index, PyObject *value)
893+
{
894+
PyTuple_SET_ITEM(tuple, index, value);
895+
}
870896

871897

872898
// Exception operations

mypyc/lib-rt/tuple_ops.c

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,16 @@
55
#include <Python.h>
66
#include "CPy.h"
77

8-
PyObject *CPySequenceTuple_GetItem(PyObject *tuple, CPyTagged index) {
8+
PyObject *CPySequenceTuple_GetItem_(PyObject *tuple, CPyTagged index) {
99
if (CPyTagged_CheckShort(index)) {
1010
Py_ssize_t n = CPyTagged_ShortAsSsize_t(index);
1111
Py_ssize_t size = PyTuple_GET_SIZE(tuple);
12-
if (n >= 0) {
13-
if (n >= size) {
14-
PyErr_SetString(PyExc_IndexError, "tuple index out of range");
15-
return NULL;
16-
}
17-
} else {
12+
if (n < 0) {
1813
n += size;
19-
if (n < 0) {
20-
PyErr_SetString(PyExc_IndexError, "tuple index out of range");
21-
return NULL;
22-
}
14+
}
15+
if (n < 0 || n >= size) {
16+
PyErr_SetString(PyExc_IndexError, "tuple index out of range");
17+
return NULL;
2318
}
2419
PyObject *result = PyTuple_GET_ITEM(tuple, n);
2520
Py_INCREF(result);
@@ -45,18 +40,3 @@ PyObject *CPySequenceTuple_GetSlice(PyObject *obj, CPyTagged start, CPyTagged en
4540
}
4641
return CPyObject_GetSlice(obj, start, end);
4742
}
48-
49-
// No error checking
50-
PyObject *CPySequenceTuple_GetItemUnsafe(PyObject *tuple, Py_ssize_t index)
51-
{
52-
PyObject *result = PyTuple_GET_ITEM(tuple, index);
53-
Py_INCREF(result);
54-
return result;
55-
}
56-
57-
// PyTuple_SET_ITEM does no error checking,
58-
// and should only be used to fill in brand new tuples.
59-
void CPySequenceTuple_SetItemUnsafe(PyObject *tuple, Py_ssize_t index, PyObject *value)
60-
{
61-
PyTuple_SET_ITEM(tuple, index, value);
62-
}

0 commit comments

Comments
 (0)