Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersTuples.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* These helpers are used to work with tuples.
4
5*/
6
7// This file is included from another C file, help IDEs to still parse it on
8// its own.
9#ifdef __IDE_ONLY__
10#include "nuitka/prelude.h"
11#endif
12
13#if NUITKA_TUPLE_HAS_FREELIST
14
15PyObject *MAKE_TUPLE_EMPTY(PyThreadState *tstate, Py_ssize_t size) {
16 PyTupleObject *result_tuple;
17
18 // Lets not get called other than this
19 assert(size > 0);
20
21 // This is the CPython name, spell-checker: ignore numfree
22#if PYTHON_VERSION < 0x3d0
23 PyTupleObject **items = tstate->interp->tuple.free_list;
24 int *numfree = tstate->interp->tuple.numfree;
25#else
26 struct _Py_object_freelists *freelists = _Nuitka_object_freelists_GET(tstate);
27 struct _Py_tuple_freelist *state = &freelists->tuples;
28 PyTupleObject **items = state->items;
29 int *numfree = state->numfree;
30#endif
31
32#if PYTHON_VERSION < 0x3b0
33 Py_ssize_t index = size;
34#else
35 Py_ssize_t index = size - 1;
36#endif
37
38 if ((size < PyTuple_MAXSAVESIZE) && (result_tuple = items[index]) != NULL) {
39 items[index] = (PyTupleObject *)result_tuple->ob_item[0];
40 numfree[index] -= 1;
41
42 assert(Py_SIZE(result_tuple) == size);
43 assert(Py_TYPE(result_tuple) == &PyTuple_Type);
44
45 Nuitka_Py_NewReference((PyObject *)result_tuple);
46 } else {
47 // Check for overflow
48 if ((size_t)size >
49 ((size_t)PY_SSIZE_T_MAX - (sizeof(PyTupleObject) - sizeof(PyObject *))) / sizeof(PyObject *)) {
50 return PyErr_NoMemory();
51 }
52
53 result_tuple = (PyTupleObject *)Nuitka_GC_NewVar(&PyTuple_Type, size);
54 }
55
56 // TODO: Why not use memset here, and can we rely on memory being cleared
57 // by allocator?
58
59 // TODO: When first initializing the tuple, we might skip this and use
60 // assignments that ignore this.
61 for (Py_ssize_t i = 0; i < size; i++) {
62 result_tuple->ob_item[i] = NULL;
63 }
64
65 Nuitka_GC_Track(result_tuple);
66
67 assert(PyTuple_CheckExact(result_tuple));
68 assert(PyTuple_GET_SIZE(result_tuple) == size);
69
70 return (PyObject *)result_tuple;
71}
72
73PyObject *MAKE_TUPLE_EMPTY_VAR(PyThreadState *tstate, Py_ssize_t size) {
74 if (size == 0) {
75 PyObject *result = const_tuple_empty;
76 Py_INCREF(result);
77 return result;
78 } else {
79 return MAKE_TUPLE_EMPTY(tstate, size);
80 }
81}
82
83#endif
84
85PyObject *TUPLE_CONCAT(PyThreadState *tstate, PyObject *tuple1, PyObject *tuple2) {
86 Py_ssize_t size = Py_SIZE(tuple1) + Py_SIZE(tuple2);
87
88 // Do not ignore MemoryError, may actually happen.
89 PyTupleObject *result = (PyTupleObject *)MAKE_TUPLE_EMPTY_VAR(tstate, size);
90 if (unlikely(result == NULL)) {
91 return NULL;
92 }
93
94 PyObject **src = ((PyTupleObject *)tuple1)->ob_item;
95 PyObject **dest = result->ob_item;
96
97 for (Py_ssize_t i = 0; i < Py_SIZE(tuple1); i++) {
98 PyObject *v = src[i];
99 Py_INCREF(v);
100 dest[i] = v;
101 }
102
103 src = ((PyTupleObject *)tuple2)->ob_item;
104 dest = result->ob_item + Py_SIZE(tuple1);
105
106 for (Py_ssize_t i = 0; i < Py_SIZE(tuple2); i++) {
107 PyObject *v = src[i];
108 Py_INCREF(v);
109 dest[i] = v;
110 }
111
112 return (PyObject *)result;
113}
114
115PyObject *TUPLE_COPY(PyThreadState *tstate, PyObject *tuple) {
116 CHECK_OBJECT(tuple);
117 assert(PyTuple_CheckExact(tuple));
118
119 Py_ssize_t size = PyTuple_GET_SIZE(tuple);
120 PyObject *result = MAKE_TUPLE_EMPTY_VAR(tstate, size);
121
122 if (unlikely(result == NULL)) {
123 return NULL;
124 }
125
126 for (Py_ssize_t i = 0; i < size; i++) {
127 PyObject *item = PyTuple_GET_ITEM(tuple, i);
128 Py_INCREF(item);
129 PyList_SET_ITEM(result, i, item);
130 }
131
132 return result;
133}
134
135// Part of "Nuitka", an optimizing Python compiler that is compatible and
136// integrates with CPython, but also works on its own.
137//
138// Licensed under the Apache License, Version 2.0 (the "License");
139// you may not use this file except in compliance with the License.
140// You may obtain a copy of the License at
141//
142// http://www.apache.org/licenses/LICENSE-2.0
143//
144// Unless required by applicable law or agreed to in writing, software
145// distributed under the License is distributed on an "AS IS" BASIS,
146// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147// See the License for the specific language governing permissions and
148// limitations under the License.