/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 | 871M | { |
28 | 871M | assert((callable != NULL) ^ (where != NULL)); |
29 | | |
30 | 871M | if (result == NULL) { |
31 | 20.3M | 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 | 20.3M | } |
48 | 851M | else { |
49 | 851M | if (_PyErr_Occurred(tstate)) { |
50 | 1 | Py_DECREF(result); |
51 | | |
52 | 1 | if (callable) { |
53 | 1 | _PyErr_FormatFromCauseTstate( |
54 | 1 | tstate, PyExc_SystemError, |
55 | 1 | "%R returned a result with an exception set", callable); |
56 | 1 | } |
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 | 1 | return NULL; |
68 | 1 | } |
69 | 851M | } |
70 | 871M | return result; |
71 | 871M | } |
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 | 24 | { |
104 | 24 | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); |
105 | 24 | PyThreadState *tstate = _PyThreadState_GET(); |
106 | 24 | return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); |
107 | 24 | } |
108 | | |
109 | | |
110 | | PyObject * |
111 | | _PyObject_VectorcallDictTstate(PyThreadState *tstate, PyObject *callable, |
112 | | PyObject *const *args, size_t nargsf, |
113 | | PyObject *kwargs) |
114 | 63.3M | { |
115 | 63.3M | 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 | 63.3M | assert(!_PyErr_Occurred(tstate)); |
121 | | |
122 | 63.3M | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
123 | 63.3M | assert(nargs >= 0); |
124 | 63.3M | assert(nargs == 0 || args != NULL); |
125 | 63.3M | assert(kwargs == NULL || PyDict_Check(kwargs)); |
126 | | |
127 | 63.3M | vectorcallfunc func = PyVectorcall_Function(callable); |
128 | 63.3M | if (func == NULL) { |
129 | | /* Use tp_call instead */ |
130 | 4.43k | return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwargs); |
131 | 4.43k | } |
132 | | |
133 | 63.3M | PyObject *res; |
134 | 63.3M | if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { |
135 | 54.9M | res = func(callable, args, nargsf, NULL); |
136 | 54.9M | } |
137 | 8.38M | else { |
138 | 8.38M | PyObject *kwnames; |
139 | 8.38M | PyObject *const *newargs; |
140 | 8.38M | newargs = _PyStack_UnpackDict(tstate, |
141 | 8.38M | args, nargs, |
142 | 8.38M | kwargs, &kwnames); |
143 | 8.38M | if (newargs == NULL) { |
144 | 0 | return NULL; |
145 | 0 | } |
146 | 8.38M | res = func(callable, newargs, |
147 | 8.38M | nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); |
148 | 8.38M | _PyStack_UnpackDict_Free(newargs, nargs, kwnames); |
149 | 8.38M | } |
150 | 63.3M | return _Py_CheckFunctionResult(tstate, callable, res, NULL); |
151 | 63.3M | } |
152 | | |
153 | | |
154 | | PyObject * |
155 | | PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, |
156 | | size_t nargsf, PyObject *kwargs) |
157 | 279k | { |
158 | 279k | PyThreadState *tstate = _PyThreadState_GET(); |
159 | 279k | return _PyObject_VectorcallDictTstate(tstate, callable, args, nargsf, kwargs); |
160 | 279k | } |
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 | 156M | { |
204 | 156M | assert(nargs >= 0); |
205 | 156M | assert(nargs == 0 || args != NULL); |
206 | 156M | 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 | 156M | ternaryfunc call = Py_TYPE(callable)->tp_call; |
211 | 156M | if (call == NULL) { |
212 | 0 | object_is_not_callable(tstate, callable); |
213 | 0 | return NULL; |
214 | 0 | } |
215 | | |
216 | 156M | PyObject *argstuple = PyTuple_FromArray(args, nargs); |
217 | 156M | if (argstuple == NULL) { |
218 | 0 | return NULL; |
219 | 0 | } |
220 | | |
221 | 156M | PyObject *kwdict; |
222 | 156M | if (keywords == NULL || PyDict_Check(keywords)) { |
223 | 147M | kwdict = keywords; |
224 | 147M | } |
225 | 8.59M | else { |
226 | 8.59M | if (PyTuple_GET_SIZE(keywords)) { |
227 | 8.59M | assert(args != NULL); |
228 | 8.59M | kwdict = _PyStack_AsDict(args + nargs, keywords); |
229 | 8.59M | if (kwdict == NULL) { |
230 | 0 | Py_DECREF(argstuple); |
231 | 0 | return NULL; |
232 | 0 | } |
233 | 8.59M | } |
234 | 0 | else { |
235 | 0 | keywords = kwdict = NULL; |
236 | 0 | } |
237 | 8.59M | } |
238 | | |
239 | 156M | PyObject *result = NULL; |
240 | 156M | if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object") == 0) |
241 | 156M | { |
242 | 156M | result = _PyCFunctionWithKeywords_TrampolineCall( |
243 | 156M | (PyCFunctionWithKeywords)call, callable, argstuple, kwdict); |
244 | 156M | _Py_LeaveRecursiveCallTstate(tstate); |
245 | 156M | } |
246 | | |
247 | 156M | Py_DECREF(argstuple); |
248 | 156M | if (kwdict != keywords) { |
249 | 8.59M | Py_DECREF(kwdict); |
250 | 8.59M | } |
251 | | |
252 | 156M | return _Py_CheckFunctionResult(tstate, callable, result, NULL); |
253 | 156M | } |
254 | | |
255 | | |
256 | | vectorcallfunc |
257 | | PyVectorcall_Function(PyObject *callable) |
258 | 110M | { |
259 | 110M | return _PyVectorcall_FunctionInline(callable); |
260 | 110M | } |
261 | | |
262 | | |
263 | | static PyObject * |
264 | | _PyVectorcall_Call(PyThreadState *tstate, vectorcallfunc func, |
265 | | PyObject *callable, PyObject *tuple, PyObject *kwargs) |
266 | 34.8M | { |
267 | 34.8M | assert(func != NULL); |
268 | | |
269 | 34.8M | Py_ssize_t nargs = PyTuple_GET_SIZE(tuple); |
270 | | |
271 | | /* Fast path for no keywords */ |
272 | 34.8M | if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { |
273 | 34.0M | return func(callable, _PyTuple_ITEMS(tuple), nargs, NULL); |
274 | 34.0M | } |
275 | | |
276 | | /* Convert arguments & call */ |
277 | 775k | PyObject *const *args; |
278 | 775k | PyObject *kwnames; |
279 | 775k | args = _PyStack_UnpackDict(tstate, |
280 | 775k | _PyTuple_ITEMS(tuple), nargs, |
281 | 775k | kwargs, &kwnames); |
282 | 775k | if (args == NULL) { |
283 | 0 | return NULL; |
284 | 0 | } |
285 | 775k | PyObject *result = func(callable, args, |
286 | 775k | nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); |
287 | 775k | _PyStack_UnpackDict_Free(args, nargs, kwnames); |
288 | | |
289 | 775k | return _Py_CheckFunctionResult(tstate, callable, result, NULL); |
290 | 775k | } |
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 | 313M | { |
326 | 313M | PyThreadState *tstate = _PyThreadState_GET(); |
327 | 313M | return _PyObject_VectorcallTstate(tstate, callable, |
328 | 313M | args, nargsf, kwnames); |
329 | 313M | } |
330 | | |
331 | | |
332 | | PyObject * |
333 | | _PyObject_Call(PyThreadState *tstate, PyObject *callable, |
334 | | PyObject *args, PyObject *kwargs) |
335 | 46.9M | { |
336 | 46.9M | ternaryfunc call; |
337 | 46.9M | 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 | 46.9M | assert(!_PyErr_Occurred(tstate)); |
343 | 46.9M | assert(PyTuple_Check(args)); |
344 | 46.9M | assert(kwargs == NULL || PyDict_Check(kwargs)); |
345 | 46.9M | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); |
346 | 46.9M | vectorcallfunc vector_func = PyVectorcall_Function(callable); |
347 | 46.9M | if (vector_func != NULL) { |
348 | 34.8M | return _PyVectorcall_Call(tstate, vector_func, callable, args, kwargs); |
349 | 34.8M | } |
350 | 12.1M | else { |
351 | 12.1M | call = Py_TYPE(callable)->tp_call; |
352 | 12.1M | if (call == NULL) { |
353 | 0 | object_is_not_callable(tstate, callable); |
354 | 0 | return NULL; |
355 | 0 | } |
356 | | |
357 | 12.1M | if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { |
358 | 0 | return NULL; |
359 | 0 | } |
360 | | |
361 | 12.1M | result = (*call)(callable, args, kwargs); |
362 | | |
363 | 12.1M | _Py_LeaveRecursiveCallTstate(tstate); |
364 | | |
365 | 12.1M | return _Py_CheckFunctionResult(tstate, callable, result, NULL); |
366 | 12.1M | } |
367 | 46.9M | } |
368 | | |
369 | | PyObject * |
370 | | PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) |
371 | 46.8M | { |
372 | 46.8M | PyThreadState *tstate = _PyThreadState_GET(); |
373 | 46.8M | return _PyObject_Call(tstate, callable, args, kwargs); |
374 | 46.8M | } |
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 | 73.8M | { |
388 | 73.8M | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); |
389 | 73.8M | assert(arg != NULL); |
390 | 73.8M | PyObject *_args[2]; |
391 | 73.8M | PyObject **args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET |
392 | 73.8M | args[0] = arg; |
393 | 73.8M | PyThreadState *tstate = _PyThreadState_GET(); |
394 | 73.8M | size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; |
395 | 73.8M | return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); |
396 | 73.8M | } |
397 | | |
398 | | |
399 | | /* --- PyFunction call functions ---------------------------------- */ |
400 | | |
401 | | PyObject * |
402 | | _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, |
403 | | size_t nargsf, PyObject *kwnames) |
404 | 223M | { |
405 | 223M | assert(PyFunction_Check(func)); |
406 | 223M | PyFunctionObject *f = (PyFunctionObject *)func; |
407 | 223M | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); |
408 | 223M | assert(nargs >= 0); |
409 | 223M | PyThreadState *tstate = _PyThreadState_GET(); |
410 | 223M | assert(nargs == 0 || stack != NULL); |
411 | 223M | EVAL_CALL_STAT_INC(EVAL_CALL_FUNCTION_VECTORCALL); |
412 | 223M | if (((PyCodeObject *)f->func_code)->co_flags & CO_OPTIMIZED) { |
413 | 223M | return _PyEval_Vector(tstate, f, NULL, stack, nargs, kwnames); |
414 | 223M | } |
415 | 0 | else { |
416 | 0 | return _PyEval_Vector(tstate, f, f->func_globals, stack, nargs, kwnames); |
417 | 0 | } |
418 | 223M | } |
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 | 107k | { |
462 | 107k | PyThreadState *tstate = _PyThreadState_GET(); |
463 | 107k | assert(!_PyErr_Occurred(tstate)); |
464 | 107k | if (args == NULL) { |
465 | 0 | return _PyObject_CallNoArgsTstate(tstate, callable); |
466 | 0 | } |
467 | 107k | 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 | 107k | return _PyObject_Call(tstate, callable, args, NULL); |
473 | 107k | } |
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 | 63.0M | { |
481 | 63.0M | assert(PyTuple_Check(args)); |
482 | | |
483 | 63.0M | PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; |
484 | 63.0M | PyObject **stack; |
485 | | |
486 | 63.0M | Py_ssize_t argcount = PyTuple_GET_SIZE(args); |
487 | 63.0M | if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { |
488 | 62.7M | stack = small_stack; |
489 | 62.7M | } |
490 | 283k | else { |
491 | 283k | stack = PyMem_Malloc((argcount + 1) * sizeof(PyObject *)); |
492 | 283k | if (stack == NULL) { |
493 | 0 | PyErr_NoMemory(); |
494 | 0 | return NULL; |
495 | 0 | } |
496 | 283k | } |
497 | | |
498 | | /* use borrowed references */ |
499 | 63.0M | stack[0] = obj; |
500 | 63.0M | memcpy(&stack[1], |
501 | 63.0M | _PyTuple_ITEMS(args), |
502 | 63.0M | argcount * sizeof(PyObject *)); |
503 | | |
504 | 63.0M | PyObject *result = _PyObject_VectorcallDictTstate(tstate, callable, |
505 | 63.0M | stack, argcount + 1, |
506 | 63.0M | kwargs); |
507 | 63.0M | if (stack != small_stack) { |
508 | 283k | PyMem_Free(stack); |
509 | 283k | } |
510 | 63.0M | return result; |
511 | 63.0M | } |
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.58M | { |
520 | 5.58M | PyObject* small_stack[_PY_FASTCALL_SMALL_STACK]; |
521 | 5.58M | const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack); |
522 | 5.58M | PyObject **stack; |
523 | 5.58M | Py_ssize_t nargs, i; |
524 | 5.58M | PyObject *result; |
525 | | |
526 | 5.58M | if (callable == NULL) { |
527 | 0 | return null_error(tstate); |
528 | 0 | } |
529 | | |
530 | 5.58M | if (!format || !*format) { |
531 | 3.33k | return _PyObject_CallNoArgsTstate(tstate, callable); |
532 | 3.33k | } |
533 | | |
534 | 5.58M | stack = _Py_VaBuildStack(small_stack, small_stack_len, |
535 | 5.58M | format, va, &nargs); |
536 | 5.58M | if (stack == NULL) { |
537 | 0 | return NULL; |
538 | 0 | } |
539 | 5.58M | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); |
540 | 5.58M | 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 | 28 | PyObject *args = stack[0]; |
546 | 28 | result = _PyObject_VectorcallTstate(tstate, callable, |
547 | 28 | _PyTuple_ITEMS(args), |
548 | 28 | PyTuple_GET_SIZE(args), |
549 | 28 | NULL); |
550 | 28 | } |
551 | 5.58M | else { |
552 | 5.58M | result = _PyObject_VectorcallTstate(tstate, callable, |
553 | 5.58M | stack, nargs, NULL); |
554 | 5.58M | } |
555 | | |
556 | 25.8M | for (i = 0; i < nargs; ++i) { |
557 | 20.2M | Py_DECREF(stack[i]); |
558 | 20.2M | } |
559 | 5.58M | if (stack != small_stack) { |
560 | 168 | PyMem_Free(stack); |
561 | 168 | } |
562 | 5.58M | return result; |
563 | 5.58M | } |
564 | | |
565 | | |
566 | | PyObject * |
567 | | PyObject_CallFunction(PyObject *callable, const char *format, ...) |
568 | 3.18M | { |
569 | 3.18M | va_list va; |
570 | 3.18M | PyObject *result; |
571 | 3.18M | PyThreadState *tstate = _PyThreadState_GET(); |
572 | | |
573 | 3.18M | va_start(va, format); |
574 | 3.18M | result = _PyObject_CallFunctionVa(tstate, callable, format, va); |
575 | 3.18M | va_end(va); |
576 | | |
577 | 3.18M | return result; |
578 | 3.18M | } |
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.39M | { |
618 | 2.39M | assert(callable != NULL); |
619 | 2.39M | 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.39M | return _PyObject_CallFunctionVa(tstate, callable, format, va); |
627 | 2.39M | } |
628 | | |
629 | | PyObject * |
630 | | PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) |
631 | 3.36k | { |
632 | 3.36k | PyThreadState *tstate = _PyThreadState_GET(); |
633 | | |
634 | 3.36k | if (obj == NULL || name == NULL) { |
635 | 0 | return null_error(tstate); |
636 | 0 | } |
637 | | |
638 | 3.36k | PyObject *callable = PyObject_GetAttrString(obj, name); |
639 | 3.36k | if (callable == NULL) { |
640 | 0 | return NULL; |
641 | 0 | } |
642 | | |
643 | 3.36k | va_list va; |
644 | 3.36k | va_start(va, format); |
645 | 3.36k | PyObject *retval = callmethod(tstate, callable, format, va); |
646 | 3.36k | va_end(va); |
647 | | |
648 | 3.36k | Py_DECREF(callable); |
649 | 3.36k | return retval; |
650 | 3.36k | } |
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.39M | { |
682 | 2.39M | PyThreadState *tstate = _PyThreadState_GET(); |
683 | 2.39M | if (obj == NULL || name == NULL) { |
684 | 0 | return null_error(tstate); |
685 | 0 | } |
686 | | |
687 | 2.39M | PyObject *callable = PyObject_GetAttr(obj, name); |
688 | 2.39M | if (callable == NULL) { |
689 | 0 | return NULL; |
690 | 0 | } |
691 | | |
692 | 2.39M | va_list va; |
693 | 2.39M | va_start(va, format); |
694 | 2.39M | PyObject *retval = callmethod(tstate, callable, format, va); |
695 | 2.39M | va_end(va); |
696 | | |
697 | 2.39M | Py_DECREF(callable); |
698 | 2.39M | return retval; |
699 | 2.39M | } |
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 | 334k | { |
773 | 334k | PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; |
774 | 334k | PyObject **stack; |
775 | 334k | Py_ssize_t nargs; |
776 | 334k | PyObject *result; |
777 | 334k | Py_ssize_t i; |
778 | 334k | va_list countva; |
779 | | |
780 | 334k | if (callable == NULL) { |
781 | 0 | return null_error(tstate); |
782 | 0 | } |
783 | | |
784 | | /* Count the number of arguments */ |
785 | 334k | va_copy(countva, vargs); |
786 | 334k | 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 | 334k | break; |
791 | 334k | } |
792 | 1.63M | nargs++; |
793 | 1.63M | } |
794 | 334k | va_end(countva); |
795 | | |
796 | | /* Copy arguments */ |
797 | 334k | if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { |
798 | 83.8k | stack = small_stack; |
799 | 83.8k | } |
800 | 251k | else { |
801 | 251k | stack = PyMem_Malloc(nargs * sizeof(stack[0])); |
802 | 251k | if (stack == NULL) { |
803 | 0 | PyErr_NoMemory(); |
804 | 0 | return NULL; |
805 | 0 | } |
806 | 251k | } |
807 | | |
808 | 334k | i = 0; |
809 | 334k | if (base) { |
810 | 50.3k | stack[i++] = base; |
811 | 50.3k | } |
812 | | |
813 | 1.97M | for (; i < nargs; ++i) { |
814 | 1.63M | stack[i] = va_arg(vargs, PyObject *); |
815 | 1.63M | } |
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 | 334k | result = _PyObject_VectorcallTstate(tstate, callable, stack, nargs, NULL); |
824 | | |
825 | 334k | if (stack != small_stack) { |
826 | 251k | PyMem_Free(stack); |
827 | 251k | } |
828 | 334k | return result; |
829 | 334k | } |
830 | | |
831 | | |
832 | | PyObject * |
833 | | PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, |
834 | | size_t nargsf, PyObject *kwnames) |
835 | 6.18M | { |
836 | 6.18M | assert(name != NULL); |
837 | 6.18M | assert(args != NULL); |
838 | 6.18M | assert(PyVectorcall_NARGS(nargsf) >= 1); |
839 | | |
840 | 6.18M | PyThreadState *tstate = _PyThreadState_GET(); |
841 | 6.18M | _PyCStackRef method; |
842 | 6.18M | _PyThreadState_PushCStackRef(tstate, &method); |
843 | | /* Use args[0] as "self" argument */ |
844 | 6.18M | int unbound = _PyObject_GetMethodStackRef(tstate, args[0], name, &method.ref); |
845 | 6.18M | if (PyStackRef_IsNull(method.ref)) { |
846 | 0 | _PyThreadState_PopCStackRef(tstate, &method); |
847 | 0 | return NULL; |
848 | 0 | } |
849 | 6.18M | PyObject *callable = PyStackRef_AsPyObjectBorrow(method.ref); |
850 | | |
851 | 6.18M | if (unbound) { |
852 | | /* We must remove PY_VECTORCALL_ARGUMENTS_OFFSET since |
853 | | * that would be interpreted as allowing to change args[-1] */ |
854 | 6.14M | nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET; |
855 | 6.14M | } |
856 | 39.9k | else { |
857 | | /* Skip "self". We can keep PY_VECTORCALL_ARGUMENTS_OFFSET since |
858 | | * args[-1] in the onward call is args[0] here. */ |
859 | 39.9k | args++; |
860 | 39.9k | nargsf--; |
861 | 39.9k | } |
862 | 6.18M | EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_METHOD, callable); |
863 | 6.18M | PyObject *result = _PyObject_VectorcallTstate(tstate, callable, |
864 | 6.18M | args, nargsf, kwnames); |
865 | 6.18M | _PyThreadState_PopCStackRef(tstate, &method); |
866 | 6.18M | return result; |
867 | 6.18M | } |
868 | | |
869 | | |
870 | | PyObject * |
871 | | PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) |
872 | 65.4k | { |
873 | 65.4k | PyThreadState *tstate = _PyThreadState_GET(); |
874 | 65.4k | if (obj == NULL || name == NULL) { |
875 | 0 | return null_error(tstate); |
876 | 0 | } |
877 | | |
878 | 65.4k | _PyCStackRef method; |
879 | 65.4k | _PyThreadState_PushCStackRef(tstate, &method); |
880 | 65.4k | int is_method = _PyObject_GetMethodStackRef(tstate, obj, name, &method.ref); |
881 | 65.4k | if (PyStackRef_IsNull(method.ref)) { |
882 | 0 | _PyThreadState_PopCStackRef(tstate, &method); |
883 | 0 | return NULL; |
884 | 0 | } |
885 | 65.4k | PyObject *callable = PyStackRef_AsPyObjectBorrow(method.ref); |
886 | 65.4k | obj = is_method ? obj : NULL; |
887 | | |
888 | 65.4k | va_list vargs; |
889 | 65.4k | va_start(vargs, name); |
890 | 65.4k | PyObject *result = object_vacall(tstate, obj, callable, vargs); |
891 | 65.4k | va_end(vargs); |
892 | | |
893 | 65.4k | _PyThreadState_PopCStackRef(tstate, &method); |
894 | 65.4k | return result; |
895 | 65.4k | } |
896 | | |
897 | | |
898 | | PyObject * |
899 | | PyObject_CallFunctionObjArgs(PyObject *callable, ...) |
900 | 269k | { |
901 | 269k | PyThreadState *tstate = _PyThreadState_GET(); |
902 | 269k | va_list vargs; |
903 | 269k | PyObject *result; |
904 | | |
905 | 269k | va_start(vargs, callable); |
906 | 269k | result = object_vacall(tstate, NULL, callable, vargs); |
907 | 269k | va_end(vargs); |
908 | | |
909 | 269k | return result; |
910 | 269k | } |
911 | | |
912 | | |
913 | | /* --- PyStack functions ------------------------------------------ */ |
914 | | |
915 | | PyObject * |
916 | | _PyStack_AsDict(PyObject *const *values, PyObject *kwnames) |
917 | 8.59M | { |
918 | 8.59M | Py_ssize_t nkwargs; |
919 | | |
920 | 8.59M | assert(kwnames != NULL); |
921 | 8.59M | nkwargs = PyTuple_GET_SIZE(kwnames); |
922 | 8.59M | return _PyDict_FromItems(&PyTuple_GET_ITEM(kwnames, 0), 1, |
923 | 8.59M | values, 1, nkwargs); |
924 | 8.59M | } |
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 | | When done, you must call _PyStack_UnpackDict_Free(stack, nargs, kwnames) */ |
939 | | PyObject *const * |
940 | | _PyStack_UnpackDict(PyThreadState *tstate, |
941 | | PyObject *const *args, Py_ssize_t nargs, |
942 | | PyObject *kwargs, PyObject **p_kwnames) |
943 | 9.16M | { |
944 | 9.16M | assert(nargs >= 0); |
945 | 9.16M | assert(kwargs != NULL); |
946 | 9.16M | assert(PyDict_Check(kwargs)); |
947 | | |
948 | 9.16M | Py_ssize_t nkwargs = PyDict_GET_SIZE(kwargs); |
949 | | /* Check for overflow in the PyMem_Malloc() call below. The subtraction |
950 | | * in this check cannot overflow: both maxnargs and nkwargs are |
951 | | * non-negative signed integers, so their difference fits in the type. */ |
952 | 9.16M | Py_ssize_t maxnargs = PY_SSIZE_T_MAX / sizeof(args[0]) - 1; |
953 | 9.16M | if (nargs > maxnargs - nkwargs) { |
954 | 0 | _PyErr_NoMemory(tstate); |
955 | 0 | return NULL; |
956 | 0 | } |
957 | | |
958 | | /* Add 1 to support PY_VECTORCALL_ARGUMENTS_OFFSET */ |
959 | 9.16M | PyObject **stack = PyMem_Malloc((1 + nargs + nkwargs) * sizeof(args[0])); |
960 | 9.16M | if (stack == NULL) { |
961 | 0 | _PyErr_NoMemory(tstate); |
962 | 0 | return NULL; |
963 | 0 | } |
964 | | |
965 | 9.16M | PyObject *kwnames = PyTuple_New(nkwargs); |
966 | 9.16M | if (kwnames == NULL) { |
967 | 0 | PyMem_Free(stack); |
968 | 0 | return NULL; |
969 | 0 | } |
970 | | |
971 | 9.16M | stack++; /* For PY_VECTORCALL_ARGUMENTS_OFFSET */ |
972 | | |
973 | | /* Copy positional arguments */ |
974 | 18.4M | for (Py_ssize_t i = 0; i < nargs; i++) { |
975 | 9.28M | stack[i] = Py_NewRef(args[i]); |
976 | 9.28M | } |
977 | | |
978 | 9.16M | PyObject **kwstack = stack + nargs; |
979 | | /* This loop doesn't support lookup function mutating the dictionary |
980 | | to change its size. It's a deliberate choice for speed, this function is |
981 | | called in the performance critical hot code. */ |
982 | 9.16M | Py_ssize_t pos = 0, i = 0; |
983 | 9.16M | PyObject *key, *value; |
984 | 9.16M | unsigned long keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; |
985 | 19.6M | while (PyDict_Next(kwargs, &pos, &key, &value)) { |
986 | 10.5M | keys_are_strings &= Py_TYPE(key)->tp_flags; |
987 | 10.5M | PyTuple_SET_ITEM(kwnames, i, Py_NewRef(key)); |
988 | 10.5M | kwstack[i] = Py_NewRef(value); |
989 | 10.5M | i++; |
990 | 10.5M | } |
991 | | |
992 | | /* keys_are_strings has the value Py_TPFLAGS_UNICODE_SUBCLASS if that |
993 | | * flag is set for all keys. Otherwise, keys_are_strings equals 0. |
994 | | * We do this check once at the end instead of inside the loop above |
995 | | * because it simplifies the deallocation in the failing case. |
996 | | * It happens to also make the loop above slightly more efficient. */ |
997 | 9.16M | if (!keys_are_strings) { |
998 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
999 | 0 | "keywords must be strings"); |
1000 | 0 | _PyStack_UnpackDict_Free(stack, nargs, kwnames); |
1001 | 0 | return NULL; |
1002 | 0 | } |
1003 | | |
1004 | 9.16M | *p_kwnames = kwnames; |
1005 | 9.16M | return stack; |
1006 | 9.16M | } |
1007 | | |
1008 | | void |
1009 | | _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, |
1010 | | PyObject *kwnames) |
1011 | 9.15M | { |
1012 | 9.15M | Py_ssize_t n = PyTuple_GET_SIZE(kwnames) + nargs; |
1013 | 28.9M | for (Py_ssize_t i = 0; i < n; i++) { |
1014 | 19.7M | Py_DECREF(stack[i]); |
1015 | 19.7M | } |
1016 | 9.15M | _PyStack_UnpackDict_FreeNoDecRef(stack, kwnames); |
1017 | 9.15M | } |
1018 | | |
1019 | | void |
1020 | | _PyStack_UnpackDict_FreeNoDecRef(PyObject *const *stack, PyObject *kwnames) |
1021 | 9.16M | { |
1022 | 9.16M | PyMem_Free((PyObject **)stack - 1); |
1023 | 9.16M | Py_DECREF(kwnames); |
1024 | 9.16M | } |
1025 | | |
1026 | | // Export for the stable ABI |
1027 | | #undef PyVectorcall_NARGS |
1028 | | Py_ssize_t |
1029 | | PyVectorcall_NARGS(size_t n) |
1030 | 0 | { |
1031 | 0 | return _PyVectorcall_NARGS(n); |
1032 | 0 | } |