Skip to content

Commit

Permalink
ffi module cleanup (#1338)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
Nicholas Sim and kngwyu authored Dec 27, 2020
1 parent 9ec937b commit 3f093d9
Show file tree
Hide file tree
Showing 15 changed files with 367 additions and 227 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 17 additions & 6 deletions src/ffi/boolobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@ 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]
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
Expand All @@ -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;
}
11 changes: 8 additions & 3 deletions src/ffi/bytesobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand All @@ -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
39 changes: 25 additions & 14 deletions src/ffi/ceval.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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")]
Expand All @@ -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
158 changes: 2 additions & 156 deletions src/ffi/code.rs
Original file line number Diff line number Diff line change
@@ -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);
10 changes: 10 additions & 0 deletions src/ffi/codecs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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")]
Expand Down Expand Up @@ -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
}
23 changes: 22 additions & 1 deletion src/ffi/compile.rs
Original file line number Diff line number Diff line change
@@ -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))]
Expand All @@ -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" {
Expand Down Expand Up @@ -58,14 +72,21 @@ 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;
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
Loading

0 comments on commit 3f093d9

Please sign in to comment.