mirror of
https://github.com/python/cpython.git
synced 2026-01-04 14:32:21 +00:00
GH-139922: Tail calling for MSVC (VS 2026) (GH-143068)
Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Co-authored-by: Brandt Bucher <brandt@python.org> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
This commit is contained in:
parent
665d2807a0
commit
be3c131640
12 changed files with 528 additions and 683 deletions
|
|
@ -1071,6 +1071,65 @@ _Py_VectorCall_StackRefSteal(
|
|||
return res;
|
||||
}
|
||||
|
||||
PyObject*
|
||||
_Py_VectorCallInstrumentation_StackRefSteal(
|
||||
_PyStackRef callable,
|
||||
_PyStackRef* arguments,
|
||||
int total_args,
|
||||
_PyStackRef kwnames,
|
||||
bool call_instrumentation,
|
||||
_PyInterpreterFrame* frame,
|
||||
_Py_CODEUNIT* this_instr,
|
||||
PyThreadState* tstate)
|
||||
{
|
||||
PyObject* res;
|
||||
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
||||
if (CONVERSION_FAILED(args_o)) {
|
||||
res = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
PyObject* callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyObject* kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
|
||||
int positional_args = total_args;
|
||||
if (kwnames_o != NULL) {
|
||||
positional_args -= (int)PyTuple_GET_SIZE(kwnames_o);
|
||||
}
|
||||
res = PyObject_Vectorcall(
|
||||
callable_o, args_o,
|
||||
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
||||
kwnames_o);
|
||||
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
||||
if (call_instrumentation) {
|
||||
PyObject* arg = total_args == 0 ?
|
||||
&_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
|
||||
if (res == NULL) {
|
||||
_Py_call_instrumentation_exc2(
|
||||
tstate, PY_MONITORING_EVENT_C_RAISE,
|
||||
frame, this_instr, callable_o, arg);
|
||||
}
|
||||
else {
|
||||
int err = _Py_call_instrumentation_2args(
|
||||
tstate, PY_MONITORING_EVENT_C_RETURN,
|
||||
frame, this_instr, callable_o, arg);
|
||||
if (err < 0) {
|
||||
Py_CLEAR(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert((res != NULL) ^ (PyErr_Occurred() != NULL));
|
||||
cleanup:
|
||||
PyStackRef_XCLOSE(kwnames);
|
||||
// arguments is a pointer into the GC visible stack,
|
||||
// so we must NULL out values as we clear them.
|
||||
for (int i = total_args - 1; i >= 0; i--) {
|
||||
_PyStackRef tmp = arguments[i];
|
||||
arguments[i] = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(tmp);
|
||||
}
|
||||
PyStackRef_CLOSE(callable);
|
||||
return res;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_Py_BuiltinCallFast_StackRefSteal(
|
||||
_PyStackRef callable,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue