python3_sys/
code.rs

1#[allow(unused_imports)]
2use libc::{c_char, c_short, c_int, c_uchar, c_void};
3
4use crate::object::*;
5use crate::pyport::Py_ssize_t;
6
7#[cfg(Py_3_8)]
8#[repr(C)]
9pub struct _PyOpcache {
10    _private: [u8; 0],
11}
12
13#[derive(Copy)]
14#[repr(C)]
15#[cfg(Py_3_11)]
16// The field orderings have completely changed in 3.11,
17// so we seperate it out into a different type declaration
18// 
19// the justification for the reordering was "optimization"
20pub struct PyCodeObject {
21    pub ob_base: PyVarObject,
22    pub co_consts: *mut PyObject,
23    pub co_names: *mut PyObject,
24    pub co_exceptiontable: *mut PyObject,
25    pub co_flags: c_int,
26    #[cfg(not(Py_3_12))]
27    pub co_warmup: c_short,
28    pub co_argcount: c_int,
29    pub co_posonlyargcount: c_int,
30    pub co_kwonlyargcount: c_int,
31    pub co_stacksize: c_int,
32    pub co_firstlineno: c_int,
33    pub co_nlocalsplus: c_int,
34    #[cfg(Py_3_12)]
35    pub co_framesize: c_int,
36    pub co_nlocals: c_int,
37    #[cfg(not(Py_3_12))]
38    pub co_nplaincellvars: c_int,
39    pub co_ncellvars: c_int,
40    pub co_nfreevars: c_int,
41    #[cfg(Py_3_12)]
42    pub co_version: u32,
43    pub co_localsplusnames: *mut PyObject,
44    pub co_localspluskinds: *mut PyObject,
45    pub co_filename: *mut PyObject,
46    pub co_name: *mut PyObject,
47    pub co_qualname: *mut PyObject,
48    pub co_linetable: *mut PyObject,
49    pub co_weakreflist: *mut PyObject,
50    // Intently omitting some internal fields at the end of this structure
51}
52
53#[repr(C)]
54#[derive(Copy)]
55#[cfg(not(Py_3_11))] 
56pub struct PyCodeObject {
57    pub ob_base: PyObject,
58    pub co_argcount: c_int,
59    #[cfg(Py_3_8)]
60    pub co_posonlyargcount: c_int,
61    pub co_kwonlyargcount: c_int,
62    pub co_nlocals: c_int,
63    pub co_stacksize: c_int,
64    pub co_flags: c_int,
65    #[cfg(Py_3_6)]
66    pub co_firstlineno: c_int,
67    pub co_code: *mut PyObject,
68    pub co_consts: *mut PyObject,
69    pub co_names: *mut PyObject,
70    pub co_varnames: *mut PyObject,
71    pub co_freevars: *mut PyObject,
72    pub co_cellvars: *mut PyObject,
73    #[cfg(not(Py_3_7))]
74    pub co_cell2arg: *mut c_uchar,
75    #[cfg(Py_3_7)]
76    pub co_cell2arg: *mut Py_ssize_t,
77    pub co_filename: *mut PyObject,
78    pub co_name: *mut PyObject,
79    #[cfg(not(Py_3_6))]
80    pub co_firstlineno: c_int,
81    #[cfg(not(Py_3_10))]
82    pub co_lnotab: *mut PyObject,
83    #[cfg(Py_3_10)]
84    pub co_linetable: *mut PyObject,
85    pub co_zombieframe: *mut c_void,
86    pub co_weakreflist: *mut PyObject,
87    #[cfg(Py_3_6)]
88    pub co_extra: *mut c_void,
89    #[cfg(Py_3_8)]
90    pub co_opcache_map: *mut c_uchar,
91    #[cfg(Py_3_8)]
92    pub co_opcache: *mut _PyOpcache,
93    #[cfg(Py_3_8)]
94    pub co_opcache_flag: c_int,
95    #[cfg(Py_3_8)]
96    pub co_opcache_size: c_uchar,
97}
98impl Clone for PyCodeObject {
99    #[inline]
100    fn clone(&self) -> Self {
101        *self
102    }
103}
104impl Default for PyCodeObject {
105    #[inline]
106    fn default() -> Self {
107        unsafe { core::mem::zeroed() }
108    }
109}
110
111/* Masks for co_flags */
112pub const CO_OPTIMIZED: c_int = 0x0001;
113pub const CO_NEWLOCALS: c_int = 0x0002;
114pub const CO_VARARGS: c_int = 0x0004;
115pub const CO_VARKEYWORDS: c_int = 0x0008;
116pub const CO_NESTED: c_int = 0x0010;
117pub const CO_GENERATOR: c_int = 0x0020;
118/* The CO_NOFREE flag is set if there are no free or cell variables.
119   This information is redundant, but it allows a single flag test
120   to determine whether there is any extra work to be done when the
121   call frame it setup.
122*/
123pub const CO_NOFREE: c_int = 0x0040;
124/* The CO_COROUTINE flag is set for coroutine functions (defined with
125``async def`` keywords) */
126#[cfg(Py_3_5)]
127pub const CO_COROUTINE: c_int = 0x0080;
128#[cfg(Py_3_5)]
129pub const CO_ITERABLE_COROUTINE: c_int = 0x0100;
130#[cfg(Py_3_6)]
131pub const CO_ASYNC_GENERATOR: c_int = 0x0200;
132
133pub const CO_FUTURE_DIVISION: c_int = 0x2000;
134pub const CO_FUTURE_ABSOLUTE_IMPORT: c_int = 0x4000; /* do absolute imports by default */
135pub const CO_FUTURE_WITH_STATEMENT: c_int = 0x8000;
136pub const CO_FUTURE_PRINT_FUNCTION: c_int = 0x10000;
137pub const CO_FUTURE_UNICODE_LITERALS: c_int = 0x20000;
138pub const CO_FUTURE_BARRY_AS_BDFL: c_int = 0x40000;
139#[cfg(Py_3_5)]
140pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x80000;
141#[cfg(Py_3_7)]
142pub const CO_FUTURE_ANNOTATIONS: c_int = 0x100000;
143
144#[cfg(not(Py_3_7))]
145pub const CO_CELL_NOT_AN_ARG: c_uchar = 255;
146#[cfg(Py_3_7)]
147pub const CO_CELL_NOT_AN_ARG: Py_ssize_t = -1;
148
149pub const CO_MAXBLOCKS: usize = 20;
150
151#[cfg_attr(windows, link(name = "pythonXY"))]
152extern "C" {
153    pub static mut PyCode_Type: PyTypeObject;
154
155    #[cfg_attr(Py_3_12, link_name = "PyUnstable_Code_New")]
156    pub fn PyCode_New(
157        argcount: c_int,
158        kwonlyargcount: c_int,
159        nlocals: c_int,
160        stacksize: c_int,
161        flags: c_int,
162        code: *mut PyObject,
163        consts: *mut PyObject,
164        names: *mut PyObject,
165        varnames: *mut PyObject,
166        freevars: *mut PyObject,
167        cellvars: *mut PyObject,
168        filename: *mut PyObject,
169        name: *mut PyObject,
170        #[cfg(Py_3_11)]
171        qualname: *mut PyObject,
172        firstlineno: c_int,
173        lnotab: *mut PyObject,
174        #[cfg(Py_3_11)]
175        exceptiontable: *mut PyObject,
176    ) -> *mut PyCodeObject;
177
178    #[cfg(Py_3_8)]
179    #[cfg_attr(Py_3_12, link_name = "PyUnstable_Code_NewWithPosOnlyArgs")]
180    pub fn PyCode_NewWithPosOnlyArgs(
181        argcount: c_int,
182        posonlyargcount: c_int,
183        kwonlyargcount: c_int,
184        nlocals: c_int,
185        stacksize: c_int,
186        flags: c_int,
187        code: *mut PyObject,
188        consts: *mut PyObject,
189        names: *mut PyObject,
190        varnames: *mut PyObject,
191        freevars: *mut PyObject,
192        cellvars: *mut PyObject,
193        filename: *mut PyObject,
194        name: *mut PyObject,
195        #[cfg(Py_3_11)]
196        qualname: *mut PyObject,
197        firstlineno: c_int,
198        lnotab: *mut PyObject,
199        #[cfg(Py_3_11)]
200        exceptiontable: *mut PyObject,
201    ) -> *mut PyCodeObject;
202
203    pub fn PyCode_NewEmpty(
204        filename: *const c_char,
205        funcname: *const c_char,
206        firstlineno: c_int,
207    ) -> *mut PyCodeObject;
208    pub fn PyCode_Addr2Line(arg1: *mut PyCodeObject, arg2: c_int) -> c_int;
209    #[cfg(Py_3_11)]
210    pub fn PyCode_Addr2Location(
211        co: *mut PyCodeObject,
212        byte_offset: c_int,
213        start_line: *mut c_int,
214        start_column: *mut c_int,
215        end_line: *mut c_int,
216        end_column: *mut c_int
217    ) -> c_int;
218    #[cfg(Py_3_11)]
219    pub fn PyCode_GetCode(co: *mut PyCodeObject) -> *mut PyObject;
220    pub fn PyCode_Optimize(
221        code: *mut PyObject,
222        consts: *mut PyObject,
223        names: *mut PyObject,
224        lnotab: *mut PyObject,
225    ) -> *mut PyObject;
226}
227
228#[inline]
229pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
230    (Py_TYPE(op) == &mut PyCode_Type) as c_int
231}
232
233#[inline]
234#[cfg(Py_3_11)]
235pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t {
236    (*op).co_nfreevars as Py_ssize_t
237}
238
239#[inline]
240#[cfg(not(Py_3_11))]
241pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t {
242    crate::tupleobject::PyTuple_GET_SIZE((*op).co_freevars)
243}