From d63997e495b1072fd73a4e35a8de1b4687b42728 Mon Sep 17 00:00:00 2001 From: Mikhail Efimov Date: Thu, 13 Nov 2025 12:50:37 +0300 Subject: [PATCH 1/5] Backport --- Lib/test/test_capi/test_opt.py | 21 ++++++++++++++++ ...-10-16-21-47-00.gh-issue-140104.A8SQIm.rst | 2 ++ Python/ceval_macros.h | 25 ++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-10-16-21-47-00.gh-issue-140104.A8SQIm.rst diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index c74c8ee0eef8e2..bdcda12c76e1bc 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1972,6 +1972,27 @@ def testfunc(n): assert ex is not None """)) + def test_next_instr_for_exception_handler_set(self): + # gh-140104: We just want the exception to be caught properly. + def f(): + for i in range(TIER2_THRESHOLD + 3): + try: + undefined_variable(i) + except Exception: + pass + + f() + + def test_next_instr_for_exception_handler_set_lasts_instr(self): + # gh-140104: We just want the exception to be caught properly. + def f(): + a_list = [] + for _ in range(TIER2_THRESHOLD + 3): + try: + a_list[""] = 0 + except Exception: + pass + def global_identity(x): return x diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-16-21-47-00.gh-issue-140104.A8SQIm.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-16-21-47-00.gh-issue-140104.A8SQIm.rst new file mode 100644 index 00000000000000..1c18cbc9ad0588 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-16-21-47-00.gh-issue-140104.A8SQIm.rst @@ -0,0 +1,2 @@ +Fix a bug with exception handling in the JIT. Patch by Ken Jin. Bug reported +by Daniel Diniz. diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 37c4b00f86df25..e09f5a2fc596e0 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -376,7 +376,9 @@ do { \ frame = tstate->current_frame; \ stack_pointer = _PyFrame_GetStackPointer(frame); \ if (next_instr == NULL) { \ - next_instr = frame->instr_ptr; \ + /* gh-140104: The exception handler expects frame->instr_ptr + to after this_instr, not this_instr! */ \ + next_instr = frame->instr_ptr + 1; \ JUMP_TO_LABEL(error); \ } \ DISPATCH(); \ @@ -393,6 +395,7 @@ do { \ } while (0) #endif +#ifdef _Py_JIT #define GOTO_TIER_ONE(TARGET) \ do \ { \ @@ -409,6 +412,26 @@ do { \ } \ DISPATCH(); \ } while (0) +#else +#define GOTO_TIER_ONE(TARGET) \ + do \ + { \ + tstate->current_executor = NULL; \ + next_instr = (TARGET); \ + assert(tstate->current_executor == NULL); \ + OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); \ + _PyFrame_SetStackPointer(frame, stack_pointer); \ + stack_pointer = _PyFrame_GetStackPointer(frame); \ + if (next_instr == NULL) \ + { \ + /* gh-140104: The exception handler expects frame->instr_ptr + to after this_instr, not this_instr! */ \ + next_instr = frame->instr_ptr + 1; \ + goto error; \ + } \ + DISPATCH(); \ + } while (0) +#endif #define CURRENT_OPARG() (next_uop[-1].oparg) #define CURRENT_OPERAND0() (next_uop[-1].operand0) From 830cfbe42708c2fd4d47946fa25393dd3ad7512f Mon Sep 17 00:00:00 2001 From: Mikhail Efimov Date: Thu, 13 Nov 2025 14:09:59 +0300 Subject: [PATCH 2/5] Simplify GOTO_TIER_ONE --- Python/ceval_macros.h | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index e09f5a2fc596e0..4a878d6dff4353 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -395,24 +395,6 @@ do { \ } while (0) #endif -#ifdef _Py_JIT -#define GOTO_TIER_ONE(TARGET) \ - do \ - { \ - tstate->current_executor = NULL; \ - next_instr = (TARGET); \ - assert(tstate->current_executor == NULL); \ - OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); \ - _PyFrame_SetStackPointer(frame, stack_pointer); \ - stack_pointer = _PyFrame_GetStackPointer(frame); \ - if (next_instr == NULL) \ - { \ - next_instr = frame->instr_ptr; \ - goto error; \ - } \ - DISPATCH(); \ - } while (0) -#else #define GOTO_TIER_ONE(TARGET) \ do \ { \ @@ -431,7 +413,6 @@ do { \ } \ DISPATCH(); \ } while (0) -#endif #define CURRENT_OPARG() (next_uop[-1].oparg) #define CURRENT_OPERAND0() (next_uop[-1].operand0) From c3442cd8a34b9633dfc4ae93db0e4e495f3236e3 Mon Sep 17 00:00:00 2001 From: Mikhail Efimov Date: Thu, 13 Nov 2025 18:31:29 +0300 Subject: [PATCH 3/5] Trigger CI --- Python/jit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/jit.c b/Python/jit.c index 9fbd8a18590411..01a82f7de53d2d 100644 --- a/Python/jit.c +++ b/Python/jit.c @@ -583,5 +583,6 @@ _PyJIT_Free(_PyExecutorObject *executor) } } } +// FIXME: remove this comment. #endif // _Py_JIT From b19661656a40bf2e92218bfa51211a519bd7e6f9 Mon Sep 17 00:00:00 2001 From: Mikhail Efimov Date: Thu, 13 Nov 2025 18:35:47 +0300 Subject: [PATCH 4/5] Trigger JIT CI --- Python/jit.c | 1 - Tools/jit/template.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/jit.c b/Python/jit.c index 01a82f7de53d2d..9fbd8a18590411 100644 --- a/Python/jit.c +++ b/Python/jit.c @@ -583,6 +583,5 @@ _PyJIT_Free(_PyExecutorObject *executor) } } } -// FIXME: remove this comment. #endif // _Py_JIT diff --git a/Tools/jit/template.c b/Tools/jit/template.c index d042699680c639..355ad19b20d419 100644 --- a/Tools/jit/template.c +++ b/Tools/jit/template.c @@ -123,3 +123,4 @@ _JIT_ENTRY(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState } PATCH_JUMP(_JIT_CONTINUE); } +// FIXME: remove this comment. From 781dbda77a2b771635d127bef89e1d9bd4ce854a Mon Sep 17 00:00:00 2001 From: Mikhail Efimov Date: Thu, 13 Nov 2025 19:13:27 +0300 Subject: [PATCH 5/5] Revert JIT file temporary change --- Tools/jit/template.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Tools/jit/template.c b/Tools/jit/template.c index 355ad19b20d419..d042699680c639 100644 --- a/Tools/jit/template.c +++ b/Tools/jit/template.c @@ -123,4 +123,3 @@ _JIT_ENTRY(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState } PATCH_JUMP(_JIT_CONTINUE); } -// FIXME: remove this comment.