Skip to content

Define a new "wasm-multivalue" calling convention#268

Open
alexcrichton wants to merge 2 commits into
WebAssembly:mainfrom
alexcrichton:wasm-multivalue-calling-convention
Open

Define a new "wasm-multivalue" calling convention#268
alexcrichton wants to merge 2 commits into
WebAssembly:mainfrom
alexcrichton:wasm-multivalue-calling-convention

Conversation

@alexcrichton
Copy link
Copy Markdown
Collaborator

This commit is an attempt to define a new calling convention for WebAssembly which I've provisionally decided to call "wasm-multivalue". This new calling convention is inspired by discussions on #247 and #88, and the primary motivation of this calling convention is to be able to use multi-return signatures for intrinsics/functions in the component model.

This is a definition of a new, parallel, calling convention to the existing, now called "C", calling convention. The intention is that this avoids breakage to existing programs. The new calling convention is opt-in, requiring an annotation. The multivalue target feature enables usage of "wasm-multivalue", but enabling or disabling multivalue-the-target-feature has no effect on the "C" calling convention.

The technical definition of this new "wasm-multivalue" calling convention is to alter the previous calling convention in three ways:

  • Primarily, struct returns are now returned directly if all fields are (optionally recursively) scalars. This means that returning a struct-by-value gets translated to multiple return values.

  • To account for Pass small structs in parameters instead of memory #88 this new calling convention additionally passes two-scalar-argument struct definitions directly instead of indirectly, matching what native calling conventions do for example.

  • Finally, __int128 and long double return values are now returned directly instead of indirectly.

On an implementation side of things, what I'd like to do is to gain consensus on this calling convention definition in the tool-conventions repository as a first step. Once the definition is settled I plan to go to LLVM/Clang to implement this calling convention, and after that I plan to go to the Rust compiler and implement the calling convention there. My plan for Rust is to implement extern "wasm-multivalue" fn(..) syntactically, and for C to use
__attribute__((wasm_multivalue)) as the opt-in. Note that this is all bikesheddable, of course.

This commit is an attempt to define a new calling convention for
WebAssembly which I've provisionally decided to call "wasm-multivalue".
This new calling convention is inspired by discussions on WebAssembly#247 and WebAssembly#88,
and the primary motivation of this calling convention is to be able to
use multi-return signatures for intrinsics/functions in the component
model.

This is a definition of a new, parallel, calling convention to the
existing, now called "C", calling convention. The intention is that this
avoids breakage to existing programs. The new calling convention is
opt-in, requiring an annotation. The `multivalue` target feature enables
usage of "wasm-multivalue", but enabling or disabling
`multivalue`-the-target-feature has no effect on the "C" calling convention.

The technical definition of this new "wasm-multivalue" calling
convention is to alter the previous calling convention in three ways:

* Primarily, `struct` returns are now returned directly if all fields
  are (optionally recursively) scalars. This means that returning a
  `struct`-by-value gets translated to multiple return values.

* To account for WebAssembly#88 this new calling convention additionally passes
  two-scalar-argument `struct` definitions directly instead of
  indirectly, matching what native calling conventions do for example.

* Finally, `__int128` and `long double` return values are now returned
  directly instead of indirectly.

On an implementation side of things, what I'd like to do is to gain
consensus on this calling convention definition in the tool-conventions
repository as a first step. Once the definition is settled I plan to go
to LLVM/Clang to implement this calling convention, and after that I
plan to go to the Rust compiler and implement the calling convention
there. My plan for Rust is to implement `extern "wasm-multivalue"
fn(..)` syntactically, and for C to use
`__attribute__((wasm_multivalue))` as the opt-in. Note that this is all
bikesheddable, of course.
@tlively
Copy link
Copy Markdown
Member

tlively commented May 24, 2026

SGTM! I like that making this opt-in lets us avoid the question of how large a struct should be allowed to be returned by value.

Comment thread BasicCABI.md Outdated
Comment thread BasicCABI.md Outdated
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.

3 participants