LCOV - code coverage report
Current view: top level - Objects - call.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 328 409 80.2 %
Date: 2022-07-20 13:12:14 Functions: 34 40 85.0 %
Branches: 123 186 66.1 %

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

Generated by: LCOV version 1.14