Repository: bytecodealliance/wasmtime
Pull request #5600 (2023-01-19 23:14:27)

component bindgen: accept strs as well as identifiers for wit identifiers

This is required because not all wit identifiers are Rust identifiers, so we can smuggle the invalid ones inside quotes.

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

- [ ] This has been discussed in issue #..., or if not, please tell us why
  here.
- [ ] A short description of what this does, why it is needed; if the
  description becomes long, the matter should probably be discussed in an issue
  first.
- [ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
  If you don't know who could review this, please indicate so. The list of
  suggested reviewers on the right can help you.

Please ensure all communication adheres to the [code of
conduct](https://github.com/bytecodealliance/wasmtime/blob/master/CODE_OF_CONDUCT.md).
-->



Patch:
diff --git a/README.md b/README.md
index 3f7c30213..d59c36806 100644
--- a/README.md
+++ b/README.md
@@ -108,7 +108,9 @@ Hello, world!
 ## Language Support
 
 You can use Wasmtime from a variety of different languages through embeddings of
-the implementation:
+the implementation.
+
+Languages supported by the Bytecode Alliance:
 
 * **[Rust]** - the [`wasmtime` crate]
 * **[C]** - the [`wasm.h`, `wasi.h`, and `wasmtime.h` headers][c-headers], [CMake](crates/c-api/CMakeLists.txt) or [`wasmtime` Conan package]
@@ -118,6 +120,10 @@ the implementation:
 * **[Go]** - the [`wasmtime-go` repository]
 * **[Ruby]** - the [`wasmtime` gem]
 
+Languages supported by the community:
+
+* **[Elixir]** - the [`wasmex` hex package]
+
 [Rust]: https://bytecodealliance.github.io/wasmtime/lang-rust.html
 [C]: https://bytecodealliance.github.io/wasmtime/examples-c-embed.html
 [`wasmtime` crate]: https://crates.io/crates/wasmtime
@@ -133,6 +139,8 @@ the implementation:
 [`wasmtime-cpp` Conan package]: https://conan.io/center/wasmtime-cpp
 [Ruby]: https://bytecodealliance.github.io/wasmtime/lang-ruby.html
 [`wasmtime` gem]: https://rubygems.org/gems/wasmtime
+[Elixir]: https://docs.wasmtime.dev/lang-elixir.html
+[`wasmex` hex package]: https://hex.pm/packages/wasmex
 
 ## Documentation
 
diff --git a/RELEASES.md b/RELEASES.md
index 30f6cd11a..8e7f581f4 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -12,7 +12,7 @@ Unreleased.
 
 ## 5.0.0
 
-Unreleased.
+Released 2023-01-20
 
 ### Added
 
diff --git a/cranelift/codegen/meta/src/shared/settings.rs b/cranelift/codegen/meta/src/shared/settings.rs
index e51cd5a5a..2db1f1303 100644
--- a/cranelift/codegen/meta/src/shared/settings.rs
+++ b/cranelift/codegen/meta/src/shared/settings.rs
@@ -58,10 +58,12 @@ pub(crate) fn define() -> SettingGroup {
         "Enable egraph-based optimization.",
         r#"
             This enables an optimization phase that converts CLIF to an egraph (equivalence graph)
-            representation, performs various rewrites, and then converts it back. This can result in
-            better optimization, but is currently considered experimental.
+            representation, performs various rewrites, and then converts it back. This should result in
+            better optimization, but the traditional optimization pass structure is also still
+            available by setting this to `false`. The `false` setting will eventually be
+            deprecated and removed.
         "#,
-        false,
+        true,
     );
 
     settings.add_bool(
diff --git a/cranelift/codegen/src/context.rs b/cranelift/codegen/src/context.rs
index 175f8e8ea..4da6cbe04 100644
--- a/cranelift/codegen/src/context.rs
+++ b/cranelift/codegen/src/context.rs
@@ -185,18 +185,20 @@ impl Context {
         self.compute_domtree();
         self.eliminate_unreachable_code(isa)?;
 
-        if isa.flags().use_egraphs() || opt_level != OptLevel::None {
+        if opt_level != OptLevel::None {
             self.dce(isa)?;
         }
 
         self.remove_constant_phis(isa)?;
 
-        if isa.flags().use_egraphs() {
-            self.egraph_pass()?;
-        } else if opt_level != OptLevel::None && isa.flags().enable_alias_analysis() {
-            for _ in 0..2 {
-                self.replace_redundant_loads()?;
-                self.simple_gvn(isa)?;
+        if opt_level != OptLevel::None {
+            if isa.flags().use_egraphs() {
+                self.egraph_pass()?;
+            } else if isa.flags().enable_alias_analysis() {
+                for _ in 0..2 {
+                    self.replace_redundant_loads()?;
+                    self.simple_gvn(isa)?;
+                }
             }
         }
 
diff --git a/cranelift/codegen/src/machinst/isle.rs b/cranelift/codegen/src/machinst/isle.rs
index def41ade3..30fcd7c24 100644
--- a/cranelift/codegen/src/machinst/isle.rs
+++ b/cranelift/codegen/src/machinst/isle.rs
@@ -16,7 +16,7 @@ pub use crate::machinst::{
     ABIArg, ABIArgSlot, InputSourceInst, Lower, LowerBackend, RealReg, Reg, RelocDistance, Sig,
     VCodeInst, Writable,
 };
-pub use crate::settings::TlsModel;
+pub use crate::settings::{OptLevel, TlsModel};
 
 pub type Unit = ();
 pub type ValueSlice = (ValueList, usize);
@@ -131,7 +131,9 @@ macro_rules! isle_lower_prelude_methods {
             // use. This lowers register pressure. (Only do this if we are
             // not using egraph-based compilation; the egraph framework
             // more efficiently rematerializes constants where needed.)
-            if !self.backend.flags().use_egraphs() {
+            if !(self.backend.flags().use_egraphs()
+                && self.backend.flags().opt_level() != OptLevel::None)
+            {
                 let inputs = self.lower_ctx.get_value_as_source_or_const(val);
                 if inputs.constant.is_some() {
                     let insn = match inputs.inst {
diff --git a/cranelift/codegen/src/settings.rs b/cranelift/codegen/src/settings.rs
index 27be5c17f..6836646e2 100644
--- a/cranelift/codegen/src/settings.rs
+++ b/cranelift/codegen/src/settings.rs
@@ -528,7 +528,7 @@ probestack_strategy = "outline"
 regalloc_checker = false
 regalloc_verbose_logs = false
 enable_alias_analysis = true
-use_egraphs = false
+use_egraphs = true
 enable_verifier = true
 is_pic = false
 use_colocated_libcalls = false
diff --git a/crates/component-macro/src/bindgen.rs b/crates/component-macro/src/bindgen.rs
index 435abbb42..d9caff8f3 100644
--- a/crates/component-macro/src/bindgen.rs
+++ b/crates/component-macro/src/bindgen.rs
@@ -226,9 +226,23 @@ impl Parse for Opt {
 }
 
 fn trappable_error_field_parse(input: ParseStream<'_>) -> Result<(String, String, String)> {
-    let interface = input.parse::<Ident>()?.to_string();
+    // Accept a Rust identifier or a string literal. This is required
+    // because not all wit identifiers are Rust identifiers, so we can
+    // smuggle the invalid ones inside quotes.
+    fn ident_or_str(input: ParseStream<'_>) -> Result<String> {
+        let l = input.lookahead1();
+        if l.peek(syn::LitStr) {
+            Ok(input.parse::<syn::LitStr>()?.value())
+        } else if l.peek(syn::Ident) {
+            Ok(input.parse::<syn::Ident>()?.to_string())
+        } else {
+            Err(l.error())
+        }
+    }
+
+    let interface = ident_or_str(input)?;
     input.parse::<Token![::]>()?;
-    let type_ = input.parse::<Ident>()?.to_string();
+    let type_ = ident_or_str(input)?;
     input.parse::<Token![:]>()?;
     let rust_type = input.parse::<Ident>()?.to_string();
     Ok((interface, type_, rust_type))
diff --git a/crates/wasmtime/src/config.rs b/crates/wasmtime/src/config.rs
index b3c32f2bc..7e42afbc4 100644
--- a/crates/wasmtime/src/config.rs
+++ b/crates/wasmtime/src/config.rs
@@ -832,14 +832,13 @@ impl Config {
     /// Configures the Cranelift code generator to use its
     /// "egraph"-based mid-end optimizer.
     ///
-    /// This optimizer is intended to replace the compiler's more
-    /// traditional pipeline of optimization passes with a unified
-    /// code-rewriting system. It is not yet on by default, but it is
-    /// intended to become the default in a future version. It may
-    /// result in faster code, at the cost of slightly more
-    /// compilation-time work.
-    ///
-    /// The default value for this is `false`.
+    /// This optimizer has replaced the compiler's more traditional
+    /// pipeline of optimization passes with a unified code-rewriting
+    /// system. It is on by default, but the traditional optimization
+    /// pass structure is still available for now (it is deprecrated and
+    /// will be removed in a future version).
+    ///
+    /// The default value for this is `true`.
     #[cfg(compiler)]
     #[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
     pub fn cranelift_use_egraphs(&mut self, enable: bool) -> &mut Self {
diff --git a/docs/lang-elixir.md b/docs/lang-elixir.md
new file mode 100644
index 000000000..d961f2ede
--- /dev/null
+++ b/docs/lang-elixir.md
@@ -0,0 +1,43 @@
+# Using WebAssembly from Elixir
+
+Wasmtime [is available on Hex](https://hex.pm/packages/wasmex) and can
+be used programmatically to interact with Wasm modules. This guide will go over
+installing the wasmex package and running a simple Wasm module from Elixir.
+
+## Getting started and simple example
+
+First, copy this example WebAssembly text module into the current directory. It exports
+a function for calculating the greatest common denominator of two numbers.
+
+```wat
+{{#include ../examples/gcd.wat}}
+```
+
+The library has a Rust-based native extension, but thanks to `rustler_precompiled`, you
+should not have to compile anything. It'll just work!
+
+This WAT file can be executed in `iex`:
+
+```elixir
+Mix.install([:wasmex])
+bytes = File.read!("gcd.wat")
+{:ok, pid} = Wasmex.start_link(%{bytes: bytes}) # starts a GenServer running a WASM instance
+Wasmex.call_function(pid, "gcd", [27, 6])
+```
+
+The last command should output:
+
+```elixir
+iex(5)> Wasmex.call_function(pid, "gcd", [27, 6])
+{:ok, [3]}
+```
+
+If this is the output you see, congrats! You've successfully ran your first
+WebAssembly code in Elixir!
+
+## More examples and contributing
+
+To learn more, check out an [another example](https://github.com/tessi/wasmex#example)
+and the [API documentation](https://hexdocs.pm/wasmex/Wasmex.html).
+If you have any questions, do not hesitate to open an issue on the
+[GitHub repository](https://github.com/tessi/wasmex).
diff --git a/docs/lang.md b/docs/lang.md
index ae3d0a13c..94e38d1b0 100644
--- a/docs/lang.md
+++ b/docs/lang.md
@@ -11,3 +11,4 @@ through a C API for a number of other languages too:
 * [Go](lang-go.md)
 * [Bash](lang-bash.md)
 * [Ruby](lang-ruby.md)
+* [Elixir](lang-elixir.md)


Test patch:
diff --git a/cranelift/filetests/filetests/egraph/algebraic.clif b/cranelift/filetests/filetests/egraph/algebraic.clif
index 6eaa6fcda..3a852b0eb 100644
--- a/cranelift/filetests/filetests/egraph/algebraic.clif
+++ b/cranelift/filetests/filetests/egraph/algebraic.clif
@@ -1,5 +1,5 @@
 test optimize
-set opt_level=none
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/egraph/alias_analysis.clif b/cranelift/filetests/filetests/egraph/alias_analysis.clif
index ce7843146..87bc50736 100644
--- a/cranelift/filetests/filetests/egraph/alias_analysis.clif
+++ b/cranelift/filetests/filetests/egraph/alias_analysis.clif
@@ -1,5 +1,5 @@
 test optimize
-set opt_level=none
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/egraph/basic-gvn.clif b/cranelift/filetests/filetests/egraph/basic-gvn.clif
index 7b3878622..823614ea2 100644
--- a/cranelift/filetests/filetests/egraph/basic-gvn.clif
+++ b/cranelift/filetests/filetests/egraph/basic-gvn.clif
@@ -1,5 +1,5 @@
 test optimize
-set opt_level=none
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/egraph/cprop.clif b/cranelift/filetests/filetests/egraph/cprop.clif
index bc76e1d54..261be6fdf 100644
--- a/cranelift/filetests/filetests/egraph/cprop.clif
+++ b/cranelift/filetests/filetests/egraph/cprop.clif
@@ -1,5 +1,5 @@
 test optimize
-set opt_level=none
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/egraph/i128-opts.clif b/cranelift/filetests/filetests/egraph/i128-opts.clif
index 24737e2c9..f30b80bd2 100644
--- a/cranelift/filetests/filetests/egraph/i128-opts.clif
+++ b/cranelift/filetests/filetests/egraph/i128-opts.clif
@@ -1,5 +1,5 @@
 test optimize
-set opt_level=speed_and_size
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/egraph/isplit.clif b/cranelift/filetests/filetests/egraph/isplit.clif
index e5cb3ea49..e40c32fef 100644
--- a/cranelift/filetests/filetests/egraph/isplit.clif
+++ b/cranelift/filetests/filetests/egraph/isplit.clif
@@ -1,6 +1,6 @@
 test interpret
 test run
-set opt_level=speed_and_size
+set opt_level=speed
 set use_egraphs=true
 set enable_llvm_abi_extensions=true
 target x86_64
diff --git a/cranelift/filetests/filetests/egraph/issue-5405.clif b/cranelift/filetests/filetests/egraph/issue-5405.clif
index c453875de..db6f582ec 100644
--- a/cranelift/filetests/filetests/egraph/issue-5405.clif
+++ b/cranelift/filetests/filetests/egraph/issue-5405.clif
@@ -1,6 +1,6 @@
 test interpret
 test run
-set opt_level=speed_and_size
+set opt_level=speed
 set use_egraphs=true
 target aarch64
 
diff --git a/cranelift/filetests/filetests/egraph/issue-5437.clif b/cranelift/filetests/filetests/egraph/issue-5437.clif
index b8eb3c938..0f20d2f5a 100644
--- a/cranelift/filetests/filetests/egraph/issue-5437.clif
+++ b/cranelift/filetests/filetests/egraph/issue-5437.clif
@@ -1,4 +1,5 @@
 test compile
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 target aarch64
diff --git a/cranelift/filetests/filetests/egraph/licm.clif b/cranelift/filetests/filetests/egraph/licm.clif
index a6f458556..3b8b62514 100644
--- a/cranelift/filetests/filetests/egraph/licm.clif
+++ b/cranelift/filetests/filetests/egraph/licm.clif
@@ -1,5 +1,5 @@
 test optimize
-set opt_level=none
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/egraph/misc.clif b/cranelift/filetests/filetests/egraph/misc.clif
index 668c643cd..811211601 100644
--- a/cranelift/filetests/filetests/egraph/misc.clif
+++ b/cranelift/filetests/filetests/egraph/misc.clif
@@ -1,5 +1,5 @@
 test optimize
-set opt_level=none
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/egraph/multivalue.clif b/cranelift/filetests/filetests/egraph/multivalue.clif
index f2e2e1147..261fbc75a 100644
--- a/cranelift/filetests/filetests/egraph/multivalue.clif
+++ b/cranelift/filetests/filetests/egraph/multivalue.clif
@@ -1,4 +1,5 @@
 test compile precise-output
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/egraph/not_a_load.clif b/cranelift/filetests/filetests/egraph/not_a_load.clif
index fde8c2d0e..99eefacca 100644
--- a/cranelift/filetests/filetests/egraph/not_a_load.clif
+++ b/cranelift/filetests/filetests/egraph/not_a_load.clif
@@ -1,4 +1,5 @@
 test compile precise-output
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/egraph/remat.clif b/cranelift/filetests/filetests/egraph/remat.clif
index 69289b7cd..f1ba8dd20 100644
--- a/cranelift/filetests/filetests/egraph/remat.clif
+++ b/cranelift/filetests/filetests/egraph/remat.clif
@@ -1,5 +1,5 @@
 test optimize
-set opt_level=none
+set opt_level=speed
 set use_egraphs=true
 target x86_64
 
diff --git a/cranelift/filetests/filetests/wasm/duplicate-loads-dynamic-memory.wat b/cranelift/filetests/filetests/wasm/duplicate-loads-dynamic-memory.wat
index aab07174d..ac5d606cd 100644
--- a/cranelift/filetests/filetests/wasm/duplicate-loads-dynamic-memory.wat
+++ b/cranelift/filetests/filetests/wasm/duplicate-loads-dynamic-memory.wat
@@ -4,7 +4,8 @@
 ;;!
 ;;! settings = [
 ;;!   "enable_heap_access_spectre_mitigation=true",
-;;!   "opt_level=speed_and_size"
+;;!   "opt_level=speed_and_size",
+;;!   "use_egraphs=false"
 ;;! ]
 ;;!
 ;;! [globals.vmctx]
@@ -112,4 +113,4 @@
 ;;
 ;;                                 block1:
 ;; @006e                               return v14, v14
-;; }
\ No newline at end of file
+;; }
diff --git a/cranelift/filetests/filetests/wasm/duplicate-loads-static-memory.wat b/cranelift/filetests/filetests/wasm/duplicate-loads-static-memory.wat
index 6a82e60b1..bef294915 100644
--- a/cranelift/filetests/filetests/wasm/duplicate-loads-static-memory.wat
+++ b/cranelift/filetests/filetests/wasm/duplicate-loads-static-memory.wat
@@ -4,7 +4,8 @@
 ;;!
 ;;! settings = [
 ;;!   "enable_heap_access_spectre_mitigation=true",
-;;!   "opt_level=speed_and_size"
+;;!   "opt_level=speed_and_size",
+;;!   "use_egraphs=false"
 ;;! ]
 ;;!
 ;;! [globals.vmctx]
diff --git a/tests/all/component_model/bindgen/results.rs b/tests/all/component_model/bindgen/results.rs
index 995a2e528..82e318948 100644
--- a/tests/all/component_model/bindgen/results.rs
+++ b/tests/all/component_model/bindgen/results.rs
@@ -373,7 +373,9 @@ mod record_error {
                 record-error: func(a: float64) -> result<float64, e2>
             }
         }",
-        trappable_error_type: { imports::e2: TrappableE2 }
+        // Literal strings can be used for the interface and typename fields instead of
+        // identifiers, because wit identifiers arent always Rust identifiers.
+        trappable_error_type: { "imports"::"e2": TrappableE2 }
     });
 
     #[test]