/src/cpython/Objects/call.c
Line | Count | Source |
1 | | #include "Python.h" |
2 | | #include "pycore_call.h" // _PyObject_CallNoArgsTstate() |
3 | | #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() |
4 | | #include "pycore_dict.h" // _PyDict_FromItems() |
5 | | #include "pycore_function.h" // _PyFunction_Vectorcall() definition |
6 | | #include "pycore_modsupport.h" // _Py_VaBuildStack() |
7 | | #include "pycore_object.h" // _PyCFunctionWithKeywords_TrampolineCall() |
8 | | #include "pycore_pyerrors.h" // _PyErr_Occurred() |
9 | | #include "pycore_pystate.h" // _PyThreadState_GET() |
10 | | #include "pycore_tuple.h" // _PyTuple_ITEMS() |
11 | | |
12 | | |
13 | | static PyObject * |
14 | | null_error(PyThreadState *tstate) |
15 | 0 | { |
16 | 0 | if (!_PyErr_Occurred(tstate)) { |
17 | 0 | _PyErr_SetString(tstate, PyExc_SystemError, |
18 | 0 | "null argument to internal routine"); |
19 | 0 | } |
20 | 0 | return NULL; |
21 | 0 | } |
22 | | |
23 | | |
24 | | PyObject* |
25 | | _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, |
26 | | PyObject *result, const char *where) |
27 | 726M | { |
28 | 726M | assert((callable != NULL) ^ (where != NULL)); |
29 | | |
30 | 726M | if (result == NULL) { |
31 | 16.2M | if (!_PyErr_Occurred(tstate)) { |
32 | 0 | if (callable) |
33 | 0 | _PyErr_Format(tstate, PyExc_SystemError, |
34 | 0 | "%R returned NULL without setting an exception", |
35 | 0 | callable); |
36 | 0 | else |
37 | 0 | _PyErr_Format(tstate, PyExc_SystemError, |
38 | 0 | "%s returned NULL without setting an exception", |
39 | 0 | where); |
40 | | #ifdef Py_DEBUG |
41 | | /* Ensure that the bug is caught in debug mode. |
42 | | Py_FatalError() logs the SystemError exception raised above. */ |
43 | | Py_FatalError("a function returned NULL without setting an exception"); |
44 | | #endif |
45 | 0 | return NULL; |
46 | 0 | } |
47 | 16.2M | } |
48 | 710M | else { |
49 | 710M | if (_PyErr_Occurred(tstate)) { |
50 | 0 | Py_DECREF(result); |
51 | |
|
52 | 0 | if (callable) { |
53 | 0 | _PyErr_FormatFromCauseTstate( |
54 | 0 | tstate, PyExc_SystemError, |
55 | 0 | "%R returned a result with an exception set", callable); |
56 | 0 | } |
57 | 0 | else { |
58 | 0 | _PyErr_FormatFromCauseTstate( |
59 | 0 | tstate, PyExc_SystemError, |
60 | 0 | "%s returned a result with an exception set", where); |
61 | 0 | } |
62 | | #ifdef Py_DEBUG |
63 | | /* Ensure that the bug is caught in debug mode. |
64 | | Py_FatalError() logs the SystemError exception raised above. */ |
65 | | Py_FatalError("a function returned a result with an exception set"); |
66 | | #endif |
67 | 0 | return NULL; |
68 | 0 | } |
69 | 710M | } |
70 | 726M | return result; |
71 | 726M | } |
72 | | |
73 | | |
74 | | int |
75 | | _Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success) |
76 | 0 | { |
77 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
78 | 0 | if (!success) { |
79 | 0 | if (!_PyErr_Occurred(tstate)) { |
80 | 0 | _Py_FatalErrorFormat(__func__, |
81 | 0 | "Slot %s of type %s failed " |
82 | 0 | "without setting an exception", |
83 | 0 | slot_name, Py_TYPE(obj)->tp_name); |
84 | 0 | } |
85 | 0 | } |
86 | 0 | else { |
87 | 0 | if (_PyErr_Occurred(tstate)) { |
88 | 0 | _Py_FatalErrorFormat(__func__, |
89 | 0 | "Slot %s of type %s succeeded " |
90 | 0 | "with an exception set", |
91 | 0 | slot_name, Py_TYPE(obj)->tp_name); |
92 | 0 | } |
93 | 0 | } |
94 | 0 | return 1; |
95 | 0 | } |
96 | | |
97 | | |
98 | | /* --- Core PyObject call functions ------------------------------- */ |
99 | | |
100 | | /* Call a callable Python object without any arguments */ |
101 | | PyObject * |
102 | | PyObject_CallNoArgs(PyObject *func) |
103 | 208 | { |
104 | 208 | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); |
105 | 208 | PyThreadState *tstate = _PyThreadState_GET(); |
106 | 208 | return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); |
107 | 208 | } |
108 | | |
109 | | |
110 | | PyObject * |
111 | | _PyObject_VectorcallDictTstate(PyThreadState *tstate, PyObject *callable, |
112 | | PyObject *const *args, size_t nargsf, |
113 | | PyObject *kwargs) |
114 | 52.4M | { |
115 | 52.4M | assert(callable != NULL); |
116 | | |
117 | | /* PyObject_VectorcallDict() must not be called with an exception set, |
118 | | because it can clear it (directly or indirectly) and so the |
119 | | caller loses its exception */ |
120 | 52.4M | assert(!_PyErr_Occurred(tstate)); |
121 | | |
122 | 52.4M | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
123 | 52.4M | assert(nargs >= 0); |
124 | 52.4M | assert(nargs == 0 || args != NULL); |
125 | 52.4M | assert(kwargs == NULL || PyDict_Check(kwargs)); |
126 | | |
127 | 52.4M | vectorcallfunc func = PyVectorcall_Function(callable); |
128 | 52.4M | if (func == NULL) { |
129 | | /* Use tp_call instead */ |
130 | 5.22k | return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwargs); |
131 | 5.22k | } |
132 | | |
133 | 52.4M | PyObject *res; |
134 | 52.4M | if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { |
135 | 46.5M | res = func(callable, args, nargsf, NULL); |
136 | 46.5M | } |
137 | 5.92M | else { |
138 | 5.92M | PyObject *kwnames; |
139 | 5.92M | PyObject *const *newargs; |
140 | 5.92M | newargs = _PyStack_UnpackDict(tstate, |
141 | 5.92M | args, nargs, |
142 | 5.92M | kwargs, &kwnames); |
143 | 5.92M | if (newargs == NULL) { |
144 | 0 | return NULL; |
145 | 0 | } |
146 | 5.92M | res = func(callable, newargs, |
147 | 5.92M | nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); |
148 | 5.92M | _PyStack_UnpackDict_Free(newargs, nargs, kwnames); |
149 | 5.92M | } |
150 | 52.4M | return _Py_CheckFunctionResult(tstate, callable, res, NULL); |
151 | 52.4M | } |
152 | | |
153 | | |
154 | | PyObject * |
155 | | PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, |
156 | | size_t nargsf, PyObject *kwargs) |
157 | 271k | { |
158 | 271k | PyThreadState *tstate = _PyThreadState_GET(); |
159 | 271k | return _PyObject_VectorcallDictTstate(tstate, callable, args, nargsf, kwargs); |
160 | 271k | } |
161 | | |
162 | | static void |
163 | | object_is_not_callable(PyThreadState *tstate, PyObject *callable) |
164 | 0 | { |
165 | 0 | if (Py_IS_TYPE(callable, &PyModule_Type)) { |
166 | | // >>> import pprint |
167 | | // >>> pprint(thing) |
168 | | // Traceback (most recent call last): |
169 | | // File "<stdin>", line 1, in <module> |
170 | | // TypeError: 'module' object is not callable. Did you mean: 'pprint.pprint(...)'? |
171 | 0 | PyObject *name = PyModule_GetNameObject(callable); |
172 | 0 | if (name == NULL) { |
173 | 0 | _PyErr_Clear(tstate); |
174 | 0 | goto basic_type_error; |
175 | 0 | } |
176 | 0 | PyObject *attr; |
177 | 0 | int res = PyObject_GetOptionalAttr(callable, name, &attr); |
178 | 0 | if (res < 0) { |
179 | 0 | _PyErr_Clear(tstate); |
180 | 0 | } |
181 | 0 | else if (res > 0 && PyCallable_Check(attr)) { |
182 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
183 | 0 | "'%.200s' object is not callable. " |
184 | 0 | "Did you mean: '%U.%U(...)'?", |
185 | 0 | Py_TYPE(callable)->tp_name, name, name); |
186 | 0 | Py_DECREF(attr); |
187 | 0 | Py_DECREF(name); |
188 | 0 | return; |
189 | 0 | } |
190 | 0 | Py_XDECREF(attr); |
191 | 0 | Py_DECREF(name); |
192 | 0 | } |
193 | 0 | basic_type_error: |
194 | 0 | _PyErr_Format(tstate, PyExc_TypeError, "'%.200s' object is not callable", |
195 | 0 | Py_TYPE(callable)->tp_name); |
196 | 0 | } |
197 | | |
198 | | |
199 | | PyObject * |
200 | | _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, |
201 | | PyObject *const *args, Py_ssize_t nargs, |
202 | | PyObject *keywords) |
203 | 110M | { |
204 | 110M | assert(nargs >= 0); |
205 | 110M | assert(nargs == 0 || args != NULL); |
206 | 110M | assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords)); |
207 | | |
208 | | /* Slow path: build a temporary tuple for positional arguments and a |
209 | | * temporary dictionary for keyword arguments (if any) */ |
210 | 110M | ternaryfunc call = Py_TYPE(callable)->tp_call; |
211 | 110M | if (call == NULL) { |
212 | 0 | object_is_not_callable(tstate, callable); |
213 | 0 | return NULL; |
214 | 0 | } |
215 | | |
216 | 110M | PyObject *argstuple = PyTuple_FromArray(args, nargs); |
217 | 110M | if (argstuple == NULL) { |
218 | 0 | return NULL; |
219 | 0 | } |
220 | | |
221 | 110M | PyObject *kwdict; |
222 | 110M | if (keywords == NULL || PyDict_Check(keywords)) { |
223 | 104M | kwdict = keywords; |
224 | 104M | } |
225 | 6.17M | else { |
226 | 6.17M | if (PyTuple_GET_SIZE(keywords)) { |
227 | 6.17M | assert(args != NULL); |
228 | 6.17M | kwdict = _PyStack_AsDict(args + nargs, keywords); |
229 | 6.17M | if (kwdict == NULL) { |
230 | 0 | Py_DECREF(argstuple); |
231 | 0 | return NULL; |
232 | 0 | } |
233 | 6.17M | } |
234 | 0 | else { |
235 | 0 | keywords = kwdict = NULL; |
236 | 0 | } |
237 | 6.17M | } |
238 | | |
239 | 110M | PyObject *result = NULL; |
240 | 110M | if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object") == 0) |
241 | 110M | { |
242 | 110M | result = _PyCFunctionWithKeywords_TrampolineCall( |
243 | 110M | (PyCFunctionWithKeywords)call, callable, argstuple, kwdict); |
244 | 110M | _Py_LeaveRecursiveCallTstate(tstate); |
245 | 110M | } |
246 | | |
247 | 110M | Py_DECREF(argstuple); |
248 | 110M | if (kwdict != keywords) { |
249 | 6.17M | Py_DECREF(kwdict); |
250 | 6.17M | } |
251 | | |
252 | 110M | return _Py_CheckFunctionResult(tstate, callable, result, NULL); |
253 | 110M | } |
254 | | |
255 | | |
256 | | vectorcallfunc |
257 | | PyVectorcall_Function(PyObject *callable) |
258 | 97.2M | { |
259 | 97.2M | return _PyVectorcall_FunctionInline(callable); |
260 | 97.2M | } |
261 | | |
262 | | |
263 | | static PyObject * |
264 | | _PyVectorcall_Call(PyThreadState *tstate, vectorcallfunc func, |
265 | | PyObject *callable, PyObject *tuple, PyObject *kwargs) |
266 | 33.4M | { |
267 | 33.4M | assert(func != NULL); |
268 | | |
269 | 33.4M | Py_ssize_t nargs = PyTuple_GET_SIZE(tuple); |
270 | | |
271 | | /* Fast path for no keywords */ |
272 | 33.4M | if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { |
273 | 32.7M | return func(callable, _PyTuple_ITEMS(tuple), nargs, NULL); |
274 | 32.7M | } |
275 | | |
276 | | /* Convert arguments & call */ |
277 | 734k | PyObject *const *args; |
278 | 734k | PyObject *kwnames; |
279 | 734k | args = _PyStack_UnpackDict(tstate, |
280 | 734k | _PyTuple_ITEMS(tuple), nargs, |
281 | 734k | kwargs, &kwnames); |
282 | 734k | if (args == NULL) { |
283 | 0 | return NULL; |
284 | 0 | } |
285 | 734k | PyObject *result = func(callable, args, |
286 | 734k | nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); |
287 | 734k | _PyStack_UnpackDict_Free(args, nargs, kwnames); |
288 | | |
289 | 734k | return _Py_CheckFunctionResult(tstate, callable, result, NULL); |
290 | 734k | } |
291 | | |
292 | | |
293 | | PyObject * |
294 | | PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) |
295 | 0 | { |
296 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
297 | | |
298 | | /* get vectorcallfunc as in _PyVectorcall_Function, but without |
299 | | * the Py_TPFLAGS_HAVE_VECTORCALL check */ |
300 | 0 | Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; |
301 | 0 | if (offset <= 0) { |
302 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
303 | 0 | "'%.200s' object does not support vectorcall", |
304 | 0 | Py_TYPE(callable)->tp_name); |
305 | 0 | return NULL; |
306 | 0 | } |
307 | 0 | assert(PyCallable_Check(callable)); |
308 | |
|
309 | 0 | vectorcallfunc func; |
310 | 0 | memcpy(&func, (char *) callable + offset, sizeof(func)); |
311 | 0 | if (func == NULL) { |
312 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
313 | 0 | "'%.200s' object does not support vectorcall", |
314 | 0 | Py_TYPE(callable)->tp_name); |
315 | 0 | return NULL; |
316 | 0 | } |
317 | | |
318 | 0 | return _PyVectorcall_Call(tstate, func, callable, tuple, kwargs); |
319 | 0 | } |
320 | | |
321 | | |
322 | | PyObject * |
323 | | PyObject_Vectorcall(PyObject *callable, PyObject *const *args, |
324 | | size_t nargsf, PyObject *kwnames) |
325 | 255M | { |
326 | 255M | PyThreadState *tstate = _PyThreadState_GET(); |
327 | 255M | return _PyObject_VectorcallTstate(tstate, callable, |
328 | 255M | args, nargsf, kwnames); |
329 | 255M | } |
330 | | |
331 | | |
332 | | PyObject * |
333 | | _PyObject_Call(PyThreadState *tstate, PyObject *callable, |
334 | | PyObject *args, PyObject *kwargs) |
335 | 44.5M | { |
336 | 44.5M | ternaryfunc call; |
337 | 44.5M | PyObject *result; |
338 | | |
339 | | /* PyObject_Call() must not be called with an exception set, |
340 | | because it can clear it (directly or indirectly) and so the |
341 | | caller loses its exception */ |
342 | 44.5M | assert(!_PyErr_Occurred(tstate)); |
343 | 44.5M | assert(PyTuple_Check(args)); |
344 | 44.5M | assert(kwargs == NULL || PyDict_Check(kwargs)); |
345 | 44.5M | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); |
346 | 44.5M | vectorcallfunc vector_func = PyVectorcall_Function(callable); |
347 | 44.5M | if (vector_func != NULL) { |
348 | 33.4M | return _PyVectorcall_Call(tstate, vector_func, callable, args, kwargs); |
349 | 33.4M | } |
350 | 11.1M | else { |
351 | 11.1M | call = Py_TYPE(callable)->tp_call; |
352 | 11.1M | if (call == NULL) { |
353 | 0 | object_is_not_callable(tstate, callable); |
354 | 0 | return NULL; |
355 | 0 | } |
356 | | |
357 | 11.1M | if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { |
358 | 0 | return NULL; |
359 | 0 | } |
360 | | |
361 | 11.1M | result = (*call)(callable, args, kwargs); |
362 | | |
363 | 11.1M | _Py_LeaveRecursiveCallTstate(tstate); |
364 | | |
365 | 11.1M | return _Py_CheckFunctionResult(tstate, callable, result, NULL); |
366 | 11.1M | } |
367 | 44.5M | } |
368 | | |
369 | | PyObject * |
370 | | PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) |
371 | 44.4M | { |
372 | 44.4M | PyThreadState *tstate = _PyThreadState_GET(); |
373 | 44.4M | return _PyObject_Call(tstate, callable, args, kwargs); |
374 | 44.4M | } |
375 | | |
376 | | |
377 | | /* Function removed in the Python 3.13 API but kept in the stable ABI. */ |
378 | | PyAPI_FUNC(PyObject *) |
379 | | PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) |
380 | 0 | { |
381 | 0 | return PyObject_Call(callable, args, kwargs); |
382 | 0 | } |
383 | | |
384 | | |
385 | | PyObject * |
386 | | PyObject_CallOneArg(PyObject *func, PyObject *arg) |
387 | 69.1M | { |
388 | 69.1M | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); |
389 | 69.1M | assert(arg != NULL); |
390 | 69.1M | PyObject *_args[2]; |
391 | 69.1M | PyObject **args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET |
392 | 69.1M | args[0] = arg; |
393 | 69.1M | PyThreadState *tstate = _PyThreadState_GET(); |
394 | 69.1M | size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; |
395 | 69.1M | return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); |
396 | 69.1M | } |
397 | | |
398 | | |
399 | | /* --- PyFunction call functions ---------------------------------- */ |
400 | | |
401 | | PyObject * |
402 | | _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, |
403 | | size_t nargsf, PyObject *kwnames) |
404 | 194M | { |
405 | 194M | assert(PyFunction_Check(func)); |
406 | 194M | PyFunctionObject *f = (PyFunctionObject *)func; |
407 | 194M | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
408 | 194M | assert(nargs >= 0); |
409 | 194M | PyThreadState *tstate = _PyThreadState_GET(); |
410 | 194M | assert(nargs == 0 || stack != NULL); |
411 | 194M | EVAL_CALL_STAT_INC(EVAL_CALL_FUNCTION_VECTORCALL); |
412 | 194M | if (((PyCodeObject *)f->func_code)->co_flags & CO_OPTIMIZED) { |
413 | 194M | return _PyEval_Vector(tstate, f, NULL, stack, nargs, kwnames); |
414 | 194M | } |
415 | 0 | else { |
416 | 0 | return _PyEval_Vector(tstate, f, f->func_globals, stack, nargs, kwnames); |
417 | 0 | } |
418 | 194M | } |
419 | | |
420 | | /* --- More complex call functions -------------------------------- */ |
421 | | |
422 | | /* External interface to call any callable object. |
423 | | The args must be a tuple or NULL. The kwargs must be a dict or NULL. |
424 | | Function removed in Python 3.13 API but kept in the stable ABI. */ |
425 | | PyAPI_FUNC(PyObject*) |
426 | | PyEval_CallObjectWithKeywords(PyObject *callable, |
427 | | PyObject *args, PyObject *kwargs) |
428 | 0 | { |
429 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
430 | | #ifdef Py_DEBUG |
431 | | /* PyEval_CallObjectWithKeywords() must not be called with an exception |
432 | | set. It raises a new exception if parameters are invalid or if |
433 | | PyTuple_New() fails, and so the original exception is lost. */ |
434 | | assert(!_PyErr_Occurred(tstate)); |
435 | | #endif |
436 | |
|
437 | 0 | if (args != NULL && !PyTuple_Check(args)) { |
438 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
439 | 0 | "argument list must be a tuple"); |
440 | 0 | return NULL; |
441 | 0 | } |
442 | | |
443 | 0 | if (kwargs != NULL && !PyDict_Check(kwargs)) { |
444 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
445 | 0 | "keyword list must be a dictionary"); |
446 | 0 | return NULL; |
447 | 0 | } |
448 | | |
449 | 0 | if (args == NULL) { |
450 | 0 | return _PyObject_VectorcallDictTstate(tstate, callable, |
451 | 0 | NULL, 0, kwargs); |
452 | 0 | } |
453 | 0 | else { |
454 | 0 | return _PyObject_Call(tstate, callable, args, kwargs); |
455 | 0 | } |
456 | 0 | } |
457 | | |
458 | | |
459 | | PyObject * |
460 | | PyObject_CallObject(PyObject *callable, PyObject *args) |
461 | 122k | { |
462 | 122k | PyThreadState *tstate = _PyThreadState_GET(); |
463 | 122k | assert(!_PyErr_Occurred(tstate)); |
464 | 122k | if (args == NULL) { |
465 | 0 | return _PyObject_CallNoArgsTstate(tstate, callable); |
466 | 0 | } |
467 | 122k | if (!PyTuple_Check(args)) { |
468 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
469 | 0 | "argument list must be a tuple"); |
470 | 0 | return NULL; |
471 | 0 | } |
472 | 122k | return _PyObject_Call(tstate, callable, args, NULL); |
473 | 122k | } |
474 | | |
475 | | |
476 | | /* Call callable(obj, *args, **kwargs). */ |
477 | | PyObject * |
478 | | _PyObject_Call_Prepend(PyThreadState *tstate, PyObject *callable, |
479 | | PyObject *obj, PyObject *args, PyObject *kwargs) |
480 | 52.2M | { |
481 | 52.2M | assert(PyTuple_Check(args)); |
482 | | |
483 | 52.2M | PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; |
484 | 52.2M | PyObject **stack; |
485 | | |
486 | 52.2M | Py_ssize_t argcount = PyTuple_GET_SIZE(args); |
487 | 52.2M | if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { |
488 | 51.9M | stack = small_stack; |
489 | 51.9M | } |
490 | 291k | else { |
491 | 291k | stack = PyMem_Malloc((argcount + 1) * sizeof(PyObject *)); |
492 | 291k | if (stack == NULL) { |
493 | 0 | PyErr_NoMemory(); |
494 | 0 | return NULL; |
495 | 0 | } |
496 | 291k | } |
497 | | |
498 | | /* use borrowed references */ |
499 | 52.2M | stack[0] = obj; |
500 | 52.2M | memcpy(&stack[1], |
501 | 52.2M | _PyTuple_ITEMS(args), |
502 | 52.2M | argcount * sizeof(PyObject *)); |
503 | | |
504 | 52.2M | PyObject *result = _PyObject_VectorcallDictTstate(tstate, callable, |
505 | 52.2M | stack, argcount + 1, |
506 | 52.2M | kwargs); |
507 | 52.2M | if (stack != small_stack) { |
508 | 291k | PyMem_Free(stack); |
509 | 291k | } |
510 | 52.2M | return result; |
511 | 52.2M | } |
512 | | |
513 | | |
514 | | /* --- Call with a format string ---------------------------------- */ |
515 | | |
516 | | static PyObject * |
517 | | _PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, |
518 | | const char *format, va_list va) |
519 | 5.54M | { |
520 | 5.54M | PyObject* small_stack[_PY_FASTCALL_SMALL_STACK]; |
521 | 5.54M | const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack); |
522 | 5.54M | PyObject **stack; |
523 | 5.54M | Py_ssize_t nargs, i; |
524 | 5.54M | PyObject *result; |
525 | | |
526 | 5.54M | if (callable == NULL) { |
527 | 0 | return null_error(tstate); |
528 | 0 | } |
529 | | |
530 | 5.54M | if (!format || !*format) { |
531 | 1.74k | return _PyObject_CallNoArgsTstate(tstate, callable); |
532 | 1.74k | } |
533 | | |
534 | 5.54M | stack = _Py_VaBuildStack(small_stack, small_stack_len, |
535 | 5.54M | format, va, &nargs); |
536 | 5.54M | if (stack == NULL) { |
537 | 0 | return NULL; |
538 | 0 | } |
539 | 5.54M | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); |
540 | 5.54M | if (nargs == 1 && PyTuple_Check(stack[0])) { |
541 | | /* Special cases for backward compatibility: |
542 | | - PyObject_CallFunction(func, "O", tuple) calls func(*tuple) |
543 | | - PyObject_CallFunction(func, "(OOO)", arg1, arg2, arg3) calls |
544 | | func(*(arg1, arg2, arg3)): func(arg1, arg2, arg3) */ |
545 | 128 | PyObject *args = stack[0]; |
546 | 128 | result = _PyObject_VectorcallTstate(tstate, callable, |
547 | 128 | _PyTuple_ITEMS(args), |
548 | 128 | PyTuple_GET_SIZE(args), |
549 | 128 | NULL); |
550 | 128 | } |
551 | 5.54M | else { |
552 | 5.54M | result = _PyObject_VectorcallTstate(tstate, callable, |
553 | 5.54M | stack, nargs, NULL); |
554 | 5.54M | } |
555 | | |
556 | 26.0M | for (i = 0; i < nargs; ++i) { |
557 | 20.5M | Py_DECREF(stack[i]); |
558 | 20.5M | } |
559 | 5.54M | if (stack != small_stack) { |
560 | 192 | PyMem_Free(stack); |
561 | 192 | } |
562 | 5.54M | return result; |
563 | 5.54M | } |
564 | | |
565 | | |
566 | | PyObject * |
567 | | PyObject_CallFunction(PyObject *callable, const char *format, ...) |
568 | 3.31M | { |
569 | 3.31M | va_list va; |
570 | 3.31M | PyObject *result; |
571 | 3.31M | PyThreadState *tstate = _PyThreadState_GET(); |
572 | | |
573 | 3.31M | va_start(va, format); |
574 | 3.31M | result = _PyObject_CallFunctionVa(tstate, callable, format, va); |
575 | 3.31M | va_end(va); |
576 | | |
577 | 3.31M | return result; |
578 | 3.31M | } |
579 | | |
580 | | |
581 | | /* PyEval_CallFunction is exact copy of PyObject_CallFunction. |
582 | | Function removed in Python 3.13 API but kept in the stable ABI. */ |
583 | | PyAPI_FUNC(PyObject*) |
584 | | PyEval_CallFunction(PyObject *callable, const char *format, ...) |
585 | 0 | { |
586 | 0 | va_list va; |
587 | 0 | PyObject *result; |
588 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
589 | |
|
590 | 0 | va_start(va, format); |
591 | 0 | result = _PyObject_CallFunctionVa(tstate, callable, format, va); |
592 | 0 | va_end(va); |
593 | |
|
594 | 0 | return result; |
595 | 0 | } |
596 | | |
597 | | |
598 | | /* _PyObject_CallFunction_SizeT is exact copy of PyObject_CallFunction. |
599 | | * This function must be kept because it is part of the stable ABI. |
600 | | */ |
601 | | PyAPI_FUNC(PyObject *) /* abi_only */ |
602 | | _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) |
603 | 0 | { |
604 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
605 | |
|
606 | 0 | va_list va; |
607 | 0 | va_start(va, format); |
608 | 0 | PyObject *result = _PyObject_CallFunctionVa(tstate, callable, format, va); |
609 | 0 | va_end(va); |
610 | |
|
611 | 0 | return result; |
612 | 0 | } |
613 | | |
614 | | |
615 | | static PyObject* |
616 | | callmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_list va) |
617 | 2.23M | { |
618 | 2.23M | assert(callable != NULL); |
619 | 2.23M | if (!PyCallable_Check(callable)) { |
620 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
621 | 0 | "attribute of type '%.200s' is not callable", |
622 | 0 | Py_TYPE(callable)->tp_name); |
623 | 0 | return NULL; |
624 | 0 | } |
625 | | |
626 | 2.23M | return _PyObject_CallFunctionVa(tstate, callable, format, va); |
627 | 2.23M | } |
628 | | |
629 | | PyObject * |
630 | | PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) |
631 | 1.78k | { |
632 | 1.78k | PyThreadState *tstate = _PyThreadState_GET(); |
633 | | |
634 | 1.78k | if (obj == NULL || name == NULL) { |
635 | 0 | return null_error(tstate); |
636 | 0 | } |
637 | | |
638 | 1.78k | PyObject *callable = PyObject_GetAttrString(obj, name); |
639 | 1.78k | if (callable == NULL) { |
640 | 0 | return NULL; |
641 | 0 | } |
642 | | |
643 | 1.78k | va_list va; |
644 | 1.78k | va_start(va, format); |
645 | 1.78k | PyObject *retval = callmethod(tstate, callable, format, va); |
646 | 1.78k | va_end(va); |
647 | | |
648 | 1.78k | Py_DECREF(callable); |
649 | 1.78k | return retval; |
650 | 1.78k | } |
651 | | |
652 | | |
653 | | /* PyEval_CallMethod is exact copy of PyObject_CallMethod. |
654 | | Function removed in Python 3.13 API but kept in the stable ABI. */ |
655 | | PyAPI_FUNC(PyObject*) |
656 | | PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...) |
657 | 0 | { |
658 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
659 | 0 | if (obj == NULL || name == NULL) { |
660 | 0 | return null_error(tstate); |
661 | 0 | } |
662 | | |
663 | 0 | PyObject *callable = PyObject_GetAttrString(obj, name); |
664 | 0 | if (callable == NULL) { |
665 | 0 | return NULL; |
666 | 0 | } |
667 | | |
668 | 0 | va_list va; |
669 | 0 | va_start(va, format); |
670 | 0 | PyObject *retval = callmethod(tstate, callable, format, va); |
671 | 0 | va_end(va); |
672 | |
|
673 | 0 | Py_DECREF(callable); |
674 | 0 | return retval; |
675 | 0 | } |
676 | | |
677 | | |
678 | | PyObject * |
679 | | _PyObject_CallMethod(PyObject *obj, PyObject *name, |
680 | | const char *format, ...) |
681 | 2.23M | { |
682 | 2.23M | PyThreadState *tstate = _PyThreadState_GET(); |
683 | 2.23M | if (obj == NULL || name == NULL) { |
684 | 0 | return null_error(tstate); |
685 | 0 | } |
686 | | |
687 | 2.23M | PyObject *callable = PyObject_GetAttr(obj, name); |
688 | 2.23M | if (callable == NULL) { |
689 | 0 | return NULL; |
690 | 0 | } |
691 | | |
692 | 2.23M | va_list va; |
693 | 2.23M | va_start(va, format); |
694 | 2.23M | PyObject *retval = callmethod(tstate, callable, format, va); |
695 | 2.23M | va_end(va); |
696 | | |
697 | 2.23M | Py_DECREF(callable); |
698 | 2.23M | return retval; |
699 | 2.23M | } |
700 | | |
701 | | |
702 | | PyObject * |
703 | | _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, |
704 | | const char *format, ...) |
705 | 0 | { |
706 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
707 | 0 | if (obj == NULL || name == NULL) { |
708 | 0 | return null_error(tstate); |
709 | 0 | } |
710 | | |
711 | 0 | _Py_COMP_DIAG_PUSH |
712 | 0 | _Py_COMP_DIAG_IGNORE_DEPR_DECLS |
713 | 0 | PyObject *callable = _PyObject_GetAttrId(obj, name); |
714 | 0 | _Py_COMP_DIAG_POP |
715 | 0 | if (callable == NULL) { |
716 | 0 | return NULL; |
717 | 0 | } |
718 | | |
719 | 0 | va_list va; |
720 | 0 | va_start(va, format); |
721 | 0 | PyObject *retval = callmethod(tstate, callable, format, va); |
722 | 0 | va_end(va); |
723 | |
|
724 | 0 | Py_DECREF(callable); |
725 | 0 | return retval; |
726 | 0 | } |
727 | | |
728 | | |
729 | | PyObject * _PyObject_CallMethodFormat(PyThreadState *tstate, PyObject *callable, |
730 | | const char *format, ...) |
731 | 0 | { |
732 | 0 | assert(callable != NULL); |
733 | 0 | va_list va; |
734 | 0 | va_start(va, format); |
735 | 0 | PyObject *retval = callmethod(tstate, callable, format, va); |
736 | 0 | va_end(va); |
737 | 0 | return retval; |
738 | 0 | } |
739 | | |
740 | | |
741 | | // _PyObject_CallMethod_SizeT is exact copy of PyObject_CallMethod. |
742 | | // This function must be kept because it is part of the stable ABI. |
743 | | PyAPI_FUNC(PyObject *) /* abi_only */ |
744 | | _PyObject_CallMethod_SizeT(PyObject *obj, const char *name, |
745 | | const char *format, ...) |
746 | 0 | { |
747 | 0 | PyThreadState *tstate = _PyThreadState_GET(); |
748 | 0 | if (obj == NULL || name == NULL) { |
749 | 0 | return null_error(tstate); |
750 | 0 | } |
751 | | |
752 | 0 | PyObject *callable = PyObject_GetAttrString(obj, name); |
753 | 0 | if (callable == NULL) { |
754 | 0 | return NULL; |
755 | 0 | } |
756 | | |
757 | 0 | va_list va; |
758 | 0 | va_start(va, format); |
759 | 0 | PyObject *retval = callmethod(tstate, callable, format, va); |
760 | 0 | va_end(va); |
761 | |
|
762 | 0 | Py_DECREF(callable); |
763 | 0 | return retval; |
764 | 0 | } |
765 | | |
766 | | |
767 | | /* --- Call with "..." arguments ---------------------------------- */ |
768 | | |
769 | | static PyObject * |
770 | | object_vacall(PyThreadState *tstate, PyObject *base, |
771 | | PyObject *callable, va_list vargs) |
772 | 331k | { |
773 | 331k | PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; |
774 | 331k | PyObject **stack; |
775 | 331k | Py_ssize_t nargs; |
776 | 331k | PyObject *result; |
777 | 331k | Py_ssize_t i; |
778 | 331k | va_list countva; |
779 | | |
780 | 331k | if (callable == NULL) { |
781 | 0 | return null_error(tstate); |
782 | 0 | } |
783 | | |
784 | | /* Count the number of arguments */ |
785 | 331k | va_copy(countva, vargs); |
786 | 331k | nargs = base ? 1 : 0; |
787 | 1.97M | while (1) { |
788 | 1.97M | PyObject *arg = va_arg(countva, PyObject *); |
789 | 1.97M | if (arg == NULL) { |
790 | 331k | break; |
791 | 331k | } |
792 | 1.64M | nargs++; |
793 | 1.64M | } |
794 | 331k | va_end(countva); |
795 | | |
796 | | /* Copy arguments */ |
797 | 331k | if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { |
798 | 76.5k | stack = small_stack; |
799 | 76.5k | } |
800 | 254k | else { |
801 | 254k | stack = PyMem_Malloc(nargs * sizeof(stack[0])); |
802 | 254k | if (stack == NULL) { |
803 | 0 | PyErr_NoMemory(); |
804 | 0 | return NULL; |
805 | 0 | } |
806 | 254k | } |
807 | | |
808 | 331k | i = 0; |
809 | 331k | if (base) { |
810 | 47.7k | stack[i++] = base; |
811 | 47.7k | } |
812 | | |
813 | 1.97M | for (; i < nargs; ++i) { |
814 | 1.64M | stack[i] = va_arg(vargs, PyObject *); |
815 | 1.64M | } |
816 | | |
817 | | #ifdef Py_STATS |
818 | | if (PyFunction_Check(callable)) { |
819 | | EVAL_CALL_STAT_INC(EVAL_CALL_API); |
820 | | } |
821 | | #endif |
822 | | /* Call the function */ |
823 | 331k | result = _PyObject_VectorcallTstate(tstate, callable, stack, nargs, NULL); |
824 | | |
825 | 331k | if (stack != small_stack) { |
826 | 254k | PyMem_Free(stack); |
827 | 254k | } |
828 | 331k | return result; |
829 | 331k | } |
830 | | |
831 | | |
832 | | PyObject * |
833 | | PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, |
834 | | size_t nargsf, PyObject *kwnames) |
835 | 5.93M | { |
836 | 5.93M | assert(name != NULL); |
837 | 5.93M | assert(args != NULL); |
838 | 5.93M | assert(PyVectorcall_NARGS(nargsf) >= 1); |
839 | | |
840 | 5.93M | PyThreadState *tstate = _PyThreadState_GET(); |
841 | 5.93M | _PyCStackRef method; |
842 | 5.93M | _PyThreadState_PushCStackRef(tstate, &method); |
843 | | /* Use args[0] as "self" argument */ |
844 | 5.93M | int unbound = _PyObject_GetMethodStackRef(tstate, args[0], name, &method.ref); |
845 | 5.93M | if (PyStackRef_IsNull(method.ref)) { |
846 | 3 | _PyThreadState_PopCStackRef(tstate, &method); |
847 | 3 | return NULL; |
848 | 3 | } |
849 | 5.93M | PyObject *callable = PyStackRef_AsPyObjectBorrow(method.ref); |
850 | | |
851 | 5.93M | if (unbound) { |
852 | | /* We must remove PY_VECTORCALL_ARGUMENTS_OFFSET since |
853 | | * that would be interpreted as allowing to change args[-1] */ |
854 | 5.89M | nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET; |
855 | 5.89M | } |
856 | 43.1k | else { |
857 | | /* Skip "self". We can keep PY_VECTORCALL_ARGUMENTS_OFFSET since |
858 | | * args[-1] in the onward call is args[0] here. */ |
859 | 43.1k | args++; |
860 | 43.1k | nargsf--; |
861 | 43.1k | } |
862 | 5.93M | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_METHOD, callable); |
863 | 5.93M | PyObject *result = _PyObject_VectorcallTstate(tstate, callable, |
864 | 5.93M | args, nargsf, kwnames); |
865 | 5.93M | _PyThreadState_PopCStackRef(tstate, &method); |
866 | 5.93M | return result; |
867 | 5.93M | } |
868 | | |
869 | | |
870 | | PyObject * |
871 | | PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) |
872 | 57.0k | { |
873 | 57.0k | PyThreadState *tstate = _PyThreadState_GET(); |
874 | 57.0k | if (obj == NULL || name == NULL) { |
875 | 0 | return null_error(tstate); |
876 | 0 | } |
877 | | |
878 | 57.0k | _PyCStackRef method; |
879 | 57.0k | _PyThreadState_PushCStackRef(tstate, &method); |
880 | 57.0k | int is_method = _PyObject_GetMethodStackRef(tstate, obj, name, &method.ref); |
881 | 57.0k | if (PyStackRef_IsNull(method.ref)) { |
882 | 0 | _PyThreadState_PopCStackRef(tstate, &method); |
883 | 0 | return NULL; |
884 | 0 | } |
885 | 57.0k | PyObject *callable = PyStackRef_AsPyObjectBorrow(method.ref); |
886 | 57.0k | obj = is_method ? obj : NULL; |
887 | | |
888 | 57.0k | va_list vargs; |
889 | 57.0k | va_start(vargs, name); |
890 | 57.0k | PyObject *result = object_vacall(tstate, obj, callable, vargs); |
891 | 57.0k | va_end(vargs); |
892 | | |
893 | 57.0k | _PyThreadState_PopCStackRef(tstate, &method); |
894 | 57.0k | return result; |
895 | 57.0k | } |
896 | | |
897 | | |
898 | | PyObject * |
899 | | PyObject_CallFunctionObjArgs(PyObject *callable, ...) |
900 | 274k | { |
901 | 274k | PyThreadState *tstate = _PyThreadState_GET(); |
902 | 274k | va_list vargs; |
903 | 274k | PyObject *result; |
904 | | |
905 | 274k | va_start(vargs, callable); |
906 | 274k | result = object_vacall(tstate, NULL, callable, vargs); |
907 | 274k | va_end(vargs); |
908 | | |
909 | 274k | return result; |
910 | 274k | } |
911 | | |
912 | | |
913 | | /* --- PyStack functions ------------------------------------------ */ |
914 | | |
915 | | PyObject * |
916 | | _PyStack_AsDict(PyObject *const *values, PyObject *kwnames) |
917 | 6.17M | { |
918 | 6.17M | Py_ssize_t nkwargs; |
919 | | |
920 | 6.17M | assert(kwnames != NULL); |
921 | 6.17M | nkwargs = PyTuple_GET_SIZE(kwnames); |
922 | 6.17M | return _PyDict_FromItems(&PyTuple_GET_ITEM(kwnames, 0), 1, |
923 | 6.17M | values, 1, nkwargs); |
924 | 6.17M | } |
925 | | |
926 | | |
927 | | /* Convert (args, nargs, kwargs: dict) into a (stack, nargs, kwnames: tuple). |
928 | | |
929 | | Allocate a new argument vector and keyword names tuple. Return the argument |
930 | | vector; return NULL with exception set on error. Return the keyword names |
931 | | tuple in *p_kwnames. |
932 | | |
933 | | This also checks that all keyword names are strings. If not, a TypeError is |
934 | | raised. |
935 | | |
936 | | The newly allocated argument vector supports PY_VECTORCALL_ARGUMENTS_OFFSET. |
937 | | |
938 | | The positional arguments are borrowed references from the input array |
939 | | (which must be kept alive by the caller). The keyword argument values |
940 | | are new references. |
941 | | |
942 | | When done, you must call _PyStack_UnpackDict_Free(stack, nargs, kwnames) */ |
943 | | PyObject *const * |
944 | | _PyStack_UnpackDict(PyThreadState *tstate, |
945 | | PyObject *const *args, Py_ssize_t nargs, |
946 | | PyObject *kwargs, PyObject **p_kwnames) |
947 | 6.65M | { |
948 | 6.65M | assert(nargs >= 0); |
949 | 6.65M | assert(kwargs != NULL); |
950 | 6.65M | assert(PyDict_Check(kwargs)); |
951 | | |
952 | 6.65M | Py_ssize_t nkwargs = PyDict_GET_SIZE(kwargs); |
953 | | /* Check for overflow in the PyMem_Malloc() call below. The subtraction |
954 | | * in this check cannot overflow: both maxnargs and nkwargs are |
955 | | * non-negative signed integers, so their difference fits in the type. */ |
956 | 6.65M | Py_ssize_t maxnargs = PY_SSIZE_T_MAX / sizeof(args[0]) - 1; |
957 | 6.65M | if (nargs > maxnargs - nkwargs) { |
958 | 0 | _PyErr_NoMemory(tstate); |
959 | 0 | return NULL; |
960 | 0 | } |
961 | | |
962 | | /* Add 1 to support PY_VECTORCALL_ARGUMENTS_OFFSET */ |
963 | 6.65M | PyObject **stack = PyMem_Malloc((1 + nargs + nkwargs) * sizeof(args[0])); |
964 | 6.65M | if (stack == NULL) { |
965 | 0 | _PyErr_NoMemory(tstate); |
966 | 0 | return NULL; |
967 | 0 | } |
968 | | |
969 | 6.65M | PyObject *kwnames = PyTuple_New(nkwargs); |
970 | 6.65M | if (kwnames == NULL) { |
971 | 0 | PyMem_Free(stack); |
972 | 0 | return NULL; |
973 | 0 | } |
974 | | |
975 | 6.65M | stack++; /* For PY_VECTORCALL_ARGUMENTS_OFFSET */ |
976 | | |
977 | | /* Copy positional arguments (borrowed references) */ |
978 | 13.4M | for (Py_ssize_t i = 0; i < nargs; i++) { |
979 | 6.79M | stack[i] = args[i]; |
980 | 6.79M | } |
981 | | |
982 | 6.65M | PyObject **kwstack = stack + nargs; |
983 | | /* This loop doesn't support lookup function mutating the dictionary |
984 | | to change its size. It's a deliberate choice for speed, this function is |
985 | | called in the performance critical hot code. */ |
986 | 6.65M | Py_ssize_t pos = 0, i = 0; |
987 | 6.65M | PyObject *key, *value; |
988 | 6.65M | unsigned long keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; |
989 | 14.6M | while (PyDict_Next(kwargs, &pos, &key, &value)) { |
990 | 7.94M | keys_are_strings &= Py_TYPE(key)->tp_flags; |
991 | 7.94M | PyTuple_SET_ITEM(kwnames, i, Py_NewRef(key)); |
992 | 7.94M | kwstack[i] = Py_NewRef(value); |
993 | 7.94M | i++; |
994 | 7.94M | } |
995 | | |
996 | | /* keys_are_strings has the value Py_TPFLAGS_UNICODE_SUBCLASS if that |
997 | | * flag is set for all keys. Otherwise, keys_are_strings equals 0. |
998 | | * We do this check once at the end instead of inside the loop above |
999 | | * because it simplifies the deallocation in the failing case. |
1000 | | * It happens to also make the loop above slightly more efficient. */ |
1001 | 6.65M | if (!keys_are_strings) { |
1002 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
1003 | 0 | "keywords must be strings"); |
1004 | 0 | _PyStack_UnpackDict_Free(stack, nargs, kwnames); |
1005 | 0 | return NULL; |
1006 | 0 | } |
1007 | | |
1008 | 6.65M | *p_kwnames = kwnames; |
1009 | 6.65M | return stack; |
1010 | 6.65M | } |
1011 | | |
1012 | | void |
1013 | | _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, |
1014 | | PyObject *kwnames) |
1015 | 6.65M | { |
1016 | | /* Only decref kwargs values, positional args are borrowed */ |
1017 | 6.65M | Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames); |
1018 | 14.6M | for (Py_ssize_t i = 0; i < nkwargs; i++) { |
1019 | 7.94M | Py_DECREF(stack[nargs + i]); |
1020 | 7.94M | } |
1021 | 6.65M | _PyStack_UnpackDict_FreeNoDecRef(stack, kwnames); |
1022 | 6.65M | } |
1023 | | |
1024 | | void |
1025 | | _PyStack_UnpackDict_FreeNoDecRef(PyObject *const *stack, PyObject *kwnames) |
1026 | 6.65M | { |
1027 | 6.65M | PyMem_Free((PyObject **)stack - 1); |
1028 | 6.65M | Py_DECREF(kwnames); |
1029 | 6.65M | } |
1030 | | |
1031 | | // Export for the stable ABI |
1032 | | #undef PyVectorcall_NARGS |
1033 | | Py_ssize_t |
1034 | | PyVectorcall_NARGS(size_t n) |
1035 | 0 | { |
1036 | 0 | return _PyVectorcall_NARGS(n); |
1037 | 0 | } |