Skip to content

Recognize modern loop back edges at EXTENDED_ARG prefixes - #11

Open
EiNSTeiN- wants to merge 3 commits into
ejfkdev:mainfrom
EiNSTeiN-:fix/loop-extended-argument-prefix
Open

EiNSTeiN- wants to merge 3 commits into
ejfkdev:mainfrom
EiNSTeiN-:fix/loop-extended-argument-prefix

Conversation

@EiNSTeiN-

@EiNSTeiN- EiNSTeiN- commented Oct 13, 2026 •

Copy link
Copy Markdown

I am opening this PR to preserve a handler's continue when a large loop's back edge lands on an EXTENDED_ARG prefix. Large variants of the following loop currently lose that continue during decompilation:

def select(rows, work):
    result = []
    for row in rows:
        try:
            work(row)
            # Additional work(row) statements make the loop operand
            # large enough to require EXTENDED_ARG.
        except ValueError:
            continue
        result.append(row)
    return result

With thirty or sixty calls in the protected body, the affected part currently becomes:

        except ValueError:
            pass
        result.append(row)

A rejected row therefore reaches result.append instead of starting the next iteration.

The decoded loop starts at FOR_ITER, while a valid back edge can target the EXTENDED_ARG prefix immediately before it. The current prefix recognizer excludes all Python 3.11+ input to avoid mistaking inline cache bytes for a prefix. The change permits a modern prefix only after checking word alignment and proving that every original two-byte instruction between the target and FOR_ITER is EXTENDED_ARG.

The alignment and original-byte checks exclude CACHE tails from valid loop targets. The older prefix-recognition path keeps its existing handling.

The same prefix comparison is used when checking for later back edges, so recognizing the prefix does not close a loop that still has a path back to its start. When a forward conditional skips a back edge, that edge stays inside the branch it terminates; this preserves the branch's statements and its recompiled jumps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant