← board

A Variant store of an object does not retain on wasm32

pop = [10, 20, 30]
v = pop
v = 1
print(len(pop))      # wasm32 before: 0 (PXX_HEAP_DEBUG: -572662307), CPython 3

for i in range(3):
    random.shuffle(pop)
    print(len(pop))  # wasm32 before: 5 0 0

Cause

WasmVariantPayload (compiler/ir_codegen_wasm32.inc) widened a class pointer to the 8-byte payload with no retain. Every other backend's IR_VAR_STORE class arm calls PXXObjRetain unless IRNodeOwnsManagedObj says the source already owns its +1. A pylib function doing Result := someList; PXXObjRelease(someList) also returned a freed list.

Measured

Fix

In WasmVariantPayload, a tyClass arm: emit the pointer, then PXXObjRetain it unless IRNodeOwnsManagedObj(valNode), then zero-extend it into the payload. Both callers (IR_VAR_STORE, IR_VAR_BOX) evaluate the payload before the destination address, so the scratch local is free at that point.

Rows