◐ Shell
reader mode source ↗
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
69 changes: 7 additions & 62 deletions Objects/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
#include "frameobject.h"


static PyObject *
cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs);

static PyObject *const *
_PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs,
PyObject **p_kwnames);
Expand Down Expand Up @@ -236,11 +233,6 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
if (_PyVectorcall_Function(callable) != NULL) {
return PyVectorcall_Call(callable, args, kwargs);
}
else if (PyCFunction_Check(callable)) {
/* This must be a METH_VARARGS function, otherwise we would be
* in the previous case */
return cfunction_call_varargs(callable, args, kwargs);
}
else {
call = callable->ob_type->tp_call;
if (call == NULL) {
Expand All @@ -261,6 +253,13 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
}


/* --- PyFunction call functions ---------------------------------- */

static PyObject* _Py_HOT_FUNCTION
Expand Down Expand Up @@ -364,60 +363,6 @@ _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack,
}


/* --- PyCFunction call functions --------------------------------- */

static PyObject *
cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs)
{
assert(!PyErr_Occurred());
assert(kwargs == NULL || PyDict_Check(kwargs));

PyCFunction meth = PyCFunction_GET_FUNCTION(func);
PyObject *self = PyCFunction_GET_SELF(func);
PyObject *result;

assert(PyCFunction_GET_FLAGS(func) & METH_VARARGS);
if (PyCFunction_GET_FLAGS(func) & METH_KEYWORDS) {
if (Py_EnterRecursiveCall(" while calling a Python object")) {
return NULL;
}

result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs);

Py_LeaveRecursiveCall();
}
else {
if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
((PyCFunctionObject*)func)->m_ml->ml_name);
return NULL;
}

if (Py_EnterRecursiveCall(" while calling a Python object")) {
return NULL;
}

result = (*meth)(self, args);

Py_LeaveRecursiveCall();
}

return _Py_CheckFunctionResult(func, result, NULL);
}


PyObject *
PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwargs)
{
/* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer
* is NULL. This is intentional, since vectorcall would be slower. */
if (PyCFunction_GET_FLAGS(func) & METH_VARARGS) {
return cfunction_call_varargs(func, args, kwargs);
}
return PyVectorcall_Call(func, args, kwargs);
}


/* --- More complex call functions -------------------------------- */

/* External interface to call any callable object.
Expand Down
37 changes: 36 additions & 1 deletion Objects/methodobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ 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);


PyObject *
Expand Up @@ -312,7 +314,7 @@ PyTypeObject PyCFunction_Type = {
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)meth_hash, /* tp_hash */
PyCFunction_Call, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
Expand Down Expand Up @@ -482,3 +484,36 @@ cfunction_vectorcall_O(
Py_LeaveRecursiveCall();
return result;
}
2 changes: 1 addition & 1 deletion Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -4997,7 +4997,7 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject
PyObject *result;

if (PyCFunction_Check(func)) {
C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
return result;
}
else if (Py_TYPE(func) == &PyMethodDescr_Type) {
Expand Down
2 changes: 1 addition & 1 deletion Tools/gdb/libpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -1564,7 +1564,7 @@ def is_other_python_frame(self):
return False

if (caller.startswith('cfunction_vectorcall_') or
caller == 'cfunction_call_varargs'):
arg_name = 'func'
# Within that frame:
# "func" is the local containing the PyObject* of the
Expand Down
Toggle all file notes Toggle all file annotations