Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use addr_of_mut in pyo3-ffi #2172

Merged
merged 3 commits into from
Feb 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 4 additions & 23 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{env, process::Command};
use std::env;

use pyo3_build_config::pyo3_build_script_impl::{cargo_env_var, errors::Result};
use pyo3_build_config::{bail, InterpreterConfig};
use pyo3_build_config::{bail, print_feature_cfgs, InterpreterConfig};

fn ensure_auto_initialize_ok(interpreter_config: &InterpreterConfig) -> Result<()> {
if cargo_env_var("CARGO_FEATURE_AUTO_INITIALIZE").is_some() {
Expand Down Expand Up @@ -32,17 +32,6 @@ fn ensure_auto_initialize_ok(interpreter_config: &InterpreterConfig) -> Result<(
Ok(())
}

fn rustc_minor_version() -> Option<u32> {
let rustc = env::var_os("RUSTC")?;
let output = Command::new(rustc).arg("--version").output().ok()?;
let version = core::str::from_utf8(&output.stdout).ok()?;
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}
pieces.next()?.parse().ok()
}

/// Prepares the PyO3 crate for compilation.
///
/// This loads the config from pyo3-build-config and then makes some additional checks to improve UX
Expand All @@ -55,18 +44,10 @@ fn configure_pyo3() -> Result<()> {

interpreter_config.emit_pyo3_cfgs();

let rustc_minor_version = rustc_minor_version().unwrap_or(0);
ensure_auto_initialize_ok(interpreter_config)?;

// Enable use of const generics on Rust 1.51 and greater
if rustc_minor_version >= 51 {
println!("cargo:rustc-cfg=min_const_generics");
}

// Enable use of std::ptr::addr_of! on Rust 1.51 and greater
if rustc_minor_version >= 51 {
println!("cargo:rustc-cfg=addr_of");
}
// Emit cfgs like `addr_of` and `min_const_generics`
print_feature_cfgs();

Ok(())
}
Expand Down
31 changes: 31 additions & 0 deletions pyo3-build-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod impl_;

#[cfg(feature = "resolve-config")]
use std::io::Cursor;
use std::{env, process::Command};

#[cfg(feature = "resolve-config")]
use once_cell::sync::OnceCell;
Expand Down Expand Up @@ -115,6 +116,36 @@ fn abi3_config() -> InterpreterConfig {
interpreter_config
}

/// Use certain features if we detect the compiler being used supports them.
///
/// Features may be removed or added as MSRV gets bumped or new features become available,
/// so this function is unstable.
#[doc(hidden)]
pub fn print_feature_cfgs() {
fn rustc_minor_version() -> Option<u32> {
let rustc = env::var_os("RUSTC")?;
let output = Command::new(rustc).arg("--version").output().ok()?;
let version = core::str::from_utf8(&output.stdout).ok()?;
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}
pieces.next()?.parse().ok()
}

let rustc_minor_version = rustc_minor_version().unwrap_or(0);

// Enable use of const generics on Rust 1.51 and greater
if rustc_minor_version >= 51 {
println!("cargo:rustc-cfg=min_const_generics");
}

// Enable use of std::ptr::addr_of! on Rust 1.51 and greater
if rustc_minor_version >= 51 {
println!("cargo:rustc-cfg=addr_of");
}
}

/// Private exports used in PyO3's build.rs
///
/// Please don't use these - they could change at any time.
Expand Down
5 changes: 4 additions & 1 deletion pyo3-ffi/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use pyo3_build_config::{
bail, ensure,
bail, ensure, print_feature_cfgs,
pyo3_build_script_impl::{
cargo_env_var, env_var, errors::Result, resolve_interpreter_config, InterpreterConfig,
PythonVersion,
Expand Down Expand Up @@ -100,6 +100,9 @@ fn configure_pyo3() -> Result<()> {
println!("{}", line);
}

// Emit cfgs like `addr_of` and `min_const_generics`
print_feature_cfgs();

Ok(())
}

Expand Down
6 changes: 3 additions & 3 deletions pyo3-ffi/src/boolobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extern "C" {

#[inline]
pub unsafe fn PyBool_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyBool_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyBool_Type)) as c_int
}

#[cfg_attr(windows, link(name = "pythonXY"))]
Expand All @@ -23,12 +23,12 @@ extern "C" {

#[inline]
pub unsafe fn Py_False() -> *mut PyObject {
&mut _Py_FalseStruct as *mut PyLongObject as *mut PyObject
addr_of_mut_shim!(_Py_FalseStruct) as *mut PyLongObject as *mut PyObject
}

#[inline]
pub unsafe fn Py_True() -> *mut PyObject {
&mut _Py_TrueStruct as *mut PyLongObject as *mut PyObject
addr_of_mut_shim!(_Py_TrueStruct) as *mut PyLongObject as *mut PyObject
}

#[inline]
Expand Down
4 changes: 2 additions & 2 deletions pyo3-ffi/src/bytearrayobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ extern "C" {

#[inline]
pub unsafe fn PyByteArray_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut PyByteArray_Type)
PyObject_TypeCheck(op, addr_of_mut_shim!(PyByteArray_Type))
}

#[inline]
pub unsafe fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyByteArray_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyByteArray_Type)) as c_int
}

extern "C" {
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/bytesobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub unsafe fn PyBytes_Check(op: *mut PyObject) -> c_int {

#[inline]
pub unsafe fn PyBytes_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyBytes_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyBytes_Type)) as c_int
}

extern "C" {
Expand Down
4 changes: 2 additions & 2 deletions pyo3-ffi/src/complexobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ extern "C" {

#[inline]
pub unsafe fn PyComplex_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut PyComplex_Type)
PyObject_TypeCheck(op, addr_of_mut_shim!(PyComplex_Type))
}

#[inline]
pub unsafe fn PyComplex_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyComplex_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyComplex_Type)) as c_int
}

extern "C" {
Expand Down
6 changes: 3 additions & 3 deletions pyo3-ffi/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ extern "C" {

#[inline]
pub unsafe fn PyContext_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyContext_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyContext_Type)) as c_int
}

#[inline]
pub unsafe fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyContextVar_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyContextVar_Type)) as c_int
}

#[inline]
pub unsafe fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyContextToken_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyContextToken_Type)) as c_int
}

extern "C" {
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ extern "C" {
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCode_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyCode_Type)) as c_int
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/frameobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ extern "C" {

#[inline]
pub unsafe fn PyFrame_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyFrame_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyFrame_Type)) as c_int
}

extern "C" {
Expand Down
8 changes: 4 additions & 4 deletions pyo3-ffi/src/dictobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub unsafe fn PyDict_Check(op: *mut PyObject) -> c_int {

#[inline]
pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDict_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyDict_Type)) as c_int
}

extern "C" {
Expand Down Expand Up @@ -76,17 +76,17 @@ extern "C" {

#[inline]
pub unsafe fn PyDictKeys_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictKeys_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyDictKeys_Type)) as c_int
}

#[inline]
pub unsafe fn PyDictValues_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictValues_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyDictValues_Type)) as c_int
}

#[inline]
pub unsafe fn PyDictItems_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictItems_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyDictItems_Type)) as c_int
}

#[inline]
Expand Down
4 changes: 2 additions & 2 deletions pyo3-ffi/src/floatobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ extern "C" {

#[inline]
pub unsafe fn PyFloat_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut PyFloat_Type)
PyObject_TypeCheck(op, addr_of_mut_shim!(PyFloat_Type))
}

#[inline]
pub unsafe fn PyFloat_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyFloat_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyFloat_Type)) as c_int
}

// skipped Py_RETURN_NAN
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/funcobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extern "C" {

#[inline]
pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyFunction_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyFunction_Type)) as c_int
}

extern "C" {
Expand Down
8 changes: 4 additions & 4 deletions pyo3-ffi/src/genobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ extern "C" {

#[inline]
pub unsafe fn PyGen_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut PyGen_Type)
PyObject_TypeCheck(op, addr_of_mut_shim!(PyGen_Type))
}

#[inline]
pub unsafe fn PyGen_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyGen_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyGen_Type)) as c_int
}

extern "C" {
Expand All @@ -55,7 +55,7 @@ extern "C" {

#[inline]
pub unsafe fn PyCoro_CheckExact(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut PyCoro_Type)
PyObject_TypeCheck(op, addr_of_mut_shim!(PyCoro_Type))
}

// skipped _PyCoro_GetAwaitableIter
Expand All @@ -75,7 +75,7 @@ extern "C" {

#[inline]
pub unsafe fn PyAsyncGen_CheckExact(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut PyAsyncGen_Type)
PyObject_TypeCheck(op, addr_of_mut_shim!(PyAsyncGen_Type))
}

// skipped _PyAsyncGenValueWrapperNew
4 changes: 2 additions & 2 deletions pyo3-ffi/src/iterobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extern "C" {

#[inline]
pub unsafe fn PySeqIter_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PySeqIter_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PySeqIter_Type)) as c_int
}

extern "C" {
Expand All @@ -19,7 +19,7 @@ extern "C" {

#[inline]
pub unsafe fn PyCallIter_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCallIter_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyCallIter_Type)) as c_int
}

extern "C" {
Expand Down
13 changes: 13 additions & 0 deletions pyo3-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,19 @@ macro_rules! opaque_struct {
};
}

macro_rules! addr_of_mut_shim {
mejrs marked this conversation as resolved.
Show resolved Hide resolved
($place:expr) => {{
#[cfg(addr_of)]
{
::std::ptr::addr_of_mut!($place)
}
#[cfg(not(addr_of))]
{
&mut $place as *mut _
}
}};
}

pub use self::abstract_::*;
pub use self::bltinmodule::*;
pub use self::boolobject::*;
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/listobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub unsafe fn PyList_Check(op: *mut PyObject) -> c_int {

#[inline]
pub unsafe fn PyList_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyList_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyList_Type)) as c_int
}

extern "C" {
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/longobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub unsafe fn PyLong_Check(op: *mut PyObject) -> c_int {

#[inline]
pub unsafe fn PyLong_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyLong_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyLong_Type)) as c_int
}

extern "C" {
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/memoryobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extern "C" {

#[inline]
pub unsafe fn PyMemoryView_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyMemoryView_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyMemoryView_Type)) as c_int
}

// skipped non-limited PyMemoryView_GET_BUFFER
Expand Down
6 changes: 3 additions & 3 deletions pyo3-ffi/src/methodobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ extern "C" {
#[cfg(Py_3_9)]
#[inline]
pub unsafe fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCFunction_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyCFunction_Type)) as c_int
}

#[cfg(Py_3_9)]
#[inline]
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut PyCFunction_Type)
PyObject_TypeCheck(op, addr_of_mut_shim!(PyCFunction_Type))
}

#[cfg(not(Py_3_9))]
#[inline]
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCFunction_Type) as c_int
(Py_TYPE(op) == addr_of_mut_shim!(PyCFunction_Type)) as c_int
}

pub type PyCFunction =
Expand Down
Loading