diff --git a/cranelift/codegen/src/regalloc/context.rs b/cranelift/codegen/src/regalloc/context.rs index 8aa1003d42..505b1d127a 100644 --- a/cranelift/codegen/src/regalloc/context.rs +++ b/cranelift/codegen/src/regalloc/context.rs @@ -203,17 +203,22 @@ impl Context { &mut self.tracker, ); - // This function runs after register allocation has taken - // place, meaning values have locations assigned already. - if isa.flags().enable_safepoints() { - emit_stack_maps(func, domtree, &self.liveness, &mut self.tracker, isa); - } else { - // Make sure no references are used. - for val in func.dfg.values() { - let ty = func.dfg.value_type(val); - if ty.lane_type().is_ref() { - panic!("reference types were found but safepoints were not enabled."); - } + // If there are any reference types used, encode safepoints and emit + // stack maps. + // + // This function runs after register allocation has taken place, meaning + // values have locations assigned already, which is necessary for + // creating the stack maps. + let safepoints_enabled = isa.flags().enable_safepoints(); + for val in func.dfg.values() { + let ty = func.dfg.value_type(val); + if ty.lane_type().is_ref() { + assert!( + safepoints_enabled, + "reference types were found but safepoints were not enabled" + ); + emit_stack_maps(func, domtree, &self.liveness, &mut self.tracker, isa); + break; } } diff --git a/crates/wasmtime/src/runtime.rs b/crates/wasmtime/src/runtime.rs index c45098f58a..a9eabd56a3 100644 --- a/crates/wasmtime/src/runtime.rs +++ b/crates/wasmtime/src/runtime.rs @@ -99,8 +99,8 @@ impl Config { memory_creator: None, max_wasm_stack: 1 << 20, wasm_threads: false, - wasm_reference_types: false, - wasm_bulk_memory: false, + wasm_reference_types: cfg!(target_arch = "x86_64"), + wasm_bulk_memory: true, wasm_simd: false, wasm_multi_value: true, } @@ -175,25 +175,17 @@ impl Config { self } - /// Configures whether the WebAssembly reference types proposal will be - /// enabled for compilation. + /// Configures whether the [WebAssembly reference types proposal][proposal] + /// will be enabled for compilation. /// - /// The [WebAssembly reference types proposal][proposal] is not currently - /// fully standardized and is undergoing development. Additionally the - /// support in wasmtime itself is still being worked on. Support for this - /// feature can be enabled through this method for appropriate wasm - /// modules. + /// This feature gates items such as the `externref` and `funcref` types as + /// well as allowing a module to define multiple tables. /// - /// This feature gates items such as the `externref` type and multiple tables - /// being in a module. Note that enabling the reference types feature will - /// also enable the bulk memory feature. + /// Note that enabling the reference types feature will also enable the bulk + /// memory feature. /// - /// This is `false` by default. - /// - /// > **Note**: Wasmtime does not implement everything for the reference - /// > types proposal spec at this time, so bugs, panics, and possibly - /// > segfaults should be expected. This should not be enabled in a - /// > production setting right now. + /// This is `true` by default on x86-64, and `false` by default on other + /// architectures. /// /// [proposal]: https://github.com/webassembly/reference-types pub fn wasm_reference_types(&mut self, enable: bool) -> &mut Self { @@ -240,19 +232,13 @@ impl Config { self } - /// Configures whether the WebAssembly bulk memory operations proposal will - /// be enabled for compilation. - /// - /// The [WebAssembly bulk memory operations proposal][proposal] is not - /// currently fully standardized and is undergoing development. - /// Additionally the support in wasmtime itself is still being worked on. - /// Support for this feature can be enabled through this method for - /// appropriate wasm modules. + /// Configures whether the [WebAssembly bulk memory operations + /// proposal][proposal] will be enabled for compilation. /// /// This feature gates items such as the `memory.copy` instruction, passive /// data/table segments, etc, being in a module. /// - /// This is `false` by default. + /// This is `true` by default. /// /// [proposal]: https://github.com/webassembly/bulk-memory-operations pub fn wasm_bulk_memory(&mut self, enable: bool) -> &mut Self { diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index cb6c419615..32b71d3cd8 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -5,26 +5,26 @@ - [Creating `hello-world.wasm`](./tutorial-create-hello-world.md) - [Running `hello-world.wasm`](./tutorial-run-hello-world.md) - [Examples](./examples.md) - - [Markdown parser](./examples-markdown.md) + - [Markdown Parser](./examples-markdown.md) - [Profiling WebAssembly](./examples-profiling.md) - [Profiling with Perf](./examples-profiling-perf.md) - [Profiling with VTune](./examples-profiling-vtune.md) - [Embedding in Rust](./examples-rust-embed.md) - [Hello, world!](./examples-rust-hello-world.md) - [Calculating the GCD](./examples-rust-gcd.md) - - [Using linear memory](./examples-rust-memory.md) + - [Using Linear Memory](./examples-rust-memory.md) - [WASI](./examples-rust-wasi.md) - - [Linking modules](./examples-rust-linking.md) + - [Linking Modules](./examples-rust-linking.md) - [Debugging](./examples-rust-debugging.md) - - [Using multi-value](./examples-rust-multi-value.md) + - [Using Multi-Value](./examples-rust-multi-value.md) - [Embedding in C](./examples-c-embed.md) - - [Hello, world!](./examples-c-hello-world.md) + - [Hello, World!](./examples-c-hello-world.md) - [Calculating the GCD](./examples-c-gcd.md) - - [Using linear memory](./examples-c-memory.md) + - [Using Linear Memory](./examples-c-memory.md) - [WASI](./examples-c-wasi.md) - - [Linking modules](./examples-c-linking.md) + - [Linking Modules](./examples-c-linking.md) - [Debugging](./examples-c-debugging.md) - - [Using multi-value](./examples-c-multi-value.md) + - [Using Multi-Value](./examples-c-multi-value.md) - [Using WebAssembly from your language](./lang.md) - [Rust](./lang-rust.md) - [C](./lang-c.md) @@ -45,6 +45,7 @@ - [Stability](stability.md) - [Release Process](./stability-release.md) - [Platform Support](./stability-platform-support.md) + - [Wasm Proposals Support](./stability-wasm-proposals-support.md) - [Security](security.md) - [Disclosure Policy](./security-disclosure.md) - [Sandboxing](./security-sandboxing.md) @@ -53,8 +54,9 @@ - [Testing](./contributing-testing.md) - [Fuzzing](./contributing-fuzzing.md) - [CI](./contributing-ci.md) - - [Coding guidelines](./contributing-coding-guidelines.md) - - [Development process](./contributing-development-process.md) + - [Coding Guidelines](./contributing-coding-guidelines.md) + - [Development Process](./contributing-development-process.md) - [Release Process](./contributing-release-process.md) + - [Implementing Wasm Proposals](./contributing-implementing-wasm-proposals.md) - [Governance](./contributing-governance.md) - [Code of Conduct](./contributing-coc.md) diff --git a/docs/contributing-coding-guidelines.md b/docs/contributing-coding-guidelines.md index 0fe5133df4..41fcfc9615 100644 --- a/docs/contributing-coding-guidelines.md +++ b/docs/contributing-coding-guidelines.md @@ -6,7 +6,7 @@ be aware of. [pull request]: https://help.github.com/articles/about-pull-requests/ -### rustfmt +### `rustfmt` All PRs must be formatted according to rustfmt, and this is checked in the continuous integration tests. You can format code locally with: @@ -19,7 +19,7 @@ at the root of the repository. You can find [more information about rustfmt online](https://github.com/rust-lang/rustfmt) too, such as how to configure your editor. -### Rustc version support +### Minimum Supported `rustc` Version Wasmtime supports the current stable version of Rust. diff --git a/docs/contributing-implementing-wasm-proposals.md b/docs/contributing-implementing-wasm-proposals.md new file mode 100644 index 0000000000..bce9db61db --- /dev/null +++ b/docs/contributing-implementing-wasm-proposals.md @@ -0,0 +1,118 @@ +# 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`](https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmparser) + crate. + +* Add support to the + [`wat`](https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wat) + and + [`wast`](https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wast) + crates. + +* Add support to the + [`wasmprinter`](https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmprinter) + crate. + +* Add a `wasmtime::Config::enable_foo_bar` method to + the `wasmtime` crate. + +* Add a `--enable-foo-bar` command line flag to the + `wasmtime` binary. + +* Enable the spec tests in + [`build.rs`](https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/build.rs#L41-L52) + but [mark them as + ignored](https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/build.rs#L196) + for now. + +* Stop ignoring individual spec tests and get them + passing one by one. + +* Enable the proposal in [the fuzz + targets](./contributing-fuzzing.html). + + * Add examples from the spec tests to [the relevant + corpora](https://github.com/bytecodealliance/wasmtime-libfuzzer-corpus). + + > 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](https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/crates/fuzzing/src/generators/table_ops.rs), + > [oracle](https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/crates/fuzzing/src/oracles.rs#L417-L467), + > and [fuzz + > target](https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/fuzz/fuzz_targets/table_ops.rs) + > 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 the `wasmtime::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`](https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/crates/c-api/include/wasmtime.h) + > and prefixed with `wasmtime_`. + +* Use the C API to expose the proposal's new + functionality in the other language embedding APIs: + + * [Python](https://github.com/bytecodealliance/wasmtime-py/) + + * [Go](https://github.com/bytecodealliance/wasmtime-go/) + + * [.NET](https://github.com/bytecodealliance/wasmtime-dotnet/) + +* 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][phases]. + +* 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 for `table` operations + > emitted by the JIT. Exercising these things was the motivation for writing + > the custom fuzz target for `table.{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. + +[phases]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md +[WABT]: https://github.com/WebAssembly/wabt/ diff --git a/docs/stability-wasm-proposals-support.md b/docs/stability-wasm-proposals-support.md new file mode 100644 index 0000000000..d38db6f3dc --- /dev/null +++ b/docs/stability-wasm-proposals-support.md @@ -0,0 +1,34 @@ +# WebAssembly Proposals Support + +The following table summarizes Wasmtime's support for WebAssembly proposals as +well as the command line flag and [`wasmtime::Config`][config] method you can +use to enable or disable support for a proposal. + +If a proposal is not listed, then it is not supported by Wasmtime. + +Wasmtime will never enable a proposal by default unless it has reached phase 4 +of [the WebAssembly standardizations process][phases] and its implementation in +Wasmtime has been [thoroughly +vetted](./contributing-supporting-new-wasm-proposals.html). + +| WebAssembly Proposal | Supported in Wasmtime? | Command Line Flag | [`Config`][config] Method | +|---------------------------------------------|----------------------------------|------------------------|---------------------------| +| **[Import and Export Mutable Globals]** | **Yes.**
Always enabled. | (none) | (none) | +| **[Sign-Extension Operations]** | **Yes.**
Always enabled. | (none) | (none) | +| **[Non-Trapping Float-to-Int Conversions]** | **Yes.**
Always enabled. | (none) | (none) | +| **[Multi-Value]** | **Yes.**
Enabled by default. | `--enable-multi-value` | [`wasm_multi_value`](https://docs.rs/wasmtime/*/wasmtime/struct.Config.html#method.wasm_multi_value) | +| **[Bulk Memory Operations]** | **Yes.**
Enabled by default. | `--enable-bulk-memory` | [`wasm_bulk_memory`](https://docs.rs/wasmtime/*/wasmtime/struct.Config.html#method.wasm_bulk_memory) | +| **[Reference Types]** | **Yes.**
Enabled by default on x86_64. Aarch64 support in progress. | `--enable-reference-types` | [`wasm_reference_types`](https://docs.rs/wasmtime/*/wasmtime/struct.Config.html#method.wasm_reference_types) | +| **[Fixed-Width SIMD]** | **In progress.** | `--enable-simd` | [`wasm_simd`](https://docs.rs/wasmtime/*/wasmtime/struct.Config.html#method.wasm_simd) | +| **[Threads and Atomics]** | **In progress.** | `--enable-threads` | [`wasm_threads`](https://docs.rs/wasmtime/*/wasmtime/struct.Config.html#method.wasm_threads) | + +[config]: https://docs.rs/wasmtime/*/wasmtime/struct.Config.html +[Multi-Value]: https://github.com/WebAssembly/spec/blob/master/proposals/multi-value/Overview.md +[Bulk Memory Operations]: https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md +[Import and Export Mutable Globals]: https://github.com/WebAssembly/mutable-global/blob/master/proposals/mutable-global/Overview.md +[Reference Types]: https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md +[Non-Trapping Float-to-Int Conversions]: https://github.com/WebAssembly/spec/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md +[Sign-Extension Operations]: https://github.com/WebAssembly/spec/blob/master/proposals/sign-extension-ops/Overview.md +[Fixed-Width SIMD]: https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md +[phases]: https://github.com/WebAssembly/meetings/blob/master/process/phases.md +[Threads and Atomics]: https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md diff --git a/src/lib.rs b/src/lib.rs index d254a95e5f..22bc9cbfc7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -110,7 +110,7 @@ struct CommonOptions { /// Enable support for reference types #[structopt(long)] - enable_reference_types: bool, + enable_reference_types: Option, /// Enable support for multi-value functions #[structopt(long)] @@ -122,7 +122,7 @@ struct CommonOptions { /// Enable support for bulk memory instructions #[structopt(long)] - enable_bulk_memory: bool, + enable_bulk_memory: Option, /// Enable all experimental Wasm features #[structopt(long)] @@ -185,9 +185,13 @@ impl CommonOptions { config .cranelift_debug_verifier(self.enable_cranelift_debug_verifier) .debug_info(self.debug_info) - .wasm_bulk_memory(self.enable_bulk_memory || self.enable_all) .wasm_simd(self.enable_simd || self.enable_all) - .wasm_reference_types(self.enable_reference_types || self.enable_all) + .wasm_bulk_memory(self.enable_bulk_memory.unwrap_or(true) || self.enable_all) + .wasm_reference_types( + self.enable_reference_types + .unwrap_or(cfg!(target_arch = "x86_64")) + || self.enable_all, + ) .wasm_multi_value(self.enable_multi_value.unwrap_or(true) || self.enable_all) .wasm_threads(self.enable_threads || self.enable_all) .cranelift_opt_level(self.opt_level())