• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef Py_CPYTHON_ABSTRACTOBJECT_H
2 #  error "this header file must not be included directly"
3 #endif
4 
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8 
9 /* === Object Protocol ================================================== */
10 
11 #ifdef PY_SSIZE_T_CLEAN
12 #  define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT
13 #endif
14 
15 /* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
16    format to a Python dictionary ("kwargs" dict).
17 
18    The type of kwnames keys is not checked. The final function getting
19    arguments is responsible to check if all keys are strings, for example using
20    PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
21 
22    Duplicate keys are merged using the last value. If duplicate keys must raise
23    an exception, the caller is responsible to implement an explicit keys on
24    kwnames. */
25 PyAPI_FUNC(PyObject *) _PyStack_AsDict(
26     PyObject *const *values,
27     PyObject *kwnames);
28 
29 /* Suggested size (number of positional arguments) for arrays of PyObject*
30    allocated on a C stack to avoid allocating memory on the heap memory. Such
31    array is used to pass positional arguments to call functions of the
32    PyObject_Vectorcall() family.
33 
34    The size is chosen to not abuse the C stack and so limit the risk of stack
35    overflow. The size is also chosen to allow using the small stack for most
36    function calls of the Python standard library. On 64-bit CPU, it allocates
37    40 bytes on the stack. */
38 #define _PY_FASTCALL_SMALL_STACK 5
39 
40 PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(
41     PyThreadState *tstate,
42     PyObject *callable,
43     PyObject *result,
44     const char *where);
45 
46 /* === Vectorcall protocol (PEP 590) ============================= */
47 
48 /* Call callable using tp_call. Arguments are like PyObject_Vectorcall()
49    or PyObject_FastCallDict() (both forms are supported),
50    except that nargs is plainly the number of arguments without flags. */
51 PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall(
52     PyThreadState *tstate,
53     PyObject *callable,
54     PyObject *const *args, Py_ssize_t nargs,
55     PyObject *keywords);
56 
57 #define PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1))
58 
59 static inline Py_ssize_t
PyVectorcall_NARGS(size_t n)60 PyVectorcall_NARGS(size_t n)
61 {
62     return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET;
63 }
64 
65 static inline vectorcallfunc
PyVectorcall_Function(PyObject * callable)66 PyVectorcall_Function(PyObject *callable)
67 {
68     PyTypeObject *tp;
69     Py_ssize_t offset;
70     vectorcallfunc *ptr;
71 
72     assert(callable != NULL);
73     tp = Py_TYPE(callable);
74     if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) {
75         return NULL;
76     }
77     assert(PyCallable_Check(callable));
78     offset = tp->tp_vectorcall_offset;
79     assert(offset > 0);
80     ptr = (vectorcallfunc *)(((char *)callable) + offset);
81     return *ptr;
82 }
83 
84 /* Call the callable object 'callable' with the "vectorcall" calling
85    convention.
86 
87    args is a C array for positional arguments.
88 
89    nargsf is the number of positional arguments plus optionally the flag
90    PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to
91    modify args[-1].
92 
93    kwnames is a tuple of keyword names. The values of the keyword arguments
94    are stored in "args" after the positional arguments (note that the number
95    of keyword arguments does not change nargsf). kwnames can also be NULL if
96    there are no keyword arguments.
97 
98    keywords must only contain strings and all keys must be unique.
99 
100    Return the result on success. Raise an exception and return NULL on
101    error. */
102 static inline PyObject *
_PyObject_VectorcallTstate(PyThreadState * tstate,PyObject * callable,PyObject * const * args,size_t nargsf,PyObject * kwnames)103 _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable,
104                            PyObject *const *args, size_t nargsf,
105                            PyObject *kwnames)
106 {
107     vectorcallfunc func;
108     PyObject *res;
109 
110     assert(kwnames == NULL || PyTuple_Check(kwnames));
111     assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0);
112 
113     func = PyVectorcall_Function(callable);
114     if (func == NULL) {
115         Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
116         return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
117     }
118     res = func(callable, args, nargsf, kwnames);
119     return _Py_CheckFunctionResult(tstate, callable, res, NULL);
120 }
121 
122 static inline PyObject *
PyObject_Vectorcall(PyObject * callable,PyObject * const * args,size_t nargsf,PyObject * kwnames)123 PyObject_Vectorcall(PyObject *callable, PyObject *const *args,
124                      size_t nargsf, PyObject *kwnames)
125 {
126     PyThreadState *tstate = PyThreadState_GET();
127     return _PyObject_VectorcallTstate(tstate, callable,
128                                       args, nargsf, kwnames);
129 }
130 
131 // Backwards compatibility aliases for API that was provisional in Python 3.8
132 #define _PyObject_Vectorcall PyObject_Vectorcall
133 #define _PyObject_VectorcallMethod PyObject_VectorcallMethod
134 #define _PyObject_FastCallDict PyObject_VectorcallDict
135 #define _PyVectorcall_Function PyVectorcall_Function
136 #define _PyObject_CallOneArg PyObject_CallOneArg
137 #define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
138 #define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
139 
140 /* Same as PyObject_Vectorcall except that keyword arguments are passed as
141    dict, which may be NULL if there are no keyword arguments. */
142 PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(
143     PyObject *callable,
144     PyObject *const *args,
145     size_t nargsf,
146     PyObject *kwargs);
147 
148 /* Call "callable" (which must support vectorcall) with positional arguments
149    "tuple" and keyword arguments "dict". "dict" may also be NULL */
150 PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict);
151 
152 static inline PyObject *
_PyObject_FastCallTstate(PyThreadState * tstate,PyObject * func,PyObject * const * args,Py_ssize_t nargs)153 _PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs)
154 {
155     return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL);
156 }
157 
158 /* Same as PyObject_Vectorcall except without keyword arguments */
159 static inline PyObject *
_PyObject_FastCall(PyObject * func,PyObject * const * args,Py_ssize_t nargs)160 _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs)
161 {
162     PyThreadState *tstate = PyThreadState_GET();
163     return _PyObject_FastCallTstate(tstate, func, args, nargs);
164 }
165 
166 /* Call a callable without any arguments
167    Private static inline function variant of public function
168    PyObject_CallNoArgs(). */
169 static inline PyObject *
_PyObject_CallNoArg(PyObject * func)170 _PyObject_CallNoArg(PyObject *func) {
171     PyThreadState *tstate = PyThreadState_GET();
172     return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
173 }
174 
175 static inline PyObject *
PyObject_CallOneArg(PyObject * func,PyObject * arg)176 PyObject_CallOneArg(PyObject *func, PyObject *arg)
177 {
178     PyObject *_args[2];
179     PyObject **args;
180     PyThreadState *tstate;
181     size_t nargsf;
182 
183     assert(arg != NULL);
184     args = _args + 1;  // For PY_VECTORCALL_ARGUMENTS_OFFSET
185     args[0] = arg;
186     tstate = PyThreadState_GET();
187     nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
188     return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL);
189 }
190 
191 PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod(
192     PyObject *name, PyObject *const *args,
193     size_t nargsf, PyObject *kwnames);
194 
195 static inline PyObject *
PyObject_CallMethodNoArgs(PyObject * self,PyObject * name)196 PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
197 {
198     return PyObject_VectorcallMethod(name, &self,
199            1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
200 }
201 
202 static inline PyObject *
PyObject_CallMethodOneArg(PyObject * self,PyObject * name,PyObject * arg)203 PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
204 {
205     PyObject *args[2] = {self, arg};
206 
207     assert(arg != NULL);
208     return PyObject_VectorcallMethod(name, args,
209            2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
210 }
211 
212 /* Like PyObject_CallMethod(), but expect a _Py_Identifier*
213    as the method name. */
214 PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
215                                               _Py_Identifier *name,
216                                               const char *format, ...);
217 
218 PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj,
219                                                     _Py_Identifier *name,
220                                                     const char *format,
221                                                     ...);
222 
223 PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs(
224     PyObject *obj,
225     struct _Py_Identifier *name,
226     ...);
227 
228 static inline PyObject *
_PyObject_VectorcallMethodId(_Py_Identifier * name,PyObject * const * args,size_t nargsf,PyObject * kwnames)229 _PyObject_VectorcallMethodId(
230     _Py_Identifier *name, PyObject *const *args,
231     size_t nargsf, PyObject *kwnames)
232 {
233     PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
234     if (!oname) {
235         return NULL;
236     }
237     return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
238 }
239 
240 static inline PyObject *
_PyObject_CallMethodIdNoArgs(PyObject * self,_Py_Identifier * name)241 _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
242 {
243     return _PyObject_VectorcallMethodId(name, &self,
244            1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
245 }
246 
247 static inline PyObject *
_PyObject_CallMethodIdOneArg(PyObject * self,_Py_Identifier * name,PyObject * arg)248 _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
249 {
250     PyObject *args[2] = {self, arg};
251 
252     assert(arg != NULL);
253     return _PyObject_VectorcallMethodId(name, args,
254            2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
255 }
256 
257 PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
258 
259 /* Guess the size of object 'o' using len(o) or o.__length_hint__().
260    If neither of those return a non-negative value, then return the default
261    value.  If one of the calls fails, this function returns -1. */
262 PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
263 
264 /* === New Buffer API ============================================ */
265 
266 /* Return 1 if the getbuffer function is available, otherwise return 0. */
267 PyAPI_FUNC(int) PyObject_CheckBuffer(PyObject *obj);
268 
269 /* This is a C-API version of the getbuffer function call.  It checks
270    to make sure object has the required function pointer and issues the
271    call.
272 
273    Returns -1 and raises an error on failure and returns 0 on success. */
274 PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view,
275                                    int flags);
276 
277 /* Get the memory area pointed to by the indices for the buffer given.
278    Note that view->ndim is the assumed size of indices. */
279 PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices);
280 
281 /* Return the implied itemsize of the data-format area from a
282    struct-style description. */
283 PyAPI_FUNC(Py_ssize_t) PyBuffer_SizeFromFormat(const char *format);
284 
285 /* Implementation in memoryobject.c */
286 PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view,
287                                       Py_ssize_t len, char order);
288 
289 PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf,
290                                         Py_ssize_t len, char order);
291 
292 /* Copy len bytes of data from the contiguous chunk of memory
293    pointed to by buf into the buffer exported by obj.  Return
294    0 on success and return -1 and raise a PyBuffer_Error on
295    error (i.e. the object does not have a buffer interface or
296    it is not working).
297 
298    If fort is 'F', then if the object is multi-dimensional,
299    then the data will be copied into the array in
300    Fortran-style (first dimension varies the fastest).  If
301    fort is 'C', then the data will be copied into the array
302    in C-style (last dimension varies the fastest).  If fort
303    is 'A', then it does not matter and the copy will be made
304    in whatever way is more efficient. */
305 PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src);
306 
307 /* Copy the data from the src buffer to the buffer of destination. */
308 PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort);
309 
310 /*Fill the strides array with byte-strides of a contiguous
311   (Fortran-style if fort is 'F' or C-style otherwise)
312   array of the given shape with the given number of bytes
313   per element. */
314 PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims,
315                                                Py_ssize_t *shape,
316                                                Py_ssize_t *strides,
317                                                int itemsize,
318                                                char fort);
319 
320 /* Fills in a buffer-info structure correctly for an exporter
321    that can only share a contiguous chunk of memory of
322    "unsigned bytes" of the given length.
323 
324    Returns 0 on success and -1 (with raising an error) on error. */
325 PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf,
326                                   Py_ssize_t len, int readonly,
327                                   int flags);
328 
329 /* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */
330 PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view);
331 
332 /* ==== Iterators ================================================ */
333 
334 #define PyIter_Check(obj) \
335     (Py_TYPE(obj)->tp_iternext != NULL && \
336      Py_TYPE(obj)->tp_iternext != &_PyObject_NextNotImplemented)
337 
338 /* === Sequence protocol ================================================ */
339 
340 /* Assume tp_as_sequence and sq_item exist and that 'i' does not
341    need to be corrected for a negative index. */
342 #define PySequence_ITEM(o, i)\
343     ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
344 
345 #define PY_ITERSEARCH_COUNT    1
346 #define PY_ITERSEARCH_INDEX    2
347 #define PY_ITERSEARCH_CONTAINS 3
348 
349 /* Iterate over seq.
350 
351    Result depends on the operation:
352 
353    PY_ITERSEARCH_COUNT:  return # of times obj appears in seq; -1 if
354      error.
355    PY_ITERSEARCH_INDEX:  return 0-based index of first occurrence of
356      obj in seq; set ValueError and return -1 if none found;
357      also return -1 on error.
358    PY_ITERSEARCH_CONTAINS:  return 1 if obj in seq, else 0; -1 on
359      error. */
360 PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq,
361                                               PyObject *obj, int operation);
362 
363 /* === Mapping protocol ================================================= */
364 
365 PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
366 
367 PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
368 
369 PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
370 
371 PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
372 
373 /* For internal use by buffer API functions */
374 PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
375                                         const Py_ssize_t *shape);
376 PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
377                                         const Py_ssize_t *shape);
378 
379 /* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */
380 PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
381 
382 #ifdef __cplusplus
383 }
384 #endif
385