Skip to content

Commit

Permalink
update definitions for objimpl.h
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Aug 18, 2023
1 parent 7f32ed9 commit 0e74bd6
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 55 deletions.
1 change: 1 addition & 0 deletions newsfragments/3402.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add FFI definitions `PyObject_GC_IsTracked` and `PyObject_GC_IsFinalized` on Python 3.9 and up (PyPy 3.10 and up).
1 change: 1 addition & 0 deletions newsfragments/3402.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Disable removed FFI definitions `_Py_GetAllocatedBlocks`, `_PyObject_GC_Malloc`, and `_PyObject_GC_Calloc` on Python 3.11 and up.
2 changes: 2 additions & 0 deletions pyo3-ffi/src/cpython/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub(crate) mod listobject;
#[cfg(all(Py_3_9, not(PyPy)))]
pub(crate) mod methodobject;
pub(crate) mod object;
pub(crate) mod objimpl;
pub(crate) mod pydebug;
pub(crate) mod pyerrors;
#[cfg(all(Py_3_8, not(PyPy)))]
Expand Down Expand Up @@ -54,6 +55,7 @@ pub use self::listobject::*;
#[cfg(all(Py_3_9, not(PyPy)))]
pub use self::methodobject::*;
pub use self::object::*;
pub use self::objimpl::*;
pub use self::pydebug::*;
pub use self::pyerrors::*;
#[cfg(all(Py_3_8, not(PyPy)))]
Expand Down
65 changes: 65 additions & 0 deletions pyo3-ffi/src/cpython/objimpl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use libc::size_t;
use std::os::raw::{c_int, c_void};

use crate::object::*;

// skipped _PyObject_SIZE
// skipped _PyObject_VAR_SIZE

#[cfg(not(Py_3_11))]
pub fn _Py_GetAllocatedBlocks() -> Py_ssize_t;

#[cfg(not(PyPy))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyObjectArenaAllocator {
pub ctx: *mut c_void,
pub alloc: Option<extern "C" fn(ctx: *mut c_void, size: size_t) -> *mut c_void>,
pub free: Option<extern "C" fn(ctx: *mut c_void, ptr: *mut c_void, size: size_t)>,
}

#[cfg(not(PyPy))]
impl Default for PyObjectArenaAllocator {
#[inline]
fn default() -> Self {
unsafe { std::mem::zeroed() }
}
}

extern "C" {
#[cfg(not(PyPy))]
pub fn PyObject_GetArenaAllocator(allocator: *mut PyObjectArenaAllocator);
#[cfg(not(PyPy))]
pub fn PyObject_SetArenaAllocator(allocator: *mut PyObjectArenaAllocator);

#[cfg(Py_3_9)]
pub fn PyObject_IS_GC(o: *mut PyObject) -> c_int;
}

#[inline]
#[cfg(not(Py_3_9))]
pub unsafe fn PyObject_IS_GC(o: *mut PyObject) -> c_int {
(PyType_IS_GC(Py_TYPE(o)) != 0
&& match (*Py_TYPE(o)).tp_is_gc {
Some(tp_is_gc) => tp_is_gc(o) != 0,
None => true,
}) as c_int
}

#[cfg(not(Py_3_11))]
pub fn _PyObject_GC_Malloc(size: size_t) -> *mut PyObject;
#[cfg(not(Py_3_11))]
pub fn _PyObject_GC_Calloc(size: size_t) -> *mut PyObject;

#[inline]
pub unsafe fn PyType_SUPPORTS_WEAKREFS(t: *mut PyTypeObject) -> c_int {
((*t).tp_weaklistoffset > 0) as c_int
}

#[inline]
pub unsafe fn PyObject_GET_WEAKREFS_LISTPTR(o: *mut PyObject) -> *mut *mut PyObject {
let weaklistoffset = (*Py_TYPE(o)).tp_weaklistoffset;
o.offset(weaklistoffset) as *mut *mut PyObject
}

// skipped PyUnstable_Object_GC_NewWithExtraData
86 changes: 31 additions & 55 deletions pyo3-ffi/src/objimpl.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
use libc::size_t;
use std::os::raw::{c_int, c_void};

use crate::object::*;
use crate::pyport::Py_ssize_t;

extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyObject_Malloc")]
pub fn PyObject_Malloc(size: size_t) -> *mut c_void;
Expand All @@ -12,8 +13,12 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyObject_Free")]
pub fn PyObject_Free(ptr: *mut c_void);

#[cfg(not(Py_LIMITED_API))]
pub fn _Py_GetAllocatedBlocks() -> Py_ssize_t;
// skipped PyObject_MALLOC
// skipped PyObject_REALLOC
// skipped PyObject_FREE
// skipped PyObject_Del
// skipped PyObject_DEL

#[cfg_attr(PyPy, link_name = "PyPyObject_Init")]
pub fn PyObject_Init(arg1: *mut PyObject, arg2: *mut PyTypeObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_InitVar")]
Expand All @@ -22,11 +27,20 @@ extern "C" {
arg2: *mut PyTypeObject,
arg3: Py_ssize_t,
) -> *mut PyVarObject;

// skipped PyObject_INIT
// skipped PyObject_INIT_VAR

#[cfg_attr(PyPy, link_name = "_PyPyObject_New")]
pub fn _PyObject_New(arg1: *mut PyTypeObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "_PyPyObject_NewVar")]
pub fn _PyObject_NewVar(arg1: *mut PyTypeObject, arg2: Py_ssize_t) -> *mut PyVarObject;

// skipped PyObject_New
// skipped PyObject_NEW
// skipped PyObject_NewVar
// skipped PyObject_NEW_VAR

pub fn PyGC_Collect() -> Py_ssize_t;

#[cfg(Py_3_10)]
Expand All @@ -40,56 +54,20 @@ extern "C" {
#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyGC_IsEnabled")]
pub fn PyGC_IsEnabled() -> c_int;
}

#[cfg(not(any(Py_LIMITED_API, PyPy)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyObjectArenaAllocator {
pub ctx: *mut c_void,
pub alloc: Option<extern "C" fn(ctx: *mut c_void, size: size_t) -> *mut c_void>,
pub free: Option<extern "C" fn(ctx: *mut c_void, ptr: *mut c_void, size: size_t)>,
}

#[cfg(not(any(Py_LIMITED_API, PyPy)))]
impl Default for PyObjectArenaAllocator {
#[inline]
fn default() -> Self {
unsafe { std::mem::zeroed() }
}
// skipped PyUnstable_GC_VisitObjects
}

extern "C" {
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
pub fn PyObject_GetArenaAllocator(allocator: *mut PyObjectArenaAllocator);
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
pub fn PyObject_SetArenaAllocator(allocator: *mut PyObjectArenaAllocator);
}

/// Test if a type has a GC head
#[inline]
pub unsafe fn PyType_IS_GC(t: *mut PyTypeObject) -> c_int {
PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC)
}

/// Test if an object has a GC head
#[inline]
#[cfg(not(Py_LIMITED_API))]
pub unsafe fn PyObject_IS_GC(o: *mut PyObject) -> c_int {
(PyType_IS_GC(Py_TYPE(o)) != 0
&& match (*Py_TYPE(o)).tp_is_gc {
Some(tp_is_gc) => tp_is_gc(o) != 0,
None => true,
}) as c_int
}

extern "C" {
pub fn _PyObject_GC_Resize(arg1: *mut PyVarObject, arg2: Py_ssize_t) -> *mut PyVarObject;

#[cfg(not(Py_LIMITED_API))]
pub fn _PyObject_GC_Malloc(size: size_t) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
pub fn _PyObject_GC_Calloc(size: size_t) -> *mut PyObject;
// skipped PyObject_GC_Resize

#[cfg_attr(PyPy, link_name = "_PyPyObject_GC_New")]
pub fn _PyObject_GC_New(arg1: *mut PyTypeObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "_PyPyObject_GC_NewVar")]
Expand All @@ -98,18 +76,16 @@ extern "C" {
pub fn PyObject_GC_UnTrack(arg1: *mut c_void);
#[cfg_attr(PyPy, link_name = "PyPyObject_GC_Del")]
pub fn PyObject_GC_Del(arg1: *mut c_void);
}

/// Test if a type supports weak references
#[inline]
#[cfg(not(Py_LIMITED_API))]
pub unsafe fn PyType_SUPPORTS_WEAKREFS(t: *mut PyTypeObject) -> c_int {
((*t).tp_weaklistoffset > 0) as c_int
}
// skipped PyObject_GC_New
// skipped PyObject_GC_NewVar

#[inline]
#[cfg(not(Py_LIMITED_API))]
pub unsafe fn PyObject_GET_WEAKREFS_LISTPTR(o: *mut PyObject) -> *mut *mut PyObject {
let weaklistoffset = (*Py_TYPE(o)).tp_weaklistoffset;
o.offset(weaklistoffset) as *mut *mut PyObject
#[cfg(any(all(Py_3_9), not(PyPy), Py_3_10))] // added in 3.9, or 3.10 on PyPy
#[cfg_attr(PyPy, link_name = "PyPyObject_GC_IsTracked")]
pub fn PyObject_GC_IsTracked(arg1: *mut PyObject) -> c_int;
#[cfg(any(all(Py_3_9), not(PyPy), Py_3_10))] // added in 3.9, or 3.10 on PyPy
#[cfg_attr(PyPy, link_name = "PyPyObject_GC_IsFinalized")]
pub fn PyObject_GC_IsFinalized(arg1: *mut PyObject) -> c_int;
}

// skipped Py_VISIT

0 comments on commit 0e74bd6

Please sign in to comment.