Skip to content

Commit 34843d7

Browse files
authored
Merge pull request #641 from ijl/pep590
FFI for PEP 590 Vectorcall
2 parents bab05e8 + caf4713 commit 34843d7

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-3
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## Unreleased
9+
10+
### Added
11+
12+
* FFI compatibility for PEP 590 Vectorcall.
13+
814
## [0.8.1]
915

1016
### Added

src/ffi/methodobject.rs

+37-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,39 @@ pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
1515
pub type PyCFunction =
1616
unsafe extern "C" fn(slf: *mut PyObject, args: *mut PyObject) -> *mut PyObject;
1717

18-
#[cfg(all(Py_3_6, not(Py_LIMITED_API)))]
18+
#[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
19+
#[cfg_attr(Py_3_8, link_name = "_PyObject_Vectorcall")]
20+
pub type PyObject_Vectorcall = unsafe extern "C" fn(
21+
slf: *mut PyObject,
22+
// positional and keyword arguments
23+
args: *const *mut PyObject,
24+
// number of position arguments in args, after which values are kwargs
25+
nargs: crate::ffi::pyport::Py_ssize_t,
26+
// tuple of kwargs, if given, or null
27+
kwnames: *mut PyObject,
28+
) -> *mut PyObject;
29+
30+
#[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
31+
#[cfg_attr(Py_3_8, link_name = "PyVectorcall_Call")]
32+
pub type PyVectorcall_Call = unsafe extern "C" fn(
33+
obj: *mut PyObject,
34+
tuple: *mut PyObject,
35+
dict: *mut PyObject,
36+
) -> *mut PyObject;
37+
38+
#[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
39+
const PY_VECTORCALL_ARGUMENTS_OFFSET: crate::ffi::pyport::Py_ssize_t =
40+
1 << (8 * std::mem::size_of::<usize>() - 1);
41+
42+
#[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
43+
#[inline(always)]
44+
pub unsafe fn PyVectorcall_NARGS(
45+
n: crate::ffi::pyport::Py_ssize_t,
46+
) -> crate::ffi::pyport::Py_ssize_t {
47+
n & !PY_VECTORCALL_ARGUMENTS_OFFSET
48+
}
49+
50+
#[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
1951
pub type _PyCFunctionFast = unsafe extern "C" fn(
2052
slf: *mut PyObject,
2153
args: *mut *mut PyObject,
@@ -102,8 +134,10 @@ slot like sq_contains. */
102134

103135
pub const METH_COEXIST: c_int = 0x0040;
104136

105-
#[cfg(all(Py_3_6, not(Py_LIMITED_API)))]
106-
pub const METHOD_FASTCALL: c_int = 0x0080;
137+
/* METH_FASTCALL indicates the PEP 590 Vectorcall calling format. It may
138+
be specified alone or with METH_KEYWORDS. */
139+
#[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
140+
pub const METH_FASTCALL: c_int = 0x0080;
107141

108142
#[cfg_attr(windows, link(name = "pythonXY"))]
109143
extern "C" {

src/ffi/object.rs

+10
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,10 @@ mod typeobject {
463463
pub tp_basicsize: Py_ssize_t,
464464
pub tp_itemsize: Py_ssize_t,
465465
pub tp_dealloc: Option<object::destructor>,
466+
#[cfg(not(Py_3_8))]
466467
pub tp_print: Option<object::printfunc>,
468+
#[cfg(Py_3_8)]
469+
pub tp_vectorcall_offset: Py_ssize_t,
467470
pub tp_getattr: Option<object::getattrfunc>,
468471
pub tp_setattr: Option<object::setattrfunc>,
469472
pub tp_as_async: *mut PyAsyncMethods,
@@ -529,7 +532,10 @@ mod typeobject {
529532
tp_basicsize: 0,
530533
tp_itemsize: 0,
531534
tp_dealloc: None,
535+
#[cfg(not(Py_3_8))]
532536
tp_print: None,
537+
#[cfg(Py_3_8)]
538+
tp_vectorcall_offset: 0,
533539
tp_getattr: None,
534540
tp_setattr: None,
535541
$tp_as_async: ptr::null_mut(),
@@ -847,6 +853,10 @@ pub const Py_TPFLAGS_HEAPTYPE: c_ulong = (1 << 9);
847853
/// Set if the type allows subclassing
848854
pub const Py_TPFLAGS_BASETYPE: c_ulong = (1 << 10);
849855

856+
/// Set if the type implements the vectorcall protocol (PEP 590)
857+
#[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
858+
pub const _Py_TPFLAGS_HAVE_VECTORCALL: c_ulong = (1 << 11);
859+
850860
/// Set if the type is 'ready' -- fully initialized
851861
pub const Py_TPFLAGS_READY: c_ulong = (1 << 12);
852862

0 commit comments

Comments
 (0)