LCOV - code coverage report
Current view: top level - Objects - methodobject.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 206 244 84.4 %
Date: 2022-07-07 18:19:46 Functions: 21 26 80.8 %

          Line data    Source code
       1             : 
       2             : /* Method object implementation */
       3             : 
       4             : #include "Python.h"
       5             : #include "pycore_ceval.h"         // _Py_EnterRecursiveCallTstate()
       6             : #include "pycore_object.h"
       7             : #include "pycore_pyerrors.h"
       8             : #include "pycore_pystate.h"       // _PyThreadState_GET()
       9             : #include "structmember.h"         // PyMemberDef
      10             : 
      11             : /* undefine macro trampoline to PyCFunction_NewEx */
      12             : #undef PyCFunction_New
      13             : /* undefine macro trampoline to PyCMethod_New */
      14             : #undef PyCFunction_NewEx
      15             : 
      16             : /* Forward declarations */
      17             : static PyObject * cfunction_vectorcall_FASTCALL(
      18             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      19             : static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS(
      20             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      21             : static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD(
      22             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      23             : static PyObject * cfunction_vectorcall_NOARGS(
      24             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      25             : static PyObject * cfunction_vectorcall_O(
      26             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
      27             : static PyObject * cfunction_call(
      28             :     PyObject *func, PyObject *args, PyObject *kwargs);
      29             : 
      30             : 
      31             : PyObject *
      32           0 : PyCFunction_New(PyMethodDef *ml, PyObject *self)
      33             : {
      34           0 :     return PyCFunction_NewEx(ml, self, NULL);
      35             : }
      36             : 
      37             : PyObject *
      38           0 : PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
      39             : {
      40           0 :     return PyCMethod_New(ml, self, module, NULL);
      41             : }
      42             : 
      43             : PyObject *
      44    31389500 : PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *cls)
      45             : {
      46             :     /* Figure out correct vectorcall function to use */
      47             :     vectorcallfunc vectorcall;
      48    31389500 :     switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS |
      49             :                             METH_O | METH_KEYWORDS | METH_METHOD))
      50             :     {
      51     4638780 :         case METH_VARARGS:
      52             :         case METH_VARARGS | METH_KEYWORDS:
      53             :             /* For METH_VARARGS functions, it's more efficient to use tp_call
      54             :              * instead of vectorcall. */
      55     4638780 :             vectorcall = NULL;
      56     4638780 :             break;
      57     4240190 :         case METH_FASTCALL:
      58     4240190 :             vectorcall = cfunction_vectorcall_FASTCALL;
      59     4240190 :             break;
      60     2807390 :         case METH_FASTCALL | METH_KEYWORDS:
      61     2807390 :             vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS;
      62     2807390 :             break;
      63     4814590 :         case METH_NOARGS:
      64     4814590 :             vectorcall = cfunction_vectorcall_NOARGS;
      65     4814590 :             break;
      66    11747700 :         case METH_O:
      67    11747700 :             vectorcall = cfunction_vectorcall_O;
      68    11747700 :             break;
      69     3140900 :         case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
      70     3140900 :             vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD;
      71     3140900 :             break;
      72           0 :         default:
      73           0 :             PyErr_Format(PyExc_SystemError,
      74             :                          "%s() method: bad call flags", ml->ml_name);
      75           0 :             return NULL;
      76             :     }
      77             : 
      78    31389500 :     PyCFunctionObject *op = NULL;
      79             : 
      80    31389500 :     if (ml->ml_flags & METH_METHOD) {
      81     3140900 :         if (!cls) {
      82           0 :             PyErr_SetString(PyExc_SystemError,
      83             :                             "attempting to create PyCMethod with a METH_METHOD "
      84             :                             "flag but no class");
      85           0 :             return NULL;
      86             :         }
      87     3140900 :         PyCMethodObject *om = PyObject_GC_New(PyCMethodObject, &PyCMethod_Type);
      88     3140900 :         if (om == NULL) {
      89           0 :             return NULL;
      90             :         }
      91     3140900 :         Py_INCREF(cls);
      92     3140900 :         om->mm_class = cls;
      93     3140900 :         op = (PyCFunctionObject *)om;
      94             :     } else {
      95    28248600 :         if (cls) {
      96           0 :             PyErr_SetString(PyExc_SystemError,
      97             :                             "attempting to create PyCFunction with class "
      98             :                             "but no METH_METHOD flag");
      99           0 :             return NULL;
     100             :         }
     101    28248600 :         op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
     102    28248600 :         if (op == NULL) {
     103          33 :             return NULL;
     104             :         }
     105             :     }
     106             : 
     107    31389500 :     op->m_weakreflist = NULL;
     108    31389500 :     op->m_ml = ml;
     109    31389500 :     Py_XINCREF(self);
     110    31389500 :     op->m_self = self;
     111    31389500 :     Py_XINCREF(module);
     112    31389500 :     op->m_module = module;
     113    31389500 :     op->vectorcall = vectorcall;
     114    31389500 :     _PyObject_GC_TRACK(op);
     115    31389500 :     return (PyObject *)op;
     116             : }
     117             : 
     118             : PyCFunction
     119        1108 : PyCFunction_GetFunction(PyObject *op)
     120             : {
     121        1108 :     if (!PyCFunction_Check(op)) {
     122           0 :         PyErr_BadInternalCall();
     123           0 :         return NULL;
     124             :     }
     125        1108 :     return PyCFunction_GET_FUNCTION(op);
     126             : }
     127             : 
     128             : PyObject *
     129           0 : PyCFunction_GetSelf(PyObject *op)
     130             : {
     131           0 :     if (!PyCFunction_Check(op)) {
     132           0 :         PyErr_BadInternalCall();
     133           0 :         return NULL;
     134             :     }
     135           0 :     return PyCFunction_GET_SELF(op);
     136             : }
     137             : 
     138             : int
     139           0 : PyCFunction_GetFlags(PyObject *op)
     140             : {
     141           0 :     if (!PyCFunction_Check(op)) {
     142           0 :         PyErr_BadInternalCall();
     143           0 :         return -1;
     144             :     }
     145           0 :     return PyCFunction_GET_FLAGS(op);
     146             : }
     147             : 
     148             : PyTypeObject *
     149           0 : PyCMethod_GetClass(PyObject *op)
     150             : {
     151           0 :     if (!PyCFunction_Check(op)) {
     152           0 :         PyErr_BadInternalCall();
     153           0 :         return NULL;
     154             :     }
     155           0 :     return PyCFunction_GET_CLASS(op);
     156             : }
     157             : 
     158             : /* Methods (the standard built-in methods, that is) */
     159             : 
     160             : static void
     161    31300200 : meth_dealloc(PyCFunctionObject *m)
     162             : {
     163             :     // The Py_TRASHCAN mechanism requires that we be able to
     164             :     // call PyObject_GC_UnTrack twice on an object.
     165    31300200 :     PyObject_GC_UnTrack(m);
     166    31300200 :     Py_TRASHCAN_BEGIN(m, meth_dealloc);
     167    31279800 :     if (m->m_weakreflist != NULL) {
     168           2 :         PyObject_ClearWeakRefs((PyObject*) m);
     169             :     }
     170             :     // Dereference class before m_self: PyCFunction_GET_CLASS accesses
     171             :     // PyMethodDef m_ml, which could be kept alive by m_self
     172    31279800 :     Py_XDECREF(PyCFunction_GET_CLASS(m));
     173    31279800 :     Py_XDECREF(m->m_self);
     174    31279800 :     Py_XDECREF(m->m_module);
     175    31279800 :     PyObject_GC_Del(m);
     176    31279800 :     Py_TRASHCAN_END;
     177    31300200 : }
     178             : 
     179             : static PyObject *
     180       16751 : meth_reduce(PyCFunctionObject *m, PyObject *Py_UNUSED(ignored))
     181             : {
     182       16751 :     if (m->m_self == NULL || PyModule_Check(m->m_self))
     183       16261 :         return PyUnicode_FromString(m->m_ml->ml_name);
     184             : 
     185         490 :     return Py_BuildValue("N(Os)", _PyEval_GetBuiltin(&_Py_ID(getattr)),
     186         490 :                          m->m_self, m->m_ml->ml_name);
     187             : }
     188             : 
     189             : static PyMethodDef meth_methods[] = {
     190             :     {"__reduce__", (PyCFunction)meth_reduce, METH_NOARGS, NULL},
     191             :     {NULL, NULL}
     192             : };
     193             : 
     194             : static PyObject *
     195         214 : meth_get__text_signature__(PyCFunctionObject *m, void *closure)
     196             : {
     197         214 :     return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc);
     198             : }
     199             : 
     200             : static PyObject *
     201       11144 : meth_get__doc__(PyCFunctionObject *m, void *closure)
     202             : {
     203       11144 :     return _PyType_GetDocFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc);
     204             : }
     205             : 
     206             : static PyObject *
     207      174182 : meth_get__name__(PyCFunctionObject *m, void *closure)
     208             : {
     209      174182 :     return PyUnicode_FromString(m->m_ml->ml_name);
     210             : }
     211             : 
     212             : static PyObject *
     213        2844 : meth_get__qualname__(PyCFunctionObject *m, void *closure)
     214             : {
     215             :     /* If __self__ is a module or NULL, return m.__name__
     216             :        (e.g. len.__qualname__ == 'len')
     217             : 
     218             :        If __self__ is a type, return m.__self__.__qualname__ + '.' + m.__name__
     219             :        (e.g. dict.fromkeys.__qualname__ == 'dict.fromkeys')
     220             : 
     221             :        Otherwise return type(m.__self__).__qualname__ + '.' + m.__name__
     222             :        (e.g. [].append.__qualname__ == 'list.append') */
     223             :     PyObject *type, *type_qualname, *res;
     224             : 
     225        2844 :     if (m->m_self == NULL || PyModule_Check(m->m_self))
     226        2015 :         return PyUnicode_FromString(m->m_ml->ml_name);
     227             : 
     228         829 :     type = PyType_Check(m->m_self) ? m->m_self : (PyObject*)Py_TYPE(m->m_self);
     229             : 
     230         829 :     type_qualname = PyObject_GetAttr(type, &_Py_ID(__qualname__));
     231         829 :     if (type_qualname == NULL)
     232           0 :         return NULL;
     233             : 
     234         829 :     if (!PyUnicode_Check(type_qualname)) {
     235           0 :         PyErr_SetString(PyExc_TypeError, "<method>.__class__."
     236             :                         "__qualname__ is not a unicode object");
     237           0 :         Py_XDECREF(type_qualname);
     238           0 :         return NULL;
     239             :     }
     240             : 
     241         829 :     res = PyUnicode_FromFormat("%S.%s", type_qualname, m->m_ml->ml_name);
     242         829 :     Py_DECREF(type_qualname);
     243         829 :     return res;
     244             : }
     245             : 
     246             : static int
     247    68948100 : meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
     248             : {
     249    68948100 :     Py_VISIT(PyCFunction_GET_CLASS(m));
     250    68948100 :     Py_VISIT(m->m_self);
     251    68948100 :     Py_VISIT(m->m_module);
     252    68948100 :     return 0;
     253             : }
     254             : 
     255             : static PyObject *
     256        4464 : meth_get__self__(PyCFunctionObject *m, void *closure)
     257             : {
     258             :     PyObject *self;
     259             : 
     260        4464 :     self = PyCFunction_GET_SELF(m);
     261        4464 :     if (self == NULL)
     262           2 :         self = Py_None;
     263        4464 :     Py_INCREF(self);
     264        4464 :     return self;
     265             : }
     266             : 
     267             : static PyGetSetDef meth_getsets [] = {
     268             :     {"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
     269             :     {"__name__", (getter)meth_get__name__, NULL, NULL},
     270             :     {"__qualname__", (getter)meth_get__qualname__, NULL, NULL},
     271             :     {"__self__", (getter)meth_get__self__, NULL, NULL},
     272             :     {"__text_signature__", (getter)meth_get__text_signature__, NULL, NULL},
     273             :     {0}
     274             : };
     275             : 
     276             : #define OFF(x) offsetof(PyCFunctionObject, x)
     277             : 
     278             : static PyMemberDef meth_members[] = {
     279             :     {"__module__",    T_OBJECT,     OFF(m_module), 0},
     280             :     {NULL}
     281             : };
     282             : 
     283             : static PyObject *
     284        4365 : meth_repr(PyCFunctionObject *m)
     285             : {
     286        4365 :     if (m->m_self == NULL || PyModule_Check(m->m_self))
     287        4299 :         return PyUnicode_FromFormat("<built-in function %s>",
     288        4299 :                                    m->m_ml->ml_name);
     289         132 :     return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",
     290          66 :                                m->m_ml->ml_name,
     291          66 :                                Py_TYPE(m->m_self)->tp_name,
     292             :                                m->m_self);
     293             : }
     294             : 
     295             : static PyObject *
     296       28164 : meth_richcompare(PyObject *self, PyObject *other, int op)
     297             : {
     298             :     PyCFunctionObject *a, *b;
     299             :     PyObject *res;
     300             :     int eq;
     301             : 
     302       56312 :     if ((op != Py_EQ && op != Py_NE) ||
     303       56296 :         !PyCFunction_Check(self) ||
     304       28148 :         !PyCFunction_Check(other))
     305             :     {
     306       20693 :         Py_RETURN_NOTIMPLEMENTED;
     307             :     }
     308        7471 :     a = (PyCFunctionObject *)self;
     309        7471 :     b = (PyCFunctionObject *)other;
     310        7471 :     eq = a->m_self == b->m_self;
     311        7471 :     if (eq)
     312        1147 :         eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
     313        7471 :     if (op == Py_EQ)
     314        6358 :         res = eq ? Py_True : Py_False;
     315             :     else
     316        1113 :         res = eq ? Py_False : Py_True;
     317        7471 :     Py_INCREF(res);
     318        7471 :     return res;
     319             : }
     320             : 
     321             : static Py_hash_t
     322      273423 : meth_hash(PyCFunctionObject *a)
     323             : {
     324             :     Py_hash_t x, y;
     325      273423 :     x = _Py_HashPointer(a->m_self);
     326      273423 :     y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
     327      273423 :     x ^= y;
     328      273423 :     if (x == -1)
     329           0 :         x = -2;
     330      273423 :     return x;
     331             : }
     332             : 
     333             : 
     334             : PyTypeObject PyCFunction_Type = {
     335             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     336             :     "builtin_function_or_method",
     337             :     sizeof(PyCFunctionObject),
     338             :     0,
     339             :     (destructor)meth_dealloc,                   /* tp_dealloc */
     340             :     offsetof(PyCFunctionObject, vectorcall),    /* tp_vectorcall_offset */
     341             :     0,                                          /* tp_getattr */
     342             :     0,                                          /* tp_setattr */
     343             :     0,                                          /* tp_as_async */
     344             :     (reprfunc)meth_repr,                        /* tp_repr */
     345             :     0,                                          /* tp_as_number */
     346             :     0,                                          /* tp_as_sequence */
     347             :     0,                                          /* tp_as_mapping */
     348             :     (hashfunc)meth_hash,                        /* tp_hash */
     349             :     cfunction_call,                             /* tp_call */
     350             :     0,                                          /* tp_str */
     351             :     PyObject_GenericGetAttr,                    /* tp_getattro */
     352             :     0,                                          /* tp_setattro */
     353             :     0,                                          /* tp_as_buffer */
     354             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
     355             :     Py_TPFLAGS_HAVE_VECTORCALL,                 /* tp_flags */
     356             :     0,                                          /* tp_doc */
     357             :     (traverseproc)meth_traverse,                /* tp_traverse */
     358             :     0,                                          /* tp_clear */
     359             :     meth_richcompare,                           /* tp_richcompare */
     360             :     offsetof(PyCFunctionObject, m_weakreflist), /* tp_weaklistoffset */
     361             :     0,                                          /* tp_iter */
     362             :     0,                                          /* tp_iternext */
     363             :     meth_methods,                               /* tp_methods */
     364             :     meth_members,                               /* tp_members */
     365             :     meth_getsets,                               /* tp_getset */
     366             :     0,                                          /* tp_base */
     367             :     0,                                          /* tp_dict */
     368             : };
     369             : 
     370             : PyTypeObject PyCMethod_Type = {
     371             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     372             :     .tp_name = "builtin_method",
     373             :     .tp_basicsize = sizeof(PyCMethodObject),
     374             :     .tp_base = &PyCFunction_Type,
     375             : };
     376             : 
     377             : /* Vectorcall functions for each of the PyCFunction calling conventions,
     378             :  * except for METH_VARARGS (possibly combined with METH_KEYWORDS) which
     379             :  * doesn't use vectorcall.
     380             :  *
     381             :  * First, common helpers
     382             :  */
     383             : 
     384             : static inline int
     385    46636700 : cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames)
     386             : {
     387    46636700 :     assert(!_PyErr_Occurred(tstate));
     388    46636700 :     assert(PyCFunction_Check(func));
     389    46636700 :     if (kwnames && PyTuple_GET_SIZE(kwnames)) {
     390          56 :         PyObject *funcstr = _PyObject_FunctionStr(func);
     391          56 :         if (funcstr != NULL) {
     392          56 :             _PyErr_Format(tstate, PyExc_TypeError,
     393             :                          "%U takes no keyword arguments", funcstr);
     394          56 :             Py_DECREF(funcstr);
     395             :         }
     396          56 :         return -1;
     397             :     }
     398    46636600 :     return 0;
     399             : }
     400             : 
     401             : typedef void (*funcptr)(void);
     402             : 
     403             : static inline funcptr
     404    58780200 : cfunction_enter_call(PyThreadState *tstate, PyObject *func)
     405             : {
     406    58780200 :     if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
     407          29 :         return NULL;
     408             :     }
     409    58780200 :     return (funcptr)PyCFunction_GET_FUNCTION(func);
     410             : }
     411             : 
     412             : /* Now the actual vectorcall functions */
     413             : static PyObject *
     414     7965450 : cfunction_vectorcall_FASTCALL(
     415             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     416             : {
     417     7965450 :     PyThreadState *tstate = _PyThreadState_GET();
     418     7965450 :     if (cfunction_check_kwargs(tstate, func, kwnames)) {
     419          14 :         return NULL;
     420             :     }
     421     7965440 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     422             :     _PyCFunctionFast meth = (_PyCFunctionFast)
     423     7965440 :                             cfunction_enter_call(tstate, func);
     424     7965440 :     if (meth == NULL) {
     425           0 :         return NULL;
     426             :     }
     427     7965440 :     PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs);
     428     7965440 :     _Py_LeaveRecursiveCallTstate(tstate);
     429     7965440 :     return result;
     430             : }
     431             : 
     432             : static PyObject *
     433     8400100 : cfunction_vectorcall_FASTCALL_KEYWORDS(
     434             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     435             : {
     436     8400100 :     PyThreadState *tstate = _PyThreadState_GET();
     437     8400100 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     438             :     _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
     439     8400100 :                                         cfunction_enter_call(tstate, func);
     440     8400100 :     if (meth == NULL) {
     441           0 :         return NULL;
     442             :     }
     443     8400100 :     PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames);
     444     8400090 :     _Py_LeaveRecursiveCallTstate(tstate);
     445     8400090 :     return result;
     446             : }
     447             : 
     448             : static PyObject *
     449     3743920 : cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD(
     450             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     451             : {
     452     3743920 :     PyThreadState *tstate = _PyThreadState_GET();
     453     3743920 :     PyTypeObject *cls = PyCFunction_GET_CLASS(func);
     454     3743920 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     455     3743920 :     PyCMethod meth = (PyCMethod)cfunction_enter_call(tstate, func);
     456     3743920 :     if (meth == NULL) {
     457           0 :         return NULL;
     458             :     }
     459     3743920 :     PyObject *result = meth(PyCFunction_GET_SELF(func), cls, args, nargs, kwnames);
     460     3743920 :     _Py_LeaveRecursiveCallTstate(tstate);
     461     3743920 :     return result;
     462             : }
     463             : 
     464             : static PyObject *
     465    22233100 : cfunction_vectorcall_NOARGS(
     466             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     467             : {
     468    22233100 :     PyThreadState *tstate = _PyThreadState_GET();
     469    22233100 :     if (cfunction_check_kwargs(tstate, func, kwnames)) {
     470          27 :         return NULL;
     471             :     }
     472    22233100 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     473    22233100 :     if (nargs != 0) {
     474         199 :         PyObject *funcstr = _PyObject_FunctionStr(func);
     475         199 :         if (funcstr != NULL) {
     476         199 :             _PyErr_Format(tstate, PyExc_TypeError,
     477             :                 "%U takes no arguments (%zd given)", funcstr, nargs);
     478         199 :             Py_DECREF(funcstr);
     479             :         }
     480         199 :         return NULL;
     481             :     }
     482    22232900 :     PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
     483    22232900 :     if (meth == NULL) {
     484           7 :         return NULL;
     485             :     }
     486    22232900 :     PyObject *result = _PyCFunction_TrampolineCall(
     487             :         meth, PyCFunction_GET_SELF(func), NULL);
     488    22232900 :     _Py_LeaveRecursiveCallTstate(tstate);
     489    22232900 :     return result;
     490             : }
     491             : 
     492             : static PyObject *
     493    16438100 : cfunction_vectorcall_O(
     494             :     PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
     495             : {
     496    16438100 :     PyThreadState *tstate = _PyThreadState_GET();
     497    16438100 :     if (cfunction_check_kwargs(tstate, func, kwnames)) {
     498          15 :         return NULL;
     499             :     }
     500    16438100 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
     501    16438100 :     if (nargs != 1) {
     502         247 :         PyObject *funcstr = _PyObject_FunctionStr(func);
     503         247 :         if (funcstr != NULL) {
     504         247 :             _PyErr_Format(tstate, PyExc_TypeError,
     505             :                 "%U takes exactly one argument (%zd given)", funcstr, nargs);
     506         247 :             Py_DECREF(funcstr);
     507             :         }
     508         247 :         return NULL;
     509             :     }
     510    16437900 :     PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
     511    16437900 :     if (meth == NULL) {
     512          22 :         return NULL;
     513             :     }
     514    16437800 :     PyObject *result = _PyCFunction_TrampolineCall(
     515             :         meth, PyCFunction_GET_SELF(func), args[0]);
     516    16437800 :     _Py_LeaveRecursiveCallTstate(tstate);
     517    16437800 :     return result;
     518             : }
     519             : 
     520             : 
     521             : static PyObject *
     522    19399600 : cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs)
     523             : {
     524    19399600 :     assert(kwargs == NULL || PyDict_Check(kwargs));
     525             : 
     526    19399600 :     PyThreadState *tstate = _PyThreadState_GET();
     527    19399600 :     assert(!_PyErr_Occurred(tstate));
     528             : 
     529    19399600 :     int flags = PyCFunction_GET_FLAGS(func);
     530    19399600 :     if (!(flags & METH_VARARGS)) {
     531             :         /* If this is not a METH_VARARGS function, delegate to vectorcall */
     532           0 :         return PyVectorcall_Call(func, args, kwargs);
     533             :     }
     534             : 
     535             :     /* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer
     536             :      * is NULL. This is intentional, since vectorcall would be slower. */
     537    19399600 :     PyCFunction meth = PyCFunction_GET_FUNCTION(func);
     538    19399600 :     PyObject *self = PyCFunction_GET_SELF(func);
     539             : 
     540             :     PyObject *result;
     541    19399600 :     if (flags & METH_KEYWORDS) {
     542    15724600 :         result = _PyCFunctionWithKeywords_TrampolineCall(
     543             :             (*(PyCFunctionWithKeywords)(void(*)(void))meth),
     544             :             self, args, kwargs);
     545             :     }
     546             :     else {
     547     3675000 :         if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
     548           5 :             _PyErr_Format(tstate, PyExc_TypeError,
     549             :                           "%.200s() takes no keyword arguments",
     550           5 :                           ((PyCFunctionObject*)func)->m_ml->ml_name);
     551           5 :             return NULL;
     552             :         }
     553     3674990 :         result = _PyCFunction_TrampolineCall(meth, self, args);
     554             :     }
     555    19399600 :     return _Py_CheckFunctionResult(tstate, func, result, NULL);
     556             : }
     557             : 
     558             : #if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
     559             : #include <emscripten.h>
     560             : 
     561             : EM_JS(PyObject*, _PyCFunctionWithKeywords_TrampolineCall, (PyCFunctionWithKeywords func, PyObject *self, PyObject *args, PyObject *kw), {
     562             :     return wasmTable.get(func)(self, args, kw);
     563             : });
     564             : #endif

Generated by: LCOV version 1.14