diff options
author | Mark Shannon <mark@hotpy.org> | 2025-03-07 14:30:31 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-07 14:30:31 +0000 |
commit | 89df62c12093bfa079860a93032468ebece3774d (patch) | |
tree | e982ec3b0a29f1c8fb727e0fe4b49b62909b5fb0 /Python/assemble.c | |
parent | e5527f2cdda501542bf94179093e1a15d7889b74 (diff) | |
download | cpython-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.c | 11 |
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; } |