← board

i386: a stackless generator called through a cursor reads its instance from the wrong slot

def gen(n):
    i = 0
    while i < n:
        yield i * 10
        i += 1
g = gen(4)
print(next(g), next(g))     # i386: empty or garbage; expected 0 10
print(list(gen(3)))         # i386: []; expected [0, 10, 20]

A for loop over the generator worked, which is the boundary.

Mechanism

The step ABI is function(__genself: Pointer): Boolean; the declared parameters live in instance slots. The for desugar still passes one pad per declared parameter (the register targets pop ParamCount argument registers), and the pygen_iter_new cursor calls the step through a pointer with ONE argument. On register targets the two agree. On i386 the instance is pushed first, so it sits deepest, and the callee's [ebp+8] held the last pad or the caller's frame.

Fix

The pads are a zero literal or the instance variable, so dropping them leaves out no evaluation that matters.

Test

test/test_nilpy_cross32_values.py (first block), with a row in test-i386. Measured wrong with pin v446 (stable_linux_amd64/default/stable_pinned) on 2026-09-28.