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

PyPy: the PyList/Tuple_GET/SET macros are defined as functions #1713

Merged
merged 1 commit into from
Jul 4, 2021
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

- Implement `IntoPy<PyObject>` for `&PathBuf` and `&OsString`. [#1721](https://github.com/PyO3/pyo3/pull/1712)

### Fixed

- Fix crashes on PyPy due to incorrect definitions of `PyList_SET_ITEM`. [#1713](https://github.com/PyO3/pyo3/pull/1713)

## [0.14.0] - 2021-07-03

### Packaging
Expand Down
3 changes: 3 additions & 0 deletions src/ffi/cpython/listobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@ pub struct PyListObject {

/// Macro, trading safety for speed
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyList_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject {
*(*(op as *mut PyListObject)).ob_item.offset(i as isize)
}

/// Macro, *only* to be used to fill in brand new lists
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyList_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) {
*(*(op as *mut PyListObject)).ob_item.offset(i as isize) = v;
}

#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyList_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
Py_SIZE(op)
}
11 changes: 11 additions & 0 deletions src/ffi/listobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,15 @@ extern "C" {
pub fn PyList_Reverse(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyList_AsTuple")]
pub fn PyList_AsTuple(arg1: *mut PyObject) -> *mut PyObject;

// CPython macros exported as functions on PyPy
#[cfg(PyPy)]
#[cfg_attr(PyPy, link_name = "PyPyList_GET_ITEM")]
pub fn PyList_GET_ITEM(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject;
#[cfg(PyPy)]
#[cfg_attr(PyPy, link_name = "PyPyList_GET_SIZE")]
pub fn PyList_GET_SIZE(arg1: *mut PyObject) -> Py_ssize_t;
#[cfg(PyPy)]
#[cfg_attr(PyPy, link_name = "PyPyList_SET_ITEM")]
pub fn PyList_SET_ITEM(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject);
}
6 changes: 3 additions & 3 deletions src/ffi/tupleobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ extern "C" {

/// Macro, trading safety for speed
#[inline]
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
pub unsafe fn PyTuple_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject {
*(*(op as *mut PyTupleObject))
.ob_item
Expand All @@ -56,14 +56,14 @@ pub unsafe fn PyTuple_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObjec
}

#[inline]
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
pub unsafe fn PyTuple_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
Py_SIZE(op)
}

/// Macro, *only* to be used to fill in brand new tuples
#[inline]
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
pub unsafe fn PyTuple_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) {
*(*(op as *mut PyTupleObject))
.ob_item
Expand Down
12 changes: 6 additions & 6 deletions src/types/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ impl PyTuple {
unsafe {
let ptr = ffi::PyTuple_New(len as Py_ssize_t);
for (i, e) in elements_iter.enumerate() {
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
ffi::PyTuple_SET_ITEM(ptr, i as Py_ssize_t, e.to_object(py).into_ptr());
#[cfg(Py_LIMITED_API)]
#[cfg(any(Py_LIMITED_API, PyPy))]
ffi::PyTuple_SetItem(ptr, i as Py_ssize_t, e.to_object(py).into_ptr());
}
py.from_owned_ptr(ptr)
Expand All @@ -43,9 +43,9 @@ impl PyTuple {
/// Gets the length of the tuple.
pub fn len(&self) -> usize {
unsafe {
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
let size = ffi::PyTuple_GET_SIZE(self.as_ptr());
#[cfg(Py_LIMITED_API)]
#[cfg(any(Py_LIMITED_API, PyPy))]
let size = ffi::PyTuple_Size(self.as_ptr());
// non-negative Py_ssize_t should always fit into Rust uint
size as usize
Expand Down Expand Up @@ -79,9 +79,9 @@ impl PyTuple {
pub fn get_item(&self, index: usize) -> &PyAny {
assert!(index < self.len());
unsafe {
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
let item = ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t);
#[cfg(Py_LIMITED_API)]
#[cfg(any(Py_LIMITED_API, PyPy))]
let item = ffi::PyTuple_GetItem(self.as_ptr(), index as Py_ssize_t);

self.py().from_borrowed_ptr(item)
Expand Down