Skip to content
Merged
Prev Previous commit
Next Next commit
Simplify function vector call using new _PyEval_Vector.
  • Loading branch information
markshannon committed Jan 29, 2021
commit b6b6dcfaea94ab4d1ee3b536a71e11f4e3135935
3 changes: 1 addition & 2 deletions Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ extern PyObject *
_PyEval_Vector(PyThreadState *tstate,
PyFrameConstructor *desc,
PyObject* const* args, size_t argcount,
PyObject *const *kwnames, PyObject *const *kwargs,
Py_ssize_t kwcount);
PyObject *kwnames, PyObject *const *kwargs);

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
extern int _PyEval_ThreadsInitialized(PyInterpreterState *interp);
Expand Down
70 changes: 3 additions & 67 deletions Objects/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,83 +328,19 @@ PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs)

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

static PyObject* _Py_HOT_FUNCTION
function_code_fastcall(PyThreadState *tstate, PyCodeObject *co,
PyObject *const *args, Py_ssize_t nargs,
PyFunctionObject *func)
{
assert(tstate != NULL);
assert(func != NULL);

PyFrameObject *f = _PyFrame_New_NoTrack(tstate, &func->func_descr);
if (f == NULL) {
return NULL;
}

PyObject **fastlocals = f->f_localsplus;

for (Py_ssize_t i = 0; i < nargs; i++) {
Py_INCREF(*args);
fastlocals[i] = *args++;
}
PyObject *result = _PyEval_EvalFrame(tstate, f, 0);

if (Py_REFCNT(f) > 1) {
Py_DECREF(f);
_PyObject_GC_TRACK(f);
}
else {
++tstate->recursion_depth;
Py_DECREF(f);
--tstate->recursion_depth;
}
return result;
}


PyObject *
_PyFunction_Vectorcall(PyObject *func, PyObject* const* stack,
size_t nargsf, PyObject *kwnames)
{
assert(PyFunction_Check(func));
assert(kwnames == NULL || PyTuple_CheckExact(kwnames));

PyFrameConstructor *f = &((PyFunctionObject *)func)->func_descr;
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
assert(nargs >= 0);
Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
assert((nargs == 0 && nkwargs == 0) || stack != NULL);
/* kwnames must only contain strings and all keys must be unique */

PyThreadState *tstate = _PyThreadState_GET();
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);

if (co->co_kwonlyargcount == 0 && nkwargs == 0 &&
(co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
{
if (argdefs == NULL && co->co_argcount == nargs) {
return function_code_fastcall(tstate, co, stack, nargs, (PyFunctionObject *)func);
}
else if (nargs == 0 && argdefs != NULL
&& co->co_argcount == PyTuple_GET_SIZE(argdefs)) {
/* function called with no arguments, but all parameters have
a default value: use default values as arguments .*/
stack = _PyTuple_ITEMS(argdefs);
return function_code_fastcall(tstate, co,
stack, PyTuple_GET_SIZE(argdefs),
(PyFunctionObject *)func);
}
}

return _PyEval_EvalCode(tstate,
PyFunction_AS_FRAME_CONSTRUCTOR(func),
stack, nargs,
nkwargs ? _PyTuple_ITEMS(kwnames) : NULL,
stack + nargs,
nkwargs, 1);
assert(nargs == 0 || stack != NULL);
return _PyEval_Vector(tstate, f, stack, nargs, kwnames, stack+nargs);
}


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

/* External interface to call any callable object.
Expand Down
20 changes: 14 additions & 6 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -4599,11 +4599,20 @@ PyFrameObject *
_PyEval_MakeFrameVector(PyThreadState *tstate,
PyFrameConstructor *desc,
PyObject *const *args, Py_ssize_t argcount,
PyObject *const *kwnames, PyObject *const *kwargs,
Py_ssize_t kwcount)
PyObject *kwnames, PyObject *const *kwargs)
{
PyObject *const *names;
Py_ssize_t kwcount;
if (kwnames == NULL) {
names = NULL;
kwcount = 0;
}
else {
names = &PyTuple_GET_ITEM(kwnames, 0);
kwcount = PyTuple_GET_SIZE(kwnames);
}
return _PyEval_MakeFrame(tstate, desc,
args, argcount, kwnames,
args, argcount, names,
kwargs, kwcount, 1);
}

Expand Down Expand Up @@ -4682,10 +4691,9 @@ PyObject *
_PyEval_Vector(PyThreadState *tstate,
PyFrameConstructor *desc,
PyObject* const* args, size_t argcount,
PyObject *const *kwnames, PyObject *const *kwargs,
Py_ssize_t kwcount)
PyObject *kwnames, PyObject *const *kwargs)
{
PyFrameObject *f = _PyEval_MakeFrameVector(tstate, desc, args, argcount, kwnames, kwargs, kwcount);
PyFrameObject *f = _PyEval_MakeFrameVector(tstate, desc, args, argcount, kwnames, kwargs);
if (f == NULL) {
return NULL;
}
Expand Down