1use crate::{PyObject, Py_ssize_t};
2use std::os::raw::{c_char, c_int};
3
4#[cfg(not(Py_3_11))]
5use crate::Py_buffer;
6
7#[cfg(Py_3_8)]
8use crate::pyport::PY_SSIZE_T_MAX;
9#[cfg(all(Py_3_8, not(PyPy)))]
10use crate::{
11 vectorcallfunc, PyCallable_Check, PyThreadState, PyThreadState_GET, PyTuple_Check,
12 PyType_HasFeature, Py_TPFLAGS_HAVE_VECTORCALL,
13};
14#[cfg(Py_3_8)]
15use libc::size_t;
16
17extern "C" {
18 #[cfg(all(Py_3_8, not(PyPy)))]
19 pub fn _PyStack_AsDict(values: *const *mut PyObject, kwnames: *mut PyObject) -> *mut PyObject;
20}
21
22#[cfg(all(Py_3_8, not(PyPy)))]
23const _PY_FASTCALL_SMALL_STACK: size_t = 5;
24
25extern "C" {
26 #[cfg(all(Py_3_8, not(PyPy)))]
27 pub fn _Py_CheckFunctionResult(
28 tstate: *mut PyThreadState,
29 callable: *mut PyObject,
30 result: *mut PyObject,
31 where_: *const c_char,
32 ) -> *mut PyObject;
33
34 #[cfg(all(Py_3_8, not(PyPy)))]
35 pub fn _PyObject_MakeTpCall(
36 tstate: *mut PyThreadState,
37 callable: *mut PyObject,
38 args: *const *mut PyObject,
39 nargs: Py_ssize_t,
40 keywords: *mut PyObject,
41 ) -> *mut PyObject;
42}
43
44#[cfg(Py_3_8)]
45const PY_VECTORCALL_ARGUMENTS_OFFSET: Py_ssize_t =
46 1 << (8 * std::mem::size_of::<Py_ssize_t>() as Py_ssize_t - 1);
47
48#[cfg(Py_3_8)]
49#[inline(always)]
50pub unsafe fn PyVectorcall_NARGS(n: size_t) -> Py_ssize_t {
51 assert!(n <= (PY_SSIZE_T_MAX as size_t));
52 (n as Py_ssize_t) & !PY_VECTORCALL_ARGUMENTS_OFFSET
53}
54
55#[cfg(all(Py_3_8, not(PyPy)))]
56#[inline(always)]
57pub unsafe fn PyVectorcall_Function(callable: *mut PyObject) -> Option<vectorcallfunc> {
58 assert!(!callable.is_null());
59 let tp: *mut PyTypeObject = crate::Py_TYPE(ob:callable);
60 if PyType_HasFeature(t:tp, Py_TPFLAGS_HAVE_VECTORCALL) == 0 {
61 return None;
62 }
63 assert!(PyCallable_Check(callable) > 0);
64 let offset: isize = (*tp).tp_vectorcall_offset;
65 assert!(offset > 0);
66 let ptr: *const Option …> = (callable as *const c_char).offset(count:offset) as *const Option<vectorcallfunc>;
67 *ptr
68}
69
70#[cfg(all(Py_3_8, not(PyPy)))]
71#[inline(always)]
72pub unsafe fn _PyObject_VectorcallTstate(
73 tstate: *mut PyThreadState,
74 callable: *mut PyObject,
75 args: *const *mut PyObject,
76 nargsf: size_t,
77 kwnames: *mut PyObject,
78) -> *mut PyObject {
79 assert!(kwnames.is_null() || PyTuple_Check(kwnames) > 0);
80 assert!(!args.is_null() || PyVectorcall_NARGS(nargsf) == 0);
81
82 match PyVectorcall_Function(callable) {
83 None => {
84 let nargs: isize = PyVectorcall_NARGS(nargsf);
85 _PyObject_MakeTpCall(tstate, callable, args, nargs, keywords:kwnames)
86 }
87 Some(func: unsafe fn(*mut PyObject, …) -> …) => {
88 let res: *mut PyObject = func(callable, args, nargsf, kwnames);
89 _Py_CheckFunctionResult(tstate, callable, result:res, where_:std::ptr::null_mut())
90 }
91 }
92}
93
94#[cfg(all(Py_3_8, not(PyPy)))]
95#[inline(always)]
96pub unsafe fn PyObject_Vectorcall(
97 callable: *mut PyObject,
98 args: *const *mut PyObject,
99 nargsf: size_t,
100 kwnames: *mut PyObject,
101) -> *mut PyObject {
102 _PyObject_VectorcallTstate(tstate:PyThreadState_GET(), callable, args, nargsf, kwnames)
103}
104
105extern "C" {
106 #[cfg(all(PyPy, Py_3_8))]
107 #[cfg_attr(not(Py_3_9), link_name = "_PyPyObject_Vectorcall")]
108 #[cfg_attr(Py_3_9, link_name = "PyPyObject_Vectorcall")]
109 pub fn PyObject_Vectorcall(
110 callable: *mut PyObject,
111 args: *const *mut PyObject,
112 nargsf: size_t,
113 kwnames: *mut PyObject,
114 ) -> *mut PyObject;
115
116 #[cfg(Py_3_8)]
117 #[cfg_attr(all(not(PyPy), not(Py_3_9)), link_name = "_PyObject_VectorcallDict")]
118 #[cfg_attr(all(PyPy, not(Py_3_9)), link_name = "_PyPyObject_VectorcallDict")]
119 #[cfg_attr(all(PyPy, Py_3_9), link_name = "PyPyObject_VectorcallDict")]
120 pub fn PyObject_VectorcallDict(
121 callable: *mut PyObject,
122 args: *const *mut PyObject,
123 nargsf: size_t,
124 kwdict: *mut PyObject,
125 ) -> *mut PyObject;
126
127 #[cfg(Py_3_8)]
128 #[cfg_attr(not(any(Py_3_9, PyPy)), link_name = "_PyVectorcall_Call")]
129 #[cfg_attr(PyPy, link_name = "PyPyVectorcall_Call")]
130 pub fn PyVectorcall_Call(
131 callable: *mut PyObject,
132 tuple: *mut PyObject,
133 dict: *mut PyObject,
134 ) -> *mut PyObject;
135}
136
137#[cfg(all(Py_3_8, not(PyPy)))]
138#[inline(always)]
139pub unsafe fn _PyObject_FastCallTstate(
140 tstate: *mut PyThreadState,
141 func: *mut PyObject,
142 args: *const *mut PyObject,
143 nargs: Py_ssize_t,
144) -> *mut PyObject {
145 _PyObject_VectorcallTstate(tstate, callable:func, args, nargsf:nargs as size_t, kwnames:std::ptr::null_mut())
146}
147
148#[cfg(all(Py_3_8, not(PyPy)))]
149#[inline(always)]
150pub unsafe fn _PyObject_FastCall(
151 func: *mut PyObject,
152 args: *const *mut PyObject,
153 nargs: Py_ssize_t,
154) -> *mut PyObject {
155 _PyObject_FastCallTstate(tstate:PyThreadState_GET(), func, args, nargs)
156}
157
158#[cfg(all(Py_3_8, not(PyPy)))]
159#[inline(always)]
160pub unsafe fn _PyObject_CallNoArg(func: *mut PyObject) -> *mut PyObject {
161 _PyObject_VectorcallTstate(
162 tstate:PyThreadState_GET(),
163 callable:func,
164 args:std::ptr::null_mut(),
165 nargsf:0,
166 kwnames:std::ptr::null_mut(),
167 )
168}
169
170extern "C" {
171 #[cfg(PyPy)]
172 #[link_name = "_PyPyObject_CallNoArg"]
173 pub fn _PyObject_CallNoArg(func: *mut PyObject) -> *mut PyObject;
174}
175
176#[cfg(all(Py_3_8, not(PyPy)))]
177#[inline(always)]
178pub unsafe fn PyObject_CallOneArg(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject {
179 assert!(!arg.is_null());
180 let args_array: [*mut PyObject; 2] = [std::ptr::null_mut(), arg];
181 let args: *const *mut PyObject = args_array.as_ptr().offset(count:1); // For PY_VECTORCALL_ARGUMENTS_OFFSET
182 let tstate: *mut PyThreadState = PyThreadState_GET();
183 let nargsf: isize = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
184 _PyObject_VectorcallTstate(tstate, callable:func, args, nargsf as size_t, kwnames:std::ptr::null_mut())
185}
186
187extern "C" {
188 #[cfg(all(Py_3_9, not(PyPy)))]
189 pub fn PyObject_VectorcallMethod(
190 name: *mut PyObject,
191 args: *const *mut PyObject,
192 nargsf: size_t,
193 kwnames: *mut PyObject,
194 ) -> *mut PyObject;
195}
196
197#[cfg(all(Py_3_9, not(PyPy)))]
198#[inline(always)]
199pub unsafe fn PyObject_CallMethodNoArgs(
200 self_: *mut PyObject,
201 name: *mut PyObject,
202) -> *mut PyObject {
203 PyObject_VectorcallMethod(
204 name,
205 &self_,
206 nargsf:1 | PY_VECTORCALL_ARGUMENTS_OFFSET as size_t,
207 kwnames:std::ptr::null_mut(),
208 )
209}
210
211#[cfg(all(Py_3_9, not(PyPy)))]
212#[inline(always)]
213pub unsafe fn PyObject_CallMethodOneArg(
214 self_: *mut PyObject,
215 name: *mut PyObject,
216 arg: *mut PyObject,
217) -> *mut PyObject {
218 let args: [*mut PyObject; 2] = [self_, arg];
219 assert!(!arg.is_null());
220 PyObject_VectorcallMethod(
221 name,
222 args:args.as_ptr(),
223 nargsf:2 | PY_VECTORCALL_ARGUMENTS_OFFSET as size_t,
224 kwnames:std::ptr::null_mut(),
225 )
226}
227
228// skipped _PyObject_VectorcallMethodId
229// skipped _PyObject_CallMethodIdNoArgs
230// skipped _PyObject_CallMethodIdOneArg
231
232// skipped _PyObject_HasLen
233
234extern "C" {
235 #[cfg_attr(PyPy, link_name = "PyPyObject_LengthHint")]
236 pub fn PyObject_LengthHint(o: *mut PyObject, arg1: Py_ssize_t) -> Py_ssize_t;
237
238 #[cfg(not(Py_3_11))] // moved to src/buffer.rs from 3.11
239 #[cfg(all(Py_3_9, not(PyPy)))]
240 pub fn PyObject_CheckBuffer(obj: *mut PyObject) -> c_int;
241}
242
243#[cfg(not(any(Py_3_9, PyPy)))]
244#[inline]
245pub unsafe fn PyObject_CheckBuffer(o: *mut PyObject) -> c_int {
246 let tp_as_buffer = (*crate::Py_TYPE(o)).tp_as_buffer;
247 (!tp_as_buffer.is_null() && (*tp_as_buffer).bf_getbuffer.is_some()) as c_int
248}
249
250#[cfg(not(Py_3_11))] // moved to src/buffer.rs from 3.11
251extern "C" {
252 #[cfg_attr(PyPy, link_name = "PyPyObject_GetBuffer")]
253 pub fn PyObject_GetBuffer(obj: *mut PyObject, view: *mut Py_buffer, flags: c_int) -> c_int;
254 #[cfg_attr(PyPy, link_name = "PyPyBuffer_GetPointer")]
255 pub fn PyBuffer_GetPointer(
256 view: *mut Py_buffer,
257 indices: *mut Py_ssize_t,
258 ) -> *mut std::os::raw::c_void;
259 #[cfg_attr(PyPy, link_name = "PyPyBuffer_SizeFromFormat")]
260 pub fn PyBuffer_SizeFromFormat(format: *const c_char) -> Py_ssize_t;
261 #[cfg_attr(PyPy, link_name = "PyPyBuffer_ToContiguous")]
262 pub fn PyBuffer_ToContiguous(
263 buf: *mut std::os::raw::c_void,
264 view: *mut Py_buffer,
265 len: Py_ssize_t,
266 order: c_char,
267 ) -> c_int;
268 #[cfg_attr(PyPy, link_name = "PyPyBuffer_FromContiguous")]
269 pub fn PyBuffer_FromContiguous(
270 view: *mut Py_buffer,
271 buf: *mut std::os::raw::c_void,
272 len: Py_ssize_t,
273 order: c_char,
274 ) -> c_int;
275 pub fn PyObject_CopyData(dest: *mut PyObject, src: *mut PyObject) -> c_int;
276 #[cfg_attr(PyPy, link_name = "PyPyBuffer_IsContiguous")]
277 pub fn PyBuffer_IsContiguous(view: *const Py_buffer, fort: c_char) -> c_int;
278 pub fn PyBuffer_FillContiguousStrides(
279 ndims: c_int,
280 shape: *mut Py_ssize_t,
281 strides: *mut Py_ssize_t,
282 itemsize: c_int,
283 fort: c_char,
284 );
285 #[cfg_attr(PyPy, link_name = "PyPyBuffer_FillInfo")]
286 pub fn PyBuffer_FillInfo(
287 view: *mut Py_buffer,
288 o: *mut PyObject,
289 buf: *mut std::os::raw::c_void,
290 len: Py_ssize_t,
291 readonly: c_int,
292 flags: c_int,
293 ) -> c_int;
294 #[cfg_attr(PyPy, link_name = "PyPyBuffer_Release")]
295 pub fn PyBuffer_Release(view: *mut Py_buffer);
296}
297
298// PyIter_Check defined in ffi/abstract_.rs
299// PyIndex_Check defined in ffi/abstract_.rs
300// Not defined here because this file is not compiled under the
301// limited API, but the macros need to be defined for 3.6, 3.7 which
302// predate the limited API changes.
303
304// skipped PySequence_ITEM
305
306pub const PY_ITERSEARCH_COUNT: c_int = 1;
307pub const PY_ITERSEARCH_INDEX: c_int = 2;
308pub const PY_ITERSEARCH_CONTAINS: c_int = 3;
309
310extern "C" {
311 #[cfg(not(PyPy))]
312 pub fn _PySequence_IterSearch(
313 seq: *mut PyObject,
314 obj: *mut PyObject,
315 operation: c_int,
316 ) -> Py_ssize_t;
317}
318
319// skipped _PyObject_RealIsInstance
320// skipped _PyObject_RealIsSubclass
321
322// skipped _PySequence_BytesToCharpArray
323
324// skipped _Py_FreeCharPArray
325
326// skipped _Py_add_one_to_index_F
327// skipped _Py_add_one_to_index_C
328
329// skipped _Py_convert_optional_to_ssize_t
330
331// skipped _PyNumber_Index(*mut PyObject o)
332