LCOV - code coverage report
Current view: top level - Objects - call.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 249 414 60.1 %
Date: 2023-03-20 08:15:36 Functions: 29 41 70.7 %
Branches: 91 186 48.9 %

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

Generated by: LCOV version 1.14