pyo3_ffi/cpython/
code.rs

1use crate::object::*;
2use crate::pyport::Py_ssize_t;
3
4#[allow(unused_imports)]
5use std::os::raw::{c_char, c_int, c_short, c_uchar, c_void};
6#[cfg(not(any(PyPy, GraalPy)))]
7use std::ptr::addr_of_mut;
8
9#[cfg(all(Py_3_8, not(any(PyPy, GraalPy)), not(Py_3_11)))]
10opaque_struct!(_PyOpcache);
11
12#[cfg(Py_3_12)]
13pub const _PY_MONITORING_LOCAL_EVENTS: usize = 10;
14#[cfg(Py_3_12)]
15pub const _PY_MONITORING_UNGROUPED_EVENTS: usize = 15;
16#[cfg(Py_3_12)]
17pub const _PY_MONITORING_EVENTS: usize = 17;
18
19#[cfg(Py_3_12)]
20#[repr(C)]
21#[derive(Clone, Copy)]
22pub struct _Py_LocalMonitors {
23    pub tools: [u8; if cfg!(Py_3_13) {
24        _PY_MONITORING_LOCAL_EVENTS
25    } else {
26        _PY_MONITORING_UNGROUPED_EVENTS
27    }],
28}
29
30#[cfg(Py_3_12)]
31#[repr(C)]
32#[derive(Clone, Copy)]
33pub struct _Py_GlobalMonitors {
34    pub tools: [u8; _PY_MONITORING_UNGROUPED_EVENTS],
35}
36
37// skipped _Py_CODEUNIT
38
39// skipped _Py_OPCODE
40// skipped _Py_OPARG
41
42// skipped _py_make_codeunit
43
44// skipped _py_set_opcode
45
46// skipped _Py_MAKE_CODEUNIT
47// skipped _Py_SET_OPCODE
48
49#[cfg(Py_3_12)]
50#[repr(C)]
51#[derive(Copy, Clone)]
52pub struct _PyCoCached {
53    pub _co_code: *mut PyObject,
54    pub _co_varnames: *mut PyObject,
55    pub _co_cellvars: *mut PyObject,
56    pub _co_freevars: *mut PyObject,
57}
58
59#[cfg(Py_3_12)]
60#[repr(C)]
61#[derive(Copy, Clone)]
62pub struct _PyCoLineInstrumentationData {
63    pub original_opcode: u8,
64    pub line_delta: i8,
65}
66
67#[cfg(Py_3_12)]
68#[repr(C)]
69#[derive(Copy, Clone)]
70pub struct _PyCoMonitoringData {
71    pub local_monitors: _Py_LocalMonitors,
72    pub active_monitors: _Py_LocalMonitors,
73    pub tools: *mut u8,
74    pub lines: *mut _PyCoLineInstrumentationData,
75    pub line_tools: *mut u8,
76    pub per_instruction_opcodes: *mut u8,
77    pub per_instruction_tools: *mut u8,
78}
79
80#[cfg(all(not(any(PyPy, GraalPy)), not(Py_3_7)))]
81opaque_struct!(PyCodeObject);
82
83#[cfg(all(not(any(PyPy, GraalPy)), Py_3_7, not(Py_3_8)))]
84#[repr(C)]
85pub struct PyCodeObject {
86    pub ob_base: PyObject,
87    pub co_argcount: c_int,
88    pub co_kwonlyargcount: c_int,
89    pub co_nlocals: c_int,
90    pub co_stacksize: c_int,
91    pub co_flags: c_int,
92    pub co_firstlineno: c_int,
93    pub co_code: *mut PyObject,
94    pub co_consts: *mut PyObject,
95    pub co_names: *mut PyObject,
96    pub co_varnames: *mut PyObject,
97    pub co_freevars: *mut PyObject,
98    pub co_cellvars: *mut PyObject,
99    pub co_cell2arg: *mut Py_ssize_t,
100    pub co_filename: *mut PyObject,
101    pub co_name: *mut PyObject,
102    pub co_lnotab: *mut PyObject,
103    pub co_zombieframe: *mut c_void,
104    pub co_weakreflist: *mut PyObject,
105    pub co_extra: *mut c_void,
106}
107
108#[cfg(Py_3_13)]
109opaque_struct!(_PyExecutorArray);
110
111#[cfg(all(not(any(PyPy, GraalPy)), Py_3_8, not(Py_3_11)))]
112#[repr(C)]
113pub struct PyCodeObject {
114    pub ob_base: PyObject,
115    pub co_argcount: c_int,
116    pub co_posonlyargcount: c_int,
117    pub co_kwonlyargcount: c_int,
118    pub co_nlocals: c_int,
119    pub co_stacksize: c_int,
120    pub co_flags: c_int,
121    pub co_firstlineno: c_int,
122    pub co_code: *mut PyObject,
123    pub co_consts: *mut PyObject,
124    pub co_names: *mut PyObject,
125    pub co_varnames: *mut PyObject,
126    pub co_freevars: *mut PyObject,
127    pub co_cellvars: *mut PyObject,
128    pub co_cell2arg: *mut Py_ssize_t,
129    pub co_filename: *mut PyObject,
130    pub co_name: *mut PyObject,
131    #[cfg(not(Py_3_10))]
132    pub co_lnotab: *mut PyObject,
133    #[cfg(Py_3_10)]
134    pub co_linetable: *mut PyObject,
135    pub co_zombieframe: *mut c_void,
136    pub co_weakreflist: *mut PyObject,
137    pub co_extra: *mut c_void,
138    pub co_opcache_map: *mut c_uchar,
139    pub co_opcache: *mut _PyOpcache,
140    pub co_opcache_flag: c_int,
141    pub co_opcache_size: c_uchar,
142}
143
144#[cfg(all(not(any(PyPy, GraalPy)), Py_3_11))]
145#[repr(C)]
146pub struct PyCodeObject {
147    pub ob_base: PyVarObject,
148    pub co_consts: *mut PyObject,
149    pub co_names: *mut PyObject,
150    pub co_exceptiontable: *mut PyObject,
151    pub co_flags: c_int,
152    #[cfg(not(Py_3_12))]
153    pub co_warmup: c_int,
154
155    pub co_argcount: c_int,
156    pub co_posonlyargcount: c_int,
157    pub co_kwonlyargcount: c_int,
158    pub co_stacksize: c_int,
159    pub co_firstlineno: c_int,
160
161    pub co_nlocalsplus: c_int,
162    #[cfg(Py_3_12)]
163    pub co_framesize: c_int,
164    pub co_nlocals: c_int,
165    #[cfg(not(Py_3_12))]
166    pub co_nplaincellvars: c_int,
167    pub co_ncellvars: c_int,
168    pub co_nfreevars: c_int,
169    #[cfg(Py_3_12)]
170    pub co_version: u32,
171
172    pub co_localsplusnames: *mut PyObject,
173    pub co_localspluskinds: *mut PyObject,
174    pub co_filename: *mut PyObject,
175    pub co_name: *mut PyObject,
176    pub co_qualname: *mut PyObject,
177    pub co_linetable: *mut PyObject,
178    pub co_weakreflist: *mut PyObject,
179    #[cfg(not(Py_3_12))]
180    pub _co_code: *mut PyObject,
181    #[cfg(not(Py_3_12))]
182    pub _co_linearray: *mut c_char,
183    #[cfg(Py_3_13)]
184    pub co_executors: *mut _PyExecutorArray,
185    #[cfg(Py_3_12)]
186    pub _co_cached: *mut _PyCoCached,
187    #[cfg(Py_3_12)]
188    pub _co_instrumentation_version: u64,
189    #[cfg(Py_3_12)]
190    pub _co_monitoring: *mut _PyCoMonitoringData,
191    pub _co_firsttraceable: c_int,
192    pub co_extra: *mut c_void,
193    pub co_code_adaptive: [c_char; 1],
194}
195
196#[cfg(PyPy)]
197#[repr(C)]
198pub struct PyCodeObject {
199    pub ob_base: PyObject,
200    pub co_name: *mut PyObject,
201    pub co_filename: *mut PyObject,
202    pub co_argcount: c_int,
203    pub co_flags: c_int,
204}
205
206/* Masks for co_flags */
207pub const CO_OPTIMIZED: c_int = 0x0001;
208pub const CO_NEWLOCALS: c_int = 0x0002;
209pub const CO_VARARGS: c_int = 0x0004;
210pub const CO_VARKEYWORDS: c_int = 0x0008;
211pub const CO_NESTED: c_int = 0x0010;
212pub const CO_GENERATOR: c_int = 0x0020;
213/* The CO_NOFREE flag is set if there are no free or cell variables.
214   This information is redundant, but it allows a single flag test
215   to determine whether there is any extra work to be done when the
216   call frame it setup.
217*/
218pub const CO_NOFREE: c_int = 0x0040;
219/* The CO_COROUTINE flag is set for coroutine functions (defined with
220``async def`` keywords) */
221pub const CO_COROUTINE: c_int = 0x0080;
222pub const CO_ITERABLE_COROUTINE: c_int = 0x0100;
223pub const CO_ASYNC_GENERATOR: c_int = 0x0200;
224
225pub const CO_FUTURE_DIVISION: c_int = 0x2000;
226pub const CO_FUTURE_ABSOLUTE_IMPORT: c_int = 0x4000; /* do absolute imports by default */
227pub const CO_FUTURE_WITH_STATEMENT: c_int = 0x8000;
228pub const CO_FUTURE_PRINT_FUNCTION: c_int = 0x1_0000;
229pub const CO_FUTURE_UNICODE_LITERALS: c_int = 0x2_0000;
230
231pub const CO_FUTURE_BARRY_AS_BDFL: c_int = 0x4_0000;
232pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x8_0000;
233// skipped CO_FUTURE_ANNOTATIONS
234// skipped CO_CELL_NOT_AN_ARG
235
236pub const CO_MAXBLOCKS: usize = 20;
237
238#[cfg(not(any(PyPy, GraalPy)))]
239#[cfg_attr(windows, link(name = "pythonXY"))]
240extern "C" {
241    pub static mut PyCode_Type: PyTypeObject;
242}
243
244#[inline]
245#[cfg(not(any(PyPy, GraalPy)))]
246pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
247    (Py_TYPE(op) == addr_of_mut!(PyCode_Type)) as c_int
248}
249
250#[inline]
251#[cfg(all(not(any(PyPy, GraalPy)), Py_3_10, not(Py_3_11)))]
252pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t {
253    crate::PyTuple_GET_SIZE((*op).co_freevars)
254}
255
256#[inline]
257#[cfg(all(not(Py_3_10), Py_3_11, not(any(PyPy, GraalPy))))]
258pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> c_int {
259    (*op).co_nfreevars
260}
261
262extern "C" {
263    #[cfg(PyPy)]
264    #[link_name = "PyPyCode_Check"]
265    pub fn PyCode_Check(op: *mut PyObject) -> c_int;
266
267    #[cfg(PyPy)]
268    #[link_name = "PyPyCode_GetNumFree"]
269    pub fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t;
270}
271
272extern "C" {
273    #[cfg(not(GraalPy))]
274    #[cfg_attr(PyPy, link_name = "PyPyCode_New")]
275    pub fn PyCode_New(
276        argcount: c_int,
277        kwonlyargcount: c_int,
278        nlocals: c_int,
279        stacksize: c_int,
280        flags: c_int,
281        code: *mut PyObject,
282        consts: *mut PyObject,
283        names: *mut PyObject,
284        varnames: *mut PyObject,
285        freevars: *mut PyObject,
286        cellvars: *mut PyObject,
287        filename: *mut PyObject,
288        name: *mut PyObject,
289        firstlineno: c_int,
290        lnotab: *mut PyObject,
291    ) -> *mut PyCodeObject;
292    #[cfg(not(GraalPy))]
293    #[cfg(Py_3_8)]
294    pub fn PyCode_NewWithPosOnlyArgs(
295        argcount: c_int,
296        posonlyargcount: c_int,
297        kwonlyargcount: c_int,
298        nlocals: c_int,
299        stacksize: c_int,
300        flags: c_int,
301        code: *mut PyObject,
302        consts: *mut PyObject,
303        names: *mut PyObject,
304        varnames: *mut PyObject,
305        freevars: *mut PyObject,
306        cellvars: *mut PyObject,
307        filename: *mut PyObject,
308        name: *mut PyObject,
309        firstlineno: c_int,
310        lnotab: *mut PyObject,
311    ) -> *mut PyCodeObject;
312    #[cfg(not(GraalPy))]
313    #[cfg_attr(PyPy, link_name = "PyPyCode_NewEmpty")]
314    pub fn PyCode_NewEmpty(
315        filename: *const c_char,
316        funcname: *const c_char,
317        firstlineno: c_int,
318    ) -> *mut PyCodeObject;
319    #[cfg(not(GraalPy))]
320    pub fn PyCode_Addr2Line(arg1: *mut PyCodeObject, arg2: c_int) -> c_int;
321    // skipped PyCodeAddressRange "for internal use only"
322    // skipped _PyCode_CheckLineNumber
323    // skipped _PyCode_ConstantKey
324    pub fn PyCode_Optimize(
325        code: *mut PyObject,
326        consts: *mut PyObject,
327        names: *mut PyObject,
328        lnotab: *mut PyObject,
329    ) -> *mut PyObject;
330    pub fn _PyCode_GetExtra(
331        code: *mut PyObject,
332        index: Py_ssize_t,
333        extra: *const *mut c_void,
334    ) -> c_int;
335    pub fn _PyCode_SetExtra(code: *mut PyObject, index: Py_ssize_t, extra: *mut c_void) -> c_int;
336}