aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Objects/methodobject.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:30 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:30 +0300
commit2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch)
tree012bb94d777798f1f56ac1cec429509766d05181 /contrib/tools/python3/src/Objects/methodobject.c
parent6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff)
downloadydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Objects/methodobject.c')
-rw-r--r--contrib/tools/python3/src/Objects/methodobject.c602
1 files changed, 301 insertions, 301 deletions
diff --git a/contrib/tools/python3/src/Objects/methodobject.c b/contrib/tools/python3/src/Objects/methodobject.c
index 2df63cfdf6..bae0664d8d 100644
--- a/contrib/tools/python3/src/Objects/methodobject.c
+++ b/contrib/tools/python3/src/Objects/methodobject.c
@@ -2,33 +2,33 @@
/* Method object implementation */
#include "Python.h"
-#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
-#include "pycore_object.h"
-#include "pycore_pyerrors.h"
-#include "pycore_pystate.h" // _PyThreadState_GET()
-#include "structmember.h" // PyMemberDef
+#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
+#include "pycore_object.h"
+#include "pycore_pyerrors.h"
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "structmember.h" // PyMemberDef
/* undefine macro trampoline to PyCFunction_NewEx */
#undef PyCFunction_New
-/* undefine macro trampoline to PyCMethod_New */
-#undef PyCFunction_NewEx
-
-/* Forward declarations */
-static PyObject * cfunction_vectorcall_FASTCALL(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
-static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
-static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
-static PyObject * cfunction_vectorcall_NOARGS(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
-static PyObject * cfunction_vectorcall_O(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
-static PyObject * cfunction_call(
- PyObject *func, PyObject *args, PyObject *kwargs);
-
-
-PyObject *
+/* undefine macro trampoline to PyCMethod_New */
+#undef PyCFunction_NewEx
+
+/* Forward declarations */
+static PyObject * cfunction_vectorcall_FASTCALL(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
+static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
+static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
+static PyObject * cfunction_vectorcall_NOARGS(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
+static PyObject * cfunction_vectorcall_O(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
+static PyObject * cfunction_call(
+ PyObject *func, PyObject *args, PyObject *kwargs);
+
+
+PyObject *
PyCFunction_New(PyMethodDef *ml, PyObject *self)
{
return PyCFunction_NewEx(ml, self, NULL);
@@ -37,80 +37,80 @@ PyCFunction_New(PyMethodDef *ml, PyObject *self)
PyObject *
PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
{
- return PyCMethod_New(ml, self, module, NULL);
-}
-
-PyObject *
-PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *cls)
-{
- /* Figure out correct vectorcall function to use */
- vectorcallfunc vectorcall;
- switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS |
- METH_O | METH_KEYWORDS | METH_METHOD))
- {
- case METH_VARARGS:
- case METH_VARARGS | METH_KEYWORDS:
- /* For METH_VARARGS functions, it's more efficient to use tp_call
- * instead of vectorcall. */
- vectorcall = NULL;
- break;
- case METH_FASTCALL:
- vectorcall = cfunction_vectorcall_FASTCALL;
- break;
- case METH_FASTCALL | METH_KEYWORDS:
- vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS;
- break;
- case METH_NOARGS:
- vectorcall = cfunction_vectorcall_NOARGS;
- break;
- case METH_O:
- vectorcall = cfunction_vectorcall_O;
- break;
- case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
- vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD;
- break;
- default:
- PyErr_Format(PyExc_SystemError,
- "%s() method: bad call flags", ml->ml_name);
- return NULL;
- }
-
- PyCFunctionObject *op = NULL;
-
- if (ml->ml_flags & METH_METHOD) {
- if (!cls) {
- PyErr_SetString(PyExc_SystemError,
- "attempting to create PyCMethod with a METH_METHOD "
- "flag but no class");
- return NULL;
- }
- PyCMethodObject *om = PyObject_GC_New(PyCMethodObject, &PyCMethod_Type);
- if (om == NULL) {
- return NULL;
- }
- Py_INCREF(cls);
- om->mm_class = cls;
- op = (PyCFunctionObject *)om;
- } else {
- if (cls) {
- PyErr_SetString(PyExc_SystemError,
- "attempting to create PyCFunction with class "
- "but no METH_METHOD flag");
- return NULL;
- }
+ return PyCMethod_New(ml, self, module, NULL);
+}
+
+PyObject *
+PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *cls)
+{
+ /* Figure out correct vectorcall function to use */
+ vectorcallfunc vectorcall;
+ switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS |
+ METH_O | METH_KEYWORDS | METH_METHOD))
+ {
+ case METH_VARARGS:
+ case METH_VARARGS | METH_KEYWORDS:
+ /* For METH_VARARGS functions, it's more efficient to use tp_call
+ * instead of vectorcall. */
+ vectorcall = NULL;
+ break;
+ case METH_FASTCALL:
+ vectorcall = cfunction_vectorcall_FASTCALL;
+ break;
+ case METH_FASTCALL | METH_KEYWORDS:
+ vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS;
+ break;
+ case METH_NOARGS:
+ vectorcall = cfunction_vectorcall_NOARGS;
+ break;
+ case METH_O:
+ vectorcall = cfunction_vectorcall_O;
+ break;
+ case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
+ vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD;
+ break;
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "%s() method: bad call flags", ml->ml_name);
+ return NULL;
+ }
+
+ PyCFunctionObject *op = NULL;
+
+ if (ml->ml_flags & METH_METHOD) {
+ if (!cls) {
+ PyErr_SetString(PyExc_SystemError,
+ "attempting to create PyCMethod with a METH_METHOD "
+ "flag but no class");
+ return NULL;
+ }
+ PyCMethodObject *om = PyObject_GC_New(PyCMethodObject, &PyCMethod_Type);
+ if (om == NULL) {
+ return NULL;
+ }
+ Py_INCREF(cls);
+ om->mm_class = cls;
+ op = (PyCFunctionObject *)om;
+ } else {
+ if (cls) {
+ PyErr_SetString(PyExc_SystemError,
+ "attempting to create PyCFunction with class "
+ "but no METH_METHOD flag");
+ return NULL;
+ }
op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
- if (op == NULL) {
+ if (op == NULL) {
return NULL;
- }
+ }
}
-
+
op->m_weakreflist = NULL;
op->m_ml = ml;
Py_XINCREF(self);
op->m_self = self;
Py_XINCREF(module);
op->m_module = module;
- op->vectorcall = vectorcall;
+ op->vectorcall = vectorcall;
_PyObject_GC_TRACK(op);
return (PyObject *)op;
}
@@ -145,39 +145,39 @@ PyCFunction_GetFlags(PyObject *op)
return PyCFunction_GET_FLAGS(op);
}
-PyTypeObject *
-PyCMethod_GetClass(PyObject *op)
-{
- if (!PyCFunction_Check(op)) {
- PyErr_BadInternalCall();
- return NULL;
- }
- return PyCFunction_GET_CLASS(op);
-}
-
+PyTypeObject *
+PyCMethod_GetClass(PyObject *op)
+{
+ if (!PyCFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return PyCFunction_GET_CLASS(op);
+}
+
/* Methods (the standard built-in methods, that is) */
static void
meth_dealloc(PyCFunctionObject *m)
{
- // The Py_TRASHCAN mechanism requires that we be able to
- // call PyObject_GC_UnTrack twice on an object.
- PyObject_GC_UnTrack(m);
- Py_TRASHCAN_BEGIN(m, meth_dealloc);
+ // The Py_TRASHCAN mechanism requires that we be able to
+ // call PyObject_GC_UnTrack twice on an object.
+ PyObject_GC_UnTrack(m);
+ Py_TRASHCAN_BEGIN(m, meth_dealloc);
if (m->m_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject*) m);
}
- // Dereference class before m_self: PyCFunction_GET_CLASS accesses
- // PyMethodDef m_ml, which could be kept alive by m_self
- Py_XDECREF(PyCFunction_GET_CLASS(m));
+ // Dereference class before m_self: PyCFunction_GET_CLASS accesses
+ // PyMethodDef m_ml, which could be kept alive by m_self
+ Py_XDECREF(PyCFunction_GET_CLASS(m));
Py_XDECREF(m->m_self);
Py_XDECREF(m->m_module);
- PyObject_GC_Del(m);
- Py_TRASHCAN_END;
+ PyObject_GC_Del(m);
+ Py_TRASHCAN_END;
}
static PyObject *
-meth_reduce(PyCFunctionObject *m, PyObject *Py_UNUSED(ignored))
+meth_reduce(PyCFunctionObject *m, PyObject *Py_UNUSED(ignored))
{
_Py_IDENTIFIER(getattr);
@@ -249,7 +249,7 @@ meth_get__qualname__(PyCFunctionObject *m, void *closure)
static int
meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
{
- Py_VISIT(PyCFunction_GET_CLASS(m));
+ Py_VISIT(PyCFunction_GET_CLASS(m));
Py_VISIT(m->m_self);
Py_VISIT(m->m_module);
return 0;
@@ -279,7 +279,7 @@ static PyGetSetDef meth_getsets [] = {
#define OFF(x) offsetof(PyCFunctionObject, x)
static PyMemberDef meth_members[] = {
- {"__module__", T_OBJECT, OFF(m_module), 0},
+ {"__module__", T_OBJECT, OFF(m_module), 0},
{NULL}
};
@@ -291,7 +291,7 @@ meth_repr(PyCFunctionObject *m)
m->m_ml->ml_name);
return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",
m->m_ml->ml_name,
- Py_TYPE(m->m_self)->tp_name,
+ Py_TYPE(m->m_self)->tp_name,
m->m_self);
}
@@ -325,7 +325,7 @@ static Py_hash_t
meth_hash(PyCFunctionObject *a)
{
Py_hash_t x, y;
- x = _Py_HashPointer(a->m_self);
+ x = _Py_HashPointer(a->m_self);
y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
x ^= y;
if (x == -1)
@@ -340,22 +340,22 @@ PyTypeObject PyCFunction_Type = {
sizeof(PyCFunctionObject),
0,
(destructor)meth_dealloc, /* tp_dealloc */
- offsetof(PyCFunctionObject, vectorcall), /* tp_vectorcall_offset */
+ offsetof(PyCFunctionObject, vectorcall), /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
- 0, /* tp_as_async */
+ 0, /* tp_as_async */
(reprfunc)meth_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)meth_hash, /* tp_hash */
- cfunction_call, /* tp_call */
+ cfunction_call, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */
0, /* tp_doc */
(traverseproc)meth_traverse, /* tp_traverse */
0, /* tp_clear */
@@ -370,186 +370,186 @@ PyTypeObject PyCFunction_Type = {
0, /* tp_dict */
};
-PyTypeObject PyCMethod_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- .tp_name = "builtin_method",
- .tp_basicsize = sizeof(PyCMethodObject),
- .tp_base = &PyCFunction_Type,
-};
-
-/* Vectorcall functions for each of the PyCFunction calling conventions,
- * except for METH_VARARGS (possibly combined with METH_KEYWORDS) which
- * doesn't use vectorcall.
- *
- * First, common helpers
- */
-
-static inline int
-cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames)
-{
- assert(!_PyErr_Occurred(tstate));
- assert(PyCFunction_Check(func));
- if (kwnames && PyTuple_GET_SIZE(kwnames)) {
- PyObject *funcstr = _PyObject_FunctionStr(func);
- if (funcstr != NULL) {
- _PyErr_Format(tstate, PyExc_TypeError,
- "%U takes no keyword arguments", funcstr);
- Py_DECREF(funcstr);
- }
- return -1;
- }
- return 0;
-}
-
-typedef void (*funcptr)(void);
-
-static inline funcptr
-cfunction_enter_call(PyThreadState *tstate, PyObject *func)
-{
- if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
- return NULL;
- }
- return (funcptr)PyCFunction_GET_FUNCTION(func);
-}
-
-/* Now the actual vectorcall functions */
-static PyObject *
-cfunction_vectorcall_FASTCALL(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
-{
- PyThreadState *tstate = _PyThreadState_GET();
- if (cfunction_check_kwargs(tstate, func, kwnames)) {
- return NULL;
- }
- Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
- _PyCFunctionFast meth = (_PyCFunctionFast)
- cfunction_enter_call(tstate, func);
- if (meth == NULL) {
- return NULL;
- }
- PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs);
- _Py_LeaveRecursiveCall(tstate);
- return result;
-}
-
-static PyObject *
-cfunction_vectorcall_FASTCALL_KEYWORDS(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
-{
- PyThreadState *tstate = _PyThreadState_GET();
- Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
- _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
- cfunction_enter_call(tstate, func);
- if (meth == NULL) {
- return NULL;
- }
- PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames);
- _Py_LeaveRecursiveCall(tstate);
- return result;
-}
-
-static PyObject *
-cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
-{
- PyThreadState *tstate = _PyThreadState_GET();
- PyTypeObject *cls = PyCFunction_GET_CLASS(func);
- Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
- PyCMethod meth = (PyCMethod)cfunction_enter_call(tstate, func);
- if (meth == NULL) {
- return NULL;
- }
- PyObject *result = meth(PyCFunction_GET_SELF(func), cls, args, nargs, kwnames);
- _Py_LeaveRecursiveCall(tstate);
- return result;
-}
-
-static PyObject *
-cfunction_vectorcall_NOARGS(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
-{
- PyThreadState *tstate = _PyThreadState_GET();
- if (cfunction_check_kwargs(tstate, func, kwnames)) {
- return NULL;
- }
- Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
- if (nargs != 0) {
- PyObject *funcstr = _PyObject_FunctionStr(func);
- if (funcstr != NULL) {
- _PyErr_Format(tstate, PyExc_TypeError,
- "%U takes no arguments (%zd given)", funcstr, nargs);
- Py_DECREF(funcstr);
- }
- return NULL;
- }
- PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
- if (meth == NULL) {
- return NULL;
- }
- PyObject *result = meth(PyCFunction_GET_SELF(func), NULL);
- _Py_LeaveRecursiveCall(tstate);
- return result;
-}
-
-static PyObject *
-cfunction_vectorcall_O(
- PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
-{
- PyThreadState *tstate = _PyThreadState_GET();
- if (cfunction_check_kwargs(tstate, func, kwnames)) {
- return NULL;
- }
- Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
- if (nargs != 1) {
- PyObject *funcstr = _PyObject_FunctionStr(func);
- if (funcstr != NULL) {
- _PyErr_Format(tstate, PyExc_TypeError,
- "%U takes exactly one argument (%zd given)", funcstr, nargs);
- Py_DECREF(funcstr);
- }
- return NULL;
- }
- PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
- if (meth == NULL) {
- return NULL;
- }
- PyObject *result = meth(PyCFunction_GET_SELF(func), args[0]);
- _Py_LeaveRecursiveCall(tstate);
- return result;
-}
-
-
-static PyObject *
-cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs)
-{
- assert(kwargs == NULL || PyDict_Check(kwargs));
-
- PyThreadState *tstate = _PyThreadState_GET();
- assert(!_PyErr_Occurred(tstate));
-
- int flags = PyCFunction_GET_FLAGS(func);
- if (!(flags & METH_VARARGS)) {
- /* If this is not a METH_VARARGS function, delegate to vectorcall */
- return PyVectorcall_Call(func, args, kwargs);
- }
-
- /* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer
- * is NULL. This is intentional, since vectorcall would be slower. */
- PyCFunction meth = PyCFunction_GET_FUNCTION(func);
- PyObject *self = PyCFunction_GET_SELF(func);
-
- PyObject *result;
- if (flags & METH_KEYWORDS) {
- result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs);
- }
- else {
- if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
- _PyErr_Format(tstate, PyExc_TypeError,
- "%.200s() takes no keyword arguments",
- ((PyCFunctionObject*)func)->m_ml->ml_name);
- return NULL;
- }
- result = meth(self, args);
- }
- return _Py_CheckFunctionResult(tstate, func, result, NULL);
-}
+PyTypeObject PyCMethod_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ .tp_name = "builtin_method",
+ .tp_basicsize = sizeof(PyCMethodObject),
+ .tp_base = &PyCFunction_Type,
+};
+
+/* Vectorcall functions for each of the PyCFunction calling conventions,
+ * except for METH_VARARGS (possibly combined with METH_KEYWORDS) which
+ * doesn't use vectorcall.
+ *
+ * First, common helpers
+ */
+
+static inline int
+cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames)
+{
+ assert(!_PyErr_Occurred(tstate));
+ assert(PyCFunction_Check(func));
+ if (kwnames && PyTuple_GET_SIZE(kwnames)) {
+ PyObject *funcstr = _PyObject_FunctionStr(func);
+ if (funcstr != NULL) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U takes no keyword arguments", funcstr);
+ Py_DECREF(funcstr);
+ }
+ return -1;
+ }
+ return 0;
+}
+
+typedef void (*funcptr)(void);
+
+static inline funcptr
+cfunction_enter_call(PyThreadState *tstate, PyObject *func)
+{
+ if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
+ return NULL;
+ }
+ return (funcptr)PyCFunction_GET_FUNCTION(func);
+}
+
+/* Now the actual vectorcall functions */
+static PyObject *
+cfunction_vectorcall_FASTCALL(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (cfunction_check_kwargs(tstate, func, kwnames)) {
+ return NULL;
+ }
+ Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+ _PyCFunctionFast meth = (_PyCFunctionFast)
+ cfunction_enter_call(tstate, func);
+ if (meth == NULL) {
+ return NULL;
+ }
+ PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs);
+ _Py_LeaveRecursiveCall(tstate);
+ return result;
+}
+
+static PyObject *
+cfunction_vectorcall_FASTCALL_KEYWORDS(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+ _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
+ cfunction_enter_call(tstate, func);
+ if (meth == NULL) {
+ return NULL;
+ }
+ PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames);
+ _Py_LeaveRecursiveCall(tstate);
+ return result;
+}
+
+static PyObject *
+cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ PyTypeObject *cls = PyCFunction_GET_CLASS(func);
+ Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+ PyCMethod meth = (PyCMethod)cfunction_enter_call(tstate, func);
+ if (meth == NULL) {
+ return NULL;
+ }
+ PyObject *result = meth(PyCFunction_GET_SELF(func), cls, args, nargs, kwnames);
+ _Py_LeaveRecursiveCall(tstate);
+ return result;
+}
+
+static PyObject *
+cfunction_vectorcall_NOARGS(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (cfunction_check_kwargs(tstate, func, kwnames)) {
+ return NULL;
+ }
+ Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+ if (nargs != 0) {
+ PyObject *funcstr = _PyObject_FunctionStr(func);
+ if (funcstr != NULL) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U takes no arguments (%zd given)", funcstr, nargs);
+ Py_DECREF(funcstr);
+ }
+ return NULL;
+ }
+ PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
+ if (meth == NULL) {
+ return NULL;
+ }
+ PyObject *result = meth(PyCFunction_GET_SELF(func), NULL);
+ _Py_LeaveRecursiveCall(tstate);
+ return result;
+}
+
+static PyObject *
+cfunction_vectorcall_O(
+ PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (cfunction_check_kwargs(tstate, func, kwnames)) {
+ return NULL;
+ }
+ Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+ if (nargs != 1) {
+ PyObject *funcstr = _PyObject_FunctionStr(func);
+ if (funcstr != NULL) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U takes exactly one argument (%zd given)", funcstr, nargs);
+ Py_DECREF(funcstr);
+ }
+ return NULL;
+ }
+ PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
+ if (meth == NULL) {
+ return NULL;
+ }
+ PyObject *result = meth(PyCFunction_GET_SELF(func), args[0]);
+ _Py_LeaveRecursiveCall(tstate);
+ return result;
+}
+
+
+static PyObject *
+cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs)
+{
+ assert(kwargs == NULL || PyDict_Check(kwargs));
+
+ PyThreadState *tstate = _PyThreadState_GET();
+ assert(!_PyErr_Occurred(tstate));
+
+ int flags = PyCFunction_GET_FLAGS(func);
+ if (!(flags & METH_VARARGS)) {
+ /* If this is not a METH_VARARGS function, delegate to vectorcall */
+ return PyVectorcall_Call(func, args, kwargs);
+ }
+
+ /* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer
+ * is NULL. This is intentional, since vectorcall would be slower. */
+ PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ PyObject *self = PyCFunction_GET_SELF(func);
+
+ PyObject *result;
+ if (flags & METH_KEYWORDS) {
+ result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs);
+ }
+ else {
+ if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%.200s() takes no keyword arguments",
+ ((PyCFunctionObject*)func)->m_ml->ml_name);
+ return NULL;
+ }
+ result = meth(self, args);
+ }
+ return _Py_CheckFunctionResult(tstate, func, result, NULL);
+}