aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/assemble.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2025-03-07 14:30:31 +0000
committerGitHub <noreply@github.com>2025-03-07 14:30:31 +0000
commit89df62c12093bfa079860a93032468ebece3774d (patch)
treee982ec3b0a29f1c8fb727e0fe4b49b62909b5fb0 /Python/assemble.c
parente5527f2cdda501542bf94179093e1a15d7889b74 (diff)
downloadcpython-89df62c12093bfa079860a93032468ebece3774d.tar.gz
cpython-89df62c12093bfa079860a93032468ebece3774d.zip
GH-128534: Fix behavior of branch monitoring for `async for` (GH-130847)
* Both branches in a pair now have a common source and are included in co_branches
Diffstat (limited to 'Python/assemble.c')
-rw-r--r--Python/assemble.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/Python/assemble.c b/Python/assemble.c
index 070be1ca54e..e33918edf8e 100644
--- a/Python/assemble.c
+++ b/Python/assemble.c
@@ -632,6 +632,10 @@ error:
return co;
}
+
+// The offset (in code units) of the END_SEND from the SEND in the `yield from` sequence.
+#define END_SEND_OFFSET 5
+
static int
resolve_jump_offsets(instr_sequence *instrs)
{
@@ -670,7 +674,12 @@ resolve_jump_offsets(instr_sequence *instrs)
if (OPCODE_HAS_JUMP(instr->i_opcode)) {
instruction *target = &instrs->s_instrs[instr->i_target];
instr->i_oparg = target->i_offset;
- if (instr->i_oparg < offset) {
+ if (instr->i_opcode == END_ASYNC_FOR) {
+ // sys.monitoring needs to be able to find the matching END_SEND
+ // but the target is the SEND, so we adjust it here.
+ instr->i_oparg = offset - instr->i_oparg - END_SEND_OFFSET;
+ }
+ else if (instr->i_oparg < offset) {
assert(IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
instr->i_oparg = offset - instr->i_oparg;
}