Skip to content

Adopt Component Model fixed-length lists (🔧) for the next WASI 0.3.x release #944

Closed as not planned

Description

@ricochet

This issue proposes that WASI adopt the Component Model's fixed-length list feature (gated as 🔧 in the Component Model's gated features), following the process described in CONTRIBUTING.md § Adopting Component Model features.

Feature

The 🔧 gate covers the optional length immediate on the list type constructor: list<T, N> (WIT.md § Types, Explainer § Type Definitions). A fixed-length list has the low-level memory representation of a homogeneous tuple of the same length. The elements are stored inline, with no pointer/length indirection while keeping the dynamic indexing and source-level bindings of a list. The length must be greater than 0.

get-ipv4-address: func() -> list<u8, 4>;

This gives interfaces a natural way to express fixed-size data like addresses, digests, coordinates, matrices. Today these must be spelled as wide tuples (e.g. tuple<u16, u16, u16, u16, u16, u16, u16, u16> for an IPv6 address) or as dynamically-sized list<u8> with out-of-band length invariants.

Unlike some WIT-level features, fixed-length lists specialize the canonical ABI representation, so adopting 🔧 requires support in runtimes and bindings generators, not just WIT tooling.

Stability

Iteration and feedback

This feature was designed nearly two years between the spec merge and this proposal with design refinements driven by implementation feedback throughout:

wit-bindgen-core defines dedicated ABI instructions FixedLengthListLift/FixedLengthListLower/FixedLengthListLowerToMemory/ FixedLengthListLiftFromMemory (crates/core/src/abi.rs:337-361) and dispatches type declarations via TypeDefKind::FixedLengthList(t, size) (crates/core/src/lib.rs:205,245).

WASI APIs that would depend on it

Fixed-size data appears throughout WASI's API surface, and proposals in the pipeline would use list<T, N> in newly added or newly stabilized APIs:

  • wasi-sockets — IP addresses, today spelled as wide tuples
    (tuple<u8, u8, u8, u8> for IPv4, tuple<u16, ...> ×8 for IPv6)
  • [wasi-webgpu] — vectors and matrices
  • Embedded-focused proposals (wasi-i2c, wasi-spi, wasi-usb) — fixed-size registers and buffers

Adopting 🔧 does not change any already-released wasi:* API: existing stable signatures keep their current types. It makes list<T, N> available to stable (@since-gated) APIs from the adopting release onward, and part of the baseline that runtimes and toolchains must support for that release.

Requested action

Per CONTRIBUTING.md § Adopting Component Model features, we believe the stability criteria are met: the design is complete, and the feature has been through an extended phase of iteration and feedback across the spec, WIT tooling, and runtime implementations.

We therefore aim to add a vote to an upcoming WASI Subgroup meeting agenda to adopt Component Model fixed-length lists (🔧) for inclusion in the next WASI 0.3.x release. Once adopted:

  • Stable (@since-gated) WASI APIs in the next release may depend on the feature.
  • The release notes for that version call out the newly adopted Component Model feature.
  • From that release onward, 🔧 is part of the baseline set of Component Model features required to implement that WASI version.

Activity

  1. lukewagner commented on Jul 23, 2026

    @lukewagner
    Member

    Coincidentally, there has just been some recent design discussion in CM/#640 about bounded lists (which would be a separate feature to complement/extend fixed-length lists 🔧) that suggests that maybe we should change the ABI flattening rules for bounded- and fixed-length lists. Until those bottom out, it's probably a good idea to hold off on releasing fixed-length lists. (cc @cpetig and @Felix-El)

  2. alexcrichton commented on Jul 23, 2026

    @alexcrichton
    Contributor

    Another aspect from Wasmtime's side at least as well is that fixed-length-lists aren't integrated into fuzzing right now, so this isn't something we'd want to turn on by default just yet in Wasmtime. That wouldn't necessarily block this, but it would mean that it'd still be gated in Wasmtime until fuzzing is implemented

  3. cpetig commented on Jul 24, 2026

    @cpetig

    To explain why it came to this situation:

    • fixed-length lists were initially modeled to behave like tuples, so the elements get individually flattened as values. This avoided introducing a whole new concept and simply accepted that flattened lists need to be stored to memory before they can be indexed or iterated over.
    • This compromise is much less appealing for bounded lists, where some arguments are simply not needed but need to be passed on the value stack. In addition this feels wasteful for passing a few bounded lists as the flat arguments quickly run out. Flattening them as (pointer+length) makes them more like normal lists.
    • This only applies to (a small number of) arguments, return values never fit into the single value slot available.
    • Felix pointed out that a new separation of a fixed number of list values into the argument or return area would solve both drawbacks. So at the complexity cost of passing some values in an argument area and some in the flat value stack, these lists get indexable, iterable and only valid values need to be loaded from memory.
    • With implementing this more reasonable model for bounded lists, fixed-length lists should flatten in the same way - fixing the previously introduced limitations while still being caller allocated in linear memory.
    • (I just realized) A lot of the complex flattening logic of fixed-length lists becomes trivial with this change, this was the single most complicated part of the implementation. Several DoS doubts arose from this.

    We promise to implement the new scheme within a few days, the only question is whether this change should require a lifting option to indicate the new flattening rule to all tools - or whether we accept a silent breaking of existing tools (I can't tell off-hand whether using an old linker/wac/wasm-tools will affect correctness here or if only wit-bindgen is affected on both sides, if wasm-tools and wasm-linker need an updated wasm-tools I would propose a loud failure, likewise if wasmtime would do anything but trap when executing old components). And if we go for the lifting option whether supporting both variants in wasmtime is necessary. I guess I should start investigating.

  4. cpetig commented on Jul 24, 2026

    @cpetig

    We found that the number of core parameters changes across this ABI incompatibility (unless you use a list<u32,1> for argument or result, which is highly unlikely). So incompatible wasm binaries should simply not validate across this change.

  5. ricochet commented on Jul 24, 2026

    @ricochet
    ContributorAuthor

    Ok then it sounds like the design and stability requirement for this feature has not yet been met. My preference is to close this issue and once ready, open a bounded-list issue that will encompass both. Sound ok @lukewagner ?

  6. cpetig commented on Jul 26, 2026

    @cpetig

    I guess more than my ABI plans @alexcrichton's latest findings support that this isn't yet ready for WASI, see the TODO entries in Implement WIT Fixed-Length-Lists .

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions