From 06b063e58ac59c09c1ee95625d52c598e8a43c63 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 3 May 2026 10:25:11 +0300 Subject: [PATCH 1/2] gh-149243: Check for recursion limits in `CALL_ALLOC_AND_ENTER_INIT` --- .jit-stamp | 0 Include/internal/pycore_opcode_metadata.h | 2 +- .../2026-05-03-10-24-50.gh-issue-149243.Zh1q9_.rst | 1 + Modules/_testinternalcapi/test_cases.c.h | 8 ++++++++ Python/bytecodes.c | 1 + Python/generated_cases.c.h | 8 ++++++++ jit_unwind_info-aarch64-apple-darwin.h | 4 ++++ jit_unwind_info.h | 6 ++++++ 8 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 .jit-stamp create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-03-10-24-50.gh-issue-149243.Zh1q9_.rst create mode 100644 jit_unwind_info-aarch64-apple-darwin.h create mode 100644 jit_unwind_info.h diff --git a/.jit-stamp b/.jit-stamp new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 4f8b48db23d1ef..0d7e367a5618b2 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1386,7 +1386,7 @@ _PyOpcode_macro_expansion[256] = { [BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, OPARG_SIMPLE, 0 } } }, [BUILD_TEMPLATE] = { .nuops = 1, .uops = { { _BUILD_TEMPLATE, OPARG_SIMPLE, 0 } } }, [BUILD_TUPLE] = { .nuops = 1, .uops = { { _BUILD_TUPLE, OPARG_SIMPLE, 0 } } }, - [CALL_ALLOC_AND_ENTER_INIT] = { .nuops = 6, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_OBJECT, 2, 1 }, { _ALLOCATE_OBJECT, OPARG_SIMPLE, 3 }, { _CREATE_INIT_FRAME, OPARG_SIMPLE, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, + [CALL_ALLOC_AND_ENTER_INIT] = { .nuops = 7, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_OBJECT, 2, 1 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _ALLOCATE_OBJECT, OPARG_SIMPLE, 3 }, { _CREATE_INIT_FRAME, OPARG_SIMPLE, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 11, .uops = { { _RECORD_BOUND_METHOD, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_BOUND_METHOD_GENERAL] = { .nuops = 8, .uops = { { _RECORD_BOUND_METHOD, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_METHOD_VERSION, 2, 1 }, { _EXPAND_METHOD, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_BUILTIN_CLASS] = { .nuops = 6, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _GUARD_CALLABLE_BUILTIN_CLASS, OPARG_SIMPLE, 3 }, { _CALL_BUILTIN_CLASS, OPARG_SIMPLE, 3 }, { _POP_TOP_OPARG, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-03-10-24-50.gh-issue-149243.Zh1q9_.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-03-10-24-50.gh-issue-149243.Zh1q9_.rst new file mode 100644 index 00000000000000..5c1956fe398364 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-03-10-24-50.gh-issue-149243.Zh1q9_.rst @@ -0,0 +1 @@ +Check for recursion limits in ``CALL_ALLOC_AND_ENTER_INIT`` opcode. diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 8897854078bd45..bd69211fd22206 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -1925,6 +1925,14 @@ JUMP_TO_PREDICTED(CALL); } } + // _CHECK_RECURSION_REMAINING + { + if (tstate->py_recursion_remaining <= 1) { + UPDATE_MISS_STATS(CALL); + assert(_PyOpcode_Deopt[opcode] == (CALL)); + JUMP_TO_PREDICTED(CALL); + } + } // _ALLOCATE_OBJECT { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 4239ba58bc390b..963391e7598fb6 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4737,6 +4737,7 @@ dummy_func( unused/1 + _CHECK_PEP_523 + _CHECK_OBJECT + + _CHECK_RECURSION_REMAINING + _ALLOCATE_OBJECT + _CREATE_INIT_FRAME + _PUSH_FRAME; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index dccee0e4a3b110..105375e41e360b 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1925,6 +1925,14 @@ JUMP_TO_PREDICTED(CALL); } } + // _CHECK_RECURSION_REMAINING + { + if (tstate->py_recursion_remaining <= 1) { + UPDATE_MISS_STATS(CALL); + assert(_PyOpcode_Deopt[opcode] == (CALL)); + JUMP_TO_PREDICTED(CALL); + } + } // _ALLOCATE_OBJECT { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); diff --git a/jit_unwind_info-aarch64-apple-darwin.h b/jit_unwind_info-aarch64-apple-darwin.h new file mode 100644 index 00000000000000..82f927bd6e96bd --- /dev/null +++ b/jit_unwind_info-aarch64-apple-darwin.h @@ -0,0 +1,4 @@ +// c304ed754b0b65e0196cd50024bcbed7c38e65943d48292f97d34e35ddca13a6 +// $ python3.14 ./Tools/jit/build.py aarch64-apple-darwin24.6.0 --output-dir . --pyconfig-dir . --cflags= --llvm-version= --llvm-tools-install-dir= --debug + +#define JIT_UNWIND_INFO_SUPPORTED 0 diff --git a/jit_unwind_info.h b/jit_unwind_info.h new file mode 100644 index 00000000000000..915fd9015bb359 --- /dev/null +++ b/jit_unwind_info.h @@ -0,0 +1,6 @@ +// $ python3.14 ./Tools/jit/build.py aarch64-apple-darwin24.6.0 --output-dir . --pyconfig-dir . --cflags= --llvm-version= --llvm-tools-install-dir= --debug +#if defined(__aarch64__) && defined(__APPLE__) +#include "jit_unwind_info-aarch64-apple-darwin.h" +#else +#error "unexpected target" +#endif From 6ed96f1459c1af5c2c18d14d91b3d931b3ae05c7 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 3 May 2026 12:34:42 +0300 Subject: [PATCH 2/2] Ignore generated files --- .jit-stamp | 0 jit_unwind_info-aarch64-apple-darwin.h | 4 ---- jit_unwind_info.h | 6 ------ 3 files changed, 10 deletions(-) delete mode 100644 .jit-stamp delete mode 100644 jit_unwind_info-aarch64-apple-darwin.h delete mode 100644 jit_unwind_info.h diff --git a/.jit-stamp b/.jit-stamp deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/jit_unwind_info-aarch64-apple-darwin.h b/jit_unwind_info-aarch64-apple-darwin.h deleted file mode 100644 index 82f927bd6e96bd..00000000000000 --- a/jit_unwind_info-aarch64-apple-darwin.h +++ /dev/null @@ -1,4 +0,0 @@ -// c304ed754b0b65e0196cd50024bcbed7c38e65943d48292f97d34e35ddca13a6 -// $ python3.14 ./Tools/jit/build.py aarch64-apple-darwin24.6.0 --output-dir . --pyconfig-dir . --cflags= --llvm-version= --llvm-tools-install-dir= --debug - -#define JIT_UNWIND_INFO_SUPPORTED 0 diff --git a/jit_unwind_info.h b/jit_unwind_info.h deleted file mode 100644 index 915fd9015bb359..00000000000000 --- a/jit_unwind_info.h +++ /dev/null @@ -1,6 +0,0 @@ -// $ python3.14 ./Tools/jit/build.py aarch64-apple-darwin24.6.0 --output-dir . --pyconfig-dir . --cflags= --llvm-version= --llvm-tools-install-dir= --debug -#if defined(__aarch64__) && defined(__APPLE__) -#include "jit_unwind_info-aarch64-apple-darwin.h" -#else -#error "unexpected target" -#endif