Skip to main content

pyo3_ffi/cpython/
code.rs

1use crate::object::*;
2use crate::pyport::Py_ssize_t;
3
4#[cfg(not(GraalPy))]
5use crate::PyCodeObject;
6#[cfg(not(GraalPy))]
7use std::ffi::c_char;
8use std::ffi::{c_int, c_void};
9#[cfg(not(PyPy))]
10use std::ptr::addr_of_mut;
11
12// skipped private _PY_MONITORING_LOCAL_EVENTS
13// skipped private _PY_MONITORING_UNGROUPED_EVENTS
14// skipped private _PY_MONITORING_EVENTS
15
16// skipped private _PyLocalMonitors
17// skipped private _Py_GlobalMonitors
18
19// skipped private _Py_CODEUNIT
20
21// skipped private _Py_OPCODE
22// skipped private _Py_OPARG
23
24// skipped private _py_make_codeunit
25
26// skipped private _py_set_opcode
27
28// skipped private _Py_MAKE_CODEUNIT
29// skipped private _Py_SET_OPCODE
30
31// skipped private _PyCoCached
32// skipped private _PyCoLineInstrumentationData
33// skipped private _PyCoMonitoringData
34
35// skipped private _PyExecutorArray
36
37/* Masks for co_flags */
38pub const CO_OPTIMIZED: c_int = 0x0001;
39pub const CO_NEWLOCALS: c_int = 0x0002;
40pub const CO_VARARGS: c_int = 0x0004;
41pub const CO_VARKEYWORDS: c_int = 0x0008;
42pub const CO_NESTED: c_int = 0x0010;
43pub const CO_GENERATOR: c_int = 0x0020;
44/* The CO_NOFREE flag is set if there are no free or cell variables.
45   This information is redundant, but it allows a single flag test
46   to determine whether there is any extra work to be done when the
47   call frame it setup.
48*/
49pub const CO_NOFREE: c_int = 0x0040;
50/* The CO_COROUTINE flag is set for coroutine functions (defined with
51``async def`` keywords) */
52pub const CO_COROUTINE: c_int = 0x0080;
53pub const CO_ITERABLE_COROUTINE: c_int = 0x0100;
54pub const CO_ASYNC_GENERATOR: c_int = 0x0200;
55
56pub const CO_FUTURE_DIVISION: c_int = 0x2000;
57pub const CO_FUTURE_ABSOLUTE_IMPORT: c_int = 0x4000; /* do absolute imports by default */
58pub const CO_FUTURE_WITH_STATEMENT: c_int = 0x8000;
59pub const CO_FUTURE_PRINT_FUNCTION: c_int = 0x1_0000;
60pub const CO_FUTURE_UNICODE_LITERALS: c_int = 0x2_0000;
61
62pub const CO_FUTURE_BARRY_AS_BDFL: c_int = 0x4_0000;
63pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x8_0000;
64// skipped CO_FUTURE_ANNOTATIONS
65// skipped CO_CELL_NOT_AN_ARG
66
67pub const CO_MAXBLOCKS: usize = 20;
68
69#[cfg(not(PyPy))]
70#[cfg_attr(windows, link(name = "pythonXY"))]
71extern "C" {
72    pub static mut PyCode_Type: PyTypeObject;
73}
74
75#[inline]
76#[cfg(not(PyPy))]
77pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
78    (Py_TYPE(op) == addr_of_mut!(PyCode_Type)) as c_int
79}
80
81extern "C" {
82    #[cfg(PyPy)]
83    #[link_name = "PyPyCode_Check"]
84    pub fn PyCode_Check(op: *mut PyObject) -> c_int;
85}
86
87// skipped PyCode_GetNumFree (requires knowledge of code object layout)
88
89extern "C" {
90    #[cfg(not(GraalPy))]
91    #[cfg_attr(PyPy, link_name = "PyPyCode_New")]
92    pub fn PyCode_New(
93        argcount: c_int,
94        kwonlyargcount: c_int,
95        nlocals: c_int,
96        stacksize: c_int,
97        flags: c_int,
98        code: *mut PyObject,
99        consts: *mut PyObject,
100        names: *mut PyObject,
101        varnames: *mut PyObject,
102        freevars: *mut PyObject,
103        cellvars: *mut PyObject,
104        filename: *mut PyObject,
105        name: *mut PyObject,
106        firstlineno: c_int,
107        lnotab: *mut PyObject,
108    ) -> *mut PyCodeObject;
109    #[cfg(not(GraalPy))]
110    #[cfg(Py_3_8)]
111    pub fn PyCode_NewWithPosOnlyArgs(
112        argcount: c_int,
113        posonlyargcount: c_int,
114        kwonlyargcount: c_int,
115        nlocals: c_int,
116        stacksize: c_int,
117        flags: c_int,
118        code: *mut PyObject,
119        consts: *mut PyObject,
120        names: *mut PyObject,
121        varnames: *mut PyObject,
122        freevars: *mut PyObject,
123        cellvars: *mut PyObject,
124        filename: *mut PyObject,
125        name: *mut PyObject,
126        firstlineno: c_int,
127        lnotab: *mut PyObject,
128    ) -> *mut PyCodeObject;
129    #[cfg(not(GraalPy))]
130    #[cfg_attr(PyPy, link_name = "PyPyCode_NewEmpty")]
131    pub fn PyCode_NewEmpty(
132        filename: *const c_char,
133        funcname: *const c_char,
134        firstlineno: c_int,
135    ) -> *mut PyCodeObject;
136    #[cfg(not(GraalPy))]
137    pub fn PyCode_Addr2Line(arg1: *mut PyCodeObject, arg2: c_int) -> c_int;
138    // skipped PyCodeAddressRange "for internal use only"
139    // skipped _PyCode_CheckLineNumber
140    // skipped _PyCode_ConstantKey
141    pub fn PyCode_Optimize(
142        code: *mut PyObject,
143        consts: *mut PyObject,
144        names: *mut PyObject,
145        lnotab: *mut PyObject,
146    ) -> *mut PyObject;
147    pub fn _PyCode_GetExtra(
148        code: *mut PyObject,
149        index: Py_ssize_t,
150        extra: *const *mut c_void,
151    ) -> c_int;
152    pub fn _PyCode_SetExtra(code: *mut PyObject, index: Py_ssize_t, extra: *mut c_void) -> c_int;
153}