1 #ifndef Py_INTERNAL_CALL_H
2 #define Py_INTERNAL_CALL_H
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6
7 #ifndef Py_BUILD_CORE
8 # error "this header requires Py_BUILD_CORE define"
9 #endif
10
11 #include "pycore_identifier.h" // _Py_Identifier
12 #include "pycore_pystate.h" // _PyThreadState_GET()
13
14 /* Suggested size (number of positional arguments) for arrays of PyObject*
15 allocated on a C stack to avoid allocating memory on the heap memory. Such
16 array is used to pass positional arguments to call functions of the
17 PyObject_Vectorcall() family.
18
19 The size is chosen to not abuse the C stack and so limit the risk of stack
20 overflow. The size is also chosen to allow using the small stack for most
21 function calls of the Python standard library. On 64-bit CPU, it allocates
22 40 bytes on the stack. */
23 #define _PY_FASTCALL_SMALL_STACK 5
24
25
26 // Export for 'math' shared extension, used via _PyObject_VectorcallTstate()
27 // static inline function.
28 PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult(
29 PyThreadState *tstate,
30 PyObject *callable,
31 PyObject *result,
32 const char *where);
33
34 extern PyObject* _PyObject_Call_Prepend(
35 PyThreadState *tstate,
36 PyObject *callable,
37 PyObject *obj,
38 PyObject *args,
39 PyObject *kwargs);
40
41 extern PyObject* _PyObject_VectorcallDictTstate(
42 PyThreadState *tstate,
43 PyObject *callable,
44 PyObject *const *args,
45 size_t nargsf,
46 PyObject *kwargs);
47
48 extern PyObject* _PyObject_Call(
49 PyThreadState *tstate,
50 PyObject *callable,
51 PyObject *args,
52 PyObject *kwargs);
53
54 extern PyObject * _PyObject_CallMethodFormat(
55 PyThreadState *tstate,
56 PyObject *callable,
57 const char *format,
58 ...);
59
60 // Export for 'array' shared extension
61 PyAPI_FUNC(PyObject*) _PyObject_CallMethod(
62 PyObject *obj,
63 PyObject *name,
64 const char *format, ...);
65
66 extern PyObject* _PyObject_CallMethodIdObjArgs(
67 PyObject *obj,
68 _Py_Identifier *name,
69 ...);
70
71 static inline PyObject *
_PyObject_VectorcallMethodId(_Py_Identifier * name,PyObject * const * args,size_t nargsf,PyObject * kwnames)72 _PyObject_VectorcallMethodId(
73 _Py_Identifier *name, PyObject *const *args,
74 size_t nargsf, PyObject *kwnames)
75 {
76 PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
77 if (!oname) {
78 return _Py_NULL;
79 }
80 return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
81 }
82
83 static inline PyObject *
_PyObject_CallMethodIdNoArgs(PyObject * self,_Py_Identifier * name)84 _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
85 {
86 size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
87 return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
88 }
89
90 static inline PyObject *
_PyObject_CallMethodIdOneArg(PyObject * self,_Py_Identifier * name,PyObject * arg)91 _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
92 {
93 PyObject *args[2] = {self, arg};
94 size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
95 assert(arg != NULL);
96 return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
97 }
98
99
100 /* === Vectorcall protocol (PEP 590) ============================= */
101
102 // Call callable using tp_call. Arguments are like PyObject_Vectorcall(),
103 // except that nargs is plainly the number of arguments without flags.
104 //
105 // Export for 'math' shared extension, used via _PyObject_VectorcallTstate()
106 // static inline function.
107 PyAPI_FUNC(PyObject*) _PyObject_MakeTpCall(
108 PyThreadState *tstate,
109 PyObject *callable,
110 PyObject *const *args, Py_ssize_t nargs,
111 PyObject *keywords);
112
113 // Static inline variant of public PyVectorcall_Function().
114 static inline vectorcallfunc
_PyVectorcall_FunctionInline(PyObject * callable)115 _PyVectorcall_FunctionInline(PyObject *callable)
116 {
117 assert(callable != NULL);
118
119 PyTypeObject *tp = Py_TYPE(callable);
120 if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) {
121 return NULL;
122 }
123 assert(PyCallable_Check(callable));
124
125 Py_ssize_t offset = tp->tp_vectorcall_offset;
126 assert(offset > 0);
127
128 vectorcallfunc ptr;
129 memcpy(&ptr, (char *) callable + offset, sizeof(ptr));
130 return ptr;
131 }
132
133
134 /* Call the callable object 'callable' with the "vectorcall" calling
135 convention.
136
137 args is a C array for positional arguments.
138
139 nargsf is the number of positional arguments plus optionally the flag
140 PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to
141 modify args[-1].
142
143 kwnames is a tuple of keyword names. The values of the keyword arguments
144 are stored in "args" after the positional arguments (note that the number
145 of keyword arguments does not change nargsf). kwnames can also be NULL if
146 there are no keyword arguments.
147
148 keywords must only contain strings and all keys must be unique.
149
150 Return the result on success. Raise an exception and return NULL on
151 error. */
152 static inline PyObject *
_PyObject_VectorcallTstate(PyThreadState * tstate,PyObject * callable,PyObject * const * args,size_t nargsf,PyObject * kwnames)153 _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable,
154 PyObject *const *args, size_t nargsf,
155 PyObject *kwnames)
156 {
157 vectorcallfunc func;
158 PyObject *res;
159
160 assert(kwnames == NULL || PyTuple_Check(kwnames));
161 assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0);
162
163 func = _PyVectorcall_FunctionInline(callable);
164 if (func == NULL) {
165 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
166 return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
167 }
168 res = func(callable, args, nargsf, kwnames);
169 return _Py_CheckFunctionResult(tstate, callable, res, NULL);
170 }
171
172
173 static inline PyObject *
_PyObject_CallNoArgsTstate(PyThreadState * tstate,PyObject * func)174 _PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) {
175 return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
176 }
177
178
179 // Private static inline function variant of public PyObject_CallNoArgs()
180 static inline PyObject *
_PyObject_CallNoArgs(PyObject * func)181 _PyObject_CallNoArgs(PyObject *func) {
182 EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
183 PyThreadState *tstate = _PyThreadState_GET();
184 return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
185 }
186
187
188 extern PyObject *const *
189 _PyStack_UnpackDict(PyThreadState *tstate,
190 PyObject *const *args, Py_ssize_t nargs,
191 PyObject *kwargs, PyObject **p_kwnames);
192
193 extern void _PyStack_UnpackDict_Free(
194 PyObject *const *stack,
195 Py_ssize_t nargs,
196 PyObject *kwnames);
197
198 extern void _PyStack_UnpackDict_FreeNoDecRef(
199 PyObject *const *stack,
200 PyObject *kwnames);
201
202 #ifdef __cplusplus
203 }
204 #endif
205 #endif /* !Py_INTERNAL_CALL_H */
206