From 374874c3e6d8c4745a52b3bc22044db607b2c9e7 Mon Sep 17 00:00:00 2001
From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Date: Sun, 21 Dec 2025 14:51:39 +0100
Subject: [PATCH 1/8] rebased + _Py_VectorCallInstrumentation_StackRefSteal
---
.github/workflows/tail-call.yml | 14 +-
Include/internal/pycore_ceval.h | 11 +
...-10-11-17-01-21.gh-issue-139922.RUkXyd.rst | 1 +
Objects/abstract.c | 8 +-
PCbuild/pythoncore.vcxproj | 4 +-
Python/bytecodes.c | 110 ++--
Python/ceval.c | 59 +++
Python/ceval_macros.h | 15 +-
Python/executor_cases.c.h | 45 +-
Python/generated_cases.c.h | 397 ++++-----------
Python/opcode_targets.h | 468 +++++++++---------
Tools/cases_generator/target_generator.py | 2 +-
12 files changed, 484 insertions(+), 650 deletions(-)
create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-10-11-17-01-21.gh-issue-139922.RUkXyd.rst
diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml
index e99e317182eaa6..a4b1591ab18ed9 100644
--- a/.github/workflows/tail-call.yml
+++ b/.github/workflows/tail-call.yml
@@ -79,19 +79,17 @@ jobs:
with:
python-version: '3.11'
- - name: Native Windows (debug)
+ - name: Native Windows MSVC (PGO)
if: runner.os == 'Windows' && matrix.architecture != 'ARM64'
shell: cmd
run: |
- choco install llvm --allow-downgrade --no-progress --version ${{ matrix.llvm }}.1.0
- set PlatformToolset=clangcl
- set LLVMToolsVersion=${{ matrix.llvm }}.1.0
- set LLVMInstallDir=C:\Program Files\LLVM
- call ./PCbuild/build.bat --tail-call-interp -d -p ${{ matrix.architecture }}
- call ./PCbuild/rt.bat -d -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
+ choco install visualstudio2026buildtools-preview --pre -allWorkloads
+ set PATH=C:\Program Files\Microsoft Visual Studio\18\Insiders\MSBuild\Current\Bin\;%PATH%
+ ./PCbuild/build.bat --tail-call-interp --pgo -p ${{ matrix.architecture }} "/p:PlatformToolset=v145"
+ ./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
# No tests (yet):
- - name: Emulated Windows (release)
+ - name: Emulated Windows Clang (release)
if: runner.os == 'Windows' && matrix.architecture == 'ARM64'
shell: cmd
run: |
diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h
index 6bf33bddd5b877..a539229bfc3e33 100644
--- a/Include/internal/pycore_ceval.h
+++ b/Include/internal/pycore_ceval.h
@@ -417,6 +417,17 @@ _Py_VectorCall_StackRefSteal(
int total_args,
_PyStackRef kwnames);
+PyAPI_FUNC(PyObject*)
+_Py_VectorCallInstrumentation_StackRefSteal(
+ _PyStackRef callable,
+ _PyStackRef* arguments,
+ int total_args,
+ _PyStackRef kwnames,
+ bool call_instrumentation,
+ _PyInterpreterFrame* frame,
+ _Py_CODEUNIT* this_instr,
+ PyThreadState* tstate);
+
PyAPI_FUNC(PyObject *)
_Py_BuiltinCallFast_StackRefSteal(
_PyStackRef callable,
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-11-17-01-21.gh-issue-139922.RUkXyd.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-11-17-01-21.gh-issue-139922.RUkXyd.rst
new file mode 100644
index 00000000000000..d498db07f91454
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-11-17-01-21.gh-issue-139922.RUkXyd.rst
@@ -0,0 +1 @@
+Allow building CPython with the tail calling interpreter on Visual Studio 2026 MSVC. This provides a performance gain over the prior interpreter for MSVC. Patch by Ken Jin, Brandt Bucher, and Chris Eibl. With help from the MSVC team including Hulon Jenkins.
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 8adad8407d04d4..1c50b6dd0d04ea 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -205,8 +205,14 @@ PyObject_GetItem(PyObject *o, PyObject *key)
return type_error("'%.200s' object is not subscriptable", o);
}
+// MSVC fails during a tail call release build with loads of
+// error C4737: Unable to perform required tail call.
+// without using Py_NO_INLINE here, but PGO works fine.
+#if defined(_MSC_VER) && !defined(__clang__) && _Py_TAIL_CALL_INTERP && !defined(_Py_USING_PGO)
+Py_NO_INLINE
+#endif
int
-PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result)
+PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **restrict result)
{
if (PyDict_CheckExact(obj)) {
return PyDict_GetItemRef(obj, key, result);
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index dcfb75ce162b2f..5e7e739dc5f787 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -600,7 +600,9 @@
-
+
+ /std:clatest %(AdditionalOptions)
+
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index d96a1944cd516a..be2e293c54f47a 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -2212,8 +2212,11 @@ dummy_func(
}
// we make no attempt to optimize here; specializations should
// handle any case whose performance we care about
- PyObject *stack[] = {class, self};
- PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
+ PyObject *super;
+ {
+ PyObject *stack[] = {class, self};
+ super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
+ }
if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
if (super == NULL) {
@@ -2272,8 +2275,12 @@ dummy_func(
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
PyTypeObject *cls = (PyTypeObject *)class;
int method_found = 0;
- PyObject *attr_o = _PySuper_Lookup(cls, self, name,
- Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
+ PyObject *attr_o;
+ {
+ int *method_found_ptr = &method_found;
+ attr_o = _PySuper_Lookup(cls, self, name,
+ Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? method_found_ptr : NULL);
+ }
if (attr_o == NULL) {
ERROR_NO_POP();
}
@@ -3499,10 +3506,13 @@ dummy_func(
}
assert(PyStackRef_IsTaggedInt(lasti));
(void)lasti; // Shut up compiler warning if asserts are off
- PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
- int has_self = !PyStackRef_IsNull(exit_self);
- PyObject *res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
- (3 + has_self) | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
+ PyObject* res_o;
+ {
+ PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
+ int has_self = !PyStackRef_IsNull(exit_self);
+ res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
+ (3 + has_self) | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
+ }
Py_XDECREF(original_tb);
ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
@@ -3734,36 +3744,18 @@ dummy_func(
frame->return_offset = INSTRUCTION_SIZE;
DISPATCH_INLINED(new_frame);
}
- /* Callable is not a normal Python function */
- STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
- if (CONVERSION_FAILED(args_o)) {
- DECREF_INPUTS();
- ERROR_IF(true);
- }
- PyObject *res_o = PyObject_Vectorcall(
- callable_o, args_o,
- total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
- NULL);
- STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
- if (opcode == INSTRUMENTED_CALL) {
- PyObject *arg = total_args == 0 ?
- &_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
- if (res_o == 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_o);
- }
- }
- }
- assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
- DECREF_INPUTS();
+ PyObject* res_o = _Py_VectorCallInstrumentation_StackRefSteal(
+ callable,
+ arguments,
+ total_args,
+ PyStackRef_NULL,
+ opcode == INSTRUMENTED_CALL,
+ frame,
+ this_instr,
+ tstate);
+ DEAD(args);
+ DEAD(self_or_null);
+ DEAD(callable);
ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
@@ -4607,35 +4599,19 @@ dummy_func(
frame->return_offset = INSTRUCTION_SIZE;
DISPATCH_INLINED(new_frame);
}
- /* Callable is not a normal Python function */
- STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
- if (CONVERSION_FAILED(args_o)) {
- DECREF_INPUTS();
- ERROR_IF(true);
- }
- PyObject *res_o = PyObject_Vectorcall(
- callable_o, args_o,
- positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
- kwnames_o);
- STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
- if (opcode == INSTRUMENTED_CALL_KW) {
- PyObject *arg = total_args == 0 ?
- &_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
- if (res_o == 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_o);
- }
- }
- }
- DECREF_INPUTS();
+ PyObject* res_o = _Py_VectorCallInstrumentation_StackRefSteal(
+ callable,
+ arguments,
+ total_args,
+ kwnames,
+ opcode == INSTRUMENTED_CALL_KW,
+ frame,
+ this_instr,
+ tstate);
+ DEAD(kwnames);
+ DEAD(args);
+ DEAD(self_or_null);
+ DEAD(callable);
ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
diff --git a/Python/ceval.c b/Python/ceval.c
index 37679d4cd183c7..394151ffbcb19d 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -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,
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index 26312d0ea5aa5c..158327ed01d818 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -87,16 +87,19 @@
# elif defined(_MSC_VER) && (_MSC_VER < 1950)
# error "You need at least VS 2026 / PlatformToolset v145 for tail calling."
# endif
-
- // Note: [[clang::musttail]] works for GCC 15, but not __attribute__((musttail)) at the moment.
-# define Py_MUSTTAIL [[clang::musttail]]
-# define Py_PRESERVE_NONE_CC __attribute__((preserve_none))
- Py_PRESERVE_NONE_CC typedef PyObject* (*py_tail_call_funcptr)(TAIL_CALL_PARAMS);
+# if defined(_MSC_VER) && !defined(__clang__)
+# define Py_MUSTTAIL [[msvc::musttail]]
+# define Py_PRESERVE_NONE_CC __preserve_none
+# else
+# define Py_MUSTTAIL __attribute__((musttail))
+# define Py_PRESERVE_NONE_CC __attribute__((preserve_none))
+# endif
+ typedef PyObject *(Py_PRESERVE_NONE_CC *py_tail_call_funcptr)(TAIL_CALL_PARAMS);
# define DISPATCH_TABLE_VAR instruction_funcptr_table
# define DISPATCH_TABLE instruction_funcptr_handler_table
# define TRACING_DISPATCH_TABLE instruction_funcptr_tracing_table
-# define TARGET(op) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
+# define TARGET(op) Py_NO_INLINE PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_##op(TAIL_CALL_PARAMS)
# define DISPATCH_GOTO() \
do { \
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index fab23f358682eb..ceff1fbb7b0011 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -7814,15 +7814,19 @@
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
PyTypeObject *cls = (PyTypeObject *)class;
int method_found = 0;
- stack_pointer[0] = global_super_st;
- stack_pointer[1] = class_st;
- stack_pointer[2] = self_st;
- stack_pointer += 3;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
- _PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *attr_o = _PySuper_Lookup(cls, self, name,
- Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
- stack_pointer = _PyFrame_GetStackPointer(frame);
+ PyObject *attr_o;
+ {
+ int *method_found_ptr = &method_found;
+ stack_pointer[0] = global_super_st;
+ stack_pointer[1] = class_st;
+ stack_pointer[2] = self_st;
+ stack_pointer += 3;
+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ attr_o = _PySuper_Lookup(cls, self, name,
+ Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? method_found_ptr : NULL);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ }
if (attr_o == NULL) {
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_ERROR();
@@ -10936,16 +10940,21 @@
}
assert(PyStackRef_IsTaggedInt(lasti));
(void)lasti;
- PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
- int has_self = !PyStackRef_IsNull(exit_self);
- stack_pointer[0] = lasti;
- stack_pointer[1] = _stack_item_1;
- stack_pointer[2] = val;
- stack_pointer += 3;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
+ PyObject* res_o;
+ {
+ PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
+ int has_self = !PyStackRef_IsNull(exit_self);
+ stack_pointer[0] = lasti;
+ stack_pointer[1] = _stack_item_1;
+ stack_pointer[2] = val;
+ stack_pointer += 3;
+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
+ (3 + has_self) | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ }
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
- (3 + has_self) | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
Py_XDECREF(original_tb);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 413593386583a8..6e13b100b7a5c3 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -1544,90 +1544,30 @@
frame->return_offset = 4u ;
DISPATCH_INLINED(new_frame);
}
- STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
- if (CONVERSION_FAILED(args_o)) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _PyStackRef tmp;
- for (int _i = oparg; --_i >= 0;) {
- tmp = args[_i];
- args[_i] = PyStackRef_NULL;
- stack_pointer[-2 - oparg] = callable;
- stack_pointer[-1 - oparg] = self_or_null;
- PyStackRef_CLOSE(tmp);
- }
- tmp = self_or_null;
- self_or_null = PyStackRef_NULL;
- stack_pointer[-1 - oparg] = self_or_null;
- PyStackRef_XCLOSE(tmp);
- tmp = callable;
- callable = PyStackRef_NULL;
- stack_pointer[-2 - oparg] = callable;
- PyStackRef_CLOSE(tmp);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- stack_pointer += -2 - oparg;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
- JUMP_TO_LABEL(error);
- }
stack_pointer[-2 - oparg] = callable;
stack_pointer[-1 - oparg] = self_or_null;
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *res_o = PyObject_Vectorcall(
- callable_o, args_o,
- total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
- NULL);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
- if (opcode == INSTRUMENTED_CALL) {
- PyObject *arg = total_args == 0 ?
- &_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
- if (res_o == NULL) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _Py_call_instrumentation_exc2(
- tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, this_instr, callable_o, arg);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- }
- else {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- int err = _Py_call_instrumentation_2args(
- tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, this_instr, callable_o, arg);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- if (err < 0) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- Py_CLEAR(res_o);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- }
- }
- }
- assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _PyStackRef tmp;
- for (int _i = oparg; --_i >= 0;) {
- tmp = args[_i];
- args[_i] = PyStackRef_NULL;
- PyStackRef_CLOSE(tmp);
- }
- tmp = self_or_null;
- self_or_null = PyStackRef_NULL;
- stack_pointer[-1 - oparg] = self_or_null;
- PyStackRef_XCLOSE(tmp);
- tmp = callable;
- callable = PyStackRef_NULL;
- stack_pointer[-2 - oparg] = callable;
- PyStackRef_CLOSE(tmp);
+ PyObject* res_o = _Py_VectorCallInstrumentation_StackRefSteal(
+ callable,
+ arguments,
+ total_args,
+ PyStackRef_NULL,
+ opcode == INSTRUMENTED_CALL,
+ frame,
+ this_instr,
+ tstate);
stack_pointer = _PyFrame_GetStackPointer(frame);
- stack_pointer += -2 - oparg;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
if (res_o == NULL) {
+ stack_pointer += -2 - oparg;
+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
JUMP_TO_LABEL(error);
}
res = PyStackRef_FromPyObjectSteal(res_o);
}
// _CHECK_PERIODIC_AT_END
{
- stack_pointer[0] = res;
- stack_pointer += 1;
+ stack_pointer[-2 - oparg] = res;
+ stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = check_periodics(tstate);
@@ -2721,93 +2661,28 @@
frame->return_offset = 4u ;
DISPATCH_INLINED(new_frame);
}
- STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
- if (CONVERSION_FAILED(args_o)) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _PyStackRef tmp = kwnames;
- kwnames = PyStackRef_NULL;
- stack_pointer[-3 - oparg] = callable;
- stack_pointer[-2 - oparg] = self_or_null;
- stack_pointer[-1] = kwnames;
- PyStackRef_CLOSE(tmp);
- for (int _i = oparg; --_i >= 0;) {
- tmp = args[_i];
- args[_i] = PyStackRef_NULL;
- PyStackRef_CLOSE(tmp);
- }
- tmp = self_or_null;
- self_or_null = PyStackRef_NULL;
- stack_pointer[-2 - oparg] = self_or_null;
- PyStackRef_XCLOSE(tmp);
- tmp = callable;
- callable = PyStackRef_NULL;
- stack_pointer[-3 - oparg] = callable;
- PyStackRef_CLOSE(tmp);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- stack_pointer += -3 - oparg;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
- JUMP_TO_LABEL(error);
- }
stack_pointer[-3 - oparg] = callable;
stack_pointer[-2 - oparg] = self_or_null;
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *res_o = PyObject_Vectorcall(
- callable_o, args_o,
- positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
- kwnames_o);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
- if (opcode == INSTRUMENTED_CALL_KW) {
- PyObject *arg = total_args == 0 ?
- &_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
- if (res_o == NULL) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _Py_call_instrumentation_exc2(
- tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, this_instr, callable_o, arg);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- }
- else {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- int err = _Py_call_instrumentation_2args(
- tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, this_instr, callable_o, arg);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- if (err < 0) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- Py_CLEAR(res_o);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- }
- }
- }
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _PyStackRef tmp = kwnames;
- kwnames = PyStackRef_NULL;
- stack_pointer[-1] = kwnames;
- PyStackRef_CLOSE(tmp);
- for (int _i = oparg; --_i >= 0;) {
- tmp = args[_i];
- args[_i] = PyStackRef_NULL;
- PyStackRef_CLOSE(tmp);
- }
- tmp = self_or_null;
- self_or_null = PyStackRef_NULL;
- stack_pointer[-2 - oparg] = self_or_null;
- PyStackRef_XCLOSE(tmp);
- tmp = callable;
- callable = PyStackRef_NULL;
- stack_pointer[-3 - oparg] = callable;
- PyStackRef_CLOSE(tmp);
+ PyObject* res_o = _Py_VectorCallInstrumentation_StackRefSteal(
+ callable,
+ arguments,
+ total_args,
+ kwnames,
+ opcode == INSTRUMENTED_CALL_KW,
+ frame,
+ this_instr,
+ tstate);
stack_pointer = _PyFrame_GetStackPointer(frame);
- stack_pointer += -3 - oparg;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
if (res_o == NULL) {
+ stack_pointer += -3 - oparg;
+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
JUMP_TO_LABEL(error);
}
res = PyStackRef_FromPyObjectSteal(res_o);
}
- stack_pointer[0] = res;
- stack_pointer += 1;
+ stack_pointer[-3 - oparg] = res;
+ stack_pointer += -2 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
DISPATCH();
}
@@ -6020,86 +5895,28 @@
frame->return_offset = 4u ;
DISPATCH_INLINED(new_frame);
}
- STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
- if (CONVERSION_FAILED(args_o)) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _PyStackRef tmp;
- for (int _i = oparg; --_i >= 0;) {
- tmp = args[_i];
- args[_i] = PyStackRef_NULL;
- PyStackRef_CLOSE(tmp);
- }
- tmp = self_or_null;
- self_or_null = PyStackRef_NULL;
- stack_pointer[-1 - oparg] = self_or_null;
- PyStackRef_XCLOSE(tmp);
- tmp = callable;
- callable = PyStackRef_NULL;
- stack_pointer[-2 - oparg] = callable;
- PyStackRef_CLOSE(tmp);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- stack_pointer += -2 - oparg;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
- JUMP_TO_LABEL(error);
- }
- _PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *res_o = PyObject_Vectorcall(
- callable_o, args_o,
- total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
- NULL);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
- if (opcode == INSTRUMENTED_CALL) {
- PyObject *arg = total_args == 0 ?
- &_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
- if (res_o == NULL) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _Py_call_instrumentation_exc2(
- tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, this_instr, callable_o, arg);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- }
- else {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- int err = _Py_call_instrumentation_2args(
- tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, this_instr, callable_o, arg);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- if (err < 0) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- Py_CLEAR(res_o);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- }
- }
- }
- assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
_PyFrame_SetStackPointer(frame, stack_pointer);
- _PyStackRef tmp;
- for (int _i = oparg; --_i >= 0;) {
- tmp = args[_i];
- args[_i] = PyStackRef_NULL;
- PyStackRef_CLOSE(tmp);
- }
- tmp = self_or_null;
- self_or_null = PyStackRef_NULL;
- stack_pointer[-1 - oparg] = self_or_null;
- PyStackRef_XCLOSE(tmp);
- tmp = callable;
- callable = PyStackRef_NULL;
- stack_pointer[-2 - oparg] = callable;
- PyStackRef_CLOSE(tmp);
+ PyObject* res_o = _Py_VectorCallInstrumentation_StackRefSteal(
+ callable,
+ arguments,
+ total_args,
+ PyStackRef_NULL,
+ opcode == INSTRUMENTED_CALL,
+ frame,
+ this_instr,
+ tstate);
stack_pointer = _PyFrame_GetStackPointer(frame);
- stack_pointer += -2 - oparg;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
if (res_o == NULL) {
+ stack_pointer += -2 - oparg;
+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
JUMP_TO_LABEL(error);
}
res = PyStackRef_FromPyObjectSteal(res_o);
}
// _CHECK_PERIODIC_AT_END
{
- stack_pointer[0] = res;
- stack_pointer += 1;
+ stack_pointer[-2 - oparg] = res;
+ stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = check_periodics(tstate);
@@ -6377,89 +6194,26 @@
frame->return_offset = 4u ;
DISPATCH_INLINED(new_frame);
}
- STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
- if (CONVERSION_FAILED(args_o)) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _PyStackRef tmp = kwnames;
- kwnames = PyStackRef_NULL;
- stack_pointer[-1] = kwnames;
- PyStackRef_CLOSE(tmp);
- for (int _i = oparg; --_i >= 0;) {
- tmp = args[_i];
- args[_i] = PyStackRef_NULL;
- PyStackRef_CLOSE(tmp);
- }
- tmp = self_or_null;
- self_or_null = PyStackRef_NULL;
- stack_pointer[-2 - oparg] = self_or_null;
- PyStackRef_XCLOSE(tmp);
- tmp = callable;
- callable = PyStackRef_NULL;
- stack_pointer[-3 - oparg] = callable;
- PyStackRef_CLOSE(tmp);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- stack_pointer += -3 - oparg;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
- JUMP_TO_LABEL(error);
- }
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *res_o = PyObject_Vectorcall(
- callable_o, args_o,
- positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
- kwnames_o);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
- if (opcode == INSTRUMENTED_CALL_KW) {
- PyObject *arg = total_args == 0 ?
- &_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
- if (res_o == NULL) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _Py_call_instrumentation_exc2(
- tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, this_instr, callable_o, arg);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- }
- else {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- int err = _Py_call_instrumentation_2args(
- tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, this_instr, callable_o, arg);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- if (err < 0) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- Py_CLEAR(res_o);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- }
- }
- }
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _PyStackRef tmp = kwnames;
- kwnames = PyStackRef_NULL;
- stack_pointer[-1] = kwnames;
- PyStackRef_CLOSE(tmp);
- for (int _i = oparg; --_i >= 0;) {
- tmp = args[_i];
- args[_i] = PyStackRef_NULL;
- PyStackRef_CLOSE(tmp);
- }
- tmp = self_or_null;
- self_or_null = PyStackRef_NULL;
- stack_pointer[-2 - oparg] = self_or_null;
- PyStackRef_XCLOSE(tmp);
- tmp = callable;
- callable = PyStackRef_NULL;
- stack_pointer[-3 - oparg] = callable;
- PyStackRef_CLOSE(tmp);
+ PyObject* res_o = _Py_VectorCallInstrumentation_StackRefSteal(
+ callable,
+ arguments,
+ total_args,
+ kwnames,
+ opcode == INSTRUMENTED_CALL_KW,
+ frame,
+ this_instr,
+ tstate);
stack_pointer = _PyFrame_GetStackPointer(frame);
- stack_pointer += -3 - oparg;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
if (res_o == NULL) {
+ stack_pointer += -3 - oparg;
+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
JUMP_TO_LABEL(error);
}
res = PyStackRef_FromPyObjectSteal(res_o);
}
- stack_pointer[0] = res;
- stack_pointer += 1;
+ stack_pointer[-3 - oparg] = res;
+ stack_pointer += -2 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
DISPATCH();
}
@@ -6776,10 +6530,13 @@
JUMP_TO_LABEL(error);
}
}
- PyObject *stack[] = {class, self};
- _PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
- stack_pointer = _PyFrame_GetStackPointer(frame);
+ PyObject *super;
+ {
+ PyObject *stack[] = {class, self};
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ }
if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
if (super == NULL) {
@@ -9166,10 +8923,13 @@
JUMP_TO_LABEL(error);
}
}
- PyObject *stack[] = {class, self};
- _PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
- stack_pointer = _PyFrame_GetStackPointer(frame);
+ PyObject *super;
+ {
+ PyObject *stack[] = {class, self};
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ }
if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
if (super == NULL) {
@@ -9334,10 +9094,14 @@
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
PyTypeObject *cls = (PyTypeObject *)class;
int method_found = 0;
- _PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *attr_o = _PySuper_Lookup(cls, self, name,
- Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
- stack_pointer = _PyFrame_GetStackPointer(frame);
+ PyObject *attr_o;
+ {
+ int *method_found_ptr = &method_found;
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ attr_o = _PySuper_Lookup(cls, self, name,
+ Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? method_found_ptr : NULL);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ }
if (attr_o == NULL) {
JUMP_TO_LABEL(error);
}
@@ -11774,11 +11538,16 @@
}
assert(PyStackRef_IsTaggedInt(lasti));
(void)lasti;
- PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
- int has_self = !PyStackRef_IsNull(exit_self);
+ PyObject* res_o;
+ {
+ PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
+ int has_self = !PyStackRef_IsNull(exit_self);
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
+ (3 + has_self) | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ }
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
- (3 + has_self) | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
Py_XDECREF(original_tb);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index b2fa7d01e8f6c2..267e707dc597fb 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -522,242 +522,242 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256];
static py_tail_call_funcptr instruction_funcptr_tracing_table[256];
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_2_error(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_1_error(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_error(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_exception_unwind(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_exit_unwind(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_start_frame(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_stop_tracing(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_pop_2_error(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_pop_1_error(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_error(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_exception_unwind(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_exit_unwind(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_start_frame(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_stop_tracing(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_ADD_FLOAT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_ADD_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_ADD_UNICODE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_EXTEND(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_INPLACE_ADD_UNICODE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_MULTIPLY_FLOAT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_MULTIPLY_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBSCR_DICT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBSCR_GETITEM(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBSCR_LIST_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBSCR_LIST_SLICE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBSCR_STR_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBSCR_TUPLE_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBTRACT_FLOAT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBTRACT_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_SLICE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_INTERPOLATION(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_LIST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_MAP(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_SET(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_SLICE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_STRING(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_TEMPLATE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BUILD_TUPLE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CACHE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_ALLOC_AND_ENTER_INIT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_BOUND_METHOD_EXACT_ARGS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_BOUND_METHOD_GENERAL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_BUILTIN_CLASS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_BUILTIN_FAST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_BUILTIN_FAST_WITH_KEYWORDS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_BUILTIN_O(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_FUNCTION_EX(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_INTRINSIC_1(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_INTRINSIC_2(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_ISINSTANCE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_KW(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_KW_BOUND_METHOD(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_KW_NON_PY(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_KW_PY(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_LEN(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_LIST_APPEND(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_METHOD_DESCRIPTOR_FAST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_METHOD_DESCRIPTOR_NOARGS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_METHOD_DESCRIPTOR_O(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_NON_PY_GENERAL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_PY_EXACT_ARGS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_PY_GENERAL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_STR_1(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_TUPLE_1(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CALL_TYPE_1(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CHECK_EG_MATCH(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CHECK_EXC_MATCH(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CLEANUP_THROW(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_COMPARE_OP(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_COMPARE_OP_FLOAT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_COMPARE_OP_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_COMPARE_OP_STR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CONTAINS_OP(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CONTAINS_OP_DICT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CONTAINS_OP_SET(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_CONVERT_VALUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_COPY(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_COPY_FREE_VARS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_DELETE_ATTR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_DELETE_DEREF(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_DELETE_FAST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_DELETE_GLOBAL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_DELETE_NAME(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_DELETE_SUBSCR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_DICT_MERGE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_DICT_UPDATE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_END_ASYNC_FOR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_END_FOR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_END_SEND(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_ENTER_EXECUTOR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_EXIT_INIT_CHECK(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_EXTENDED_ARG(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FORMAT_SIMPLE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FORMAT_WITH_SPEC(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FOR_ITER(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FOR_ITER_GEN(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FOR_ITER_LIST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FOR_ITER_RANGE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FOR_ITER_TUPLE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_GET_AITER(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_GET_ANEXT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_GET_AWAITABLE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_GET_ITER(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_GET_LEN(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_GET_YIELD_FROM_ITER(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_IMPORT_FROM(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_IMPORT_NAME(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_CALL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_CALL_FUNCTION_EX(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_CALL_KW(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_END_ASYNC_FOR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_END_FOR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_END_SEND(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_FOR_ITER(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_INSTRUCTION(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_JUMP_BACKWARD(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_JUMP_FORWARD(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_LINE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_LOAD_SUPER_ATTR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_NOT_TAKEN(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_POP_ITER(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_FALSE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_NONE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_NOT_NONE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_TRUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_RESUME(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_RETURN_VALUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_YIELD_VALUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INTERPRETER_EXIT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_IS_OP(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_JUMP_BACKWARD(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_JUMP_BACKWARD_JIT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_JUMP_BACKWARD_NO_INTERRUPT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_JUMP_BACKWARD_NO_JIT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_JUMP_FORWARD(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LIST_APPEND(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LIST_EXTEND(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_CLASS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_CLASS_WITH_METACLASS_CHECK(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_INSTANCE_VALUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_METHOD_LAZY_DICT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_METHOD_NO_DICT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_METHOD_WITH_VALUES(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_MODULE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_NONDESCRIPTOR_NO_DICT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_PROPERTY(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_SLOT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_ATTR_WITH_HINT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_BUILD_CLASS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_COMMON_CONSTANT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_CONST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_DEREF(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_FAST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_FAST_AND_CLEAR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_FAST_BORROW(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_FAST_BORROW_LOAD_FAST_BORROW(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_FAST_CHECK(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_FAST_LOAD_FAST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_FROM_DICT_OR_DEREF(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_FROM_DICT_OR_GLOBALS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_GLOBAL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_GLOBAL_BUILTIN(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_GLOBAL_MODULE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_LOCALS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_NAME(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_SMALL_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_SPECIAL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_SUPER_ATTR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_SUPER_ATTR_ATTR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_LOAD_SUPER_ATTR_METHOD(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MAKE_CELL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MAKE_FUNCTION(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MAP_ADD(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_CLASS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_KEYS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_MAPPING(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_MATCH_SEQUENCE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_NOP(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_NOT_TAKEN(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_EXCEPT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_ITER(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_JUMP_IF_FALSE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_JUMP_IF_NONE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_JUMP_IF_NOT_NONE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_JUMP_IF_TRUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_TOP(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_PUSH_EXC_INFO(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_PUSH_NULL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_RAISE_VARARGS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_RERAISE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_RESERVED(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_RESUME(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_RESUME_CHECK(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_RETURN_GENERATOR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_RETURN_VALUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_SEND(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_SEND_GEN(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_SETUP_ANNOTATIONS(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_SET_ADD(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_SET_FUNCTION_ATTRIBUTE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_SET_UPDATE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_ATTR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_ATTR_INSTANCE_VALUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_ATTR_SLOT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_ATTR_WITH_HINT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_DEREF(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_FAST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_FAST_LOAD_FAST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_FAST_STORE_FAST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_GLOBAL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_NAME(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_SLICE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_SUBSCR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_SUBSCR_DICT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_SUBSCR_LIST_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_SWAP(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TO_BOOL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TO_BOOL_ALWAYS_TRUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TO_BOOL_BOOL(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TO_BOOL_INT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TO_BOOL_LIST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TO_BOOL_NONE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TO_BOOL_STR(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TRACE_RECORD(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNARY_INVERT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNARY_NEGATIVE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNARY_NOT(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNPACK_EX(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNPACK_SEQUENCE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNPACK_SEQUENCE_LIST(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNPACK_SEQUENCE_TUPLE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNPACK_SEQUENCE_TWO_TUPLE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_WITH_EXCEPT_START(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_YIELD_VALUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_ADD_FLOAT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_ADD_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_ADD_UNICODE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_EXTEND(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_INPLACE_ADD_UNICODE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_MULTIPLY_FLOAT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_MULTIPLY_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_SUBSCR_DICT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_SUBSCR_GETITEM(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_SUBSCR_LIST_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_SUBSCR_LIST_SLICE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_SUBSCR_STR_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_SUBSCR_TUPLE_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_SUBTRACT_FLOAT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_OP_SUBTRACT_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BINARY_SLICE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BUILD_INTERPOLATION(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BUILD_LIST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BUILD_MAP(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BUILD_SET(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BUILD_SLICE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BUILD_STRING(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BUILD_TEMPLATE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_BUILD_TUPLE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CACHE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_ALLOC_AND_ENTER_INIT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_BOUND_METHOD_EXACT_ARGS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_BOUND_METHOD_GENERAL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_BUILTIN_CLASS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_BUILTIN_FAST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_BUILTIN_FAST_WITH_KEYWORDS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_BUILTIN_O(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_FUNCTION_EX(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_INTRINSIC_1(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_INTRINSIC_2(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_ISINSTANCE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_KW(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_KW_BOUND_METHOD(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_KW_NON_PY(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_KW_PY(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_LEN(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_LIST_APPEND(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_METHOD_DESCRIPTOR_FAST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_METHOD_DESCRIPTOR_NOARGS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_METHOD_DESCRIPTOR_O(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_NON_PY_GENERAL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_PY_EXACT_ARGS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_PY_GENERAL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_STR_1(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_TUPLE_1(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CALL_TYPE_1(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CHECK_EG_MATCH(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CHECK_EXC_MATCH(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CLEANUP_THROW(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_COMPARE_OP(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_COMPARE_OP_FLOAT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_COMPARE_OP_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_COMPARE_OP_STR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CONTAINS_OP(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CONTAINS_OP_DICT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CONTAINS_OP_SET(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_CONVERT_VALUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_COPY(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_COPY_FREE_VARS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_DELETE_ATTR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_DELETE_DEREF(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_DELETE_FAST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_DELETE_GLOBAL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_DELETE_NAME(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_DELETE_SUBSCR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_DICT_MERGE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_DICT_UPDATE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_END_ASYNC_FOR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_END_FOR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_END_SEND(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_ENTER_EXECUTOR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_EXIT_INIT_CHECK(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_EXTENDED_ARG(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_FORMAT_SIMPLE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_FORMAT_WITH_SPEC(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_FOR_ITER(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_FOR_ITER_GEN(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_FOR_ITER_LIST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_FOR_ITER_RANGE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_FOR_ITER_TUPLE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_AITER(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_ANEXT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_AWAITABLE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_ITER(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_LEN(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_GET_YIELD_FROM_ITER(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_IMPORT_FROM(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_IMPORT_NAME(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_CALL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_CALL_FUNCTION_EX(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_CALL_KW(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_END_ASYNC_FOR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_END_FOR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_END_SEND(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_FOR_ITER(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_INSTRUCTION(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_JUMP_BACKWARD(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_JUMP_FORWARD(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_LINE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_LOAD_SUPER_ATTR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_NOT_TAKEN(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_POP_ITER(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_FALSE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_NONE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_NOT_NONE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_TRUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_RESUME(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_RETURN_VALUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INSTRUMENTED_YIELD_VALUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_INTERPRETER_EXIT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_IS_OP(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_JUMP_BACKWARD(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_JUMP_BACKWARD_JIT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_JUMP_BACKWARD_NO_INTERRUPT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_JUMP_BACKWARD_NO_JIT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_JUMP_FORWARD(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LIST_APPEND(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LIST_EXTEND(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_CLASS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_CLASS_WITH_METACLASS_CHECK(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_INSTANCE_VALUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_METHOD_LAZY_DICT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_METHOD_NO_DICT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_METHOD_WITH_VALUES(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_MODULE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_NONDESCRIPTOR_NO_DICT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_PROPERTY(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_SLOT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_ATTR_WITH_HINT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_BUILD_CLASS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_COMMON_CONSTANT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_CONST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_DEREF(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_FAST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_FAST_AND_CLEAR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_FAST_BORROW(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_FAST_BORROW_LOAD_FAST_BORROW(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_FAST_CHECK(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_FAST_LOAD_FAST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_FROM_DICT_OR_DEREF(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_FROM_DICT_OR_GLOBALS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_GLOBAL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_GLOBAL_BUILTIN(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_GLOBAL_MODULE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_LOCALS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_NAME(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_SMALL_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_SPECIAL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_SUPER_ATTR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_SUPER_ATTR_ATTR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_LOAD_SUPER_ATTR_METHOD(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_MAKE_CELL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_MAKE_FUNCTION(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_MAP_ADD(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_MATCH_CLASS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_MATCH_KEYS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_MATCH_MAPPING(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_MATCH_SEQUENCE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_NOP(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_NOT_TAKEN(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_POP_EXCEPT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_POP_ITER(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_POP_JUMP_IF_FALSE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_POP_JUMP_IF_NONE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_POP_JUMP_IF_NOT_NONE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_POP_JUMP_IF_TRUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_POP_TOP(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_PUSH_EXC_INFO(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_PUSH_NULL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RAISE_VARARGS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RERAISE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESERVED(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESUME(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESUME_CHECK(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RETURN_GENERATOR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RETURN_VALUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SEND(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SEND_GEN(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SETUP_ANNOTATIONS(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SET_ADD(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SET_FUNCTION_ATTRIBUTE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SET_UPDATE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_ATTR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_ATTR_INSTANCE_VALUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_ATTR_SLOT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_ATTR_WITH_HINT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_DEREF(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_FAST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_FAST_LOAD_FAST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_FAST_STORE_FAST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_GLOBAL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_NAME(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_SLICE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_SUBSCR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_SUBSCR_DICT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_STORE_SUBSCR_LIST_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SWAP(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_TO_BOOL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_TO_BOOL_ALWAYS_TRUE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_TO_BOOL_BOOL(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_TO_BOOL_INT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_TO_BOOL_LIST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_TO_BOOL_NONE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_TO_BOOL_STR(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_TRACE_RECORD(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_UNARY_INVERT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_UNARY_NEGATIVE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_UNARY_NOT(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_UNPACK_EX(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_UNPACK_SEQUENCE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_UNPACK_SEQUENCE_LIST(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_UNPACK_SEQUENCE_TUPLE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_UNPACK_SEQUENCE_TWO_TUPLE(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_WITH_EXCEPT_START(TAIL_CALL_PARAMS);
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_YIELD_VALUE(TAIL_CALL_PARAMS);
-Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNKNOWN_OPCODE(TAIL_CALL_PARAMS) {
+static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_UNKNOWN_OPCODE(TAIL_CALL_PARAMS) {
int opcode = next_instr->op.code;
_PyErr_Format(tstate, PyExc_SystemError,
"%U:%d: unknown opcode %d",
diff --git a/Tools/cases_generator/target_generator.py b/Tools/cases_generator/target_generator.py
index f633f704485819..e7cf6c223d22dc 100644
--- a/Tools/cases_generator/target_generator.py
+++ b/Tools/cases_generator/target_generator.py
@@ -44,7 +44,7 @@ def write_opcode_targets(analysis: Analysis, out: CWriter) -> None:
out.emit("#else /* _Py_TAIL_CALL_INTERP */\n")
def function_proto(name: str) -> str:
- return f"Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_{name}(TAIL_CALL_PARAMS)"
+ return f"static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_{name}(TAIL_CALL_PARAMS)"
def write_tailcall_dispatch_table(analysis: Analysis, out: CWriter) -> None:
From 7e5555aec4c8091cfe394581c6487810547d1fc8 Mon Sep 17 00:00:00 2001
From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Date: Mon, 22 Dec 2025 14:22:11 +0100
Subject: [PATCH 2/8] try to fix MSVC tail call CI
---
.github/workflows/tail-call.yml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml
index a4b1591ab18ed9..627fc34a6b78e0 100644
--- a/.github/workflows/tail-call.yml
+++ b/.github/workflows/tail-call.yml
@@ -79,14 +79,14 @@ jobs:
with:
python-version: '3.11'
- - name: Native Windows MSVC (PGO)
+ - name: Native Windows MSVC (release)
if: runner.os == 'Windows' && matrix.architecture != 'ARM64'
shell: cmd
run: |
- choco install visualstudio2026buildtools-preview --pre -allWorkloads
- set PATH=C:\Program Files\Microsoft Visual Studio\18\Insiders\MSBuild\Current\Bin\;%PATH%
- ./PCbuild/build.bat --tail-call-interp --pgo -p ${{ matrix.architecture }} "/p:PlatformToolset=v145"
- ./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
+ choco install visualstudio2026buildtools -y --force --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --locale en-US --passive"
+ set PATH=C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;%PATH%
+ call ./PCbuild/build.bat --tail-call-interp -c Release -p ${{ matrix.architecture }} "/p:PlatformToolset=v145"
+ call ./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
# No tests (yet):
- name: Emulated Windows Clang (release)
From a75042a73e7173ea9652b1c01ead78239b7e0d52 Mon Sep 17 00:00:00 2001
From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Date: Mon, 22 Dec 2025 15:34:25 +0100
Subject: [PATCH 3/8] Alternative to restrict and conditional Py_NO_INLINE for
PyMapping_GetOptionalItem
---
Include/abstract.h | 1 +
Objects/abstract.c | 16 +++++++++-------
Python/bytecodes.c | 21 +++++++++++----------
Python/executor_cases.c.h | 12 ++++++------
Python/generated_cases.c.h | 20 ++++++++++----------
5 files changed, 37 insertions(+), 33 deletions(-)
diff --git a/Include/abstract.h b/Include/abstract.h
index 80f3298701d249..d02151306e37e0 100644
--- a/Include/abstract.h
+++ b/Include/abstract.h
@@ -887,6 +887,7 @@ PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o,
*/
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000
PyAPI_FUNC(int) PyMapping_GetOptionalItem(PyObject *, PyObject *, PyObject **);
+PyAPI_FUNC(PyObject*) PyMapping_GetOptionalItem2(PyObject *, PyObject *, int *);
PyAPI_FUNC(int) PyMapping_GetOptionalItemString(PyObject *, const char *, PyObject **);
#endif
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 1c50b6dd0d04ea..b37fe3ed60445f 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -205,14 +205,8 @@ PyObject_GetItem(PyObject *o, PyObject *key)
return type_error("'%.200s' object is not subscriptable", o);
}
-// MSVC fails during a tail call release build with loads of
-// error C4737: Unable to perform required tail call.
-// without using Py_NO_INLINE here, but PGO works fine.
-#if defined(_MSC_VER) && !defined(__clang__) && _Py_TAIL_CALL_INTERP && !defined(_Py_USING_PGO)
-Py_NO_INLINE
-#endif
int
-PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **restrict result)
+PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result)
{
if (PyDict_CheckExact(obj)) {
return PyDict_GetItemRef(obj, key, result);
@@ -230,6 +224,14 @@ PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **restrict resu
return 0;
}
+PyObject*
+PyMapping_GetOptionalItem2(PyObject *obj, PyObject *key, int *err)
+{
+ PyObject* result;
+ *err = PyMapping_GetOptionalItem(obj, key, &result);
+ return result;
+}
+
int
PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value)
{
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 66081c7051812d..0af7d741f4819c 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -1507,8 +1507,8 @@ dummy_func(
}
inst(LOAD_BUILD_CLASS, ( -- bc)) {
- PyObject *bc_o;
- int err = PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc_o);
+ int err;
+ PyObject *bc_o = PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
ERROR_IF(err < 0);
if (bc_o == NULL) {
_PyErr_SetString(tstate, PyExc_NameError,
@@ -1711,8 +1711,9 @@ dummy_func(
inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
- PyObject *v_o;
- int err = PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o);
+ int err;
+ PyObject *v_o = PyMapping_GetOptionalItem2(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &err);
+
PyStackRef_CLOSE(mod_or_class_dict);
ERROR_IF(err < 0);
if (v_o == NULL) {
@@ -1735,11 +1736,11 @@ dummy_func(
else {
/* Slow-path if globals or builtins is not a dict */
/* namespace 1: globals */
- int err = PyMapping_GetOptionalItem(GLOBALS(), name, &v_o);
+ v_o = PyMapping_GetOptionalItem2(GLOBALS(), name, &err);
ERROR_IF(err < 0);
if (v_o == NULL) {
/* namespace 2: builtins */
- int err = PyMapping_GetOptionalItem(BUILTINS(), name, &v_o);
+ v_o = PyMapping_GetOptionalItem2(BUILTINS(), name, &err);
ERROR_IF(err < 0);
if (v_o == NULL) {
_PyEval_FormatExcCheckArg(
@@ -1898,14 +1899,14 @@ dummy_func(
}
inst(LOAD_FROM_DICT_OR_DEREF, (class_dict_st -- value)) {
- PyObject *value_o;
PyObject *name;
PyObject *class_dict = PyStackRef_AsPyObjectBorrow(class_dict_st);
assert(class_dict);
assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus);
name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg);
- int err = PyMapping_GetOptionalItem(class_dict, name, &value_o);
+ int err;
+ PyObject* value_o = PyMapping_GetOptionalItem2(class_dict, name, &err);
if (err < 0) {
ERROR_NO_POP();
}
@@ -2074,14 +2075,14 @@ dummy_func(
}
inst(SETUP_ANNOTATIONS, (--)) {
- PyObject *ann_dict;
if (LOCALS() == NULL) {
_PyErr_Format(tstate, PyExc_SystemError,
"no locals found when setting up annotations");
ERROR_IF(true);
}
/* check if __annotations__ in locals()... */
- int err = PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict);
+ int err;
+ PyObject* ann_dict = PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
ERROR_IF(err < 0);
if (ann_dict == NULL) {
ann_dict = PyDict_New();
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 442f7fa2b19911..fdb547ab74734d 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -5965,9 +5965,9 @@
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef bc;
- PyObject *bc_o;
+ int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- int err = PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc_o);
+ PyObject *bc_o = PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
SET_CURRENT_CACHED_VALUES(0);
@@ -6812,17 +6812,17 @@
_PyStackRef _stack_item_0 = _tos_cache0;
oparg = CURRENT_OPARG();
class_dict_st = _stack_item_0;
- PyObject *value_o;
PyObject *name;
PyObject *class_dict = PyStackRef_AsPyObjectBorrow(class_dict_st);
assert(class_dict);
assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus);
name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg);
+ int err;
stack_pointer[0] = class_dict_st;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
- int err = PyMapping_GetOptionalItem(class_dict, name, &value_o);
+ PyObject* value_o = PyMapping_GetOptionalItem2(class_dict, name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
SET_CURRENT_CACHED_VALUES(0);
@@ -7339,7 +7339,6 @@
case _SETUP_ANNOTATIONS_r00: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
- PyObject *ann_dict;
if (LOCALS() == NULL) {
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyErr_Format(tstate, PyExc_SystemError,
@@ -7348,8 +7347,9 @@
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_ERROR();
}
+ int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- int err = PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict);
+ PyObject* ann_dict = PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
SET_CURRENT_CACHED_VALUES(0);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 5a11bf56997c77..445c3db9b995ca 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -8386,9 +8386,9 @@
next_instr += 1;
INSTRUCTION_STATS(LOAD_BUILD_CLASS);
_PyStackRef bc;
- PyObject *bc_o;
+ int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- int err = PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc_o);
+ PyObject *bc_o = PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
@@ -8599,14 +8599,14 @@
_PyStackRef class_dict_st;
_PyStackRef value;
class_dict_st = stack_pointer[-1];
- PyObject *value_o;
PyObject *name;
PyObject *class_dict = PyStackRef_AsPyObjectBorrow(class_dict_st);
assert(class_dict);
assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus);
name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg);
+ int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- int err = PyMapping_GetOptionalItem(class_dict, name, &value_o);
+ PyObject* value_o = PyMapping_GetOptionalItem2(class_dict, name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
@@ -8645,9 +8645,9 @@
_PyStackRef v;
mod_or_class_dict = stack_pointer[-1];
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
- PyObject *v_o;
+ int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- int err = PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o);
+ PyObject *v_o = PyMapping_GetOptionalItem2(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -8678,14 +8678,14 @@
}
else {
_PyFrame_SetStackPointer(frame, stack_pointer);
- int err = PyMapping_GetOptionalItem(GLOBALS(), name, &v_o);
+ v_o = PyMapping_GetOptionalItem2(GLOBALS(), name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
}
if (v_o == NULL) {
_PyFrame_SetStackPointer(frame, stack_pointer);
- int err = PyMapping_GetOptionalItem(BUILTINS(), name, &v_o);
+ v_o = PyMapping_GetOptionalItem2(BUILTINS(), name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
@@ -10199,7 +10199,6 @@
frame->instr_ptr = next_instr;
next_instr += 1;
INSTRUCTION_STATS(SETUP_ANNOTATIONS);
- PyObject *ann_dict;
if (LOCALS() == NULL) {
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyErr_Format(tstate, PyExc_SystemError,
@@ -10207,8 +10206,9 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
JUMP_TO_LABEL(error);
}
+ int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- int err = PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict);
+ PyObject* ann_dict = PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
From fdfd8a0476b5d09ea727f898d0265619fa0d573c Mon Sep 17 00:00:00 2001
From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Date: Mon, 22 Dec 2025 16:37:22 +0100
Subject: [PATCH 4/8] make _PyMapping_GetOptionalItem2 private and comment
scopes
Co-Authored-By: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Co-Authored-By: Brandt Bucher
---
Include/abstract.h | 1 -
Include/internal/pycore_ceval.h | 5 +++++
Objects/abstract.c | 2 +-
Python/bytecodes.c | 15 +++++++++------
Python/executor_cases.c.h | 6 +++---
Python/generated_cases.c.h | 12 ++++++------
6 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/Include/abstract.h b/Include/abstract.h
index d02151306e37e0..80f3298701d249 100644
--- a/Include/abstract.h
+++ b/Include/abstract.h
@@ -887,7 +887,6 @@ PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o,
*/
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000
PyAPI_FUNC(int) PyMapping_GetOptionalItem(PyObject *, PyObject *, PyObject **);
-PyAPI_FUNC(PyObject*) PyMapping_GetOptionalItem2(PyObject *, PyObject *, int *);
PyAPI_FUNC(int) PyMapping_GetOptionalItemString(PyObject *, const char *, PyObject **);
#endif
diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h
index 62dafe6b7e1cc4..c6c82038d7c85f 100644
--- a/Include/internal/pycore_ceval.h
+++ b/Include/internal/pycore_ceval.h
@@ -475,6 +475,11 @@ _Py_assert_within_stack_bounds(
_PyInterpreterFrame *frame, _PyStackRef *stack_pointer,
const char *filename, int lineno);
+// Like PyMapping_GetOptionalItem, but returns the PyObject* instead of taking
+// it as an out parameter. This helps MSVC's escape analysis when used with
+// tail calling.
+PyAPI_FUNC(PyObject*) _PyMapping_GetOptionalItem2(PyObject* obj, PyObject* key, int* err);
+
#ifdef __cplusplus
}
#endif
diff --git a/Objects/abstract.c b/Objects/abstract.c
index b37fe3ed60445f..f2c7de3d1ef1ad 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -225,7 +225,7 @@ PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result)
}
PyObject*
-PyMapping_GetOptionalItem2(PyObject *obj, PyObject *key, int *err)
+_PyMapping_GetOptionalItem2(PyObject *obj, PyObject *key, int *err)
{
PyObject* result;
*err = PyMapping_GetOptionalItem(obj, key, &result);
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 0af7d741f4819c..42dbee3fc47e38 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -1508,7 +1508,7 @@ dummy_func(
inst(LOAD_BUILD_CLASS, ( -- bc)) {
int err;
- PyObject *bc_o = PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
+ PyObject *bc_o = _PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
ERROR_IF(err < 0);
if (bc_o == NULL) {
_PyErr_SetString(tstate, PyExc_NameError,
@@ -1712,7 +1712,7 @@ dummy_func(
inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err;
- PyObject *v_o = PyMapping_GetOptionalItem2(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &err);
+ PyObject *v_o = _PyMapping_GetOptionalItem2(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &err);
PyStackRef_CLOSE(mod_or_class_dict);
ERROR_IF(err < 0);
@@ -1736,11 +1736,11 @@ dummy_func(
else {
/* Slow-path if globals or builtins is not a dict */
/* namespace 1: globals */
- v_o = PyMapping_GetOptionalItem2(GLOBALS(), name, &err);
+ v_o = _PyMapping_GetOptionalItem2(GLOBALS(), name, &err);
ERROR_IF(err < 0);
if (v_o == NULL) {
/* namespace 2: builtins */
- v_o = PyMapping_GetOptionalItem2(BUILTINS(), name, &err);
+ v_o = _PyMapping_GetOptionalItem2(BUILTINS(), name, &err);
ERROR_IF(err < 0);
if (v_o == NULL) {
_PyEval_FormatExcCheckArg(
@@ -1906,7 +1906,7 @@ dummy_func(
assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus);
name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg);
int err;
- PyObject* value_o = PyMapping_GetOptionalItem2(class_dict, name, &err);
+ PyObject* value_o = _PyMapping_GetOptionalItem2(class_dict, name, &err);
if (err < 0) {
ERROR_NO_POP();
}
@@ -2082,7 +2082,7 @@ dummy_func(
}
/* check if __annotations__ in locals()... */
int err;
- PyObject* ann_dict = PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
+ PyObject* ann_dict = _PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
ERROR_IF(err < 0);
if (ann_dict == NULL) {
ann_dict = PyDict_New();
@@ -2188,6 +2188,7 @@ dummy_func(
// handle any case whose performance we care about
PyObject *super;
{
+ // scope to tell MSVC that stack is not escaping
PyObject *stack[] = {class, self};
super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
}
@@ -2251,6 +2252,7 @@ dummy_func(
int method_found = 0;
PyObject *attr_o;
{
+ // scope to tell MSVC that method_found_ptr is not escaping
int *method_found_ptr = &method_found;
attr_o = _PySuper_Lookup(cls, self, name,
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? method_found_ptr : NULL);
@@ -3482,6 +3484,7 @@ dummy_func(
(void)lasti; // Shut up compiler warning if asserts are off
PyObject* res_o;
{
+ // scope to tell MSVC that stack is not escaping
PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
int has_self = !PyStackRef_IsNull(exit_self);
res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index fdb547ab74734d..c2969bb596aa5f 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -5967,7 +5967,7 @@
_PyStackRef bc;
int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *bc_o = PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
+ PyObject *bc_o = _PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
SET_CURRENT_CACHED_VALUES(0);
@@ -6822,7 +6822,7 @@
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject* value_o = PyMapping_GetOptionalItem2(class_dict, name, &err);
+ PyObject* value_o = _PyMapping_GetOptionalItem2(class_dict, name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
SET_CURRENT_CACHED_VALUES(0);
@@ -7349,7 +7349,7 @@
}
int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject* ann_dict = PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
+ PyObject* ann_dict = _PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
SET_CURRENT_CACHED_VALUES(0);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 445c3db9b995ca..3b7ac33b26ae92 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -8388,7 +8388,7 @@
_PyStackRef bc;
int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *bc_o = PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
+ PyObject *bc_o = _PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
@@ -8606,7 +8606,7 @@
name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg);
int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject* value_o = PyMapping_GetOptionalItem2(class_dict, name, &err);
+ PyObject* value_o = _PyMapping_GetOptionalItem2(class_dict, name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
@@ -8647,7 +8647,7 @@
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *v_o = PyMapping_GetOptionalItem2(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &err);
+ PyObject *v_o = _PyMapping_GetOptionalItem2(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -8678,14 +8678,14 @@
}
else {
_PyFrame_SetStackPointer(frame, stack_pointer);
- v_o = PyMapping_GetOptionalItem2(GLOBALS(), name, &err);
+ v_o = _PyMapping_GetOptionalItem2(GLOBALS(), name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
}
if (v_o == NULL) {
_PyFrame_SetStackPointer(frame, stack_pointer);
- v_o = PyMapping_GetOptionalItem2(BUILTINS(), name, &err);
+ v_o = _PyMapping_GetOptionalItem2(BUILTINS(), name, &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
@@ -10208,7 +10208,7 @@
}
int err;
_PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject* ann_dict = PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
+ PyObject* ann_dict = _PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
JUMP_TO_LABEL(error);
From c8d051ba8122870fdf69e251795d06d883829d3a Mon Sep 17 00:00:00 2001
From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Date: Mon, 22 Dec 2025 17:44:46 +0100
Subject: [PATCH 5/8] Apply suggestions from code review
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
---
.github/workflows/tail-call.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml
index 627fc34a6b78e0..f4d2408a22917e 100644
--- a/.github/workflows/tail-call.yml
+++ b/.github/workflows/tail-call.yml
@@ -81,7 +81,7 @@ jobs:
- name: Native Windows MSVC (release)
if: runner.os == 'Windows' && matrix.architecture != 'ARM64'
- shell: cmd
+ shell: pwsh
run: |
choco install visualstudio2026buildtools -y --force --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --locale en-US --passive"
set PATH=C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;%PATH%
@@ -91,7 +91,7 @@ jobs:
# No tests (yet):
- name: Emulated Windows Clang (release)
if: runner.os == 'Windows' && matrix.architecture == 'ARM64'
- shell: cmd
+ shell: pwsh
run: |
choco install llvm --allow-downgrade --no-progress --version ${{ matrix.llvm }}.1.0
set PlatformToolset=clangcl
From ab70524effc3ded3b24e0b6bde197f3461ef0388 Mon Sep 17 00:00:00 2001
From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Date: Mon, 22 Dec 2025 17:45:28 +0100
Subject: [PATCH 6/8] Update .github/workflows/tail-call.yml
I could not add this one to batch, so have to do it separately
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
---
.github/workflows/tail-call.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml
index f4d2408a22917e..a0c8bca7fb7937 100644
--- a/.github/workflows/tail-call.yml
+++ b/.github/workflows/tail-call.yml
@@ -84,9 +84,9 @@ jobs:
shell: pwsh
run: |
choco install visualstudio2026buildtools -y --force --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --locale en-US --passive"
- set PATH=C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;%PATH%
- call ./PCbuild/build.bat --tail-call-interp -c Release -p ${{ matrix.architecture }} "/p:PlatformToolset=v145"
- call ./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
+ $env:PATH = "C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;$env:PATH"
+ ./PCbuild/build.bat --tail-call-interp -c Release -p ${{ matrix.architecture }} "/p:PlatformToolset=v145"
+ ./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
# No tests (yet):
- name: Emulated Windows Clang (release)
From 5c1c240c59b5e8ab37ec84742dc27d44dc57054f Mon Sep 17 00:00:00 2001
From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Date: Mon, 22 Dec 2025 18:13:23 +0100
Subject: [PATCH 7/8] enable "Emulated Windows Clang (release)"
try to fix "Native Windows MSVC (release)"
---
.github/workflows/tail-call.yml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml
index a0c8bca7fb7937..055c8027d4fd27 100644
--- a/.github/workflows/tail-call.yml
+++ b/.github/workflows/tail-call.yml
@@ -53,9 +53,9 @@ jobs:
- target: x86_64-pc-windows-msvc/msvc
architecture: x64
runner: windows-2022
-# - target: aarch64-pc-windows-msvc/msvc
-# architecture: ARM64
-# runner: windows-2022
+ - target: aarch64-pc-windows-msvc/msvc
+ architecture: ARM64
+ runner: windows-2022
- target: x86_64-apple-darwin/clang
architecture: x86_64
runner: macos-15-intel
@@ -84,7 +84,7 @@ jobs:
shell: pwsh
run: |
choco install visualstudio2026buildtools -y --force --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --locale en-US --passive"
- $env:PATH = "C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;$env:PATH"
+ set PATH=C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;%PATH%
./PCbuild/build.bat --tail-call-interp -c Release -p ${{ matrix.architecture }} "/p:PlatformToolset=v145"
./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
From da1adaf41e08d367cf6e45e181ebbfd4a065f11c Mon Sep 17 00:00:00 2001
From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Date: Mon, 22 Dec 2025 19:16:34 +0100
Subject: [PATCH 8/8] revert to cmd but keep Hugo's other changes
add --no-progress to choco
---
.github/workflows/tail-call.yml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml
index 055c8027d4fd27..76a8c05aa52ed2 100644
--- a/.github/workflows/tail-call.yml
+++ b/.github/workflows/tail-call.yml
@@ -53,9 +53,9 @@ jobs:
- target: x86_64-pc-windows-msvc/msvc
architecture: x64
runner: windows-2022
- - target: aarch64-pc-windows-msvc/msvc
- architecture: ARM64
- runner: windows-2022
+# - target: aarch64-pc-windows-msvc/msvc
+# architecture: ARM64
+# runner: windows-2022
- target: x86_64-apple-darwin/clang
architecture: x86_64
runner: macos-15-intel
@@ -81,17 +81,17 @@ jobs:
- name: Native Windows MSVC (release)
if: runner.os == 'Windows' && matrix.architecture != 'ARM64'
- shell: pwsh
+ shell: cmd
run: |
- choco install visualstudio2026buildtools -y --force --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --locale en-US --passive"
- set PATH=C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;%PATH%
+ choco install visualstudio2026buildtools --no-progress -y --force --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --locale en-US --passive"
+ $env:PATH = "C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;$env:PATH"
./PCbuild/build.bat --tail-call-interp -c Release -p ${{ matrix.architecture }} "/p:PlatformToolset=v145"
./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
# No tests (yet):
- name: Emulated Windows Clang (release)
if: runner.os == 'Windows' && matrix.architecture == 'ARM64'
- shell: pwsh
+ shell: cmd
run: |
choco install llvm --allow-downgrade --no-progress --version ${{ matrix.llvm }}.1.0
set PlatformToolset=clangcl