pyo3_ffi/cpython/
code.rs

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