mirror of
https://github.com/python/cpython.git
synced 2025-09-09 18:32:22 +00:00
gh-98003: Inline call frames for CALL_FUNCTION_EX (GH-98004)
This commit is contained in:
parent
accb417c33
commit
ed95e8cbd4
6 changed files with 148 additions and 55 deletions
|
@ -212,6 +212,9 @@ static _PyInterpreterFrame *
|
|||
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
|
||||
PyObject *locals, PyObject* const* args,
|
||||
size_t argcount, PyObject *kwnames);
|
||||
static _PyInterpreterFrame *
|
||||
_PyEvalFramePushAndInit_Ex(PyThreadState *tstate, PyFunctionObject *func,
|
||||
PyObject *locals, Py_ssize_t nargs, PyObject *callargs, PyObject *kwargs);
|
||||
static void
|
||||
_PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame);
|
||||
|
||||
|
@ -1501,6 +1504,49 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Same as _PyEvalFramePushAndInit but takes an args tuple and kwargs dict.
|
||||
Steals references to func, callargs and kwargs.
|
||||
*/
|
||||
static _PyInterpreterFrame *
|
||||
_PyEvalFramePushAndInit_Ex(PyThreadState *tstate, PyFunctionObject *func,
|
||||
PyObject *locals, Py_ssize_t nargs, PyObject *callargs, PyObject *kwargs)
|
||||
{
|
||||
bool has_dict = (kwargs != NULL && PyDict_GET_SIZE(kwargs) > 0);
|
||||
PyObject *kwnames = NULL;
|
||||
PyObject *const *newargs;
|
||||
if (has_dict) {
|
||||
newargs = _PyStack_UnpackDict(tstate, _PyTuple_ITEMS(callargs), nargs, kwargs, &kwnames);
|
||||
if (newargs == NULL) {
|
||||
Py_DECREF(func);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
newargs = &PyTuple_GET_ITEM(callargs, 0);
|
||||
/* We need to incref all our args since the new frame steals the references. */
|
||||
for (Py_ssize_t i = 0; i < nargs; ++i) {
|
||||
Py_INCREF(PyTuple_GET_ITEM(callargs, i));
|
||||
}
|
||||
}
|
||||
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
|
||||
tstate, (PyFunctionObject *)func, locals,
|
||||
newargs, nargs, kwnames
|
||||
);
|
||||
if (has_dict) {
|
||||
_PyStack_UnpackDict_FreeNoDecRef(newargs, kwnames);
|
||||
}
|
||||
/* No need to decref func here because the reference has been stolen by
|
||||
_PyEvalFramePushAndInit.
|
||||
*/
|
||||
Py_DECREF(callargs);
|
||||
Py_XDECREF(kwargs);
|
||||
return new_frame;
|
||||
error:
|
||||
Py_DECREF(callargs);
|
||||
Py_XDECREF(kwargs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func,
|
||||
PyObject *locals,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue