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)]
85#[derive(Copy, Clone)]
86pub struct PyCodeObject {
87    pub ob_base: PyObject,
88    pub co_argcount: c_int,
89    pub co_kwonlyargcount: c_int,
90    pub co_nlocals: c_int,
91    pub co_stacksize: c_int,
92    pub co_flags: c_int,
93    pub co_firstlineno: c_int,
94    pub co_code: *mut PyObject,
95    pub co_consts: *mut PyObject,
96    pub co_names: *mut PyObject,
97    pub co_varnames: *mut PyObject,
98    pub co_freevars: *mut PyObject,
99    pub co_cellvars: *mut PyObject,
100    pub co_cell2arg: *mut Py_ssize_t,
101    pub co_filename: *mut PyObject,
102    pub co_name: *mut PyObject,
103    pub co_lnotab: *mut PyObject,
104    pub co_zombieframe: *mut c_void,
105    pub co_weakreflist: *mut PyObject,
106    pub co_extra: *mut c_void,
107}
108
109#[cfg(Py_3_13)]
110opaque_struct!(_PyExecutorArray);
111
112#[cfg(all(not(any(PyPy, GraalPy)), Py_3_8, not(Py_3_11)))]
113#[repr(C)]
114#[derive(Copy, Clone)]
115pub struct PyCodeObject {
116    pub ob_base: PyObject,
117    pub co_argcount: c_int,
118    pub co_posonlyargcount: c_int,
119    pub co_kwonlyargcount: c_int,
120    pub co_nlocals: c_int,
121    pub co_stacksize: c_int,
122    pub co_flags: c_int,
123    pub co_firstlineno: c_int,
124    pub co_code: *mut PyObject,
125    pub co_consts: *mut PyObject,
126    pub co_names: *mut PyObject,
127    pub co_varnames: *mut PyObject,
128    pub co_freevars: *mut PyObject,
129    pub co_cellvars: *mut PyObject,
130    pub co_cell2arg: *mut Py_ssize_t,
131    pub co_filename: *mut PyObject,
132    pub co_name: *mut PyObject,
133    #[cfg(not(Py_3_10))]
134    pub co_lnotab: *mut PyObject,
135    #[cfg(Py_3_10)]
136    pub co_linetable: *mut PyObject,
137    pub co_zombieframe: *mut c_void,
138    pub co_weakreflist: *mut PyObject,
139    pub co_extra: *mut c_void,
140    pub co_opcache_map: *mut c_uchar,
141    pub co_opcache: *mut _PyOpcache,
142    pub co_opcache_flag: c_int,
143    pub co_opcache_size: c_uchar,
144}
145
146#[cfg(all(not(any(PyPy, GraalPy)), Py_3_11))]
147#[repr(C)]
148#[derive(Copy, Clone)]
149pub struct PyCodeObject {
150    pub ob_base: PyVarObject,
151    pub co_consts: *mut PyObject,
152    pub co_names: *mut PyObject,
153    pub co_exceptiontable: *mut PyObject,
154    pub co_flags: c_int,
155    #[cfg(not(Py_3_12))]
156    pub co_warmup: c_int,
157
158    pub co_argcount: c_int,
159    pub co_posonlyargcount: c_int,
160    pub co_kwonlyargcount: c_int,
161    pub co_stacksize: c_int,
162    pub co_firstlineno: c_int,
163
164    pub co_nlocalsplus: c_int,
165    #[cfg(Py_3_12)]
166    pub co_framesize: c_int,
167    pub co_nlocals: c_int,
168    #[cfg(not(Py_3_12))]
169    pub co_nplaincellvars: c_int,
170    pub co_ncellvars: c_int,
171    pub co_nfreevars: c_int,
172    #[cfg(Py_3_12)]
173    pub co_version: u32,
174
175    pub co_localsplusnames: *mut PyObject,
176    pub co_localspluskinds: *mut PyObject,
177    pub co_filename: *mut PyObject,
178    pub co_name: *mut PyObject,
179    pub co_qualname: *mut PyObject,
180    pub co_linetable: *mut PyObject,
181    pub co_weakreflist: *mut PyObject,
182    #[cfg(not(Py_3_12))]
183    pub _co_code: *mut PyObject,
184    #[cfg(not(Py_3_12))]
185    pub _co_linearray: *mut c_char,
186    #[cfg(Py_3_13)]
187    pub co_executors: *mut _PyExecutorArray,
188    #[cfg(Py_3_12)]
189    pub _co_cached: *mut _PyCoCached,
190    #[cfg(Py_3_12)]
191    pub _co_instrumentation_version: u64,
192    #[cfg(Py_3_12)]
193    pub _co_monitoring: *mut _PyCoMonitoringData,
194    pub _co_firsttraceable: c_int,
195    pub co_extra: *mut c_void,
196    pub co_code_adaptive: [c_char; 1],
197}
198
199#[cfg(PyPy)]
200#[repr(C)]
201#[derive(Copy, Clone)]
202pub struct PyCodeObject {
203    pub ob_base: PyObject,
204    pub co_name: *mut PyObject,
205    pub co_filename: *mut PyObject,
206    pub co_argcount: c_int,
207    pub co_flags: c_int,
208}
209
210/* Masks for co_flags */
211pub const CO_OPTIMIZED: c_int = 0x0001;
212pub const CO_NEWLOCALS: c_int = 0x0002;
213pub const CO_VARARGS: c_int = 0x0004;
214pub const CO_VARKEYWORDS: c_int = 0x0008;
215pub const CO_NESTED: c_int = 0x0010;
216pub const CO_GENERATOR: c_int = 0x0020;
217/* The CO_NOFREE flag is set if there are no free or cell variables.
218   This information is redundant, but it allows a single flag test
219   to determine whether there is any extra work to be done when the
220   call frame it setup.
221*/
222pub const CO_NOFREE: c_int = 0x0040;
223/* The CO_COROUTINE flag is set for coroutine functions (defined with
224``async def`` keywords) */
225pub const CO_COROUTINE: c_int = 0x0080;
226pub const CO_ITERABLE_COROUTINE: c_int = 0x0100;
227pub const CO_ASYNC_GENERATOR: c_int = 0x0200;
228
229pub const CO_FUTURE_DIVISION: c_int = 0x2000;
230pub const CO_FUTURE_ABSOLUTE_IMPORT: c_int = 0x4000; /* do absolute imports by default */
231pub const CO_FUTURE_WITH_STATEMENT: c_int = 0x8000;
232pub const CO_FUTURE_PRINT_FUNCTION: c_int = 0x1_0000;
233pub const CO_FUTURE_UNICODE_LITERALS: c_int = 0x2_0000;
234
235pub const CO_FUTURE_BARRY_AS_BDFL: c_int = 0x4_0000;
236pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x8_0000;
237// skipped CO_FUTURE_ANNOTATIONS
238// skipped CO_CELL_NOT_AN_ARG
239
240pub const CO_MAXBLOCKS: usize = 20;
241
242#[cfg(not(any(PyPy, GraalPy)))]
243#[cfg_attr(windows, link(name = "pythonXY"))]
244extern "C" {
245    pub static mut PyCode_Type: PyTypeObject;
246}
247
248#[inline]
249#[cfg(not(any(PyPy, GraalPy)))]
250pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
251    (Py_TYPE(op) == addr_of_mut!(PyCode_Type)) as c_int
252}
253
254#[inline]
255#[cfg(all(not(any(PyPy, GraalPy)), Py_3_10, not(Py_3_11)))]
256pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t {
257    crate::PyTuple_GET_SIZE((*op).co_freevars)
258}
259
260#[inline]
261#[cfg(all(not(Py_3_10), Py_3_11, not(any(PyPy, GraalPy))))]
262pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> c_int {
263    (*op).co_nfreevars
264}
265
266extern "C" {
267    #[cfg(PyPy)]
268    #[link_name = "PyPyCode_Check"]
269    pub fn PyCode_Check(op: *mut PyObject) -> c_int;
270
271    #[cfg(PyPy)]
272    #[link_name = "PyPyCode_GetNumFree"]
273    pub fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t;
274}
275
276extern "C" {
277    #[cfg(not(GraalPy))]
278    #[cfg_attr(PyPy, link_name = "PyPyCode_New")]
279    pub fn PyCode_New(
280        argcount: c_int,
281        kwonlyargcount: c_int,
282        nlocals: c_int,
283        stacksize: c_int,
284        flags: c_int,
285        code: *mut PyObject,
286        consts: *mut PyObject,
287        names: *mut PyObject,
288        varnames: *mut PyObject,
289        freevars: *mut PyObject,
290        cellvars: *mut PyObject,
291        filename: *mut PyObject,
292        name: *mut PyObject,
293        firstlineno: c_int,
294        lnotab: *mut PyObject,
295    ) -> *mut PyCodeObject;
296    #[cfg(not(GraalPy))]
297    #[cfg(Py_3_8)]
298    pub fn PyCode_NewWithPosOnlyArgs(
299        argcount: c_int,
300        posonlyargcount: c_int,
301        kwonlyargcount: c_int,
302        nlocals: c_int,
303        stacksize: c_int,
304        flags: c_int,
305        code: *mut PyObject,
306        consts: *mut PyObject,
307        names: *mut PyObject,
308        varnames: *mut PyObject,
309        freevars: *mut PyObject,
310        cellvars: *mut PyObject,
311        filename: *mut PyObject,
312        name: *mut PyObject,
313        firstlineno: c_int,
314        lnotab: *mut PyObject,
315    ) -> *mut PyCodeObject;
316    #[cfg(not(GraalPy))]
317    #[cfg_attr(PyPy, link_name = "PyPyCode_NewEmpty")]
318    pub fn PyCode_NewEmpty(
319        filename: *const c_char,
320        funcname: *const c_char,
321        firstlineno: c_int,
322    ) -> *mut PyCodeObject;
323    #[cfg(not(GraalPy))]
324    pub fn PyCode_Addr2Line(arg1: *mut PyCodeObject, arg2: c_int) -> c_int;
325    // skipped PyCodeAddressRange "for internal use only"
326    // skipped _PyCode_CheckLineNumber
327    // skipped _PyCode_ConstantKey
328    pub fn PyCode_Optimize(
329        code: *mut PyObject,
330        consts: *mut PyObject,
331        names: *mut PyObject,
332        lnotab: *mut PyObject,
333    ) -> *mut PyObject;
334    pub fn _PyCode_GetExtra(
335        code: *mut PyObject,
336        index: Py_ssize_t,
337        extra: *const *mut c_void,
338    ) -> c_int;
339    pub fn _PyCode_SetExtra(code: *mut PyObject, index: Py_ssize_t, extra: *mut c_void) -> c_int;
340}