Skip to content

wasm codegen: ++ list-concat is a placeholder I32Add (produces garbage/zero-length lists) #264

@hyperpolymath

Description

@hyperpolymath

Summary

lib/codegen.ml gen_binop: | OpConcat -> I32Add (* Placeholder *). a ++ b emitted as I32Add of the two list pointers, so the result is a garbage integer, not a concatenated list. Any for/iteration over a ++ result sees a bogus length ⇒ 0 elements.

Repro (returns 0, expected 30):

fn main() -> Int { let xs = [10] ++ [20]; let mut s = 0; for x in xs { s = s + x; } s }

Pre-existing + untested

Same class as #255: ++ is used in stdlib (collections.affine [x] ++ result) but stdlib AOT only checks compile, never runtime; no asserted fixture exercised ++. Surfaced while implementing #225 PR3d (Http.readResponse builds headers via headers ++ [pair]).

Fix

Implemented real list concatenation in the ExprBinary handler (canonical [len@+0][elem i@+4+i*4] layout from #255): allocate len(a)+len(b), store combined length, copy a's then b's elements with two index loops. Added asserting tests/codegen/list_concat.{affine,mjs} (literal++literal, loop-append, loop-prepend ⇒ 166).

Verified: dune test --force 278/278; tools/run_codegen_wasm_tests.sh all pass incl. the new regression.

Surfaced by #225 PR3d. Refs #225 #255.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions