| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-22 17:27:35 +02:00
										 |  |  | #include "pycore_call.h"          // _PyObject_CallNoArgTstate()
 | 
					
						
							|  |  |  | #include "pycore_ceval.h"         // _PyEval_EvalFrame()
 | 
					
						
							|  |  |  | #include "pycore_object.h"        // _PyObject_GC_TRACK()
 | 
					
						
							|  |  |  | #include "pycore_pyerrors.h"      // _PyErr_Occurred()
 | 
					
						
							|  |  |  | #include "pycore_pystate.h"       // _PyThreadState_GET()
 | 
					
						
							|  |  |  | #include "pycore_tuple.h"         // _PyTuple_ITEMS()
 | 
					
						
							|  |  |  | #include "frameobject.h"          // _PyFrame_New_NoTrack()
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  | static PyObject *const * | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  | _PyStack_UnpackDict(PyThreadState *tstate, | 
					
						
							|  |  |  |                     PyObject *const *args, Py_ssize_t nargs, | 
					
						
							|  |  |  |                     PyObject *kwargs, PyObject **p_kwnames); | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, | 
					
						
							|  |  |  |                          PyObject *kwnames); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | null_error(PyThreadState *tstate) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     if (!_PyErr_Occurred(tstate)) { | 
					
						
							|  |  |  |         _PyErr_SetString(tstate, PyExc_SystemError, | 
					
						
							|  |  |  |                          "null argument to internal routine"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject* | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  | _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, | 
					
						
							|  |  |  |                         PyObject *result, const char *where) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     assert((callable != NULL) ^ (where != NULL)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (result == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-07 12:42:07 +01:00
										 |  |  |         if (!_PyErr_Occurred(tstate)) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             if (callable) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |                 _PyErr_Format(tstate, PyExc_SystemError, | 
					
						
							|  |  |  |                               "%R returned NULL without setting an error", | 
					
						
							|  |  |  |                               callable); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             else | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |                 _PyErr_Format(tstate, PyExc_SystemError, | 
					
						
							|  |  |  |                               "%s returned NULL without setting an error", | 
					
						
							|  |  |  |                               where); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | #ifdef Py_DEBUG
 | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |             /* Ensure that the bug is caught in debug mode.
 | 
					
						
							|  |  |  |                Py_FatalError() logs the SystemError exception raised above. */ | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             Py_FatalError("a function returned NULL without setting an error"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-11-07 12:42:07 +01:00
										 |  |  |         if (_PyErr_Occurred(tstate)) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             Py_DECREF(result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (callable) { | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |                 _PyErr_FormatFromCauseTstate( | 
					
						
							|  |  |  |                     tstate, PyExc_SystemError, | 
					
						
							|  |  |  |                     "%R returned a result with an error set", callable); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |                 _PyErr_FormatFromCauseTstate( | 
					
						
							|  |  |  |                     tstate, PyExc_SystemError, | 
					
						
							|  |  |  |                     "%s returned a result with an error set", where); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             } | 
					
						
							|  |  |  | #ifdef Py_DEBUG
 | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |             /* Ensure that the bug is caught in debug mode.
 | 
					
						
							|  |  |  |                Py_FatalError() logs the SystemError exception raised above. */ | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             Py_FatalError("a function returned a result with an error set"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- Core PyObject call functions ------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-17 14:27:23 +02:00
										 |  |  | /* Call a callable Python object without any arguments */ | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PyObject_CallNoArgs(PyObject *func) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  |     return _PyObject_CallNoArgTstate(tstate, func); | 
					
						
							| 
									
										
										
										
											2019-06-17 14:27:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | _PyObject_FastCallDictTstate(PyThreadState *tstate, PyObject *callable, | 
					
						
							|  |  |  |                              PyObject *const *args, size_t nargsf, | 
					
						
							|  |  |  |                              PyObject *kwargs) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |     assert(callable != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 17:46:57 +01:00
										 |  |  |     /* PyObject_VectorcallDict() must not be called with an exception set,
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |        because it can clear it (directly or indirectly) and so the | 
					
						
							|  |  |  |        caller loses its exception */ | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |     assert(!_PyErr_Occurred(tstate)); | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     assert(nargs >= 0); | 
					
						
							|  |  |  |     assert(nargs == 0 || args != NULL); | 
					
						
							|  |  |  |     assert(kwargs == NULL || PyDict_Check(kwargs)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 17:46:57 +01:00
										 |  |  |     vectorcallfunc func = PyVectorcall_Function(callable); | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     if (func == NULL) { | 
					
						
							|  |  |  |         /* Use tp_call instead */ | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  |         return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwargs); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyObject *res; | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |         res = func(callable, args, nargsf, NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |         PyObject *kwnames; | 
					
						
							|  |  |  |         PyObject *const *newargs; | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |         newargs = _PyStack_UnpackDict(tstate, | 
					
						
							|  |  |  |                                       args, nargs, | 
					
						
							|  |  |  |                                       kwargs, &kwnames); | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |         if (newargs == NULL) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |         res = func(callable, newargs, | 
					
						
							|  |  |  |                    nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); | 
					
						
							|  |  |  |         _PyStack_UnpackDict_Free(newargs, nargs, kwnames); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |     return _Py_CheckFunctionResult(tstate, callable, res, NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2020-02-11 17:46:57 +01:00
										 |  |  | PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |                        size_t nargsf, PyObject *kwargs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  |     return _PyObject_FastCallDictTstate(tstate, callable, args, nargsf, kwargs); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  | _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, | 
					
						
							|  |  |  |                      PyObject *const *args, Py_ssize_t nargs, | 
					
						
							|  |  |  |                      PyObject *keywords) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     assert(nargs >= 0); | 
					
						
							|  |  |  |     assert(nargs == 0 || args != NULL); | 
					
						
							|  |  |  |     assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     /* Slow path: build a temporary tuple for positional arguments and a
 | 
					
						
							|  |  |  |      * temporary dictionary for keyword arguments (if any) */ | 
					
						
							|  |  |  |     ternaryfunc call = Py_TYPE(callable)->tp_call; | 
					
						
							|  |  |  |     if (call == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |         _PyErr_Format(tstate, PyExc_TypeError, | 
					
						
							|  |  |  |                       "'%.200s' object is not callable", | 
					
						
							|  |  |  |                       Py_TYPE(callable)->tp_name); | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     PyObject *argstuple = _PyTuple_FromArray(args, nargs); | 
					
						
							|  |  |  |     if (argstuple == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyObject *kwdict; | 
					
						
							|  |  |  |     if (keywords == NULL || PyDict_Check(keywords)) { | 
					
						
							|  |  |  |         kwdict = keywords; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |         if (PyTuple_GET_SIZE(keywords)) { | 
					
						
							|  |  |  |             assert(args != NULL); | 
					
						
							|  |  |  |             kwdict = _PyStack_AsDict(args + nargs, keywords); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             if (kwdict == NULL) { | 
					
						
							|  |  |  |                 Py_DECREF(argstuple); | 
					
						
							|  |  |  |                 return NULL; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |             keywords = kwdict = NULL; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     PyObject *result = NULL; | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |     if (_Py_EnterRecursiveCall(tstate, " while calling a Python object") == 0) | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         result = call(callable, argstuple, kwdict); | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |         _Py_LeaveRecursiveCall(tstate); | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     Py_DECREF(argstuple); | 
					
						
							|  |  |  |     if (kwdict != keywords) { | 
					
						
							|  |  |  |         Py_DECREF(kwdict); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     return _Py_CheckFunctionResult(tstate, callable, result, NULL); | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 17:46:57 +01:00
										 |  |  |     /* get vectorcallfunc as in PyVectorcall_Function, but without
 | 
					
						
							|  |  |  |      * the Py_TPFLAGS_HAVE_VECTORCALL check */ | 
					
						
							| 
									
										
										
										
											2019-06-02 23:52:20 +02:00
										 |  |  |     Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; | 
					
						
							| 
									
										
										
										
											2019-06-24 12:41:05 +02:00
										 |  |  |     if (offset <= 0) { | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |         _PyErr_Format(tstate, PyExc_TypeError, | 
					
						
							|  |  |  |                       "'%.200s' object does not support vectorcall", | 
					
						
							|  |  |  |                       Py_TYPE(callable)->tp_name); | 
					
						
							| 
									
										
										
										
											2019-06-02 23:52:20 +02:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset); | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     if (func == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |         _PyErr_Format(tstate, PyExc_TypeError, | 
					
						
							|  |  |  |                       "'%.200s' object does not support vectorcall", | 
					
						
							|  |  |  |                       Py_TYPE(callable)->tp_name); | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-02 23:52:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     Py_ssize_t nargs = PyTuple_GET_SIZE(tuple); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Fast path for no keywords */ | 
					
						
							|  |  |  |     if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { | 
					
						
							|  |  |  |         return func(callable, _PyTuple_ITEMS(tuple), nargs, NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 23:52:20 +02:00
										 |  |  |     /* Convert arguments & call */ | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     PyObject *const *args; | 
					
						
							|  |  |  |     PyObject *kwnames; | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |     args = _PyStack_UnpackDict(tstate, | 
					
						
							|  |  |  |                                _PyTuple_ITEMS(tuple), nargs, | 
					
						
							|  |  |  |                                kwargs, &kwnames); | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     if (args == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     PyObject *result = func(callable, args, | 
					
						
							|  |  |  |                             nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); | 
					
						
							|  |  |  |     _PyStack_UnpackDict_Free(args, nargs, kwnames); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |     return _Py_CheckFunctionResult(tstate, callable, result, NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | _PyObject_Call(PyThreadState *tstate, PyObject *callable, | 
					
						
							|  |  |  |                PyObject *args, PyObject *kwargs) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     ternaryfunc call; | 
					
						
							|  |  |  |     PyObject *result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* PyObject_Call() must not be called with an exception set,
 | 
					
						
							|  |  |  |        because it can clear it (directly or indirectly) and so the | 
					
						
							|  |  |  |        caller loses its exception */ | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |     assert(!_PyErr_Occurred(tstate)); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     assert(PyTuple_Check(args)); | 
					
						
							|  |  |  |     assert(kwargs == NULL || PyDict_Check(kwargs)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 17:46:57 +01:00
										 |  |  |     if (PyVectorcall_Function(callable) != NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |         return PyVectorcall_Call(callable, args, kwargs); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2020-02-07 03:04:21 +01:00
										 |  |  |         call = Py_TYPE(callable)->tp_call; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         if (call == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |             _PyErr_Format(tstate, PyExc_TypeError, | 
					
						
							|  |  |  |                           "'%.200s' object is not callable", | 
					
						
							| 
									
										
										
										
											2020-02-07 03:04:21 +01:00
										 |  |  |                           Py_TYPE(callable)->tp_name); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |         if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             return NULL; | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         result = (*call)(callable, args, kwargs); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |         _Py_LeaveRecursiveCall(tstate); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |         return _Py_CheckFunctionResult(tstate, callable, result, NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  |     return _PyObject_Call(tstate, callable, args, kwargs); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-11 13:01:01 +02:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  |     return _PyObject_Call(tstate, callable, args, kwargs); | 
					
						
							| 
									
										
										
										
											2019-09-11 13:01:01 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | /* --- PyFunction call functions ---------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject* _Py_HOT_FUNCTION | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  | function_code_fastcall(PyThreadState *tstate, PyCodeObject *co, | 
					
						
							|  |  |  |                        PyObject *const *args, Py_ssize_t nargs, | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |                        PyObject *globals) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |     assert(tstate != NULL); | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |     assert(globals != NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* XXX Perhaps we should create a specialized
 | 
					
						
							|  |  |  |        _PyFrame_New_NoTrack() that doesn't take locals, but does | 
					
						
							|  |  |  |        take builtins without sanity checking them. | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |     PyFrameObject *f = _PyFrame_New_NoTrack(tstate, co, globals, NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (f == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |     PyObject **fastlocals = f->f_localsplus; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 00:51:22 +01:00
										 |  |  |     for (Py_ssize_t i = 0; i < nargs; i++) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         Py_INCREF(*args); | 
					
						
							|  |  |  |         fastlocals[i] = *args++; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-14 12:20:46 +01:00
										 |  |  |     PyObject *result = _PyEval_EvalFrame(tstate, f, 0); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (Py_REFCNT(f) > 1) { | 
					
						
							|  |  |  |         Py_DECREF(f); | 
					
						
							|  |  |  |         _PyObject_GC_TRACK(f); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         ++tstate->recursion_depth; | 
					
						
							|  |  |  |         Py_DECREF(f); | 
					
						
							|  |  |  |         --tstate->recursion_depth; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2019-05-30 15:11:22 +02:00
										 |  |  | _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, | 
					
						
							|  |  |  |                        size_t nargsf, PyObject *kwnames) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     assert(PyFunction_Check(func)); | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |     assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 20:31:52 +02:00
										 |  |  |     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     assert(nargs >= 0); | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |     Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     assert((nargs == 0 && nkwargs == 0) || stack != NULL); | 
					
						
							| 
									
										
										
										
											2019-08-16 12:41:27 +02:00
										 |  |  |     /* kwnames must only contain strings and all keys must be unique */ | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  |     PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); | 
					
						
							|  |  |  |     PyObject *globals = PyFunction_GET_GLOBALS(func); | 
					
						
							|  |  |  |     PyObject *argdefs = PyFunction_GET_DEFAULTS(func); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (co->co_kwonlyargcount == 0 && nkwargs == 0 && | 
					
						
							| 
									
										
										
										
											2017-10-25 05:26:17 -07:00
										 |  |  |         (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-06-01 18:08:04 +01:00
										 |  |  |         if (argdefs == NULL && co->co_argcount == nargs) { | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |             return function_code_fastcall(tstate, co, stack, nargs, globals); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         else if (nargs == 0 && argdefs != NULL | 
					
						
							| 
									
										
										
										
											2019-06-01 18:08:04 +01:00
										 |  |  |                  && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |             /* function called with no arguments, but all parameters have
 | 
					
						
							|  |  |  |                a default value: use default values as arguments .*/ | 
					
						
							| 
									
										
										
										
											2018-11-09 16:56:48 +01:00
										 |  |  |             stack = _PyTuple_ITEMS(argdefs); | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |             return function_code_fastcall(tstate, co, | 
					
						
							|  |  |  |                                           stack, PyTuple_GET_SIZE(argdefs), | 
					
						
							| 
									
										
										
										
											2017-03-21 08:53:25 +02:00
										 |  |  |                                           globals); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |     PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func); | 
					
						
							|  |  |  |     PyObject *closure = PyFunction_GET_CLOSURE(func); | 
					
						
							|  |  |  |     PyObject *name = ((PyFunctionObject *)func) -> func_name; | 
					
						
							|  |  |  |     PyObject *qualname = ((PyFunctionObject *)func) -> func_qualname; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |     PyObject **d; | 
					
						
							|  |  |  |     Py_ssize_t nd; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (argdefs != NULL) { | 
					
						
							| 
									
										
										
										
											2018-11-09 16:56:48 +01:00
										 |  |  |         d = _PyTuple_ITEMS(argdefs); | 
					
						
							| 
									
										
										
										
											2017-03-21 08:53:25 +02:00
										 |  |  |         nd = PyTuple_GET_SIZE(argdefs); | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |         assert(nd <= INT_MAX); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         d = NULL; | 
					
						
							|  |  |  |         nd = 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-16 01:03:22 +01:00
										 |  |  |     return _PyEval_EvalCode(tstate, | 
					
						
							|  |  |  |                 (PyObject*)co, globals, (PyObject *)NULL, | 
					
						
							|  |  |  |                 stack, nargs, | 
					
						
							|  |  |  |                 nkwargs ? _PyTuple_ITEMS(kwnames) : NULL, | 
					
						
							|  |  |  |                 stack + nargs, | 
					
						
							|  |  |  |                 nkwargs, 1, | 
					
						
							|  |  |  |                 d, (int)nd, kwdefs, | 
					
						
							|  |  |  |                 closure, name, qualname); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- More complex call functions -------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* External interface to call any callable object.
 | 
					
						
							|  |  |  |    The args must be a tuple or NULL.  The kwargs must be a dict or NULL. */ | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PyEval_CallObjectWithKeywords(PyObject *callable, | 
					
						
							|  |  |  |                               PyObject *args, PyObject *kwargs) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | #ifdef Py_DEBUG
 | 
					
						
							|  |  |  |     /* PyEval_CallObjectWithKeywords() must not be called with an exception
 | 
					
						
							|  |  |  |        set. It raises a new exception if parameters are invalid or if | 
					
						
							|  |  |  |        PyTuple_New() fails, and so the original exception is lost. */ | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     assert(!_PyErr_Occurred(tstate)); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-01 20:41:03 +09:00
										 |  |  |     if (args != NULL && !PyTuple_Check(args)) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         _PyErr_SetString(tstate, PyExc_TypeError, | 
					
						
							|  |  |  |                          "argument list must be a tuple"); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (kwargs != NULL && !PyDict_Check(kwargs)) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         _PyErr_SetString(tstate, PyExc_TypeError, | 
					
						
							|  |  |  |                          "keyword list must be a dictionary"); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-01 20:41:03 +09:00
										 |  |  |     if (args == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return _PyObject_FastCallDictTstate(tstate, callable, NULL, 0, kwargs); | 
					
						
							| 
									
										
										
										
											2017-03-01 20:41:03 +09:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return _PyObject_Call(tstate, callable, args, kwargs); | 
					
						
							| 
									
										
										
										
											2017-03-01 20:41:03 +09:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PyObject_CallObject(PyObject *callable, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							|  |  |  |     assert(!_PyErr_Occurred(tstate)); | 
					
						
							| 
									
										
										
										
											2019-07-11 17:57:32 +02:00
										 |  |  |     if (args == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return _PyObject_CallNoArgTstate(tstate, callable); | 
					
						
							| 
									
										
										
										
											2019-07-11 17:57:32 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (!PyTuple_Check(args)) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         _PyErr_SetString(tstate, PyExc_TypeError, | 
					
						
							|  |  |  |                          "argument list must be a tuple"); | 
					
						
							| 
									
										
										
										
											2019-07-11 17:57:32 +02:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     return _PyObject_Call(tstate, callable, args, NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Call callable(obj, *args, **kwargs). */ | 
					
						
							|  |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | _PyObject_Call_Prepend(PyThreadState *tstate, PyObject *callable, | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |                        PyObject *obj, PyObject *args, PyObject *kwargs) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     assert(PyTuple_Check(args)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; | 
					
						
							|  |  |  |     PyObject **stack; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     Py_ssize_t argcount = PyTuple_GET_SIZE(args); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { | 
					
						
							|  |  |  |         stack = small_stack; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         stack = PyMem_Malloc((argcount + 1) * sizeof(PyObject *)); | 
					
						
							|  |  |  |         if (stack == NULL) { | 
					
						
							|  |  |  |             PyErr_NoMemory(); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* use borrowed references */ | 
					
						
							|  |  |  |     stack[0] = obj; | 
					
						
							|  |  |  |     memcpy(&stack[1], | 
					
						
							| 
									
										
										
										
											2018-11-09 16:56:48 +01:00
										 |  |  |            _PyTuple_ITEMS(args), | 
					
						
							|  |  |  |            argcount * sizeof(PyObject *)); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *result = _PyObject_FastCallDictTstate(tstate, callable, | 
					
						
							|  |  |  |                                                     stack, argcount + 1, | 
					
						
							|  |  |  |                                                     kwargs); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (stack != small_stack) { | 
					
						
							|  |  |  |         PyMem_Free(stack); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- Call with a format string ---------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | _PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, | 
					
						
							|  |  |  |                          const char *format, va_list va, int is_size_t) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject* small_stack[_PY_FASTCALL_SMALL_STACK]; | 
					
						
							|  |  |  |     const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack); | 
					
						
							|  |  |  |     PyObject **stack; | 
					
						
							|  |  |  |     Py_ssize_t nargs, i; | 
					
						
							|  |  |  |     PyObject *result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (callable == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return null_error(tstate); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!format || !*format) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return _PyObject_CallNoArgTstate(tstate, callable); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (is_size_t) { | 
					
						
							|  |  |  |         stack = _Py_VaBuildStack_SizeT(small_stack, small_stack_len, | 
					
						
							|  |  |  |                                        format, va, &nargs); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         stack = _Py_VaBuildStack(small_stack, small_stack_len, | 
					
						
							|  |  |  |                                  format, va, &nargs); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (stack == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (nargs == 1 && PyTuple_Check(stack[0])) { | 
					
						
							|  |  |  |         /* Special cases for backward compatibility:
 | 
					
						
							|  |  |  |            - PyObject_CallFunction(func, "O", tuple) calls func(*tuple) | 
					
						
							|  |  |  |            - PyObject_CallFunction(func, "(OOO)", arg1, arg2, arg3) calls | 
					
						
							|  |  |  |              func(*(arg1, arg2, arg3)): func(arg1, arg2, arg3) */ | 
					
						
							|  |  |  |         PyObject *args = stack[0]; | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         result = _PyObject_VectorcallTstate(tstate, callable, | 
					
						
							|  |  |  |                                             _PyTuple_ITEMS(args), | 
					
						
							|  |  |  |                                             PyTuple_GET_SIZE(args), | 
					
						
							|  |  |  |                                             NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         result = _PyObject_VectorcallTstate(tstate, callable, | 
					
						
							|  |  |  |                                             stack, nargs, NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < nargs; ++i) { | 
					
						
							|  |  |  |         Py_DECREF(stack[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (stack != small_stack) { | 
					
						
							|  |  |  |         PyMem_Free(stack); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PyObject_CallFunction(PyObject *callable, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     va_list va; | 
					
						
							|  |  |  |     PyObject *result; | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     va_start(va, format); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_end(va); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  | /* PyEval_CallFunction is exact copy of PyObject_CallFunction.
 | 
					
						
							|  |  |  |  * This function is kept for backward compatibility. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyEval_CallFunction(PyObject *callable, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  |     va_list va; | 
					
						
							|  |  |  |     PyObject *result; | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  |     va_start(va, format); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  |     va_end(va); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  |     return result; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     va_list va; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_start(va, format); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *result = _PyObject_CallFunctionVa(tstate, callable, format, va, 1); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_end(va); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject* | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | callmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_list va, int is_size_t) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     assert(callable != NULL); | 
					
						
							|  |  |  |     if (!PyCallable_Check(callable)) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         _PyErr_Format(tstate, PyExc_TypeError, | 
					
						
							|  |  |  |                       "attribute of type '%.200s' is not callable", | 
					
						
							|  |  |  |                       Py_TYPE(callable)->tp_name); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     return _PyObject_CallFunctionVa(tstate, callable, format, va, is_size_t); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (obj == NULL || name == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return null_error(tstate); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *callable = PyObject_GetAttrString(obj, name); | 
					
						
							|  |  |  |     if (callable == NULL) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     va_list va; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_start(va, format); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *retval = callmethod(tstate, callable, format, va, 0); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_end(va); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(callable); | 
					
						
							|  |  |  |     return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  | /* PyEval_CallMethod is exact copy of PyObject_CallMethod.
 | 
					
						
							|  |  |  |  * This function is kept for backward compatibility. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  |     if (obj == NULL || name == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return null_error(tstate); | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *callable = PyObject_GetAttrString(obj, name); | 
					
						
							|  |  |  |     if (callable == NULL) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     va_list va; | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  |     va_start(va, format); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *retval = callmethod(tstate, callable, format, va, 0); | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  |     va_end(va); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-14 18:00:59 +09:00
										 |  |  |     Py_DECREF(callable); | 
					
						
							|  |  |  |     return retval; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, | 
					
						
							|  |  |  |                        const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (obj == NULL || name == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return null_error(tstate); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *callable = _PyObject_GetAttrId(obj, name); | 
					
						
							|  |  |  |     if (callable == NULL) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     va_list va; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_start(va, format); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *retval = callmethod(tstate, callable, format, va, 0); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_end(va); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(callable); | 
					
						
							|  |  |  |     return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | _PyObject_CallMethod_SizeT(PyObject *obj, const char *name, | 
					
						
							|  |  |  |                            const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (obj == NULL || name == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return null_error(tstate); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *callable = PyObject_GetAttrString(obj, name); | 
					
						
							|  |  |  |     if (callable == NULL) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     va_list va; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_start(va, format); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *retval = callmethod(tstate, callable, format, va, 1); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_end(va); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(callable); | 
					
						
							|  |  |  |     return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, | 
					
						
							|  |  |  |                              const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (obj == NULL || name == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return null_error(tstate); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *callable = _PyObject_GetAttrId(obj, name); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (callable == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     va_list va; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_start(va, format); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *retval = callmethod(tstate, callable, format, va, 1); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_end(va); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(callable); | 
					
						
							|  |  |  |     return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- Call with "..." arguments ---------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  | object_vacall(PyThreadState *tstate, PyObject *base, | 
					
						
							|  |  |  |               PyObject *callable, va_list vargs) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; | 
					
						
							|  |  |  |     PyObject **stack; | 
					
						
							|  |  |  |     Py_ssize_t nargs; | 
					
						
							|  |  |  |     PyObject *result; | 
					
						
							|  |  |  |     Py_ssize_t i; | 
					
						
							|  |  |  |     va_list countva; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (callable == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return null_error(tstate); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Count the number of arguments */ | 
					
						
							|  |  |  |     va_copy(countva, vargs); | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  |     nargs = base ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     while (1) { | 
					
						
							|  |  |  |         PyObject *arg = va_arg(countva, PyObject *); | 
					
						
							|  |  |  |         if (arg == NULL) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         nargs++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     va_end(countva); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Copy arguments */ | 
					
						
							|  |  |  |     if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { | 
					
						
							|  |  |  |         stack = small_stack; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         stack = PyMem_Malloc(nargs * sizeof(stack[0])); | 
					
						
							|  |  |  |         if (stack == NULL) { | 
					
						
							|  |  |  |             PyErr_NoMemory(); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  |     i = 0; | 
					
						
							|  |  |  |     if (base) { | 
					
						
							|  |  |  |         stack[i++] = base; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (; i < nargs; ++i) { | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         stack[i] = va_arg(vargs, PyObject *); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Call the function */ | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     result = _PyObject_VectorcallTstate(tstate, callable, stack, nargs, NULL); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (stack != small_stack) { | 
					
						
							|  |  |  |         PyMem_Free(stack); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 11:49:00 +02:00
										 |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2020-02-11 17:46:57 +01:00
										 |  |  | PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, | 
					
						
							| 
									
										
										
										
											2019-06-28 11:49:00 +02:00
										 |  |  |                            size_t nargsf, PyObject *kwnames) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(name != NULL); | 
					
						
							|  |  |  |     assert(args != NULL); | 
					
						
							|  |  |  |     assert(PyVectorcall_NARGS(nargsf) >= 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2019-06-28 11:49:00 +02:00
										 |  |  |     PyObject *callable = NULL; | 
					
						
							|  |  |  |     /* Use args[0] as "self" argument */ | 
					
						
							|  |  |  |     int unbound = _PyObject_GetMethod(args[0], name, &callable); | 
					
						
							|  |  |  |     if (callable == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (unbound) { | 
					
						
							|  |  |  |         /* We must remove PY_VECTORCALL_ARGUMENTS_OFFSET since
 | 
					
						
							|  |  |  |          * that would be interpreted as allowing to change args[-1] */ | 
					
						
							|  |  |  |         nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         /* Skip "self". We can keep PY_VECTORCALL_ARGUMENTS_OFFSET since
 | 
					
						
							|  |  |  |          * args[-1] in the onward call is args[0] here. */ | 
					
						
							|  |  |  |         args++; | 
					
						
							|  |  |  |         nargsf--; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-08 10:05:17 +01:00
										 |  |  |     PyObject *result = _PyObject_VectorcallTstate(tstate, callable, | 
					
						
							|  |  |  |                                                   args, nargsf, kwnames); | 
					
						
							| 
									
										
										
										
											2019-06-28 11:49:00 +02:00
										 |  |  |     Py_DECREF(callable); | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  | PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  |     if (obj == NULL || name == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return null_error(tstate); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  |     PyObject *callable = NULL; | 
					
						
							|  |  |  |     int is_method = _PyObject_GetMethod(obj, name, &callable); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (callable == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  |     obj = is_method ? obj : NULL; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  |     va_list vargs; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_start(vargs, name); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *result = object_vacall(tstate, obj, callable, vargs); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_end(vargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(callable); | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | _PyObject_CallMethodIdObjArgs(PyObject *obj, | 
					
						
							|  |  |  |                               struct _Py_Identifier *name, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (obj == NULL || name == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |         return null_error(tstate); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  |     PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ | 
					
						
							|  |  |  |     if (!oname) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyObject *callable = NULL; | 
					
						
							|  |  |  |     int is_method = _PyObject_GetMethod(obj, oname, &callable); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (callable == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  |     obj = is_method ? obj : NULL; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 00:23:34 -07:00
										 |  |  |     va_list vargs; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_start(vargs, name); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyObject *result = object_vacall(tstate, obj, callable, vargs); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_end(vargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(callable); | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PyObject_CallFunctionObjArgs(PyObject *callable, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     PyThreadState *tstate = _PyThreadState_GET(); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_list vargs; | 
					
						
							|  |  |  |     PyObject *result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     va_start(vargs, callable); | 
					
						
							| 
									
										
										
										
											2019-11-14 13:36:21 +01:00
										 |  |  |     result = object_vacall(tstate, NULL, callable, vargs); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     va_end(vargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- PyStack functions ------------------------------------------ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							| 
									
										
										
										
											2017-12-15 13:11:11 +02:00
										 |  |  | _PyStack_AsDict(PyObject *const *values, PyObject *kwnames) | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     Py_ssize_t nkwargs; | 
					
						
							|  |  |  |     PyObject *kwdict; | 
					
						
							|  |  |  |     Py_ssize_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(kwnames != NULL); | 
					
						
							|  |  |  |     nkwargs = PyTuple_GET_SIZE(kwnames); | 
					
						
							|  |  |  |     kwdict = _PyDict_NewPresized(nkwargs); | 
					
						
							|  |  |  |     if (kwdict == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < nkwargs; i++) { | 
					
						
							|  |  |  |         PyObject *key = PyTuple_GET_ITEM(kwnames, i); | 
					
						
							|  |  |  |         PyObject *value = *values++; | 
					
						
							|  |  |  |         /* If key already exists, replace it with the new value */ | 
					
						
							|  |  |  |         if (PyDict_SetItem(kwdict, key, value)) { | 
					
						
							|  |  |  |             Py_DECREF(kwdict); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return kwdict; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  | /* Convert (args, nargs, kwargs: dict) into a (stack, nargs, kwnames: tuple).
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |    Allocate a new argument vector and keyword names tuple. Return the argument | 
					
						
							|  |  |  |    vector; return NULL with exception set on error. Return the keyword names | 
					
						
							|  |  |  |    tuple in *p_kwnames. | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-16 12:41:27 +02:00
										 |  |  |    This also checks that all keyword names are strings. If not, a TypeError is | 
					
						
							|  |  |  |    raised. | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-16 12:41:27 +02:00
										 |  |  |    The newly allocated argument vector supports PY_VECTORCALL_ARGUMENTS_OFFSET. | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-16 12:41:27 +02:00
										 |  |  |    When done, you must call _PyStack_UnpackDict_Free(stack, nargs, kwnames) */ | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  | static PyObject *const * | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  | _PyStack_UnpackDict(PyThreadState *tstate, | 
					
						
							|  |  |  |                     PyObject *const *args, Py_ssize_t nargs, | 
					
						
							|  |  |  |                     PyObject *kwargs, PyObject **p_kwnames) | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     assert(nargs >= 0); | 
					
						
							|  |  |  |     assert(kwargs != NULL); | 
					
						
							|  |  |  |     assert(PyDict_Check(kwargs)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_ssize_t nkwargs = PyDict_GET_SIZE(kwargs); | 
					
						
							|  |  |  |     /* Check for overflow in the PyMem_Malloc() call below. The subtraction
 | 
					
						
							|  |  |  |      * in this check cannot overflow: both maxnargs and nkwargs are | 
					
						
							|  |  |  |      * non-negative signed integers, so their difference fits in the type. */ | 
					
						
							|  |  |  |     Py_ssize_t maxnargs = PY_SSIZE_T_MAX / sizeof(args[0]) - 1; | 
					
						
							|  |  |  |     if (nargs > maxnargs - nkwargs) { | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |         _PyErr_NoMemory(tstate); | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     /* Add 1 to support PY_VECTORCALL_ARGUMENTS_OFFSET */ | 
					
						
							|  |  |  |     PyObject **stack = PyMem_Malloc((1 + nargs + nkwargs) * sizeof(args[0])); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (stack == NULL) { | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |         _PyErr_NoMemory(tstate); | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     PyObject *kwnames = PyTuple_New(nkwargs); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     if (kwnames == NULL) { | 
					
						
							|  |  |  |         PyMem_Free(stack); | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     stack++;  /* For PY_VECTORCALL_ARGUMENTS_OFFSET */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-22 13:09:35 +02:00
										 |  |  |     /* Copy positional arguments */ | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     for (Py_ssize_t i = 0; i < nargs; i++) { | 
					
						
							| 
									
										
										
										
											2019-05-22 13:09:35 +02:00
										 |  |  |         Py_INCREF(args[i]); | 
					
						
							|  |  |  |         stack[i] = args[i]; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     PyObject **kwstack = stack + nargs; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     /* This loop doesn't support lookup function mutating the dictionary
 | 
					
						
							|  |  |  |        to change its size. It's a deliberate choice for speed, this function is | 
					
						
							|  |  |  |        called in the performance critical hot code. */ | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     Py_ssize_t pos = 0, i = 0; | 
					
						
							|  |  |  |     PyObject *key, *value; | 
					
						
							| 
									
										
										
										
											2019-08-16 12:41:27 +02:00
										 |  |  |     unsigned long keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     while (PyDict_Next(kwargs, &pos, &key, &value)) { | 
					
						
							| 
									
										
										
										
											2019-08-16 12:41:27 +02:00
										 |  |  |         keys_are_strings &= Py_TYPE(key)->tp_flags; | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         Py_INCREF(key); | 
					
						
							| 
									
										
										
										
											2019-05-22 13:09:35 +02:00
										 |  |  |         Py_INCREF(value); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |         PyTuple_SET_ITEM(kwnames, i, key); | 
					
						
							|  |  |  |         kwstack[i] = value; | 
					
						
							|  |  |  |         i++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-16 12:41:27 +02:00
										 |  |  |     /* keys_are_strings has the value Py_TPFLAGS_UNICODE_SUBCLASS if that
 | 
					
						
							|  |  |  |      * flag is set for all keys. Otherwise, keys_are_strings equals 0. | 
					
						
							|  |  |  |      * We do this check once at the end instead of inside the loop above | 
					
						
							|  |  |  |      * because it simplifies the deallocation in the failing case. | 
					
						
							|  |  |  |      * It happens to also make the loop above slightly more efficient. */ | 
					
						
							|  |  |  |     if (!keys_are_strings) { | 
					
						
							| 
									
										
										
										
											2019-11-05 01:22:12 +01:00
										 |  |  |         _PyErr_SetString(tstate, PyExc_TypeError, | 
					
						
							|  |  |  |                          "keywords must be strings"); | 
					
						
							| 
									
										
										
										
											2019-08-16 12:41:27 +02:00
										 |  |  |         _PyStack_UnpackDict_Free(stack, nargs, kwnames); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  |     *p_kwnames = kwnames; | 
					
						
							| 
									
										
										
										
											2019-07-02 11:49:40 +02:00
										 |  |  |     return stack; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, | 
					
						
							|  |  |  |                          PyObject *kwnames) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_ssize_t n = PyTuple_GET_SIZE(kwnames) + nargs; | 
					
						
							|  |  |  |     for (Py_ssize_t i = 0; i < n; i++) { | 
					
						
							|  |  |  |         Py_DECREF(stack[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     PyMem_Free((PyObject **)stack - 1); | 
					
						
							|  |  |  |     Py_DECREF(kwnames); | 
					
						
							| 
									
										
										
										
											2017-02-12 19:27:05 +01:00
										 |  |  | } |