6.9 KiB
Implementing WebAssembly Proposals
Adding New Support for a Wasm Proposal
The following checkboxes enumerate the steps required to add support for a new WebAssembly proposal to Wasmtime. They can be completed over the course of multiple pull requests.
-
Add support to the
wasmparser
crate. -
Add support to the
wasmprinter
crate. -
Add support to the
wasm-encoder
crate. -
Add support to the
wasm-smith
crate. -
Add a
wasmtime::Config::enable_foo_bar
method to thewasmtime
crate. -
Add a
--enable-foo-bar
command line flag to thewasmtime
binary. -
Enable the spec tests in
build.rs
but mark them as ignored for now. -
Stop ignoring individual spec tests and get them passing one by one.
-
Enable the proposal in the fuzz targets.
-
Add examples from the spec tests to the relevant corpora.
The
wast2json
tool from WABT is useful for this. -
Write a custom fuzz target, oracle, and/or test case generator for fuzzing this proposal in particular.
For example, we wrote a custom generator, oracle, and fuzz target for exercising
table.{get,set}
instructions and their interaction with GC while implementing the reference types proposal.
-
-
Expose the proposal's new functionality in the
wasmtime
crate's API.For example, the bulk memory operations proposal introduced a
table.copy
instruction, and we exposed its functionality as thewasmtime::Table::copy
method. -
Expose the proposal's new functionality in the C API.
This may require extensions to the standard C API, and if so, should be defined in
wasmtime.h
and prefixed withwasmtime_
. -
Use the C API to expose the proposal's new functionality in the other language embedding APIs:
-
Document support for the proposal in
wasmtime/docs/stability-wasm-proposals-support.md
.
Enabling Support for a Proposal by Default
These are the standards that must be met to enable support for a proposal by default in Wasmtime, and can be used as a review checklist.
-
The proposal must be in phase 4, or greater, of the WebAssembly standardization process.
-
All spec tests must be passing in Wasmtime.
-
No open questions, design concerns, or serious known bugs.
-
Has been fuzzed for at least a week minimum.
-
We are confident that the fuzzers are fully exercising the proposal's functionality.
For example, it would not have been enough to simply enable reference types in the
compile
fuzz target to enable that proposal by default. Compiling a module that uses reference types but not instantiating it nor running any of its functions doesn't exercise any of the GC implementation and does not run the inline fast paths fortable
operations emitted by the JIT. Exercising these things was the motivation for writing the custom fuzz target fortable.{get,set}
instructions. -
The proposal's functionality is exposed in the
wasmtime
crate's API. -
The proposal's functionality is exposed in the C API.
-
The proposal's functionality is exposed in at least one of the other languages' APIs.
Adding component functionality to WASI
The cap-std repository contains crates which implement the capability-based version of the Rust standard library and extensions to that functionality. Once the functionality has been added to the relevant crates of that repository, they can be added into wasmtime by including them in the preview2 directory of the wasi crate.
Currently, WebAssembly modules which rely on preview2 ABI cannot be directly executed by the wasmtime command. The following steps allow for testing such changes.
-
Build wasmtime with the changes
cargo build --release
-
Create a simple Webassembly module to test the new component functionality by compiling your test code to the
wasm32-wasi
build target. -
Build the wasi-preview1-component-adapter as a command adapter.
cargo build -p wasi-preview1-component-adapter --target wasm32-wasi --release --features command --no-default-features
-
Use wasm-tools to convert the test module to a component.
wasm-tools component new --adapt wasi_snapshot_preview1=wasi_snapshot_preview1.command.wasm -o component.wasm path/to/test/module
-
Run the test component created in the previous step with the locally built wasmtime.
wasmtime -W component-model=y -S preview2=y component.wasm