summaryrefslogtreecommitdiff
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorKen Jin <kenjin@python.org>2023-04-30 21:08:26 +0800
committerGitHub <noreply@github.com>2023-04-30 21:08:26 +0800
commited95e8cbd4cbc813666c7ce7760257cc0f169d03 (patch)
tree55929b3092e83753baa34eac09f63666d072d286 /Python/bytecodes.c
parentaccb417c338630ac6e836a5c811a89d54a3cd1d3 (diff)
downloadcpython-git-ed95e8cbd4cbc813666c7ce7760257cc0f169d03.tar.gz
gh-98003: Inline call frames for CALL_FUNCTION_EX (GH-98004)
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r--Python/bytecodes.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 9de0d92e38..e83894e890 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -3103,6 +3103,25 @@ dummy_func(
}
}
else {
+ if (Py_TYPE(func) == &PyFunction_Type &&
+ tstate->interp->eval_frame == NULL &&
+ ((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) {
+ assert(PyTuple_CheckExact(callargs));
+ Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
+ int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags;
+ PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func));
+
+ _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(tstate,
+ (PyFunctionObject *)func, locals,
+ nargs, callargs, kwargs);
+ // Need to manually shrink the stack since we exit with DISPATCH_INLINED.
+ STACK_SHRINK(oparg + 3);
+ if (new_frame == NULL) {
+ goto error;
+ }
+ frame->return_offset = 0;
+ DISPATCH_INLINED(new_frame);
+ }
result = PyObject_Call(func, callargs, kwargs);
}
DECREF_INPUTS();