1 #ifndef Py_CPYTHON_ABSTRACTOBJECT_H
2 #  error "this header file must not be included directly"
3 #endif
4 
5 /* === Object Protocol ================================================== */
6 
7 #ifdef PY_SSIZE_T_CLEAN
8 #  define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT
9 #endif
10 
11 /* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
12    format to a Python dictionary ("kwargs" dict).
13 
14    The type of kwnames keys is not checked. The final function getting
15    arguments is responsible to check if all keys are strings, for example using
16    PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
17 
18    Duplicate keys are merged using the last value. If duplicate keys must raise
19    an exception, the caller is responsible to implement an explicit keys on
20    kwnames. */
21 PyAPI_FUNC(PyObject *) _PyStack_AsDict(
22     PyObject *const *values,
23     PyObject *kwnames);
24 
25 /* Suggested size (number of positional arguments) for arrays of PyObject*
26    allocated on a C stack to avoid allocating memory on the heap memory. Such
27    array is used to pass positional arguments to call functions of the
28    PyObject_Vectorcall() family.
29 
30    The size is chosen to not abuse the C stack and so limit the risk of stack
31    overflow. The size is also chosen to allow using the small stack for most
32    function calls of the Python standard library. On 64-bit CPU, it allocates
33    40 bytes on the stack. */
34 #define _PY_FASTCALL_SMALL_STACK 5
35 
36 PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(
37     PyThreadState *tstate,
38     PyObject *callable,
39     PyObject *result,
40     const char *where);
41 
42 /* === Vectorcall protocol (PEP 590) ============================= */
43 
44 /* Call callable using tp_call. Arguments are like PyObject_Vectorcall()
45    or PyObject_FastCallDict() (both forms are supported),
46    except that nargs is plainly the number of arguments without flags. */
47 PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall(
48     PyThreadState *tstate,
49     PyObject *callable,
50     PyObject *const *args, Py_ssize_t nargs,
51     PyObject *keywords);
52 
53 #define PY_VECTORCALL_ARGUMENTS_OFFSET \
54     (_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1))
55 
56 static inline Py_ssize_t
PyVectorcall_NARGS(size_t n)57 PyVectorcall_NARGS(size_t n)
58 {
59     return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET;
60 }
61 
62 PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable);
63 
64 PyAPI_FUNC(PyObject *) PyObject_Vectorcall(
65     PyObject *callable,
66     PyObject *const *args,
67     size_t nargsf,
68     PyObject *kwnames);
69 
70 // Backwards compatibility aliases for API that was provisional in Python 3.8
71 #define _PyObject_Vectorcall PyObject_Vectorcall
72 #define _PyObject_VectorcallMethod PyObject_VectorcallMethod
73 #define _PyObject_FastCallDict PyObject_VectorcallDict
74 #define _PyVectorcall_Function PyVectorcall_Function
75 #define _PyObject_CallOneArg PyObject_CallOneArg
76 #define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
77 #define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
78 
79 /* Same as PyObject_Vectorcall except that keyword arguments are passed as
80    dict, which may be NULL if there are no keyword arguments. */
81 PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(
82     PyObject *callable,
83     PyObject *const *args,
84     size_t nargsf,
85     PyObject *kwargs);
86 
87 /* Call "callable" (which must support vectorcall) with positional arguments
88    "tuple" and keyword arguments "dict". "dict" may also be NULL */
89 PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict);
90 
91 // Same as PyObject_Vectorcall(), except without keyword arguments
92 PyAPI_FUNC(PyObject *) _PyObject_FastCall(
93     PyObject *func,
94     PyObject *const *args,
95     Py_ssize_t nargs);
96 
97 PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg);
98 
99 PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod(
100     PyObject *name, PyObject *const *args,
101     size_t nargsf, PyObject *kwnames);
102 
103 static inline PyObject *
PyObject_CallMethodNoArgs(PyObject * self,PyObject * name)104 PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
105 {
106     size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
107     return PyObject_VectorcallMethod(name, &self, nargsf, _Py_NULL);
108 }
109 
110 static inline PyObject *
PyObject_CallMethodOneArg(PyObject * self,PyObject * name,PyObject * arg)111 PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
112 {
113     PyObject *args[2] = {self, arg};
114     size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
115     assert(arg != NULL);
116     return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL);
117 }
118 
119 PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj,
120                                             PyObject *name,
121                                             const char *format, ...);
122 
123 /* Like PyObject_CallMethod(), but expect a _Py_Identifier*
124    as the method name. */
125 PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
126                                               _Py_Identifier *name,
127                                               const char *format, ...);
128 
129 PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj,
130                                                     _Py_Identifier *name,
131                                                     const char *format,
132                                                     ...);
133 
134 PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs(
135     PyObject *obj,
136     _Py_Identifier *name,
137     ...);
138 
139 static inline PyObject *
_PyObject_VectorcallMethodId(_Py_Identifier * name,PyObject * const * args,size_t nargsf,PyObject * kwnames)140 _PyObject_VectorcallMethodId(
141     _Py_Identifier *name, PyObject *const *args,
142     size_t nargsf, PyObject *kwnames)
143 {
144     PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
145     if (!oname) {
146         return _Py_NULL;
147     }
148     return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
149 }
150 
151 static inline PyObject *
_PyObject_CallMethodIdNoArgs(PyObject * self,_Py_Identifier * name)152 _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
153 {
154     size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
155     return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
156 }
157 
158 static inline PyObject *
_PyObject_CallMethodIdOneArg(PyObject * self,_Py_Identifier * name,PyObject * arg)159 _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
160 {
161     PyObject *args[2] = {self, arg};
162     size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
163     assert(arg != NULL);
164     return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
165 }
166 
167 PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
168 
169 /* Guess the size of object 'o' using len(o) or o.__length_hint__().
170    If neither of those return a non-negative value, then return the default
171    value.  If one of the calls fails, this function returns -1. */
172 PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
173 
174 /* === Sequence protocol ================================================ */
175 
176 /* Assume tp_as_sequence and sq_item exist and that 'i' does not
177    need to be corrected for a negative index. */
178 #define PySequence_ITEM(o, i)\
179     ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
180 
181 #define PY_ITERSEARCH_COUNT    1
182 #define PY_ITERSEARCH_INDEX    2
183 #define PY_ITERSEARCH_CONTAINS 3
184 
185 /* Iterate over seq.
186 
187    Result depends on the operation:
188 
189    PY_ITERSEARCH_COUNT:  return # of times obj appears in seq; -1 if
190      error.
191    PY_ITERSEARCH_INDEX:  return 0-based index of first occurrence of
192      obj in seq; set ValueError and return -1 if none found;
193      also return -1 on error.
194    PY_ITERSEARCH_CONTAINS:  return 1 if obj in seq, else 0; -1 on
195      error. */
196 PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq,
197                                               PyObject *obj, int operation);
198 
199 /* === Mapping protocol ================================================= */
200 
201 PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
202 
203 PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
204 
205 PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
206 
207 PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
208 
209 /* For internal use by buffer API functions */
210 PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
211                                         const Py_ssize_t *shape);
212 PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
213                                         const Py_ssize_t *shape);
214 
215 /* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */
216 PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
217 
218 /* Same as PyNumber_Index but can return an instance of a subclass of int. */
219 PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o);
220