ffi module cleanup (#1338)

* initial work to clean up ffi module

* ffi: mirror cpython Includes

* ffi: start to alphebetise, note skipped headers

* ffi: temporarily move _PyFrameEvalFunction back

* ffi cleanup: fix pypy compilation

* Update src/ffi/mod.rs

Co-authored-by: Yuji Kanagawa <yuji.kngw.80s.revive@gmail.com>

* add suggested changes

* ffi cleanup: remove unnecessary use stmt

* ffi cleanup: add deprecation warning

* ffi cleanup: transitively deprecate, update changelog

Co-authored-by: Yuji Kanagawa <yuji.kngw.80s.revive@gmail.com>
This commit is contained in:
Nicholas Sim 2020-12-27 10:53:18 +08:00 committed by GitHub
parent 9ec937bc63
commit 3f093d9e59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 367 additions and 227 deletions

View File

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Fixed
- Stop including `Py_TRACE_REFS` config setting automatically if `Py_DEBUG` is set on Python 3.8 and up. [#1334](https://github.com/PyO3/pyo3/pull/1334)
- Remove `#[deny(warnings)]` attribute (and instead refuse warnings only in CI). [#1340](https://github.com/PyO3/pyo3/pull/1340)
- Deprecate FFI definitions `PyEval_CallObjectWithKeywords`, `PyEval_CallObject`, `PyEval_CallFunction`, `PyEval_CallMethod` when building for Python 3.9. [#1338](https://github.com/PyO3/pyo3/pull/1338)
## [0.13.0] - 2020-12-22
### Packaging

View File

@ -6,12 +6,6 @@ use std::os::raw::{c_int, c_long};
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyBool_Type")]
pub static mut PyBool_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "_PyPy_FalseStruct")]
static mut _Py_FalseStruct: PyLongObject;
#[cfg_attr(PyPy, link_name = "_PyPy_TrueStruct")]
static mut _Py_TrueStruct: PyLongObject;
#[cfg_attr(PyPy, link_name = "PyPyBool_FromLong")]
pub fn PyBool_FromLong(arg1: c_long) -> *mut PyObject;
}
#[inline]
@ -19,6 +13,14 @@ pub unsafe fn PyBool_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyBool_Type) as c_int
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "_PyPy_FalseStruct")]
static mut _Py_FalseStruct: PyLongObject;
#[cfg_attr(PyPy, link_name = "_PyPy_TrueStruct")]
static mut _Py_TrueStruct: PyLongObject;
}
#[inline]
pub unsafe fn Py_False() -> *mut PyObject {
&mut _Py_FalseStruct as *mut PyLongObject as *mut PyObject
@ -28,3 +30,12 @@ pub unsafe fn Py_False() -> *mut PyObject {
pub unsafe fn Py_True() -> *mut PyObject {
&mut _Py_TrueStruct as *mut PyLongObject as *mut PyObject
}
// skipped Py_RETURN_TRUE
// skipped Py_RETURN_FALSE
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyBool_FromLong")]
pub fn PyBool_FromLong(arg1: c_long) -> *mut PyObject;
}

View File

@ -25,7 +25,8 @@ extern "C" {
pub fn PyBytes_FromString(arg1: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyBytes_FromObject")]
pub fn PyBytes_FromObject(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyBytes_FromFormatV")]
// skipped PyBytes_FromFormatV
//#[cfg_attr(PyPy, link_name = "PyPyBytes_FromFormatV")]
//pub fn PyBytes_FromFormatV(arg1: *const c_char, arg2: va_list)
// -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyBytes_FromFormat")]
@ -52,6 +53,10 @@ extern "C" {
s: *mut *mut c_char,
len: *mut Py_ssize_t,
) -> c_int;
#[cfg(not(PyPy))]
pub fn _PyBytes_Resize(bytes: *mut *mut PyObject, newsize: Py_ssize_t) -> c_int;
}
// skipped F_LJUST
// skipped F_SIGN
// skipped F_BLANK
// skipped F_ALT
// skipped F_ZERO

View File

@ -1,10 +1,13 @@
#[cfg(not(Py_LIMITED_API))]
use crate::ffi::code::FreeFunc;
use crate::ffi::object::PyObject;
use crate::ffi::pystate::{PyThreadState, Py_tracefunc};
use crate::ffi::pystate::PyThreadState;
use std::os::raw::{c_char, c_int, c_void};
// TODO: move to cpython
pub type _PyFrameEvalFunction =
extern "C" fn(*mut crate::ffi::PyFrameObject, c_int) -> *mut PyObject;
extern "C" {
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
#[cfg_attr(PyPy, link_name = "PyPyEval_CallObjectWithKeywords")]
pub fn PyEval_CallObjectWithKeywords(
func: *mut PyObject,
@ -13,14 +16,18 @@ extern "C" {
) -> *mut PyObject;
}
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
#[inline]
pub unsafe fn PyEval_CallObject(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject {
#[allow(deprecated)]
PyEval_CallObjectWithKeywords(func, arg, ::std::ptr::null_mut())
}
extern "C" {
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
#[cfg_attr(PyPy, link_name = "PyPyEval_CallFunction")]
pub fn PyEval_CallFunction(obj: *mut PyObject, format: *const c_char, ...) -> *mut PyObject;
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
#[cfg_attr(PyPy, link_name = "PyPyEval_CallMethod")]
pub fn PyEval_CallMethod(
obj: *mut PyObject,
@ -49,28 +56,20 @@ extern "C" {
fn _Py_CheckRecursiveCall(_where: *mut c_char) -> c_int;
}
// TODO: Py_EnterRecursiveCall etc
pub type _PyFrameEvalFunction =
extern "C" fn(*mut crate::ffi::PyFrameObject, c_int) -> *mut PyObject;
// TODO
// skipped Py_EnterRecursiveCall
// skipped Py_LeaveRecursiveCall
extern "C" {
pub fn PyEval_GetFuncName(arg1: *mut PyObject) -> *const c_char;
pub fn PyEval_GetFuncDesc(arg1: *mut PyObject) -> *const c_char;
pub fn PyEval_GetCallStats(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyEval_EvalFrame(arg1: *mut crate::ffi::PyFrameObject) -> *mut PyObject;
pub fn _PyEval_EvalFrameDefault(
arg1: *mut crate::ffi::PyFrameObject,
exc: c_int,
) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
pub fn _PyEval_RequestCodeExtraIndex(func: FreeFunc) -> c_int;
pub fn PyEval_EvalFrameEx(f: *mut crate::ffi::PyFrameObject, exc: c_int) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyEval_SaveThread")]
pub fn PyEval_SaveThread() -> *mut PyThreadState;
#[cfg_attr(PyPy, link_name = "PyPyEval_RestoreThread")]
pub fn PyEval_RestoreThread(arg1: *mut PyThreadState);
pub fn PyEval_SetProfile(trace_func: Py_tracefunc, arg1: *mut PyObject);
pub fn PyEval_SetTrace(trace_func: Py_tracefunc, arg1: *mut PyObject);
}
#[cfg(py_sys_config = "WITH_THREAD")]
@ -88,3 +87,15 @@ extern "C" {
#[cfg(not(Py_3_8))]
pub fn PyEval_ReInitThreads();
}
// skipped Py_BEGIN_ALLOW_THREADS
// skipped Py_BLOCK_THREADS
// skipped Py_UNBLOCK_THREADS
// skipped Py_END_ALLOW_THREADS
// skipped FVC_MASK
// skipped FVC_NONE
// skipped FVC_STR
// skipped FVC_REPR
// skipped FVC_ASCII
// skipped FVS_MASK
// skipped FVS_HAVE_SPEC

View File

@ -1,156 +1,2 @@
use crate::ffi::object::*;
use crate::ffi::pyport::Py_ssize_t;
use std::os::raw::{c_char, c_int, c_uchar, c_void};
#[cfg(Py_3_8)]
opaque_struct!(_PyOpcache);
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCodeObject {
pub ob_base: PyObject,
pub co_argcount: c_int,
#[cfg(Py_3_8)]
pub co_posonlyargcount: c_int,
pub co_kwonlyargcount: c_int,
pub co_nlocals: c_int,
pub co_stacksize: c_int,
pub co_flags: c_int,
pub co_firstlineno: c_int,
pub co_code: *mut PyObject,
pub co_consts: *mut PyObject,
pub co_names: *mut PyObject,
pub co_varnames: *mut PyObject,
pub co_freevars: *mut PyObject,
pub co_cellvars: *mut PyObject,
pub co_cell2arg: *mut c_uchar,
pub co_filename: *mut PyObject,
pub co_name: *mut PyObject,
pub co_lnotab: *mut PyObject,
pub co_zombieframe: *mut c_void,
pub co_weakreflist: *mut PyObject,
pub co_extra: *mut c_void,
#[cfg(Py_3_8)]
pub co_opcache_map: *mut c_uchar,
#[cfg(Py_3_8)]
pub co_opcache: *mut _PyOpcache,
#[cfg(Py_3_8)]
pub co_opcache_flag: c_int,
#[cfg(Py_3_8)]
pub co_opcache_size: c_uchar,
}
/* Masks for co_flags */
pub const CO_OPTIMIZED: c_int = 0x0001;
pub const CO_NEWLOCALS: c_int = 0x0002;
pub const CO_VARARGS: c_int = 0x0004;
pub const CO_VARKEYWORDS: c_int = 0x0008;
pub const CO_NESTED: c_int = 0x0010;
pub const CO_GENERATOR: c_int = 0x0020;
/* The CO_NOFREE flag is set if there are no free or cell variables.
This information is redundant, but it allows a single flag test
to determine whether there is any extra work to be done when the
call frame it setup.
*/
pub const CO_NOFREE: c_int = 0x0040;
/* The CO_COROUTINE flag is set for coroutine functions (defined with
``async def`` keywords) */
pub const CO_COROUTINE: c_int = 0x0080;
pub const CO_ITERABLE_COROUTINE: c_int = 0x0100;
pub const CO_ASYNC_GENERATOR: c_int = 0x0200;
pub const CO_FUTURE_DIVISION: c_int = 0x2000;
pub const CO_FUTURE_ABSOLUTE_IMPORT: c_int = 0x4000; /* do absolute imports by default */
pub const CO_FUTURE_WITH_STATEMENT: c_int = 0x8000;
pub const CO_FUTURE_PRINT_FUNCTION: c_int = 0x1_0000;
pub const CO_FUTURE_UNICODE_LITERALS: c_int = 0x2_0000;
pub const CO_FUTURE_BARRY_AS_BDFL: c_int = 0x4_0000;
pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x8_0000;
pub const CO_MAXBLOCKS: usize = 20;
pub type FreeFunc = extern "C" fn(*mut c_void) -> c_void;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut PyCode_Type: PyTypeObject;
}
extern "C" {
pub fn _PyCode_GetExtra(
code: *mut PyObject,
index: Py_ssize_t,
extra: *const *mut c_void,
) -> c_int;
pub fn _PyCode_SetExtra(code: *mut PyObject, index: Py_ssize_t, extra: *mut c_void) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCode_New")]
pub fn PyCode_New(
argcount: c_int,
kwonlyargcount: c_int,
nlocals: c_int,
stacksize: c_int,
flags: c_int,
code: *mut PyObject,
consts: *mut PyObject,
names: *mut PyObject,
varnames: *mut PyObject,
freevars: *mut PyObject,
cellvars: *mut PyObject,
filename: *mut PyObject,
name: *mut PyObject,
firstlineno: c_int,
lnotab: *mut PyObject,
) -> *mut PyCodeObject;
#[cfg(Py_3_8)]
pub fn PyCode_NewWithPosOnlyArgs(
argcount: c_int,
posonlyargcount: c_int,
kwonlyargcount: c_int,
nlocals: c_int,
stacksize: c_int,
flags: c_int,
code: *mut PyObject,
consts: *mut PyObject,
names: *mut PyObject,
varnames: *mut PyObject,
freevars: *mut PyObject,
cellvars: *mut PyObject,
filename: *mut PyObject,
name: *mut PyObject,
firstlineno: c_int,
lnotab: *mut PyObject,
) -> *mut PyCodeObject;
#[cfg_attr(PyPy, link_name = "PyPyCode_NewEmpty")]
pub fn PyCode_NewEmpty(
filename: *const c_char,
funcname: *const c_char,
firstlineno: c_int,
) -> *mut PyCodeObject;
pub fn PyCode_Addr2Line(arg1: *mut PyCodeObject, arg2: c_int) -> c_int;
pub fn PyCode_Optimize(
code: *mut PyObject,
consts: *mut PyObject,
names: *mut PyObject,
lnotab: *mut PyObject,
) -> *mut PyObject;
#[cfg(PyPy)]
#[link_name = "PyPyCode_Check"]
pub fn PyCode_Check(op: *mut PyObject) -> c_int;
#[cfg(PyPy)]
#[link_name = "PyPyCode_GetNumFree"]
pub fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t;
}
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCode_Type) as c_int
}
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t {
crate::ffi::tupleobject::PyTuple_GET_SIZE((*op).co_freevars)
}
#[cfg(Py_LIMITED_API)]
opaque_struct!(PyCodeObject);

View File

@ -3,6 +3,9 @@ use std::os::raw::{c_char, c_int};
extern "C" {
pub fn PyCodec_Register(search_function: *mut PyObject) -> c_int;
// skipped PyCodec_Unregister
// skipped non-limited _PyCodec_Lookup from Include/codecs.h
// skipped non-limited _PyCodec_Forget from Include/codecs.h
pub fn PyCodec_KnownEncoding(encoding: *const c_char) -> c_int;
pub fn PyCodec_Encode(
object: *mut PyObject,
@ -14,6 +17,11 @@ extern "C" {
encoding: *const c_char,
errors: *const c_char,
) -> *mut PyObject;
// skipped non-limited _PyCodec_LookupTextEncoding from Include/codecs.h
// skipped non-limited _PyCodec_EncodeText from Include/codecs.h
// skipped non-limited _PyCodec_DecodeText from Include/codecs.h
// skipped non-limited _PyCodecInfo_GetIncrementalDecoder from Include/codecs.h
// skipped non-limited _PyCodecInfo_GetIncrementalEncoder from Include/codecs.h
pub fn PyCodec_Encoder(encoding: *const c_char) -> *mut PyObject;
pub fn PyCodec_Decoder(encoding: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyCodec_IncrementalEncoder")]
@ -43,4 +51,6 @@ extern "C" {
pub fn PyCodec_ReplaceErrors(exc: *mut PyObject) -> *mut PyObject;
pub fn PyCodec_XMLCharRefReplaceErrors(exc: *mut PyObject) -> *mut PyObject;
pub fn PyCodec_BackslashReplaceErrors(exc: *mut PyObject) -> *mut PyObject;
// skipped non-limited PyCodec_NameReplaceErrors from Include/codecs.h
// skipped non-limited Py_hexdigits from Include/codecs.h
}

View File

@ -1,9 +1,22 @@
use crate::ffi::code::*;
use crate::ffi::object::PyObject;
use crate::ffi::pyarena::*;
use crate::ffi::pythonrun::*;
use crate::ffi::PyCodeObject;
use std::os::raw::{c_char, c_int};
// skipped non-limited PyCF_MASK
// skipped non-limited PyCF_MASK_OBSOLETE
// skipped non-limited PyCF_SOURCE_IS_UTF8
// skipped non-limited PyCF_DONT_IMPLY_DEDENT
// skipped non-limited PyCF_ONLY_AST
// skipped non-limited PyCF_IGNORE_COOKIE
// skipped non-limited PyCF_TYPE_COMMENTS
// skipped non-limited PyCF_ALLOW_TOP_LEVEL_AWAIT
// skipped non-limited PyCF_COMPILE_MASK
// skipped non-limited PyCompilerFlags
// skipped non-limited _PyCompilerFlags_INIT
#[repr(C)]
#[derive(Copy, Clone)]
#[cfg(not(Py_LIMITED_API))]
@ -30,6 +43,7 @@ pub const FUTURE_UNICODE_LITERALS: &str = "unicode_literals";
pub const FUTURE_BARRY_AS_BDFL: &str = "barry_as_FLUFL";
#[cfg(not(Py_LIMITED_API))]
pub const FUTURE_GENERATOR_STOP: &str = "generator_stop";
// skipped non-limited FUTURE_ANNOTATIONS
#[cfg(not(Py_LIMITED_API))]
extern "C" {
@ -58,10 +72,16 @@ extern "C" {
filename: *mut PyObject,
) -> *mut PyFutureFeatures;
// skipped non-limited _Py_Mangle
// skipped non-limited PY_INVALID_STACK_EFFECT
pub fn PyCompile_OpcodeStackEffect(opcode: c_int, oparg: c_int) -> c_int;
#[cfg(Py_3_8)]
pub fn PyCompile_OpcodeStackEffectWithJump(opcode: c_int, oparg: c_int, jump: c_int) -> c_int;
// skipped non-limited _PyASTOptimizeState
// skipped non-limited _PyAST_Optimize
}
pub const Py_single_input: c_int = 256;
@ -69,3 +89,4 @@ pub const Py_file_input: c_int = 257;
pub const Py_eval_input: c_int = 258;
#[cfg(Py_3_8)]
pub const Py_func_type_input: c_int = 345;
// skipped Py_fstring_input

View File

@ -1,6 +1,37 @@
use crate::ffi::object::*;
use std::os::raw::{c_double, c_int};
#[repr(C)]
#[derive(Copy, Clone)]
// non-limited
pub struct Py_complex {
pub real: c_double,
pub imag: c_double,
}
#[cfg(not(Py_LIMITED_API))]
extern "C" {
pub fn _Py_c_sum(left: Py_complex, right: Py_complex) -> Py_complex;
pub fn _Py_c_diff(left: Py_complex, right: Py_complex) -> Py_complex;
pub fn _Py_c_neg(complex: Py_complex) -> Py_complex;
pub fn _Py_c_prod(left: Py_complex, right: Py_complex) -> Py_complex;
pub fn _Py_c_quot(dividend: Py_complex, divisor: Py_complex) -> Py_complex;
pub fn _Py_c_pow(num: Py_complex, exp: Py_complex) -> Py_complex;
pub fn _Py_c_abs(arg: Py_complex) -> c_double;
#[cfg_attr(PyPy, link_name = "PyPyComplex_FromCComplex")]
pub fn PyComplex_FromCComplex(v: Py_complex) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyComplex_AsCComplex")]
pub fn PyComplex_AsCComplex(op: *mut PyObject) -> Py_complex;
}
#[repr(C)]
#[derive(Copy, Clone)]
// non-limited
pub struct PyComplexObject {
pub ob_base: PyObject,
pub cval: Py_complex,
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyComplex_Type")]
@ -18,39 +49,13 @@ pub unsafe fn PyComplex_CheckExact(op: *mut PyObject) -> c_int {
}
extern "C" {
// skipped non-limited PyComplex_FromCComplex
#[cfg_attr(PyPy, link_name = "PyPyComplex_FromDoubles")]
pub fn PyComplex_FromDoubles(real: c_double, imag: c_double) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyComplex_RealAsDouble")]
pub fn PyComplex_RealAsDouble(op: *mut PyObject) -> c_double;
#[cfg_attr(PyPy, link_name = "PyPyComplex_ImagAsDouble")]
pub fn PyComplex_ImagAsDouble(op: *mut PyObject) -> c_double;
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Py_complex {
pub real: c_double,
pub imag: c_double,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyComplexObject {
pub ob_base: PyObject,
pub cval: Py_complex,
}
#[cfg(not(Py_LIMITED_API))]
extern "C" {
pub fn _Py_c_sum(left: Py_complex, right: Py_complex) -> Py_complex;
pub fn _Py_c_diff(left: Py_complex, right: Py_complex) -> Py_complex;
pub fn _Py_c_neg(complex: Py_complex) -> Py_complex;
pub fn _Py_c_prod(left: Py_complex, right: Py_complex) -> Py_complex;
pub fn _Py_c_quot(dividend: Py_complex, divisor: Py_complex) -> Py_complex;
pub fn _Py_c_pow(num: Py_complex, exp: Py_complex) -> Py_complex;
pub fn _Py_c_abs(arg: Py_complex) -> c_double;
#[cfg_attr(PyPy, link_name = "PyPyComplex_FromCComplex")]
pub fn PyComplex_FromCComplex(v: Py_complex) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyComplex_AsCComplex")]
pub fn PyComplex_AsCComplex(op: *mut PyObject) -> Py_complex;
// skipped non-limited PyComplex_AsCComplex
// skipped non-limited _PyComplex_FormatAdvancedWriter
}

View File

@ -0,0 +1,7 @@
use crate::ffi::object::PyObject;
use crate::ffi::pyport::Py_ssize_t;
use std::os::raw::c_int;
extern "C" {
pub fn _PyBytes_Resize(bytes: *mut *mut PyObject, newsize: Py_ssize_t) -> c_int;
}

16
src/ffi/cpython/ceval.rs Normal file
View File

@ -0,0 +1,16 @@
#[cfg(not(Py_LIMITED_API))]
use crate::ffi::object::FreeFunc;
use crate::ffi::object::PyObject;
use crate::ffi::pystate::Py_tracefunc;
use std::os::raw::c_int;
extern "C" {
pub fn _PyEval_EvalFrameDefault(
arg1: *mut crate::ffi::PyFrameObject,
exc: c_int,
) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
pub fn _PyEval_RequestCodeExtraIndex(func: FreeFunc) -> c_int;
pub fn PyEval_SetProfile(trace_func: Py_tracefunc, arg1: *mut PyObject);
pub fn PyEval_SetTrace(trace_func: Py_tracefunc, arg1: *mut PyObject);
}

166
src/ffi/cpython/code.rs Normal file
View File

@ -0,0 +1,166 @@
use crate::ffi::object::*;
use crate::ffi::pyport::Py_ssize_t;
use std::os::raw::{c_char, c_int, c_uchar, c_void};
// skipped _Py_CODEUNIT
// skipped _Py_OPCODE
// skipped _Py_OPARG
#[cfg(Py_3_8)]
opaque_struct!(_PyOpcache);
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCodeObject {
pub ob_base: PyObject,
pub co_argcount: c_int,
#[cfg(Py_3_8)]
pub co_posonlyargcount: c_int,
pub co_kwonlyargcount: c_int,
pub co_nlocals: c_int,
pub co_stacksize: c_int,
pub co_flags: c_int,
pub co_firstlineno: c_int,
pub co_code: *mut PyObject,
pub co_consts: *mut PyObject,
pub co_names: *mut PyObject,
pub co_varnames: *mut PyObject,
pub co_freevars: *mut PyObject,
pub co_cellvars: *mut PyObject,
pub co_cell2arg: *mut c_uchar,
pub co_filename: *mut PyObject,
pub co_name: *mut PyObject,
pub co_lnotab: *mut PyObject,
pub co_zombieframe: *mut c_void,
pub co_weakreflist: *mut PyObject,
pub co_extra: *mut c_void,
#[cfg(Py_3_8)]
pub co_opcache_map: *mut c_uchar,
#[cfg(Py_3_8)]
pub co_opcache: *mut _PyOpcache,
#[cfg(Py_3_8)]
pub co_opcache_flag: c_int,
#[cfg(Py_3_8)]
pub co_opcache_size: c_uchar,
}
/* Masks for co_flags */
pub const CO_OPTIMIZED: c_int = 0x0001;
pub const CO_NEWLOCALS: c_int = 0x0002;
pub const CO_VARARGS: c_int = 0x0004;
pub const CO_VARKEYWORDS: c_int = 0x0008;
pub const CO_NESTED: c_int = 0x0010;
pub const CO_GENERATOR: c_int = 0x0020;
/* The CO_NOFREE flag is set if there are no free or cell variables.
This information is redundant, but it allows a single flag test
to determine whether there is any extra work to be done when the
call frame it setup.
*/
pub const CO_NOFREE: c_int = 0x0040;
/* The CO_COROUTINE flag is set for coroutine functions (defined with
``async def`` keywords) */
pub const CO_COROUTINE: c_int = 0x0080;
pub const CO_ITERABLE_COROUTINE: c_int = 0x0100;
pub const CO_ASYNC_GENERATOR: c_int = 0x0200;
pub const CO_FUTURE_DIVISION: c_int = 0x2000;
pub const CO_FUTURE_ABSOLUTE_IMPORT: c_int = 0x4000; /* do absolute imports by default */
pub const CO_FUTURE_WITH_STATEMENT: c_int = 0x8000;
pub const CO_FUTURE_PRINT_FUNCTION: c_int = 0x1_0000;
pub const CO_FUTURE_UNICODE_LITERALS: c_int = 0x2_0000;
pub const CO_FUTURE_BARRY_AS_BDFL: c_int = 0x4_0000;
pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x8_0000;
// skipped CO_FUTURE_ANNOTATIONS
// skipped CO_CELL_NOT_AN_ARG
pub const CO_MAXBLOCKS: usize = 20;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut PyCode_Type: PyTypeObject;
}
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCode_Type) as c_int
}
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t {
crate::ffi::tupleobject::PyTuple_GET_SIZE((*op).co_freevars)
}
extern "C" {
#[cfg(PyPy)]
#[link_name = "PyPyCode_Check"]
pub fn PyCode_Check(op: *mut PyObject) -> c_int;
#[cfg(PyPy)]
#[link_name = "PyPyCode_GetNumFree"]
pub fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t;
}
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyCode_New")]
pub fn PyCode_New(
argcount: c_int,
kwonlyargcount: c_int,
nlocals: c_int,
stacksize: c_int,
flags: c_int,
code: *mut PyObject,
consts: *mut PyObject,
names: *mut PyObject,
varnames: *mut PyObject,
freevars: *mut PyObject,
cellvars: *mut PyObject,
filename: *mut PyObject,
name: *mut PyObject,
firstlineno: c_int,
lnotab: *mut PyObject,
) -> *mut PyCodeObject;
#[cfg(Py_3_8)]
pub fn PyCode_NewWithPosOnlyArgs(
argcount: c_int,
posonlyargcount: c_int,
kwonlyargcount: c_int,
nlocals: c_int,
stacksize: c_int,
flags: c_int,
code: *mut PyObject,
consts: *mut PyObject,
names: *mut PyObject,
varnames: *mut PyObject,
freevars: *mut PyObject,
cellvars: *mut PyObject,
filename: *mut PyObject,
name: *mut PyObject,
firstlineno: c_int,
lnotab: *mut PyObject,
) -> *mut PyCodeObject;
#[cfg_attr(PyPy, link_name = "PyPyCode_NewEmpty")]
pub fn PyCode_NewEmpty(
filename: *const c_char,
funcname: *const c_char,
firstlineno: c_int,
) -> *mut PyCodeObject;
pub fn PyCode_Addr2Line(arg1: *mut PyCodeObject, arg2: c_int) -> c_int;
// skipped PyCodeAddressRange "for internal use only"
// skipped _PyCode_CheckLineNumber
// skipped _PyCode_ConstantKey
pub fn PyCode_Optimize(
code: *mut PyObject,
consts: *mut PyObject,
names: *mut PyObject,
lnotab: *mut PyObject,
) -> *mut PyObject;
pub fn _PyCode_GetExtra(
code: *mut PyObject,
index: Py_ssize_t,
extra: *const *mut c_void,
) -> c_int;
pub fn _PyCode_SetExtra(code: *mut PyObject, index: Py_ssize_t, extra: *mut c_void) -> c_int;
}

View File

@ -1,3 +1,11 @@
pub mod abstract_;
#[cfg(not(PyPy))]
pub mod bytesobject;
pub mod ceval;
pub mod code;
pub use self::abstract_::*;
#[cfg(not(PyPy))]
pub use self::bytesobject::*;
pub use self::ceval::*;
pub use self::code::*;

View File

@ -1,4 +1,4 @@
use crate::ffi::code::{PyCodeObject, CO_MAXBLOCKS};
use crate::ffi::cpython::code::{PyCodeObject, CO_MAXBLOCKS};
use crate::ffi::object::*;
use crate::ffi::pystate::PyThreadState;
use std::os::raw::{c_char, c_int};

View File

@ -46,7 +46,7 @@ pub use self::methodobject::*;
pub use self::modsupport::*;
pub use self::moduleobject::*;
pub use self::object::*;
pub use self::objectabstract::*;
pub use self::objectabstract::*; // FIXME: no matching objectabstract.h in cpython master
pub use self::objimpl::*;
pub use self::osmodule::*;
pub use self::pyarena::*;
@ -75,6 +75,53 @@ pub use self::weakrefobject::*;
#[cfg(not(Py_LIMITED_API))]
pub use self::cpython::*;
// skipped abstract.h
// skipped asdl.h
// skipped ast.h
mod bltinmodule;
mod boolobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod bytearrayobject;
mod bytesobject;
// skipped cellobject.h
mod ceval; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// skipped classobject.h
mod code;
mod codecs; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod compile; // TODO: incomplete
mod complexobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// skipped dynamic_annotations.h
// skipped errcode.h
// skipped exports.h
// skipped fileutils.h
// skipped genericaliasobject.h
// skipped interpreteridobject.h
// skipped longintrepr.h
// skipped namespaceobject.h
// skipped odictobject.h
// skipped opcode.h
// skipped osdefs.h
// skipped parser_interface.h
// skipped patchlevel.h
// skipped picklebufobject.h
// skipped pyctype.h
// skipped py_curses.h
// skipped pydecimal.h
// skipped pydtrace.h
// skipped pyexpat.h
// skipped pyfpe.h
// skipped pyframe.h
// skipped pymacconfig.h
// skipped pymacro.h
// skipped pymath.h
// skipped pystrcmp.h
// skipped pystrhex.h
// skipped Python-ast.h
// this file is Python.h
// skipped pythread.h
// skipped pytime.h
mod pyport;
// mod pymacro; contains nothing of interest for Rust
// mod pyatomic; contains nothing of interest for Rust
@ -92,13 +139,9 @@ mod pyhash;
mod pymem;
mod typeslots;
mod bytearrayobject;
mod bytesobject;
mod longobject;
mod unicodeobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod longintrepr; TODO excluded by PEP-384
mod boolobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod complexobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod dictobject;
mod floatobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod listobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
@ -123,9 +166,6 @@ mod iterobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 a
mod structseq;
mod warnings; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod weakrefobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod namespaceobject; TODO
mod codecs; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod pyerrors; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod pylifecycle;
@ -138,22 +178,13 @@ mod modsupport; // TODO supports PEP-384 only; needs adjustment for Python 3.3 a
mod pyarena; // TODO: incomplete
mod pythonrun; // TODO some functions need to be moved to pylifecycle
//mod pylifecycle; // TODO new in 3.5
mod ceval; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod import;
mod intrcheck; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod osmodule;
mod sysmodule; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod bltinmodule;
mod objectabstract; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
#[cfg(Py_LIMITED_API)]
mod code {}
#[cfg(not(Py_LIMITED_API))]
mod code;
mod compile; // TODO: incomplete
#[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
mod context; // It's actually 3.7.1, but no cfg for patches.

View File

@ -3,6 +3,8 @@ use std::mem;
use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_void};
use std::ptr;
pub type FreeFunc = extern "C" fn(*mut c_void) -> c_void;
#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg(not(PyPy))]