10#include "nuitka/prelude.h"
13#if NUITKA_TUPLE_HAS_FREELIST
15PyObject *MAKE_TUPLE_EMPTY(PyThreadState *tstate, Py_ssize_t size) {
16 PyTupleObject *result_tuple;
21#if PYTHON_VERSION >= 0x3e0
22 Py_ssize_t index = size - 1;
23 bool needs_recycle =
false;
25 if (index < PyTuple_MAXSAVESIZE) {
26 result_tuple = (PyTupleObject *)Nuitka_PyFreeList_Pop(&Nuitka_Py_freelists_GET(tstate)->tuples[index]);
31 if (result_tuple == NULL) {
32 result_tuple = (PyTupleObject *)Nuitka_GC_NewVar(&PyTuple_Type, size);
34 Nuitka_Py_NewReference((PyObject *)result_tuple);
39#if PYTHON_VERSION < 0x3d0
40 PyTupleObject **items = tstate->interp->tuple.free_list;
41 int *numfree = tstate->interp->tuple.numfree;
43 struct _Py_object_freelists *freelists = _Nuitka_object_freelists_GET(tstate);
44 struct _Py_tuple_freelist *state = &freelists->tuples;
45 PyTupleObject **items = state->items;
46 int *numfree = state->numfree;
49#if PYTHON_VERSION < 0x3b0
50 Py_ssize_t index = size;
52 Py_ssize_t index = size - 1;
55 if ((size < PyTuple_MAXSAVESIZE) && (result_tuple = items[index]) != NULL) {
56 items[index] = (PyTupleObject *)result_tuple->ob_item[0];
59 assert(Py_SIZE(result_tuple) == size);
60 assert(Py_TYPE(result_tuple) == &PyTuple_Type);
62 Nuitka_Py_NewReference((PyObject *)result_tuple);
66 ((
size_t)PY_SSIZE_T_MAX - (
sizeof(PyTupleObject) -
sizeof(PyObject *))) /
sizeof(PyObject *)) {
67 return PyErr_NoMemory();
70 result_tuple = (PyTupleObject *)Nuitka_GC_NewVar(&PyTuple_Type, size);
79 for (Py_ssize_t i = 0; i < size; i++) {
80 result_tuple->ob_item[i] = NULL;
83#if PYTHON_VERSION >= 0x3e0
87 _PyTuple_RESET_HASH_CACHE((PyObject *)result_tuple);
88 if (!needs_recycle || !_PyObject_GC_IS_TRACKED((PyObject *)result_tuple)) {
89 Nuitka_GC_Track(result_tuple);
92 Nuitka_GC_Track(result_tuple);
95 assert(PyTuple_CheckExact(result_tuple));
96 assert(PyTuple_GET_SIZE(result_tuple) == size);
98 return (PyObject *)result_tuple;
101PyObject *MAKE_TUPLE_EMPTY_VAR(PyThreadState *tstate, Py_ssize_t size) {
103 PyObject *result = const_tuple_empty;
107 return MAKE_TUPLE_EMPTY(tstate, size);
113PyObject *TUPLE_CONCAT(PyThreadState *tstate, PyObject *tuple1, PyObject *tuple2) {
114 Py_ssize_t size = Py_SIZE(tuple1) + Py_SIZE(tuple2);
117 PyTupleObject *result = (PyTupleObject *)MAKE_TUPLE_EMPTY_VAR(tstate, size);
118 if (unlikely(result == NULL)) {
122 PyObject **src = ((PyTupleObject *)tuple1)->ob_item;
123 PyObject **dest = result->ob_item;
125 for (Py_ssize_t i = 0; i < Py_SIZE(tuple1); i++) {
126 PyObject *v = src[i];
131 src = ((PyTupleObject *)tuple2)->ob_item;
132 dest = result->ob_item + Py_SIZE(tuple1);
134 for (Py_ssize_t i = 0; i < Py_SIZE(tuple2); i++) {
135 PyObject *v = src[i];
140 return (PyObject *)result;
143PyObject *TUPLE_COPY(PyThreadState *tstate, PyObject *tuple) {
145 assert(PyTuple_CheckExact(tuple));
147 Py_ssize_t size = PyTuple_GET_SIZE(tuple);
148 PyObject *result = MAKE_TUPLE_EMPTY_VAR(tstate, size);
150 if (unlikely(result == NULL)) {
154 for (Py_ssize_t i = 0; i < size; i++) {
155 PyObject *item = PyTuple_GET_ITEM(tuple, i);
157 PyList_SET_ITEM(result, i, item);