Nuitka
The Python compiler
Loading...
Searching...
No Matches
python_internals_access.h
1// Copyright 2026, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* This file is auto-generated by bin/generate-specialized-c-code. Do not edit. */
4#ifndef NUITKA_PYTHON_INTERNALS_ACCESS_H
5#define NUITKA_PYTHON_INTERNALS_ACCESS_H
6
7#undef _PyRuntime
8
9// spell-checker: ignore PYRUNTIME,offsetof,GNUC,ceval,stoptheworld
10
11#if _NUITKA_MODULE_MODE && PYTHON_VERSION >= 0x3e0 && PYTHON_VERSION < 0x3f0 && !defined(Py_GIL_DISABLED)
12static inline struct _Py_interp_cached_objects *Nuitka_PyInterpreterState_GetCachedObjects(PyInterpreterState *interp) {
13 return (struct _Py_interp_cached_objects *)Nuitka_PyInterpreterState_AdjustPostQsbrPointer(&interp->cached_objects);
14}
15
16static inline struct _Py_interp_static_objects *Nuitka_PyInterpreterState_GetStaticObjects(PyInterpreterState *interp) {
17 return (struct _Py_interp_static_objects *)Nuitka_PyInterpreterState_AdjustPostQsbrPointer(&interp->static_objects);
18}
19#endif
20
21#if PYTHON_VERSION >= 0x3c0
22static inline bool Nuitka_RuntimeHasPerfTrampoline(void) {
23 static int cached_result = -1;
24 if (cached_result != -1) {
25 return cached_result != 0;
26 }
27 PyObject *func = PySys_GetObject("activate_stack_trampoline");
28 assert(func != NULL);
29
30 // Deliberately use an invalid backend, so we can detect support without
31 // activating the trampoline.
32 NUITKA_MAY_BE_UNUSED PyObject *res = PyObject_CallFunction(func, "s", "s");
33 assert(res == NULL);
34 bool has_perf = true;
35
36 PyThreadState *tstate = PyThreadState_GET();
37 PyObject *exception_value = tstate->current_exception;
38 assert(exception_value != NULL);
39 assert((PyObject *)Py_TYPE(exception_value) == PyExc_ValueError);
40
41 PyObject *args = ((PyBaseExceptionObject *)exception_value)->args;
42 assert(PyTuple_CheckExact(args) && PyTuple_GET_SIZE(args) > 0);
43 PyObject *arg = PyTuple_GET_ITEM(args, 0);
44 assert(PyUnicode_CheckExact(arg));
45
46 const char *msg = PyUnicode_AsUTF8(arg);
47 assert(msg != NULL);
48 if (strcmp(msg, "perf trampoline not available") == 0) {
49 has_perf = false;
50 }
51
52 tstate->current_exception = NULL;
53 Py_DECREF(exception_value);
54
55 cached_result = has_perf ? 1 : 0;
56 return has_perf;
57}
58#endif
59
60#if PYTHON_VERSION >= 0x3d0 && PYTHON_VERSION < 0x3e0 && !defined(Py_GIL_DISABLED)
61#if defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
62
63#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_ceval 1272
64#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_imports 1252
65#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_static_objects 8612
66#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_stoptheworld 5140
67
68#endif /* defined(_WIN32) && (defined(__i386__) || defined(_M_IX86)) */
69
70#endif
71
72#if PYTHON_VERSION >= 0x3d0 && PYTHON_VERSION < 0x3e0 && !defined(Py_GIL_DISABLED)
73#if defined(_WIN32) && (defined(__x86_64__) || defined(_M_X64))
74
75#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_ceval 1864
76#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_imports 1824
77#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_static_objects 13032
78#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_stoptheworld 9520
79
80#endif /* defined(_WIN32) && (defined(__x86_64__) || defined(_M_X64)) */
81
82#endif
83
84#if PYTHON_VERSION >= 0x3e0 && PYTHON_VERSION < 0x3f0 && !defined(Py_GIL_DISABLED)
85#if defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
86
87#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_ceval 1452
88#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_imports 1432
89#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_static_objects 8812
90#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_stoptheworld 5324
91
92#endif /* defined(_WIN32) && (defined(__i386__) || defined(_M_IX86)) */
93
94#endif
95
96#if PYTHON_VERSION >= 0x3e0 && PYTHON_VERSION < 0x3f0 && !defined(Py_GIL_DISABLED)
97#if defined(_WIN32) && (defined(__x86_64__) || defined(_M_X64))
98
99#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_ceval 2048
100#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_imports 2008
101#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_static_objects 13240
102#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_stoptheworld 9712
103
104#endif /* defined(_WIN32) && (defined(__x86_64__) || defined(_M_X64)) */
105
106#endif
107
108#if defined(__linux__) && _NUITKA_MODULE_MODE
109
110#if PYTHON_VERSION >= 0x3c0 && PYTHON_VERSION < 0x3d0
111struct _Nuitka_perf_trampoline_missing_delta {
112 int status;
113 Py_ssize_t extra_code_index;
114 void *code_arena;
115 void *trampoline_api[5];
116 FILE *map_file;
117};
118#elif PYTHON_VERSION >= 0x3d0
119struct _Nuitka_perf_trampoline_missing_delta_early {
120 int status;
121 int perf_trampoline_type;
122 Py_ssize_t extra_code_index;
123 void *code_arena;
124 void *trampoline_api[5];
125 FILE *map_file;
126 Py_ssize_t persist_after_fork;
127};
128struct _Nuitka_perf_trampoline_missing_delta_late {
129 int status;
130 int perf_trampoline_type;
131 Py_ssize_t extra_code_index;
132 void *code_arena;
133 void *trampoline_api[5];
134 FILE *map_file;
135 Py_ssize_t persist_after_fork;
136 void *prev_eval_frame;
137 Py_ssize_t trampoline_refcount;
138 int code_watcher_id;
139};
140#endif
141
142#if PYTHON_VERSION >= 0x3c0
143static inline size_t _Nuitka_perf_trampoline_get_deduction(void) {
144#if PYTHON_VERSION < 0x3d0 || PYTHON_VERSION >= 0x3f0
145 return sizeof(struct _Nuitka_perf_trampoline_missing_delta) - sizeof(int);
146#else
147 int ver = Nuitka_GetRuntimeVersion();
148 // 3.13 micro-version cutoff is 3.13.12
149 // 3.14 micro-version cutoff is 3.14.3
150 if ((ver >= 0x3d0 && ver < 0x3e0 && ver >= 0x3dc) || (ver >= 0x3e0 && ver < 0x3f0 && ver >= 0x3e3)) {
151 return sizeof(struct _Nuitka_perf_trampoline_missing_delta_late) - sizeof(int);
152 } else {
153 return sizeof(struct _Nuitka_perf_trampoline_missing_delta_early) - sizeof(int);
154 }
155#endif
156}
157
158static inline size_t _Nuitka_perf_trampoline_get_deduction_compile_time(void) {
159#if PYTHON_VERSION < 0x3d0 || PYTHON_VERSION >= 0x3f0
160 return sizeof(struct _Nuitka_perf_trampoline_missing_delta) - sizeof(int);
161#else
162 // Use PYTHON_VERSION macro for compile-time deduction
163#if (PYTHON_VERSION >= 0x3d0 && PYTHON_VERSION < 0x3e0 && PYTHON_VERSION >= 0x3dc) || \
164 (PYTHON_VERSION >= 0x3e0 && PYTHON_VERSION < 0x3f0 && PYTHON_VERSION >= 0x3e3)
165 return sizeof(struct _Nuitka_perf_trampoline_missing_delta_late) - sizeof(int);
166#else
167 return sizeof(struct _Nuitka_perf_trampoline_missing_delta_early) - sizeof(int);
168#endif
169#endif
170}
171#endif
172
173static inline size_t Nuitka_PyRuntime_GetOffset__PyRuntimeState_imports(void) {
174 size_t c_offset = offsetof(_PyRuntimeState, imports);
175#if PYTHON_VERSION >= 0x3c0
176 if (c_offset > offsetof(_PyRuntimeState, ceval)) {
177#if defined(PY_HAVE_PERF_TRAMPOLINE)
178 c_offset -= _Nuitka_perf_trampoline_get_deduction_compile_time();
179#endif
180 if (Nuitka_RuntimeHasPerfTrampoline()) {
181 c_offset += _Nuitka_perf_trampoline_get_deduction();
182 }
183 }
184#endif
185 return c_offset;
186}
187#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_imports Nuitka_PyRuntime_GetOffset__PyRuntimeState_imports()
188static inline size_t Nuitka_PyRuntime_GetOffset__PyRuntimeState_static_objects(void) {
189 size_t c_offset = offsetof(_PyRuntimeState, static_objects);
190#if PYTHON_VERSION >= 0x3c0
191 if (c_offset > offsetof(_PyRuntimeState, ceval)) {
192#if defined(PY_HAVE_PERF_TRAMPOLINE)
193 c_offset -= _Nuitka_perf_trampoline_get_deduction_compile_time();
194#endif
195 if (Nuitka_RuntimeHasPerfTrampoline()) {
196 c_offset += _Nuitka_perf_trampoline_get_deduction();
197 }
198 }
199#endif
200 return c_offset;
201}
202#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_static_objects \
203 Nuitka_PyRuntime_GetOffset__PyRuntimeState_static_objects()
204static inline size_t Nuitka_PyRuntime_GetOffset__PyRuntimeState_ceval(void) {
205 size_t c_offset = offsetof(_PyRuntimeState, ceval);
206#if PYTHON_VERSION >= 0x3c0
207 if (c_offset > offsetof(_PyRuntimeState, ceval)) {
208#if defined(PY_HAVE_PERF_TRAMPOLINE)
209 c_offset -= _Nuitka_perf_trampoline_get_deduction_compile_time();
210#endif
211 if (Nuitka_RuntimeHasPerfTrampoline()) {
212 c_offset += _Nuitka_perf_trampoline_get_deduction();
213 }
214 }
215#endif
216 return c_offset;
217}
218#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_ceval Nuitka_PyRuntime_GetOffset__PyRuntimeState_ceval()
219#if PYTHON_VERSION >= 0x3d0
220static inline size_t Nuitka_PyRuntime_GetOffset__PyRuntimeState_stoptheworld(void) {
221 size_t c_offset = offsetof(_PyRuntimeState, stoptheworld);
222#if PYTHON_VERSION >= 0x3c0
223 if (c_offset > offsetof(_PyRuntimeState, ceval)) {
224#if defined(PY_HAVE_PERF_TRAMPOLINE)
225 c_offset -= _Nuitka_perf_trampoline_get_deduction_compile_time();
226#endif
227 if (Nuitka_RuntimeHasPerfTrampoline()) {
228 c_offset += _Nuitka_perf_trampoline_get_deduction();
229 }
230 }
231#endif
232 return c_offset;
233}
234#define NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_stoptheworld Nuitka_PyRuntime_GetOffset__PyRuntimeState_stoptheworld()
235#endif
236#endif
237#if (!_NUITKA_MODULE_MODE && !defined(__MINGW64__)) || (!defined(__linux__) && !defined(_WIN32))
238#define NUITKA_PYRUNTIME_PTR(struct_start, comp) ((char *)(struct_start) + offsetof(_PyRuntimeState, comp))
239#else
240#define NUITKA_PYRUNTIME_PTR(struct_start, comp) \
241 ((char *)(struct_start) + NUITKA_PYRUNTIME_OFFSET__PyRuntimeState_##comp)
242#endif
243
244/*
245 * Dynamic offset extraction with compiler-enforced Type Safety.
246 * If Nuitka developer casts to the wrong structural C type, CI triggers an incompatible-pointer error natively.
247 */
248#if defined(__GNUC__) || defined(__clang__)
249#define NUITKA_PYRUNTIME_DYNAMIC(var, comp, type) \
250 ({ \
251 __typeof__(((_PyRuntimeState *)0)->comp) *_type_check = (type *)0; \
252 (void)_type_check; \
253 (type *)NUITKA_PYRUNTIME_PTR(var, comp); \
254 })
255#else
256#define NUITKA_PYRUNTIME_DYNAMIC(var, comp, type) ((type *)NUITKA_PYRUNTIME_PTR(var, comp))
257#endif
258
259/*
260 * Poison direct access to _PyRuntime.
261 * This guarantees any direct references in the Nuitka codebase cause a compile
262 * error, enforcing cross-compiler ABI safety via NUITKA_PYRUNTIME_PTR.
263 */
264PyAPI_DATA(_PyRuntimeState) _PyRuntime;
265
266static inline _PyRuntimeState *_Nuitka_Get_PyRuntime_PTR(void) { return &_PyRuntime; }
267#define _Nuitka_PyRuntime_PTR (_Nuitka_Get_PyRuntime_PTR())
268
269/* Nuitka C API strongly-typed access macros */
270#if PYTHON_VERSION >= 0x3c0
271#define Nuitka_PyRuntime__imports NUITKA_PYRUNTIME_DYNAMIC(_Nuitka_PyRuntime_PTR, imports, struct _import_runtime_state)
272#define Nuitka_PyRuntime__static_objects \
273 NUITKA_PYRUNTIME_DYNAMIC(_Nuitka_PyRuntime_PTR, static_objects, struct _Py_static_objects)
274#endif
275
276#if PYTHON_VERSION >= 0x3d0
277#define _PyRuntime (*((struct NUITKA_ERROR_Do_not_use_PyRuntime_directly_use_NUITKA_PYRUNTIME_PTR *)0))
278#endif
279
280#endif
281
282// Part of "Nuitka", an optimizing Python compiler that is compatible and
283// integrates with CPython, but also works on its own.
284//
285// Licensed under the GNU Affero General Public License, Version 3 (the "License");
286// you may not use this file except in compliance with the License.
287// You may obtain a copy of the License at
288//
289// http://www.gnu.org/licenses/agpl.txt
290//
291// Unless required by applicable law or agreed to in writing, software
292// distributed under the License is distributed on an "AS IS" BASIS,
293// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
294// See the License for the specific language governing permissions and
295// limitations under the License.