8000 GH-96793: Change `FOR_ITER` to not pop the iterator on exhaustion. (G… · python/cpython@22863df · GitHub
[go: up one dir, main page]

Skip to content

Commit 22863df

Browse files
authored
GH-96793: Change FOR_ITER to not pop the iterator on exhaustion. (GH-96801)
Change FOR_ITER to have the same stack effect regardless of whether it branches or not. Performance is unchanged as FOR_ITER (and specialized forms jump over the cleanup code).
1 parent e60892f commit 22863df

File tree

14 files changed

+277
-247
lines changed
  • Python
  • 14 files changed

    +277
    -247
    lines changed

    Doc/library/dis.rst

    Lines changed: 12 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -413,6 +413,15 @@ The Python compiler currently generates the following bytecode instructions.
    413413
    Removes the top-of-stack (TOS) item.
    414414

    415415

    416+
    .. opcode:: END_FOR
    417+
    418+
    Removes the top two values from the stack.
    419+
    Equivalent to POP_TOP; POP_TOP.
    420+
    Used to clean up at the end of loops, hence the name.
    421+
    422+
    .. versionadded:: 3.12
    423+
    424+
    416425
    .. opcode:: COPY (i)
    417426

    418427
    Push the *i*-th item to the top of the stack. The item is not removed from its
    @@ -1088,9 +1097,11 @@ iterations of the loop.
    10881097

    10891098
    TOS is an :term:`iterator`. Call its :meth:`~iterator.__next__` method. If
    10901099
    this yields a new value, push it on the stack (leaving the iterator below
    1091-
    it). If the iterator indicates it is exhausted, TOS is popped, and the byte
    1100+
    it). If the iterator indicates it is exhausted then the byte
    10921101
    code counter is incremented by *delta*.
    10931102

    1103+
    .. versionchanged:: 3.12
    1104+
    Up until 3.11 the iterator was popped when it was exhausted.
    10941105

    10951106
    .. opcode:: LOAD_GLOBAL (namei)
    10961107

    Include/internal/pycore_opcode.h

    Lines changed: 20 additions & 20 deletions
    Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

    Include/opcode.h

    Lines changed: 73 additions & 72 deletions
    Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

    Lib/importlib/_bootstrap_external.py

    Lines changed: 2 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -423,6 +423,7 @@ def _write_atomic(path, data, mode=0o666):
    423423
    # Python 3.12a1 3507 (Set lineno of module's RESUME to 0)
    424424
    # Python 3.12a1 3508 (Add CLEANUP_THROW)
    425425
    # Python 3.12a1 3509 (Conditional jumps only jump forward)
    426+
    # Python 3.12a1 3510 (FOR_ITER leaves iterator on the stack)
    426427

    427428
    # Python 3.13 will start with 3550
    428429

    @@ -435,7 +436,7 @@ def _write_atomic(path, data, mode=0o666):
    435436
    # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
    436437
    # in PC/launcher.c must also be updated.
    437438

    438-
    MAGIC_NUMBER = (3509).to_bytes(2, 'little') + b'\r\n'
    439+
    MAGIC_NUMBER = (3510).to_bytes(2, 'little') + b'\r\n'
    439440

    440441
    _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
    441442

    Lib/opcode.py

    Lines changed: 2 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -78,6 +78,8 @@ def pseudo_op(name, op, real_ops):
    7878
    def_op('POP_TOP', 1)
    7979
    def_op('PUSH_NULL', 2)
    8080

    81+
    def_op('END_FOR', 4)
    82+
    8183
    def_op('NOP', 9)
    8284
    def_op('UNARY_POSITIVE', 10)
    8385
    def_op('UNARY_NEGATIVE', 11)

    0 commit comments

    Comments
     (0)
    0