gh-145866: Convert END_[FOR/SEND] to leave its inputs on the stack to be cleaned up by _POP_TOP#148477
gh-145866: Convert END_[FOR/SEND] to leave its inputs on the stack to be cleaned up by _POP_TOP#148477NekoAsakura wants to merge 3 commits intopython:mainfrom
END_[FOR/SEND] to leave its inputs on the stack to be cleaned up by _POP_TOP#148477Conversation
…stack to be cleaned up by `_POP_TOP`
|
#146185 (comment) |
| no_save_ip inst(END_FOR, (value -- )) { | ||
| /* Don't update instr_ptr, so that POP_ITER sees | ||
| * the FOR_ITER as the previous instruction. | ||
| * This has the benign side effect that if value is | ||
| * finalized it will see the location as the FOR_ITER's. | ||
| */ |
There was a problem hiding this comment.
Remove the no_save_ip will change the INSTRUMENTED_POP_ITER's prev_instr from FOR_ITER to END_FOR, this may affect the sys.monitoring callback and may cause differences in behavior between for loops that use generators and other for loops, such as for x in [1,2,3].
| res = PyStackRef_NULL; | ||
| } | ||
|
|
||
| no_save_ip inst(END_FOR, (value -- )) { |
There was a problem hiding this comment.
And END_FOR will be executed. You can try:
def foo():
yield 42
for x in foo():
pass
|
Good catch, thanks for pointing that out. You're right, I added a new test that captures this. I'm starting to wonder whether this change is actually worth it for |
…to be cleaned up by `_POP_TOP`
If I (and opus...) am not mistaken, no code path actually jumps to
END_FOR. It's only there forFOR_ITER's oparg calibration and as an instrumentation slot (gets swapped toINSTRUMENTED_END_FOR). So converting it tomacro(END_FOR) = POP_TOPshould be safe.PyStackRef_CLOSEorPyStackRef_XCLOSEdoesn't matter.ref:
_FOR_ITERcpython/Python/bytecodes.c
Line 3631 in 03d2f03
INSTRUMENTED_FOR_ITERcpython/Python/bytecodes.c
Line 3661 in 03d2f03
_ITER_JUMP_LISTcpython/Python/bytecodes.c
Line 3690 in 03d2f03
_ITER_NEXT_LIST(free-threaded)cpython/Python/bytecodes.c
Line 3719 in 03d2f03
_ITER_JUMP_TUPLEcpython/Python/bytecodes.c
Line 3767 in 03d2f03
_ITER_JUMP_RANGEcpython/Python/bytecodes.c
Line 3811 in 03d2f03
_FOR_ITER_TIER_TWOcpython/Python/bytecodes.c
Lines 3644 to 3645 in 03d2f03
_FOR_ITER_GEN_FRAMEcpython/Python/bytecodes.c
Line 3855 in 03d2f03
codegen_unwind_fblockcpython/Python/codegen.c
Lines 546 to 553 in 03d2f03
_POP_TOP#145866