Nuitka
The Python compiler
Loading...
Searching...
No Matches
CompiledCellType.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
14/* This file is included from another C file, help IDEs to still parse it on its own. */
15#ifdef __IDE_ONLY__
16#include "nuitka/prelude.h"
17#endif
18
19#if _DEBUG_REFCOUNTS
20int count_active_Nuitka_Cell_Type;
21int count_allocated_Nuitka_Cell_Type;
22int count_released_Nuitka_Cell_Type;
23#endif
24
25// Freelist setup
26#define MAX_CELL_FREE_LIST_COUNT 1000
27static struct Nuitka_CellObject *free_list_cells = NULL;
28static int free_list_cells_count = 0;
29
30static void Nuitka_Cell_tp_dealloc(struct Nuitka_CellObject *cell) {
31#if _DEBUG_REFCOUNTS
32 count_active_Nuitka_Cell_Type -= 1;
33 count_released_Nuitka_Cell_Type += 1;
34#endif
35
36 Nuitka_GC_UnTrack(cell);
37 Py_XDECREF(cell->ob_ref);
38
39 releaseToFreeList(free_list_cells, cell, MAX_CELL_FREE_LIST_COUNT);
40}
41
42#if PYTHON_VERSION < 0x300
43static int Nuitka_Cell_tp_compare(PyObject *a, PyObject *b) {
44 struct Nuitka_CellObject *cell_a = (struct Nuitka_CellObject *)a;
45 struct Nuitka_CellObject *cell_b = (struct Nuitka_CellObject *)b;
46
47 /* Empty cells compare specifically different. */
48 if (cell_a->ob_ref == NULL) {
49 if (cell_b->ob_ref == NULL) {
50 return 0;
51 }
52
53 return -1;
54 }
55
56 if (cell_b->ob_ref == NULL) {
57 return 1;
58 }
59
60 return PyObject_Compare(cell_a->ob_ref, cell_b->ob_ref);
61}
62#else
63#define Nuitka_Cell_tp_compare (NULL)
64
65static PyObject *Nuitka_Cell_tp_richcompare(PyObject *a, PyObject *b, int op) {
66 PyObject *result;
67
68 CHECK_OBJECT(a);
69 CHECK_OBJECT(b);
70
71 if (unlikely(!Nuitka_Cell_Check(a) || !Nuitka_Cell_Check(b))) {
72 result = Py_NotImplemented;
73 Py_INCREF(result);
74
75 return result;
76 }
77
78 // Now just dereference cell value, and compare from there by contents, which can
79 // be NULL however.
80 a = ((struct Nuitka_CellObject *)a)->ob_ref;
81 b = ((struct Nuitka_CellObject *)b)->ob_ref;
82
83 if (a != NULL && b != NULL) {
84 switch (op) {
85 case Py_EQ:
86 return RICH_COMPARE_EQ_OBJECT_OBJECT_OBJECT(a, b);
87 case Py_NE:
88 return RICH_COMPARE_NE_OBJECT_OBJECT_OBJECT(a, b);
89 case Py_LE:
90 return RICH_COMPARE_LE_OBJECT_OBJECT_OBJECT(a, b);
91 case Py_GE:
92 return RICH_COMPARE_GE_OBJECT_OBJECT_OBJECT(a, b);
93 case Py_LT:
94 return RICH_COMPARE_LT_OBJECT_OBJECT_OBJECT(a, b);
95 case Py_GT:
96 return RICH_COMPARE_GT_OBJECT_OBJECT_OBJECT(a, b);
97 default:
98 PyErr_BadArgument();
99 return NULL;
100 }
101 }
102
103 int res = (b == NULL) - (a == NULL);
104 switch (op) {
105 case Py_EQ:
106 result = BOOL_FROM(res == 0);
107 break;
108 case Py_NE:
109 result = BOOL_FROM(res != 0);
110 break;
111 case Py_LE:
112 result = BOOL_FROM(res <= 0);
113 break;
114 case Py_GE:
115 result = BOOL_FROM(res >= 0);
116 break;
117 case Py_LT:
118 result = BOOL_FROM(res < 0);
119 break;
120 case Py_GT:
121 result = BOOL_FROM(res > 0);
122 break;
123 default:
124 PyErr_BadArgument();
125 return NULL;
126 }
127
128 Py_INCREF_IMMORTAL(result);
129 return result;
130}
131#endif
132
133static PyObject *Nuitka_Cell_tp_repr(struct Nuitka_CellObject *cell) {
134 if (cell->ob_ref == NULL) {
135 return Nuitka_String_FromFormat("<compiled_cell at %p: empty>", cell);
136 } else {
137 return Nuitka_String_FromFormat("<compiled_cell at %p: %s object at %p>", cell, cell->ob_ref->ob_type->tp_name,
138 cell->ob_ref);
139 }
140}
141
142static int Nuitka_Cell_tp_traverse(struct Nuitka_CellObject *cell, visitproc visit, void *arg) {
143 Py_VISIT(cell->ob_ref);
144
145 return 0;
146}
147
148static int Nuitka_Cell_tp_clear(struct Nuitka_CellObject *cell) {
149 Py_CLEAR(cell->ob_ref);
150
151 return 0;
152}
153
154static PyObject *Nuitka_Cell_get_contents(PyObject *self, void *data) {
155 struct Nuitka_CellObject *cell = (struct Nuitka_CellObject *)self;
156 if (unlikely(cell->ob_ref == NULL)) {
157 PyThreadState *tstate = PyThreadState_GET();
158
159 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, "Cell is empty");
160 return NULL;
161 }
162
163 Py_INCREF(cell->ob_ref);
164 return cell->ob_ref;
165}
166
167#if PYTHON_VERSION >= 0x370
168static int Nuitka_Cell_set_contents(PyObject *self, PyObject *value, void *data) {
169 struct Nuitka_CellObject *cell = (struct Nuitka_CellObject *)self;
170 PyObject *old = cell->ob_ref;
171
172 if (old != NULL && value == NULL) {
173 PyThreadState *tstate = PyThreadState_GET();
174
175 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_RuntimeError,
176 "cell_contents cannot be used to delete values Nuitka");
177 return -1;
178 }
179
180 cell->ob_ref = value;
181 Py_XINCREF(value);
182 Py_XDECREF(old);
183
184 return 0;
185}
186#endif
187
188static PyGetSetDef Nuitka_Cell_tp_getset[] = {
189#if PYTHON_VERSION < 0x370
190 {(char *)"cell_contents", Nuitka_Cell_get_contents, NULL, NULL},
191#else
192 {(char *)"cell_contents", Nuitka_Cell_get_contents, Nuitka_Cell_set_contents, NULL},
193#endif
194 {NULL}};
195
196PyTypeObject Nuitka_Cell_Type = {
197 PyVarObject_HEAD_INIT(NULL, 0) "compiled_cell",
198 sizeof(struct Nuitka_CellObject), // tp_basicsize
199 0, // tp_itemsize
200 (destructor)Nuitka_Cell_tp_dealloc, // tp_dealloc
201 0, // tp_print
202 0, // tp_getattr
203 0, // tp_setattr
204 Nuitka_Cell_tp_compare, // tp_compare / tp_reserved
205 (reprfunc)Nuitka_Cell_tp_repr, // tp_repr
206 0, // tp_as_number
207 0, // tp_as_sequence
208 0, // tp_as_mapping
209 0, // tp_hash
210 0, // tp_call
211 0, // tp_str
212 0, // tp_getattro (PyObject_GenericGetAttr)
213 0, // tp_setattro
214 0, // tp_as_buffer
215 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
216 0, // tp_doc
217 (traverseproc)Nuitka_Cell_tp_traverse, // tp_traverse
218 (inquiry)Nuitka_Cell_tp_clear, // tp_clear
219#if PYTHON_VERSION < 0x300
220 0, // tp_richcompare
221#else
222 Nuitka_Cell_tp_richcompare, // tp_richcompare
223#endif
224 0, // tp_weaklistoffset
225 0, // tp_iter
226 0, // tp_iternext
227 0, // tp_methods
228 0, // tp_members
229 Nuitka_Cell_tp_getset, // tp_getset
230};
231
232void _initCompiledCellType(void) { Nuitka_PyType_Ready(&Nuitka_Cell_Type, NULL, true, false, false, false, false); }
233
234struct Nuitka_CellObject *Nuitka_Cell_NewEmpty(void) {
235#if _DEBUG_REFCOUNTS
236 count_active_Nuitka_Cell_Type += 1;
237 count_allocated_Nuitka_Cell_Type += 1;
238#endif
239
240 struct Nuitka_CellObject *result;
241
242 allocateFromFreeListFixed(free_list_cells, struct Nuitka_CellObject, Nuitka_Cell_Type);
243
244 result->ob_ref = NULL;
245
246 Nuitka_GC_Track(result);
247
248 return result;
249}
250
251struct Nuitka_CellObject *Nuitka_Cell_New0(PyObject *value) {
252#if _DEBUG_REFCOUNTS
253 count_active_Nuitka_Cell_Type += 1;
254 count_allocated_Nuitka_Cell_Type += 1;
255#endif
256 CHECK_OBJECT(value);
257
258 struct Nuitka_CellObject *result;
259
260 allocateFromFreeListFixed(free_list_cells, struct Nuitka_CellObject, Nuitka_Cell_Type);
261
262 result->ob_ref = value;
263 Py_INCREF(value);
264
265 Nuitka_GC_Track(result);
266
267 return result;
268}
269
270struct Nuitka_CellObject *Nuitka_Cell_New1(PyObject *value) {
271#if _DEBUG_REFCOUNTS
272 count_active_Nuitka_Cell_Type += 1;
273 count_allocated_Nuitka_Cell_Type += 1;
274#endif
275 CHECK_OBJECT(value);
276
277 struct Nuitka_CellObject *result;
278
279 allocateFromFreeListFixed(free_list_cells, struct Nuitka_CellObject, Nuitka_Cell_Type);
280
281 result->ob_ref = value;
282
283 Nuitka_GC_Track(result);
284
285 return result;
286}
287// Part of "Nuitka", an optimizing Python compiler that is compatible and
288// integrates with CPython, but also works on its own.
289//
290// Licensed under the Apache License, Version 2.0 (the "License");
291// you may not use this file except in compliance with the License.
292// You may obtain a copy of the License at
293//
294// http://www.apache.org/licenses/LICENSE-2.0
295//
296// Unless required by applicable law or agreed to in writing, software
297// distributed under the License is distributed on an "AS IS" BASIS,
298// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
299// See the License for the specific language governing permissions and
300// limitations under the License.
Definition compiled_cell.h:14