1 | use crate::{PyObject, Py_ssize_t}; |
2 | use std::os::raw::{c_char, c_int}; |
3 | |
4 | #[cfg (not(Py_3_11))] |
5 | use crate::Py_buffer; |
6 | |
7 | #[cfg (Py_3_8)] |
8 | use crate::pyport::PY_SSIZE_T_MAX; |
9 | #[cfg (all(Py_3_8, not(PyPy)))] |
10 | use crate::{ |
11 | vectorcallfunc, PyCallable_Check, PyThreadState, PyThreadState_GET, PyTuple_Check, |
12 | PyType_HasFeature, Py_TPFLAGS_HAVE_VECTORCALL, |
13 | }; |
14 | #[cfg (Py_3_8)] |
15 | use libc::size_t; |
16 | |
17 | extern "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)))] |
23 | const _PY_FASTCALL_SMALL_STACK: size_t = 5; |
24 | |
25 | extern "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)] |
45 | const 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)] |
50 | pub 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)] |
57 | pub 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)] |
72 | pub 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)] |
96 | pub 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 | |
105 | extern "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)] |
139 | pub 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)] |
150 | pub 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)] |
160 | pub 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 | |
170 | extern "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)] |
178 | pub 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 | |
187 | extern "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)] |
199 | pub 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)] |
213 | pub 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 | |
234 | extern "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 ] |
245 | pub 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 |
251 | extern "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 | |
306 | pub const PY_ITERSEARCH_COUNT: c_int = 1; |
307 | pub const PY_ITERSEARCH_INDEX: c_int = 2; |
308 | pub const PY_ITERSEARCH_CONTAINS: c_int = 3; |
309 | |
310 | extern "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 | |