From 58c2e83d561e47f7238aff6cc5ed733fc96129c0 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Thu, 19 Feb 2026 19:18:17 +0000 Subject: [PATCH 1/3] Maintain stack consistency in CALL_BOUND_METHOD_GENERAL --- Include/internal/pycore_opcode_metadata.h | 2 +- Python/bytecodes.c | 4 +++- Python/generated_cases.c.h | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index a3d31bcbc4ab54..610e3cc2f2024d 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1221,7 +1221,7 @@ _PyOpcode_macro_expansion[256] = { [BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, 0, 0 } } }, [BUILD_TUPLE] = { .nuops = 1, .uops = { { _BUILD_TUPLE, 0, 0 } } }, [CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 9, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _CHECK_RECURSION_REMAINING, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } }, - [CALL_BOUND_METHOD_GENERAL] = { .nuops = 7, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_METHOD_VERSION, 2, 1 }, { _EXPAND_METHOD, 0, 0 }, { _CHECK_RECURSION_REMAINING, 0, 0 }, { _PY_FRAME_GENERAL, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } }, + [CALL_BOUND_METHOD_GENERAL] = { .nuops = 7, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_RECURSION_REMAINING, 0, 0 }, { _CHECK_METHOD_VERSION, 2, 1 }, { _EXPAND_METHOD, 0, 0 }, { _PY_FRAME_GENERAL, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } }, [CALL_BUILTIN_CLASS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_CLASS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } }, [CALL_BUILTIN_FAST] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } }, [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } }, diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 42cddac048f3f6..de67f7a27a7b60 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3241,9 +3241,11 @@ dummy_func( macro(CALL_BOUND_METHOD_GENERAL) = unused/1 + // Skip over the counter _CHECK_PEP_523 + + // gh-145008: We must check recursion before expanding method, + // otherwise we may leave the stack in an inconsistent state in 3.13. + _CHECK_RECURSION_REMAINING + _CHECK_METHOD_VERSION + _EXPAND_METHOD + - _CHECK_RECURSION_REMAINING + _PY_FRAME_GENERAL + _SAVE_RETURN_OFFSET + _PUSH_FRAME; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index d21499b2f5724a..ad49becdfcaa67 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1024,6 +1024,10 @@ { DEOPT_IF(tstate->interp->eval_frame, CALL); } + // _CHECK_RECURSION_REMAINING + { + DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL); + } // _CHECK_METHOD_VERSION null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1047,10 +1051,6 @@ Py_INCREF(method); Py_DECREF(callable); } - // _CHECK_RECURSION_REMAINING - { - DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL); - } // _PY_FRAME_GENERAL args = &stack_pointer[-oparg]; self_or_null = self; From d60638ab56451a86aa92dc37109de7fbf7c49ba4 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 19:23:21 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-02-19-19-23-12.gh-issue-145008.tHYQv6.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-19-23-12.gh-issue-145008.tHYQv6.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-19-23-12.gh-issue-145008.tHYQv6.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-19-23-12.gh-issue-145008.tHYQv6.rst new file mode 100644 index 00000000000000..d378d2acb6924a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-19-23-12.gh-issue-145008.tHYQv6.rst @@ -0,0 +1 @@ +Fix a bug when calling certain methods at the recursion limit which manifested as a corruption of Python's operand stack. Patch by Ken Jin. From 51e6f71f55caa3372dab373885fa2c6306330eb9 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Thu, 19 Feb 2026 19:26:08 +0000 Subject: [PATCH 3/3] lint --- Python/bytecodes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index de67f7a27a7b60..24568489f2d25d 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3243,7 +3243,7 @@ dummy_func( _CHECK_PEP_523 + // gh-145008: We must check recursion before expanding method, // otherwise we may leave the stack in an inconsistent state in 3.13. - _CHECK_RECURSION_REMAINING + + _CHECK_RECURSION_REMAINING + _CHECK_METHOD_VERSION + _EXPAND_METHOD + _PY_FRAME_GENERAL +