Bug 1559099: Bump Cranelift in Spidermonkey to e455f6ae; r=lth
authorBenjamin Bouvier <benj@benj.me>
Fri, 28 Jun 2019 15:25:47 +0200
changeset 540424 e73151bcaff8a776ee5536da1dbe6e6b91799032
parent 540413 98d86b9328ef5cf0454b98385f056020a4569f72
child 540425 b684d4532b91357024ec0ac6810565d442bc54f3
push id11529
push userarchaeopteryx@coole-files.de
push dateThu, 04 Jul 2019 15:22:33 +0000
treeherdermozilla-beta@ebb510a784b8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1559099
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1559099: Bump Cranelift in Spidermonkey to e455f6ae; r=lth Changes have been reviewed on the Cranelift side; this is just a bump to the latest version. Differential Revision: https://phabricator.services.mozilla.com/D36327
.cargo/config.in
Cargo.lock
Cargo.toml
third_party/rust/cranelift-bforest/.cargo-checksum.json
third_party/rust/cranelift-bforest/src/path.rs
third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
third_party/rust/cranelift-codegen-meta/src/gen_legalizer.rs
third_party/rust/cranelift-codegen-meta/src/shared/instructions.rs
third_party/rust/cranelift-codegen/.cargo-checksum.json
third_party/rust/cranelift-codegen/meta-python/base/instructions.py
third_party/rust/cranelift-codegen/meta-python/isa/riscv/encodings.py
third_party/rust/cranelift-codegen/meta-python/isa/riscv/recipes.py
third_party/rust/cranelift-codegen/meta-python/isa/x86/encodings.py
third_party/rust/cranelift-codegen/src/binemit/memorysink.rs
third_party/rust/cranelift-codegen/src/binemit/relaxation.rs
third_party/rust/cranelift-codegen/src/binemit/shrink.rs
third_party/rust/cranelift-codegen/src/cfg_printer.rs
third_party/rust/cranelift-codegen/src/context.rs
third_party/rust/cranelift-codegen/src/cursor.rs
third_party/rust/cranelift-codegen/src/ir/dfg.rs
third_party/rust/cranelift-codegen/src/ir/entities.rs
third_party/rust/cranelift-codegen/src/ir/function.rs
third_party/rust/cranelift-codegen/src/ir/globalvalue.rs
third_party/rust/cranelift-codegen/src/ir/libcall.rs
third_party/rust/cranelift-codegen/src/isa/arm32/mod.rs
third_party/rust/cranelift-codegen/src/isa/arm64/mod.rs
third_party/rust/cranelift-codegen/src/isa/mod.rs
third_party/rust/cranelift-codegen/src/isa/riscv/mod.rs
third_party/rust/cranelift-codegen/src/isa/x86/abi.rs
third_party/rust/cranelift-codegen/src/isa/x86/enc_tables.rs
third_party/rust/cranelift-codegen/src/isa/x86/mod.rs
third_party/rust/cranelift-codegen/src/legalizer/boundary.rs
third_party/rust/cranelift-codegen/src/legalizer/call.rs
third_party/rust/cranelift-codegen/src/legalizer/globalvalue.rs
third_party/rust/cranelift-codegen/src/legalizer/heap.rs
third_party/rust/cranelift-codegen/src/legalizer/libcall.rs
third_party/rust/cranelift-codegen/src/legalizer/mod.rs
third_party/rust/cranelift-codegen/src/legalizer/table.rs
third_party/rust/cranelift-codegen/src/licm.rs
third_party/rust/cranelift-codegen/src/postopt.rs
third_party/rust/cranelift-codegen/src/print_errors.rs
third_party/rust/cranelift-codegen/src/regalloc/affinity.rs
third_party/rust/cranelift-codegen/src/regalloc/coalescing.rs
third_party/rust/cranelift-codegen/src/regalloc/coloring.rs
third_party/rust/cranelift-codegen/src/regalloc/context.rs
third_party/rust/cranelift-codegen/src/regalloc/liveness.rs
third_party/rust/cranelift-codegen/src/regalloc/pressure.rs
third_party/rust/cranelift-codegen/src/regalloc/reload.rs
third_party/rust/cranelift-codegen/src/regalloc/solver.rs
third_party/rust/cranelift-codegen/src/regalloc/spilling.rs
third_party/rust/cranelift-codegen/src/settings.rs
third_party/rust/cranelift-codegen/src/value_label.rs
third_party/rust/cranelift-codegen/src/verifier/flags.rs
third_party/rust/cranelift-codegen/src/verifier/liveness.rs
third_party/rust/cranelift-codegen/src/verifier/locations.rs
third_party/rust/cranelift-codegen/src/verifier/mod.rs
third_party/rust/cranelift-codegen/src/write.rs
third_party/rust/cranelift-entity/.cargo-checksum.json
third_party/rust/cranelift-entity/src/lib.rs
third_party/rust/cranelift-frontend/.cargo-checksum.json
third_party/rust/cranelift-frontend/src/frontend.rs
third_party/rust/cranelift-wasm/.cargo-checksum.json
third_party/rust/cranelift-wasm/Cargo.toml
third_party/rust/cranelift-wasm/src/code_translator.rs
third_party/rust/cranelift-wasm/src/module_translator.rs
third_party/rust/cranelift-wasm/src/sections_translator.rs
third_party/rust/cranelift-wasm/src/translation_utils.rs
third_party/rust/wasmparser/.cargo-checksum.json
third_party/rust/wasmparser/Cargo.toml
third_party/rust/wasmparser/benches/benchmark.rs
third_party/rust/wasmparser/compare-master.sh
third_party/rust/wasmparser/examples/dump.rs
third_party/rust/wasmparser/src/binary_reader.rs
third_party/rust/wasmparser/src/lib.rs
third_party/rust/wasmparser/src/limits.rs
third_party/rust/wasmparser/src/operators_validator.rs
third_party/rust/wasmparser/src/parser.rs
third_party/rust/wasmparser/src/primitives.rs
third_party/rust/wasmparser/src/tests.rs
third_party/rust/wasmparser/src/validator.rs
--- a/.cargo/config.in
+++ b/.cargo/config.in
@@ -19,13 +19,13 @@ replace-with = "vendored-sources"
 
 [source."https://github.com/rust-lang-nursery/packed_simd"]
 git = "https://github.com/hsivonen/packed_simd"
 branch = "rust_1_32"
 replace-with = "vendored-sources"
 
 [source."https://github.com/CraneStation/Cranelift"]
 git = "https://github.com/CraneStation/Cranelift"
-rev = "475aa632fea5360c6f8c4cc1f26e3ee0369385ef"
+rev = "e455f6ae0f3577ceb210c0ce167181c33c133a69"
 replace-with = "vendored-sources"
 
 [source.vendored-sources]
 directory = '@top_srcdir@/third_party/rust'
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -192,18 +192,18 @@ dependencies = [
  "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "baldrdash"
 version = "0.1.0"
 dependencies = [
  "bindgen 0.49.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
- "cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
+ "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
+ "cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "base64"
 version = "0.9.3"
@@ -608,70 +608,70 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cose 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-bforest"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef#475aa632fea5360c6f8c4cc1f26e3ee0369385ef"
-dependencies = [
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69#e455f6ae0f3577ceb210c0ce167181c33c133a69"
+dependencies = [
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
 ]
 
 [[package]]
 name = "cranelift-codegen"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef#475aa632fea5360c6f8c4cc1f26e3ee0369385ef"
-dependencies = [
- "cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
- "cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69#e455f6ae0f3577ceb210c0ce167181c33c133a69"
+dependencies = [
+ "cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
+ "cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
  "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-codegen-meta"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef#475aa632fea5360c6f8c4cc1f26e3ee0369385ef"
-dependencies = [
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69#e455f6ae0f3577ceb210c0ce167181c33c133a69"
+dependencies = [
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
 ]
 
 [[package]]
 name = "cranelift-entity"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef#475aa632fea5360c6f8c4cc1f26e3ee0369385ef"
+source = "git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69#e455f6ae0f3577ceb210c0ce167181c33c133a69"
 
 [[package]]
 name = "cranelift-frontend"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef#475aa632fea5360c6f8c4cc1f26e3ee0369385ef"
-dependencies = [
- "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69#e455f6ae0f3577ceb210c0ce167181c33c133a69"
+dependencies = [
+ "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-wasm"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef#475aa632fea5360c6f8c4cc1f26e3ee0369385ef"
-dependencies = [
- "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
- "cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69#e455f6ae0f3577ceb210c0ce167181c33c133a69"
+dependencies = [
+ "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
+ "cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)",
  "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmparser 0.31.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "crc"
 version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3535,17 +3535,17 @@ dependencies = [
  "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "tungstenite 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "urlencoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "wasmparser"
-version = "0.29.2"
+version = "0.31.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "webdriver"
 version = "0.39.0"
 dependencies = [
  "base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3882,22 +3882,22 @@ dependencies = [
 "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
 "checksum cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1465f8134efa296b4c19db34d909637cb2bf0f7aaf21299e23e18fa29ac557cf"
 "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
 "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
 "checksum core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "62ceafe1622ffc9a332199096841d0ff9912ec8cf8f9cde01e254a7d5217cd10"
 "checksum core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f46450d6f2397261af420b4ccce23807add2e45fa206410a03d66fb7f050ae"
 "checksum cose 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72fa26cb151d3ae4b70f63d67d0fed57ce04220feafafbae7f503bef7aae590d"
 "checksum cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "49726015ab0ca765144fcca61e4a7a543a16b795a777fa53f554da2fffff9a94"
-"checksum cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)" = "<none>"
-"checksum cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)" = "<none>"
-"checksum cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)" = "<none>"
-"checksum cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)" = "<none>"
-"checksum cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)" = "<none>"
-"checksum cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=475aa632fea5360c6f8c4cc1f26e3ee0369385ef)" = "<none>"
+"checksum cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)" = "<none>"
+"checksum cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)" = "<none>"
+"checksum cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)" = "<none>"
+"checksum cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)" = "<none>"
+"checksum cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)" = "<none>"
+"checksum cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=e455f6ae0f3577ceb210c0ce167181c33c133a69)" = "<none>"
 "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7"
 "checksum crossbeam-channel 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8d4f5844607ce8da3fff431e7dba56cda8bfcc570aa50bee36adba8a32b8cad7"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
 "checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
@@ -4153,17 +4153,17 @@ dependencies = [
 "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
 "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
 "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
 "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
 "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
 "checksum warp 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a120bf7041d4381a5429c4e6d12633bfb874c968a78ec3a3563e9ca6e12d6"
-"checksum wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "981a8797cf89762e0233ec45fae731cb79a4dfaee12d9f0fe6cee01e4ac58d00"
+"checksum wasmparser 0.31.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6f324afc05fd8282bbc49dae854a1c20f74aeff10a575b5a43453d1864db97"
 "checksum weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26a4c67f132386d965390b8a734d5d10adbcd30eb5cc74bd9229af8b83f10044"
 "checksum which 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4be6cfa54dab45266e98b5d7be2f8ce959ddd49abd141a05d52dce4b07f803bb"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)" = "<none>"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)" = "<none>"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)" = "<none>"
 "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -59,13 +59,13 @@ codegen-units = 1
 [patch.crates-io]
 libudev-sys = { path = "dom/webauthn/libudev-sys" }
 serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums10" }
 winapi = { git = "https://github.com/froydnj/winapi-rs", branch = "aarch64" }
 packed_simd = { git = "https://github.com/hsivonen/packed_simd", branch = "rust_1_32" }
 
 [patch.crates-io.cranelift-codegen]
 git = "https://github.com/CraneStation/Cranelift"
-rev = "475aa632fea5360c6f8c4cc1f26e3ee0369385ef"
+rev = "e455f6ae0f3577ceb210c0ce167181c33c133a69"
 
 [patch.crates-io.cranelift-wasm]
 git = "https://github.com/CraneStation/Cranelift"
-rev = "475aa632fea5360c6f8c4cc1f26e3ee0369385ef"
+rev = "e455f6ae0f3577ceb210c0ce167181c33c133a69"
--- a/third_party/rust/cranelift-bforest/.cargo-checksum.json
+++ b/third_party/rust/cranelift-bforest/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"4fb2be5a108736ec2eeb257fd9c90d7e4384321e34eaef0fc7c5517a8e096650","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"1b23abbfe5850a4cd77ae6ae5dcfc2f678ef36b4032fd7496f2b333c51e63301","src/map.rs":"5d891d62814941e19dfc88ff36538efa3da5479f3f97de8219a6f610c9a1ee32","src/node.rs":"e620c64e78488035f11723b14892c7986c06ad37dc5b115a35a453ff1ae66ca3","src/path.rs":"4868e59ff67db1c504747e4b7e202dd20c9da4cbd73d9fa82d53e5f3406dbb78","src/pool.rs":"6090f8c0e0da16ebee0e31bca66392d0075b3aff529d30d4e716fa20cd0aef99","src/set.rs":"b411158f813a310c7a6c337d4ada3bf0a021088c443875dc25233415dcbe0633"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"4fb2be5a108736ec2eeb257fd9c90d7e4384321e34eaef0fc7c5517a8e096650","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"1b23abbfe5850a4cd77ae6ae5dcfc2f678ef36b4032fd7496f2b333c51e63301","src/map.rs":"5d891d62814941e19dfc88ff36538efa3da5479f3f97de8219a6f610c9a1ee32","src/node.rs":"e620c64e78488035f11723b14892c7986c06ad37dc5b115a35a453ff1ae66ca3","src/path.rs":"a86ee1c882c173e8af96fd53a416a0fb485dd3f045ac590ef313a9d9ecf90f56","src/pool.rs":"6090f8c0e0da16ebee0e31bca66392d0075b3aff529d30d4e716fa20cd0aef99","src/set.rs":"b411158f813a310c7a6c337d4ada3bf0a021088c443875dc25233415dcbe0633"},"package":null}
\ No newline at end of file
--- a/third_party/rust/cranelift-bforest/src/path.rs
+++ b/third_party/rust/cranelift-bforest/src/path.rs
@@ -44,17 +44,17 @@ impl<F: Forest> Path<F> {
     /// - A key between the stored keys of adjacent leaf nodes returns a path to one beyond the
     ///   last entry of the first of the leaf nodes.
     ///
     pub fn find(
         &mut self,
         key: F::Key,
         root: Node,
         pool: &NodePool<F>,
-        comp: &Comparator<F::Key>,
+        comp: &dyn Comparator<F::Key>,
     ) -> Option<F::Value> {
         let mut node = root;
         for level in 0.. {
             self.size = level + 1;
             self.node[level] = node;
             match pool[node] {
                 NodeData::Inner { size, keys, tree } => {
                     // Invariant: `tree[i]` contains keys smaller than
--- a/third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
+++ b/third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"253c80832ab598570d604ae8a8108ea9835b8eef8d9b9645408ed025ce3b574a","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/ast.rs":"170f0526c73e4ebdd22cf25290607b6610e9e3fe0b1d79ee38962085f878d2e4","src/cdsl/cpu_modes.rs":"57c40621115a58faa7af1c729ecaf8cda01c2b143008bde6d8c70885e7c3fd75","src/cdsl/formats.rs":"8eaee84c9c574e7a2ab73b4bf63b97c1cea3ffce0a477f1701e75a7a523ada57","src/cdsl/instructions.rs":"dd734b1ff0750ec09a06e5746338f479ae97eb122dc64dba37b656ab5ae79ebd","src/cdsl/isa.rs":"569bf078c68c800fbd36fde1b52e0371747f6249252655e2dc4715d4e975be40","src/cdsl/mod.rs":"86149f101e1b00a9623028dcd779ad66b6a67f0f67b423c5ac88cd96dabdd227","src/cdsl/operands.rs":"1cda258798d861c4f467783b5c70c1202a57f554861017eead6477af2ee34063","src/cdsl/regs.rs":"049d299c63a757aad7adb7945b3919bd62c9204348a4f8b9727ca84fecbf3115","src/cdsl/settings.rs":"b6b1653b486fb4b86aaab59328a959cf784cb4b61b3216fe7acebe0490849642","src/cdsl/type_inference.rs":"2771631701c150e077c5dcf705c8ae8705944d86ab945ae9e7adc82f3ca5447a","src/cdsl/types.rs":"4cc1f20eb8383fdee6a9e7ca0f7758e563a4fb715056b5edbd4db72f8dfd471b","src/cdsl/typevar.rs":"7249fcd7c3cd3645e8489c73595bd5327bedc499bd7bc87f2a68e241fba329c3","src/cdsl/xform.rs":"005bd2fca7f8b737c605a75a0f44f2d70f0138e67f3013343ced81f639dce8bb","src/constant_hash.rs":"b8acd3f8712a4999819d9d9beced2938d9940a5748ba016c182f1132d97eefab","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_inst.rs":"94e71181683f022fdcc55abf487a20be5d4dd51fe3092345b6bc4e2bde04441b","src/gen_legalizer.rs":"8c525a42df0b8283c445a1abd5376682500b49ee8033bc66575f8e14f29f4de3","src/gen_registers.rs":"a544a2b91fafe08639e39e50bea0892fda89fe2f6eaf111b2d5f3e98e4d07b86","src/gen_settings.rs":"4469bf496f9539835fce3cd9743ac0fbc270b3029b0e6c949f406e790685199c","src/gen_types.rs":"3935da6c6a53f9332e06f74bc3a46270656b4d4231ad28ed2648d7b1d2774e90","src/isa/arm32/mod.rs":"54e88d89644c5cee61cdc8315f1d77b01c232dc322c52f6e244cef9e7688a3ad","src/isa/arm64/mod.rs":"c5169b92c1bcb562649a48b7880033f542c9affa73274d23b3817e4ac83942fe","src/isa/mod.rs":"fce60d19dd3c099ebee3ac5ae64a2bee363f13da9ff5a4960d3c1a0bee71d29a","src/isa/riscv/mod.rs":"2da05e3974ef0b72431c9fdda14314890f72500b94def1d74cdf5e74bd950bc0","src/isa/x86/instructions.rs":"ad88f311fd51f341f7dfe395f98d8805ea55e1c86d1a89272ed999f5ae8dc3f0","src/isa/x86/legalize.rs":"251af731b2514fead08e27e812ca44dc674a41bd4a9637d9d919259497961961","src/isa/x86/mod.rs":"14715e552eedfeae1693a416bb82bda2156b31cd4b306e07530a3c1acdc17125","src/isa/x86/registers.rs":"c0bc60336a8c8b7b4db92dc623e9419a60af14dd6252f0b19e227e46f7166178","src/isa/x86/settings.rs":"1a74b3d1ef5e99e0b7c75528b9fd5afbb3394979615b005b43b72108757a9886","src/lib.rs":"8c9364c6fce73c158abfb7c88ecff01dc608a05c250e89df9bec3082773cde6d","src/shared/entities.rs":"80b8ff57a09c7b2f9dab755abbcc2738317de474776fe1de0d2a581310aa9af8","src/shared/formats.rs":"20908b1048c5e71a185de6b6ded79cdff2c26ddb38ba7b134b7a27f37e8324f3","src/shared/immediates.rs":"804c4c9ffa2fe55d90279ee158aaa6bd6c7f0c604d63d7457a98e82269cec9a7","src/shared/instructions.rs":"4222d17a9a8be083cc729715527290ca22c8ebe1f9679812a5237025a0479dcd","src/shared/legalize.rs":"e3ed83c004afd088bedad0db6664983bfc15149fb99d7d28dea535b2ff48d761","src/shared/mod.rs":"6e30631fe2ba19d819330ea14d29cce4910b435f030e706be2fc94af23b88d71","src/shared/settings.rs":"42c2c5b6f5fdef090c35760c5920d5013afe4ddc472ee9cc37eb6d8ddaae2906","src/shared/types.rs":"158d73840185e6aa8385463bbf6568efdda0c8de8284cf6b4e565f425ec5d921","src/srcgen.rs":"79fee2f603b33f76f7c9c8b9452c745a363d732c40c0814d84001ff3ef805677","src/unique_table.rs":"90b7203b29241a1ede70f0a3e50d96799e0b41d8f7455170d6ffb127f87f3cc3"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"253c80832ab598570d604ae8a8108ea9835b8eef8d9b9645408ed025ce3b574a","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/ast.rs":"170f0526c73e4ebdd22cf25290607b6610e9e3fe0b1d79ee38962085f878d2e4","src/cdsl/cpu_modes.rs":"57c40621115a58faa7af1c729ecaf8cda01c2b143008bde6d8c70885e7c3fd75","src/cdsl/formats.rs":"8eaee84c9c574e7a2ab73b4bf63b97c1cea3ffce0a477f1701e75a7a523ada57","src/cdsl/instructions.rs":"dd734b1ff0750ec09a06e5746338f479ae97eb122dc64dba37b656ab5ae79ebd","src/cdsl/isa.rs":"569bf078c68c800fbd36fde1b52e0371747f6249252655e2dc4715d4e975be40","src/cdsl/mod.rs":"86149f101e1b00a9623028dcd779ad66b6a67f0f67b423c5ac88cd96dabdd227","src/cdsl/operands.rs":"1cda258798d861c4f467783b5c70c1202a57f554861017eead6477af2ee34063","src/cdsl/regs.rs":"049d299c63a757aad7adb7945b3919bd62c9204348a4f8b9727ca84fecbf3115","src/cdsl/settings.rs":"b6b1653b486fb4b86aaab59328a959cf784cb4b61b3216fe7acebe0490849642","src/cdsl/type_inference.rs":"2771631701c150e077c5dcf705c8ae8705944d86ab945ae9e7adc82f3ca5447a","src/cdsl/types.rs":"4cc1f20eb8383fdee6a9e7ca0f7758e563a4fb715056b5edbd4db72f8dfd471b","src/cdsl/typevar.rs":"7249fcd7c3cd3645e8489c73595bd5327bedc499bd7bc87f2a68e241fba329c3","src/cdsl/xform.rs":"005bd2fca7f8b737c605a75a0f44f2d70f0138e67f3013343ced81f639dce8bb","src/constant_hash.rs":"b8acd3f8712a4999819d9d9beced2938d9940a5748ba016c182f1132d97eefab","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_inst.rs":"94e71181683f022fdcc55abf487a20be5d4dd51fe3092345b6bc4e2bde04441b","src/gen_legalizer.rs":"368ea72fe2d253f7d4d7548ae449fde875781e43ce0ecb9a604765595e387cc2","src/gen_registers.rs":"a544a2b91fafe08639e39e50bea0892fda89fe2f6eaf111b2d5f3e98e4d07b86","src/gen_settings.rs":"4469bf496f9539835fce3cd9743ac0fbc270b3029b0e6c949f406e790685199c","src/gen_types.rs":"3935da6c6a53f9332e06f74bc3a46270656b4d4231ad28ed2648d7b1d2774e90","src/isa/arm32/mod.rs":"54e88d89644c5cee61cdc8315f1d77b01c232dc322c52f6e244cef9e7688a3ad","src/isa/arm64/mod.rs":"c5169b92c1bcb562649a48b7880033f542c9affa73274d23b3817e4ac83942fe","src/isa/mod.rs":"fce60d19dd3c099ebee3ac5ae64a2bee363f13da9ff5a4960d3c1a0bee71d29a","src/isa/riscv/mod.rs":"2da05e3974ef0b72431c9fdda14314890f72500b94def1d74cdf5e74bd950bc0","src/isa/x86/instructions.rs":"ad88f311fd51f341f7dfe395f98d8805ea55e1c86d1a89272ed999f5ae8dc3f0","src/isa/x86/legalize.rs":"251af731b2514fead08e27e812ca44dc674a41bd4a9637d9d919259497961961","src/isa/x86/mod.rs":"14715e552eedfeae1693a416bb82bda2156b31cd4b306e07530a3c1acdc17125","src/isa/x86/registers.rs":"c0bc60336a8c8b7b4db92dc623e9419a60af14dd6252f0b19e227e46f7166178","src/isa/x86/settings.rs":"1a74b3d1ef5e99e0b7c75528b9fd5afbb3394979615b005b43b72108757a9886","src/lib.rs":"8c9364c6fce73c158abfb7c88ecff01dc608a05c250e89df9bec3082773cde6d","src/shared/entities.rs":"80b8ff57a09c7b2f9dab755abbcc2738317de474776fe1de0d2a581310aa9af8","src/shared/formats.rs":"20908b1048c5e71a185de6b6ded79cdff2c26ddb38ba7b134b7a27f37e8324f3","src/shared/immediates.rs":"804c4c9ffa2fe55d90279ee158aaa6bd6c7f0c604d63d7457a98e82269cec9a7","src/shared/instructions.rs":"85f74df59fb0564613055df2173699e61d9e711fb481015635de47c5286690fd","src/shared/legalize.rs":"e3ed83c004afd088bedad0db6664983bfc15149fb99d7d28dea535b2ff48d761","src/shared/mod.rs":"6e30631fe2ba19d819330ea14d29cce4910b435f030e706be2fc94af23b88d71","src/shared/settings.rs":"42c2c5b6f5fdef090c35760c5920d5013afe4ddc472ee9cc37eb6d8ddaae2906","src/shared/types.rs":"158d73840185e6aa8385463bbf6568efdda0c8de8284cf6b4e565f425ec5d921","src/srcgen.rs":"79fee2f603b33f76f7c9c8b9452c745a363d732c40c0814d84001ff3ef805677","src/unique_table.rs":"90b7203b29241a1ede70f0a3e50d96799e0b41d8f7455170d6ffb127f87f3cc3"},"package":null}
\ No newline at end of file
--- a/third_party/rust/cranelift-codegen-meta/src/gen_legalizer.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/gen_legalizer.rs
@@ -405,17 +405,17 @@ fn gen_transform_group<'a>(
     fmt.line("#[allow(unused_variables,unused_assignments,non_snake_case)]");
 
     // Function arguments.
     fmtln!(fmt, "pub fn {}(", group.name);
     fmt.indent(|fmt| {
         fmt.line("inst: crate::ir::Inst,");
         fmt.line("func: &mut crate::ir::Function,");
         fmt.line("cfg: &mut crate::flowgraph::ControlFlowGraph,");
-        fmt.line("isa: &crate::isa::TargetIsa,");
+        fmt.line("isa: &dyn crate::isa::TargetIsa,");
     });
     fmtln!(fmt, ") -> bool {");
 
     // Function body.
     fmt.indent(|fmt| {
         fmt.line("use crate::ir::InstBuilder;");
         fmt.line("use crate::cursor::{Cursor, FuncCursor};");
         fmt.line("let mut pos = FuncCursor::new(func).at_inst(inst);");
--- a/third_party/rust/cranelift-codegen-meta/src/shared/instructions.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/shared/instructions.rs
@@ -304,17 +304,18 @@ pub fn define(
     ``addr`` with a specific ``Size``. The retrieved entry may need to be
     decoded after loading, depending upon the jump table type used.
 
     Currently, the only type supported is entries which are relative to the
     base of the jump table.
     "#,
         )
         .operands_in(vec![x, addr, Size, JT])
-        .operands_out(vec![entry]),
+        .operands_out(vec![entry])
+        .can_load(true),
     );
 
     ig.push(
         Inst::new(
             "jump_table_base",
             r#"
     Get the absolute base address of a jump table.
 
--- a/third_party/rust/cranelift-codegen/.cargo-checksum.json
+++ b/third_party/rust/cranelift-codegen/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"9e1e9d197a2fcdb9bfd3c32a7608ab772ed4301aa0b9f2e60b73c98f542ac760","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"e5127227a7db4a8aa92fa6613ed71801025790e696bb41b0323fb7f3c6f7495a","build.rs":"7c0919d12ff966e0c400e7cfa0a555b2e50ede20c0dfb4f4401e35a828134ea9","meta-python/base/__init__.py":"4fac8bb055541dc964383bb04223bae6dfbfe348abf5e23f83655966cbb4aa8f","meta-python/base/entities.py":"f956b8ba863cd26f6867e13c1b2db3c202e9b07c48c1e43a9c2b41ad0deb8922","meta-python/base/formats.py":"6f8cf7cbdfb613acfd4ba3a8e4a9a173cbaa8afd254f03218c5f01daa1078d6c","meta-python/base/immediates.py":"f42682d86bda7b569ec2fc2debd9036355999e61caaa9fbf8307e0be8a164814","meta-python/base/instructions.py":"560a9e86f658d7627c596e992919f696cf6275dbb5de47aa9bf09ec3dec789f8","meta-python/base/legalize.py":"beddc21c03ffba30a509a6df28ad87e3162cf8c60debd036082e32f3c732b7d2","meta-python/base/predicates.py":"53a5a9a37021a9762f0faec9f9e3c5b713411d47dd9192423cfe0f7a61916809","meta-python/base/semantics.py":"b90cbca9a143676ac37496c83634a66a83360248e4505ff7bda12b0d454efd92","meta-python/base/settings.py":"97fca9ddaab347f50f1594c93283f8f474e53a7232eae65949f56a6a702c2bba","meta-python/base/types.py":"9616d6fe4cab050827ab02eeb9843eacebbb8f7555521f504b5ee2ddf7214fdb","meta-python/build.py":"254a7fb51f6025c54f5b08135b83ffadfc2e6c02cb8c3078fdd06c0eff4b91da","meta-python/cdsl/__init__.py":"b534ec129a0e517f0d13313c2b4bb3a345d3e5b62693a31d8d42c80a219e39fa","meta-python/cdsl/ast.py":"8509f15eaaaf2fed2bec93eba19d313d37c2ddd70d1399a491a394206cbfabe4","meta-python/cdsl/formats.py":"fedfeaec754b40d6a9cc92b827976782c615d8eab1c7f47f6b47510cbef585f4","meta-python/cdsl/instructions.py":"50fe9329a56e6294a27306aad7be22c88a5b5ef42c3b030ec59218167157f62f","meta-python/cdsl/isa.py":"dc530a4dd5642e3379398dfc8a90ad6ae1692302de63851370bdfa8abf4cdce0","meta-python/cdsl/operands.py":"e24914eae4059b88781bf5a5d7a14ecf98b10a701ed6cf6e88d15981b2ccbfdf","meta-python/cdsl/predicates.py":"fe2dc6e78ff6d4bcb6b1d5448ded343ede0f03b96a965a11aef0f5bbe7bb8f56","meta-python/cdsl/registers.py":"939dafd1b8976a6cd456c9a5e4b374af81fafb9da979ea3a1f6d14e4645914a6","meta-python/cdsl/settings.py":"400d853a815f64c0294d0c0e03d3c514942760faa8b06152b1078a92ddb9f62c","meta-python/cdsl/test_ast.py":"947e934e2862445a158bf266dff58a8c88aae31fb34a7f823309ee58a15c5393","meta-python/cdsl/test_package.py":"ffa53d20e023ecb89137294bb13614f4de9b09e1bf05d9772131570bf78f7987","meta-python/cdsl/test_ti.py":"04656e2da99ec37875f91172bb2fa423da1ee27bf523a4d41af311ea22492d1b","meta-python/cdsl/test_typevar.py":"768bf3c35481950264ad6fd7059a532ac62b121ac439983bb4fe1ae76a1d1248","meta-python/cdsl/test_xform.py":"ddb6633c7941bbf68570701cb887a81d6b4b27f4bc45eabccf2ce287ad9b77e9","meta-python/cdsl/ti.py":"566e91f0bb3ebacd5abf9f5a663caee69706c2e829dee1ed735d229198689f76","meta-python/cdsl/types.py":"adee4bbc1a9478288fa4b53ee1edeb5ee3296dba2c70bfbe01e923895064999e","meta-python/cdsl/typevar.py":"b5669934eddaf5b9cc0c27b966e2566b5f669f1c5a345f005960930fb499097e","meta-python/cdsl/xform.py":"bf200b711570b905f0fb30611ba64f131f98593060eedbe5575054cca4928593","meta-python/check.sh":"707cda14534882e8d4593f93c056390560394c9bc8a687e99f10a56d7b09cb92","meta-python/constant_hash.py":"c752e6dadf3a9a5bd00c978e85ab27a20c49138a1ccdc6fc9a1904797a4bfe48","meta-python/gen_binemit.py":"76472fb199a330b934ba9ad0a1bbacfb52f0eae7c9a66d83f0d7890970323a2d","meta-python/gen_build_deps.py":"53bbdd591c91f8e28da95e4da02c9299a01a32d8be6a0c7490b6b7c60a4fbebe","meta-python/gen_encoding.py":"471c5f4ecf24a2a173864c62a48920e5fbe1aacd2229b3eb4483637570bb26b2","meta-python/isa/__init__.py":"e499c1206cd095a926fa0ca7eb9d0a50a802ed71c8eb7598e5d3a0f939c8ada5","meta-python/isa/arm32/__init__.py":"eecba73231aa398ded7304690bdba3450dc163afd4360f1b0ad02a28e2380363","meta-python/isa/arm32/defs.py":"01c41dbd7406c624e26229df6befa0992194bddcc7d11e8f6174abfe2b33bf61","meta-python/isa/arm32/registers.py":"c03ca6435828ad5f262049e42f1f71bcf74903831f85daa92c3f322a6c1050ea","meta-python/isa/arm32/settings.py":"afd5a04a9d029f578d6f62dc7c539191886cc9f9dea15d65fc66bf37a63b8814","meta-python/isa/arm64/__init__.py":"f6877253cf786d7ee972881e7d9b3c78c11e6b024e4e227487340dd01d0c44e4","meta-python/isa/arm64/defs.py":"797c5bb6d11fc7a44afe67476136dbd11c40f5e13a1c8f52f9f96be4441677b2","meta-python/isa/arm64/registers.py":"9bdd06edaa382be96042e1ac36d63137e73292292b61dcf4becb7d1428130317","meta-python/isa/arm64/settings.py":"f7b1f8733e775ea8005372ee35f1c2a627b3a69d722e837295599e4cf1f5eb43","meta-python/isa/riscv/__init__.py":"c11607c9eef0bc2707daa3edd4174e934c7a0dcc8ce90cee2c9292a85b1ac596","meta-python/isa/riscv/defs.py":"e73740055c4fb123c45453fc149a807e9720466de848022d5375049bdcfc311c","meta-python/isa/riscv/encodings.py":"ecaad5ea98273ade1cb10606354e893342c495bb48771df50121f789566d7be6","meta-python/isa/riscv/recipes.py":"3852e5b7aa6995fa721ba91744a0470343ce1834651e7b9cc97b5d69af7dfdc5","meta-python/isa/riscv/registers.py":"ef9aca3a6ec2b08ee8f5952186d232861b64a919b671b41911a365e7672b01bd","meta-python/isa/riscv/settings.py":"dfe29722d67be0620a70e08cfb802829a26f5fd339a9342a8ac2dd419daf8a85","meta-python/isa/x86/__init__.py":"ad579de68ea7bf5dc2bce0e3a6f09e7978b1697f1afec8a5ce5dc591136e590d","meta-python/isa/x86/defs.py":"b5eb7889b6f5e5b221ed3923d0137bbb1566c55b5961448cc39e4ea2f13cf4b7","meta-python/isa/x86/encodings.py":"6dff12042c50bca59b891e6b1e70a34e12ecc83194efbf02e42ea7071da8f4f7","meta-python/isa/x86/instructions.py":"530cde78e6b9f6e4ea2192985f4c5c77a987cdc19001d50fb47fa8e36a62f52e","meta-python/isa/x86/legalize.py":"1375ded072c29459e7c0e40ecb02f28d5395d9d8c603eb70e338b2bf2991c9cd","meta-python/isa/x86/recipes.py":"5dc66c8e0d0ac3aff05dfe42822b4711c677d52177f9753b50daa73eeee4b690","meta-python/isa/x86/registers.py":"ff934491d07ec6b51fbfd454b865a7c7c191ffbd31b1804615735266b120f4b2","meta-python/isa/x86/settings.py":"7ef2e43521b9b11e90a93c1c60946e65d420ecf6e15ba17f933c7a24a5124e5b","meta-python/mypy.ini":"5ec2f7cc0bbc4fd0435643d6b72e715bd9568a3a0fe14c043f9e559c405b66fb","meta-python/semantics/__init__.py":"c9dd72fde0ab020d3328dde532d92b39e438e4147930e41df7613c27727e11eb","meta-python/semantics/elaborate.py":"3a3fbba83a6818c2d1ce236fd0413111380875a0307f7a5f4b5dd66d8ef714b1","meta-python/semantics/macros.py":"b218c52e1bd4f019dc14a27d315b4f3405a10e5bdc6f2523fe709c8faf91b418","meta-python/semantics/primitives.py":"4e5eb0c90fcc295686732c8c66ad7a793997645c9a676c97babf06823fd2b60d","meta-python/semantics/smtlib.py":"48ef80320f21682860bbf5f79f18739f1d10f0b1fe581ebb05541e90dc2f2f4f","meta-python/semantics/test_elaborate.py":"3a4c850a7385007422c7549661b211903cd1dd1606dad7a86262ae27e697bca6","meta-python/srcgen.py":"999557d683e808a2ca90688c489ec4aff65798f44ac321ecf7de34d307261913","meta-python/stubs/z3/__init__.pyi":"6aaeb80f783b29c4364dee21da45f6df041c0a4807189a15777ee5447f6515dc","meta-python/stubs/z3/z3core.pyi":"c01a41d468e07cc4f8b405c292ed7f8c82bc1077f8b82dfde1e474577ade3335","meta-python/stubs/z3/z3types.pyi":"30009c951af99b9028d47cd4cabae95ff9742b77b690bd8dd63f6b7dba580759","meta-python/test_constant_hash.py":"157cf4f8964e0f04c041ffd349e889ce565b144453436690578c5d03c3a60216","meta-python/test_srcgen.py":"d6d7775e19a5b2621360c00eb6d92dfcb4568e49220993e0ceaac9628dbfd661","meta-python/unique_table.py":"5bd500667430c15f6ae586603d8612fb3bda07b072e40d86286e08392bdc3127","src/abi.rs":"76ee030cf0780fe63ccbf855b1161f215e3e2991cb9abe71ca9aff25e5f1dbc2","src/binemit/memorysink.rs":"25c02b556782598e83a7a59f4a2c47a8cfede21388e6640a87f1af1092a570ea","src/binemit/mod.rs":"ed63c382e6f58a9f7417d8913c15387f88d511a4ef02cba191c341496db50863","src/binemit/relaxation.rs":"6d8a993c224bedf283ca61af62caa4d4bf58e889b0997c59d5ad1fec78ce562d","src/binemit/shrink.rs":"45434d5fb17804f5199f5fa80fd96aedaeac1ca3824766236eb16b6b529155b4","src/bitset.rs":"d57a79058a31b094b4bbe9d34876a5543286df1e08b5ceadfd05a9efc5a3b1ce","src/cfg_printer.rs":"69b4f16132c886ef0b883c8b78b59d041ceec3c8b96dd8015e990ac06733ce91","src/constant_hash.rs":"330e8289789ee351d0abeaf4b5e859b8db8772306e0820d34864fc9905d53b38","src/context.rs":"573beb0e83268bdd1dddf0b477d6dbafe6915d37a6d6b9a61dd582f3c22d2406","src/cursor.rs":"dcce946ad85d8fc2f1c9cc885ae8a0440c37d9e512606fb8a518aaffcc6d6f8f","src/dbg.rs":"1898d94cff0975815eb348651702e95c8f2f63886501d3b7043ee75668480472","src/dce.rs":"d8ab7c0cac0416f9d75afdacc60ba02e532361ec927c3f8bd171b1a53ec8b31a","src/divconst_magic_numbers.rs":"09691389c9055bef7a0cfd5d77fbfeba4be468d05d981d4de088516a94b8b28e","src/dominator_tree.rs":"7ee4114026011b11d49e48c5a9202970bafe3b22c2074f7c1390b98ebb2edb7a","src/flowgraph.rs":"bf520026c32c5454554d0b078b64a78bd44f3c0f4f198eddf71bcfd78cc963a3","src/fx.rs":"8a5d07487906d8316a179e826fcd817a92a4860686256a6fd9d78ba47c63f330","src/ir/builder.rs":"1a12c57f4168fa3c2fcf6be2f19d0d377eee40f24ae4390e6ba9d954f85a8a3e","src/ir/condcodes.rs":"5247c8d849e1372d2a22379c33a4a88226ec6187be18ca6f2c4e0f315d812aa8","src/ir/dfg.rs":"f5cb672656c7e56185544c3ff7f60f8a4b7b9f172d9a9920144616bc165d5928","src/ir/entities.rs":"8bae1166b59afd38953e7d9154ae141c979ab77153b9512f45db7b82a256fdf4","src/ir/extfunc.rs":"9806734eeb480724481128d8c1de78a3b1f80f1214c20f24131196a0df137872","src/ir/extname.rs":"ed2c0b52cdaecc7f0ba9a894ef9fffe139e09b520e43dcd6f0c887a3d41a31ac","src/ir/function.rs":"91bda86993e6f664ba3fef8da286d0efe34b17d7e77cec692e09cf014c81b6e5","src/ir/globalvalue.rs":"1f6125788a9a5c118716f87fd72e85009d2e0a7f4c13b2a7904be8c7412ee4eb","src/ir/heap.rs":"a59d3e5901412b53c0b53a8cdf10765ff5921de9c410ae9acea226c89827df3c","src/ir/immediates.rs":"029a8aa905e6fd0f3334e17a28e73ac36684df2ca0829dcae0158ea8cf64ca8c","src/ir/instructions.rs":"2180de1d127ab5878c5743d8e096d551edb973e0ff1d373c4239c32e7981364c","src/ir/jumptable.rs":"7764abc9aa027a5a89d22059b360372bd9a19686887c5a7830f7637d6f188e1e","src/ir/layout.rs":"bb45eefde16ac9423f637dfcc2796ae7b955a97f38a55f23a19cc45da5decce1","src/ir/libcall.rs":"55fd77f6e32370812a271f4fd5d9817c03904733be79d49e17e2683fe516e30e","src/ir/memflags.rs":"dbcf3798ab66dc764b73fb7f139a621c54cc6bcc683f1f70a33ed7e8c3486bfd","src/ir/mod.rs":"37685305acb21dc24896e5d7977784988fe723c09bdf8ab8cc7830ccabd76a11","src/ir/progpoint.rs":"49433f22bd6ff3a96ad0733ff612f3617b312e4492b6b663187141966f6aa701","src/ir/sourceloc.rs":"37ef5fd8cef1de99620797d7d5aba3630e737171853c8471495c685dafac19b6","src/ir/stackslot.rs":"2f54359339837bb1d0d817d3af21bb4b1b050c31703885dfaced29f6e41153c2","src/ir/table.rs":"dcc3b663a989b2b084402b08dc9a0e928dbd052e194a46a1886cc6f0cf1a5f2c","src/ir/trapcode.rs":"59e223193617b8c1043ddd3a907c6131f2987e8fe0965ebfd9f7c056c064b7c5","src/ir/types.rs":"1f644beba2c797f7bd89378d930c3eca1491ec5f82c4715945ac63a0a5754473","src/ir/valueloc.rs":"4c676c2d21d75611ef922a230ee82846afb565ce0f55bc71e33c70e1a1d92a07","src/isa/arm32/abi.rs":"74775c5f1eb95764e46815fa8b31891416a616fdd212972eb77aead43b3345a9","src/isa/arm32/binemit.rs":"52b2f4b3c6d8683ed6963c1f53907ac57b6aab7cc149464c9a12d6875aa3b5c6","src/isa/arm32/enc_tables.rs":"b5b7f2fdcaf1d1878a357c54ab757e94f0d06e5bd391ac5d876e96f5b30d6b7a","src/isa/arm32/mod.rs":"24492cfe9120a3ebb199b1d0a0b58425c58970bae32349b3cf2dd390ce51e62f","src/isa/arm32/registers.rs":"254b568a02480f46bb4967a24a438390231014258f0c159f0a41dbafe8e66d56","src/isa/arm32/settings.rs":"188f3cc445168b472b488e73b011e83edd31ac17e3841dacda07a55ccf923468","src/isa/arm64/abi.rs":"52353ed2e2133dacddaad70a876ecebb9c179c19b911ffa823b5b89d3ee7a17c","src/isa/arm64/binemit.rs":"4465cceb68d03ae4d0fdf188c9b86870fb57b3617d67f0bb7d476e5afb581e81","src/isa/arm64/enc_tables.rs":"8c829c544daeed9adc8458891614a0be6f149e775bd22651465f2c165d4a9e56","src/isa/arm64/mod.rs":"f9ca60e7407b69595cb4ef42103ed079e7bcb40546f11d944ddcfc6a04a7fd11","src/isa/arm64/registers.rs":"308cfcfd9ff2191d7656e7350bb36e41803664eb86ae490fb4b4d3549b25b6a2","src/isa/arm64/settings.rs":"0dff47e995e5d9740deb0116b59e91fbcb725a7fa1bdbd802bf83c13381b17f7","src/isa/call_conv.rs":"833ac811ff78ab8d3a5052165e76c51c6da7686020d95462c18074750fb790ed","src/isa/constraints.rs":"bddb5c68e56b122a53d8be215e41d22ccf8c4563630b1486e6eb31c0d3337565","src/isa/enc_tables.rs":"3497f3d701f21d6f952424abf31515fde9e67aea1cde26236c9ee8b033c61ae6","src/isa/encoding.rs":"7ea5b4400530172f96e263561682886ea6c67e706398d44a83933ef7f0ac98a5","src/isa/mod.rs":"40ab1c6d86f903a88bc7ef83b7cdcbee0eedbfdf7112fb7a6749c0c8cc9ee42c","src/isa/registers.rs":"4a91d4888df5eeed1802f34c43a42b82aaf1f9928a58329b0cbc9c3c57c75485","src/isa/riscv/abi.rs":"36557b91ad16a1344c80fbb16a62b46eac88500d76cb9ebcd4eae224dd67b2de","src/isa/riscv/binemit.rs":"0bd76b005b53b71bdb59057a20671fbcd8ab1c37d767bfd4ab0a92d05e192d9a","src/isa/riscv/enc_tables.rs":"ab73c80fef6b1256fbd3c0e1bdd8e43a20f7d132a32236f6bfc028e9003adfe0","src/isa/riscv/mod.rs":"377dfc7dc9940d284b21bf3d2433916dd9c3df79cce172a2a75ef572dcafe98f","src/isa/riscv/registers.rs":"666c2abe1a93db5f1573d1603db6c13c37f3fc877c0c93b64d1b971921bfa950","src/isa/riscv/settings.rs":"d018d23418ff3fb98571bcdeeddde3277bf213b4b8ac1e55b6573e128b3931ce","src/isa/stack.rs":"d023c57feb944c94c4dc8b7138dcbc9d37ff18ca23c23d83e9bab3c88299ffa0","src/isa/x86/abi.rs":"98092944de6b8a8171f1c7d24a63d23ee6dc77a5b4048be113582c5362ac0158","src/isa/x86/binemit.rs":"9b7a3a5aacbf382145ac39c2bfd767bdfa92a8d0447a84dcc19672f1db34d047","src/isa/x86/enc_tables.rs":"7f710f042a2be316f6540515b8838df84f26af3a7c5b290a9cafdf36ef92f0a0","src/isa/x86/mod.rs":"15488d60a950aa4cb75afb63d42d4524e1fcea3b77c7c160e2cb862ec2236a92","src/isa/x86/registers.rs":"bed70bbe1f56f3ef03ea7cd1bea68eb911913cb4c8b93167e044dfc639f7f461","src/isa/x86/settings.rs":"cd8f8c5255663f6e247f0634088b16b53d785ee8c62cb5c0926b3d27597c12ff","src/iterators.rs":"f85f52d3fa707a0eb974c92215b3e976923ce8f9481219f7812e0f2869c2bd37","src/legalizer/boundary.rs":"435707e84b5e406843238d27f5cc4886f4ae37e2c4d25a749e189a378b3af632","src/legalizer/call.rs":"6a82a9daeba5f452a7db0c47dcc43829b119b0652961bc2aa336b809c3f34ef1","src/legalizer/globalvalue.rs":"896f59dc5b8c4a5aee45e3f59211066f214d3ab9142865d80ad6610633363ac9","src/legalizer/heap.rs":"6e13c96f364de71c507aec330d991862a8f925947bb1ffbf1c1493c546c5aacd","src/legalizer/libcall.rs":"6e58da5e1c2419192a3393debc6e9714df9728e59e1740ff569e8a9c0daa40d5","src/legalizer/mod.rs":"7df6ed89a80c9dab7f6e3ddbedcb1c4bcc86c3c6e5bdc3e71e51d5322cb1ce52","src/legalizer/split.rs":"13fe4d2cecea166ecdc1ebb11f5254374ee170518f1a61de7ac0a921bc8fb25d","src/legalizer/table.rs":"d6e09f8340ca597fdb13f86021e5c53bd3161dc4258effc56c1f6d9be7b819ec","src/lib.rs":"1e3a026f3ab6a1d133722227f1f9b8d2cd214e576e31c6c68d252326984dafc5","src/licm.rs":"a4b482c995daf0ecf928a525747316760986a42234331554ae68fe9ef8c7145e","src/loop_analysis.rs":"58fc3cc0e700f05e3131ff1b16ff975d4f32a68c790f095d8445bd300356d3c0","src/nan_canonicalization.rs":"9619bb5554791bd1be75ecd98564d6c9f5b65132bc07c5c4d8c210cd79b66f82","src/partition_slice.rs":"bc13504e7658aab565918d965a0b67e941eb572e583870571bc6dbb2b9aad272","src/postopt.rs":"f3af3f27496de14e4e65b7efb0748ca11edff8fedd7b57d680b310de5156aa62","src/predicates.rs":"44bbc09ae0c7d5b54c05eb6061b062e92d1893edc7dda43ae2bccfedc6bb25e3","src/print_errors.rs":"aaa01084e1655f086d958c7e3b54b0ff6345f96aac06e0f65d7330a15ea2fe27","src/ref_slice.rs":"421a61323c11858a596d50220487f399e1bcedeff0e8d1b716dd4b3531eb01a5","src/regalloc/affinity.rs":"66ee6b9789ec207393c318b14177e1439a54f197b13ebefdb0c4ab77acf38c00","src/regalloc/coalescing.rs":"881c8be32eb4d4b34cf208d0dba3e18b8469bc19f19aa7120514c801562392d3","src/regalloc/coloring.rs":"72bef8b5e3425c805d62cf2329acd29510f1be0886ee73308b69938cf2de203f","src/regalloc/context.rs":"b358a31a6e914502d88a4f1fdad20fc66d1b07a7bdb0213001a94c9335875937","src/regalloc/diversion.rs":"d46d733f6d00a8f536d5c7c8b8fc6f348c3d0605dd0ee77e1d8359367ba53347","src/regalloc/live_value_tracker.rs":"28823003dc72e8a4702776a8ab5ffd878712700a272b64376b0de2022e0ee31a","src/regalloc/liveness.rs":"d2d227a0e6074b2d6ca7d564cf60bc1b565697f4502d1943f5ea3993275fbbf9","src/regalloc/liverange.rs":"7a28454e5f70d570db439b966a01ead759b65eb65c5845f9c58bf2f230a5f2ab","src/regalloc/mod.rs":"6254df639f9289fd578e01b7dca99bc9c9e3c6680c6d031405e8df8d0cff31ad","src/regalloc/pressure.rs":"c9d1098266c5b8b89eff84a55be3bc4838b70416c2446edf57f5257a6232d059","src/regalloc/register_set.rs":"bc58f93f22f0adbe43260fe20c6089be1fca64f5bcc4acff85dc0a5ec5b61937","src/regalloc/reload.rs":"6f82976e779967f3fd492445b6c1f645f69a3a14ab1688e7cfc1f49b8b025f05","src/regalloc/solver.rs":"e2a6d2782d213676dec9781aeb5a37806e092d6daac3249a6cd4d4c92a9d117f","src/regalloc/spilling.rs":"f21ae054e6546b0cd774a94bb301517ba341b985223b6db36e6c9ba995eecfd8","src/regalloc/virtregs.rs":"e5c8da6860ba9495f9396621530347e1dd6fc5b2fae2eb23c171ea77429356f1","src/result.rs":"c10354d615f93caa446c3c8c49d6ba3af762816af470f9c4accf04315cce9753","src/scoped_hash_map.rs":"5afafb3a4039094c3a2aad1582354220d21f399aa50046e7f4a1259e1976597e","src/settings.rs":"3d60acb7eff7f1681f3b23a1a10f067461c35008b94d3a022eaf9e27d9706f09","src/simple_gvn.rs":"c8feb380d4831badc59aa1e65efeafa6702711585817fe5f6b31de6b265fac24","src/simple_preopt.rs":"d2800d1345dc02e2ff5ef5c8b3d1bf9fcaee8f62e78df9f1681338ffc780d520","src/stack_layout.rs":"c5de271e296fc424f1a30017620bc88500369c8e553fef6e95beccb9c6640e7c","src/timing.rs":"a6808943eec68f5d3ff32132d40c07c142e6aa8073473561573a013978883e4f","src/topo_order.rs":"b01ed68a7300691f41ac434e58a5267b10a8b4a7056d65035e24aa8a6722122a","src/unreachable_code.rs":"40cc71a02887ee4065c76ce96dda0a363a8cc134ec784fe5ed1f276db76596ce","src/value_label.rs":"20741ee3fd6fbd48e018d57342fee2414707f35ae77c779ea4a350c65a39b4a4","src/verifier/cssa.rs":"e3e1d77b763c0ba82d3b59ab5b4667fd3152d5a08be50b58b0c82f86376bb062","src/verifier/flags.rs":"f4ba0e0c13fd643bdbec6466219a25a33993a6e170debb48497a859d9f79d914","src/verifier/liveness.rs":"2631037bafa88659bc47d2174e261f5acb1702ca522722a597fa28e474994d79","src/verifier/locations.rs":"9623bbc2d2f86f36893eebe60330fd51b99c9f9c8e5162c61cc89ab221e75b5a","src/verifier/mod.rs":"10c22e51a0c2f73db4a44d8c458361a8af0024e18e47458cb064dc80f51fe07f","src/write.rs":"c672f1fe00cce47ebbb7e33d60df88f80e36b02a2e3c37b0a0c4027e8dec301f"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"9e1e9d197a2fcdb9bfd3c32a7608ab772ed4301aa0b9f2e60b73c98f542ac760","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"e5127227a7db4a8aa92fa6613ed71801025790e696bb41b0323fb7f3c6f7495a","build.rs":"7c0919d12ff966e0c400e7cfa0a555b2e50ede20c0dfb4f4401e35a828134ea9","meta-python/base/__init__.py":"4fac8bb055541dc964383bb04223bae6dfbfe348abf5e23f83655966cbb4aa8f","meta-python/base/entities.py":"f956b8ba863cd26f6867e13c1b2db3c202e9b07c48c1e43a9c2b41ad0deb8922","meta-python/base/formats.py":"6f8cf7cbdfb613acfd4ba3a8e4a9a173cbaa8afd254f03218c5f01daa1078d6c","meta-python/base/immediates.py":"f42682d86bda7b569ec2fc2debd9036355999e61caaa9fbf8307e0be8a164814","meta-python/base/instructions.py":"797dc0c47dd0ea1698201695ff2b5d3c7e8a7aca94396c2685189d9cc53b1419","meta-python/base/legalize.py":"beddc21c03ffba30a509a6df28ad87e3162cf8c60debd036082e32f3c732b7d2","meta-python/base/predicates.py":"53a5a9a37021a9762f0faec9f9e3c5b713411d47dd9192423cfe0f7a61916809","meta-python/base/semantics.py":"b90cbca9a143676ac37496c83634a66a83360248e4505ff7bda12b0d454efd92","meta-python/base/settings.py":"97fca9ddaab347f50f1594c93283f8f474e53a7232eae65949f56a6a702c2bba","meta-python/base/types.py":"9616d6fe4cab050827ab02eeb9843eacebbb8f7555521f504b5ee2ddf7214fdb","meta-python/build.py":"254a7fb51f6025c54f5b08135b83ffadfc2e6c02cb8c3078fdd06c0eff4b91da","meta-python/cdsl/__init__.py":"b534ec129a0e517f0d13313c2b4bb3a345d3e5b62693a31d8d42c80a219e39fa","meta-python/cdsl/ast.py":"8509f15eaaaf2fed2bec93eba19d313d37c2ddd70d1399a491a394206cbfabe4","meta-python/cdsl/formats.py":"fedfeaec754b40d6a9cc92b827976782c615d8eab1c7f47f6b47510cbef585f4","meta-python/cdsl/instructions.py":"50fe9329a56e6294a27306aad7be22c88a5b5ef42c3b030ec59218167157f62f","meta-python/cdsl/isa.py":"dc530a4dd5642e3379398dfc8a90ad6ae1692302de63851370bdfa8abf4cdce0","meta-python/cdsl/operands.py":"e24914eae4059b88781bf5a5d7a14ecf98b10a701ed6cf6e88d15981b2ccbfdf","meta-python/cdsl/predicates.py":"fe2dc6e78ff6d4bcb6b1d5448ded343ede0f03b96a965a11aef0f5bbe7bb8f56","meta-python/cdsl/registers.py":"939dafd1b8976a6cd456c9a5e4b374af81fafb9da979ea3a1f6d14e4645914a6","meta-python/cdsl/settings.py":"400d853a815f64c0294d0c0e03d3c514942760faa8b06152b1078a92ddb9f62c","meta-python/cdsl/test_ast.py":"947e934e2862445a158bf266dff58a8c88aae31fb34a7f823309ee58a15c5393","meta-python/cdsl/test_package.py":"ffa53d20e023ecb89137294bb13614f4de9b09e1bf05d9772131570bf78f7987","meta-python/cdsl/test_ti.py":"04656e2da99ec37875f91172bb2fa423da1ee27bf523a4d41af311ea22492d1b","meta-python/cdsl/test_typevar.py":"768bf3c35481950264ad6fd7059a532ac62b121ac439983bb4fe1ae76a1d1248","meta-python/cdsl/test_xform.py":"ddb6633c7941bbf68570701cb887a81d6b4b27f4bc45eabccf2ce287ad9b77e9","meta-python/cdsl/ti.py":"566e91f0bb3ebacd5abf9f5a663caee69706c2e829dee1ed735d229198689f76","meta-python/cdsl/types.py":"adee4bbc1a9478288fa4b53ee1edeb5ee3296dba2c70bfbe01e923895064999e","meta-python/cdsl/typevar.py":"b5669934eddaf5b9cc0c27b966e2566b5f669f1c5a345f005960930fb499097e","meta-python/cdsl/xform.py":"bf200b711570b905f0fb30611ba64f131f98593060eedbe5575054cca4928593","meta-python/check.sh":"707cda14534882e8d4593f93c056390560394c9bc8a687e99f10a56d7b09cb92","meta-python/constant_hash.py":"c752e6dadf3a9a5bd00c978e85ab27a20c49138a1ccdc6fc9a1904797a4bfe48","meta-python/gen_binemit.py":"76472fb199a330b934ba9ad0a1bbacfb52f0eae7c9a66d83f0d7890970323a2d","meta-python/gen_build_deps.py":"53bbdd591c91f8e28da95e4da02c9299a01a32d8be6a0c7490b6b7c60a4fbebe","meta-python/gen_encoding.py":"471c5f4ecf24a2a173864c62a48920e5fbe1aacd2229b3eb4483637570bb26b2","meta-python/isa/__init__.py":"e499c1206cd095a926fa0ca7eb9d0a50a802ed71c8eb7598e5d3a0f939c8ada5","meta-python/isa/arm32/__init__.py":"eecba73231aa398ded7304690bdba3450dc163afd4360f1b0ad02a28e2380363","meta-python/isa/arm32/defs.py":"01c41dbd7406c624e26229df6befa0992194bddcc7d11e8f6174abfe2b33bf61","meta-python/isa/arm32/registers.py":"c03ca6435828ad5f262049e42f1f71bcf74903831f85daa92c3f322a6c1050ea","meta-python/isa/arm32/settings.py":"afd5a04a9d029f578d6f62dc7c539191886cc9f9dea15d65fc66bf37a63b8814","meta-python/isa/arm64/__init__.py":"f6877253cf786d7ee972881e7d9b3c78c11e6b024e4e227487340dd01d0c44e4","meta-python/isa/arm64/defs.py":"797c5bb6d11fc7a44afe67476136dbd11c40f5e13a1c8f52f9f96be4441677b2","meta-python/isa/arm64/registers.py":"9bdd06edaa382be96042e1ac36d63137e73292292b61dcf4becb7d1428130317","meta-python/isa/arm64/settings.py":"f7b1f8733e775ea8005372ee35f1c2a627b3a69d722e837295599e4cf1f5eb43","meta-python/isa/riscv/__init__.py":"c11607c9eef0bc2707daa3edd4174e934c7a0dcc8ce90cee2c9292a85b1ac596","meta-python/isa/riscv/defs.py":"e73740055c4fb123c45453fc149a807e9720466de848022d5375049bdcfc311c","meta-python/isa/riscv/encodings.py":"2f890f47d8ee13141c45b1126dd8cb1dfdcde96df03208ce19e96ea3ae53c5d2","meta-python/isa/riscv/recipes.py":"57eb830d0e01858c7f01cda71a26854eb8f69cb46aae6456873766e1e0a40389","meta-python/isa/riscv/registers.py":"ef9aca3a6ec2b08ee8f5952186d232861b64a919b671b41911a365e7672b01bd","meta-python/isa/riscv/settings.py":"dfe29722d67be0620a70e08cfb802829a26f5fd339a9342a8ac2dd419daf8a85","meta-python/isa/x86/__init__.py":"ad579de68ea7bf5dc2bce0e3a6f09e7978b1697f1afec8a5ce5dc591136e590d","meta-python/isa/x86/defs.py":"b5eb7889b6f5e5b221ed3923d0137bbb1566c55b5961448cc39e4ea2f13cf4b7","meta-python/isa/x86/encodings.py":"0130a8eb7e7415f538fd9ee5b15eea008b1cad609325fd7399750b402e5fc916","meta-python/isa/x86/instructions.py":"530cde78e6b9f6e4ea2192985f4c5c77a987cdc19001d50fb47fa8e36a62f52e","meta-python/isa/x86/legalize.py":"1375ded072c29459e7c0e40ecb02f28d5395d9d8c603eb70e338b2bf2991c9cd","meta-python/isa/x86/recipes.py":"5dc66c8e0d0ac3aff05dfe42822b4711c677d52177f9753b50daa73eeee4b690","meta-python/isa/x86/registers.py":"ff934491d07ec6b51fbfd454b865a7c7c191ffbd31b1804615735266b120f4b2","meta-python/isa/x86/settings.py":"7ef2e43521b9b11e90a93c1c60946e65d420ecf6e15ba17f933c7a24a5124e5b","meta-python/mypy.ini":"5ec2f7cc0bbc4fd0435643d6b72e715bd9568a3a0fe14c043f9e559c405b66fb","meta-python/semantics/__init__.py":"c9dd72fde0ab020d3328dde532d92b39e438e4147930e41df7613c27727e11eb","meta-python/semantics/elaborate.py":"3a3fbba83a6818c2d1ce236fd0413111380875a0307f7a5f4b5dd66d8ef714b1","meta-python/semantics/macros.py":"b218c52e1bd4f019dc14a27d315b4f3405a10e5bdc6f2523fe709c8faf91b418","meta-python/semantics/primitives.py":"4e5eb0c90fcc295686732c8c66ad7a793997645c9a676c97babf06823fd2b60d","meta-python/semantics/smtlib.py":"48ef80320f21682860bbf5f79f18739f1d10f0b1fe581ebb05541e90dc2f2f4f","meta-python/semantics/test_elaborate.py":"3a4c850a7385007422c7549661b211903cd1dd1606dad7a86262ae27e697bca6","meta-python/srcgen.py":"999557d683e808a2ca90688c489ec4aff65798f44ac321ecf7de34d307261913","meta-python/stubs/z3/__init__.pyi":"6aaeb80f783b29c4364dee21da45f6df041c0a4807189a15777ee5447f6515dc","meta-python/stubs/z3/z3core.pyi":"c01a41d468e07cc4f8b405c292ed7f8c82bc1077f8b82dfde1e474577ade3335","meta-python/stubs/z3/z3types.pyi":"30009c951af99b9028d47cd4cabae95ff9742b77b690bd8dd63f6b7dba580759","meta-python/test_constant_hash.py":"157cf4f8964e0f04c041ffd349e889ce565b144453436690578c5d03c3a60216","meta-python/test_srcgen.py":"d6d7775e19a5b2621360c00eb6d92dfcb4568e49220993e0ceaac9628dbfd661","meta-python/unique_table.py":"5bd500667430c15f6ae586603d8612fb3bda07b072e40d86286e08392bdc3127","src/abi.rs":"76ee030cf0780fe63ccbf855b1161f215e3e2991cb9abe71ca9aff25e5f1dbc2","src/binemit/memorysink.rs":"3ac1d77f178dabe3b2201735f9c7aa577fcc680424ad9ed435736b76fe583dfa","src/binemit/mod.rs":"ed63c382e6f58a9f7417d8913c15387f88d511a4ef02cba191c341496db50863","src/binemit/relaxation.rs":"697c4041b7e9605dd09b93be389cc18d54666ce16637383f2916a35788df32c9","src/binemit/shrink.rs":"63384c0eee75f0c0260cc385d7eb097dc67c85432f37dd28115a27fb17cfc3c9","src/bitset.rs":"d57a79058a31b094b4bbe9d34876a5543286df1e08b5ceadfd05a9efc5a3b1ce","src/cfg_printer.rs":"d285f1ce7d960089b9c28a3ab280bb1e6b3026f9f23ec0fac6b1a170b504d164","src/constant_hash.rs":"330e8289789ee351d0abeaf4b5e859b8db8772306e0820d34864fc9905d53b38","src/context.rs":"cf97e03ee2a5eaba6dd84208b937664a825e778aa49da34f5311b1f1c9a70a53","src/cursor.rs":"6643149791795257bd6bd8ce184dcb32e8aec835bd57711facfbe1f645c0d89e","src/dbg.rs":"1898d94cff0975815eb348651702e95c8f2f63886501d3b7043ee75668480472","src/dce.rs":"d8ab7c0cac0416f9d75afdacc60ba02e532361ec927c3f8bd171b1a53ec8b31a","src/divconst_magic_numbers.rs":"09691389c9055bef7a0cfd5d77fbfeba4be468d05d981d4de088516a94b8b28e","src/dominator_tree.rs":"7ee4114026011b11d49e48c5a9202970bafe3b22c2074f7c1390b98ebb2edb7a","src/flowgraph.rs":"bf520026c32c5454554d0b078b64a78bd44f3c0f4f198eddf71bcfd78cc963a3","src/fx.rs":"8a5d07487906d8316a179e826fcd817a92a4860686256a6fd9d78ba47c63f330","src/ir/builder.rs":"1a12c57f4168fa3c2fcf6be2f19d0d377eee40f24ae4390e6ba9d954f85a8a3e","src/ir/condcodes.rs":"5247c8d849e1372d2a22379c33a4a88226ec6187be18ca6f2c4e0f315d812aa8","src/ir/dfg.rs":"caa494cc32dbf27e87e5cfe3ed13e0116bf0f94f436cdeca75a59fe4b047b181","src/ir/entities.rs":"48a6fa7e43bd2d53bf7900e456fd80103088e16148e6ca859f71f0250df90ede","src/ir/extfunc.rs":"9806734eeb480724481128d8c1de78a3b1f80f1214c20f24131196a0df137872","src/ir/extname.rs":"ed2c0b52cdaecc7f0ba9a894ef9fffe139e09b520e43dcd6f0c887a3d41a31ac","src/ir/function.rs":"af8f8e09a2482865d8bd9be9f475fa5627c9a6886c2675286a47597fa54fcecd","src/ir/globalvalue.rs":"906d29f3d4190b811f66fc549c4e0408bdd2807eac98e33c0b3d5c2b876acc02","src/ir/heap.rs":"a59d3e5901412b53c0b53a8cdf10765ff5921de9c410ae9acea226c89827df3c","src/ir/immediates.rs":"029a8aa905e6fd0f3334e17a28e73ac36684df2ca0829dcae0158ea8cf64ca8c","src/ir/instructions.rs":"2180de1d127ab5878c5743d8e096d551edb973e0ff1d373c4239c32e7981364c","src/ir/jumptable.rs":"7764abc9aa027a5a89d22059b360372bd9a19686887c5a7830f7637d6f188e1e","src/ir/layout.rs":"bb45eefde16ac9423f637dfcc2796ae7b955a97f38a55f23a19cc45da5decce1","src/ir/libcall.rs":"413c46df13831c7d453ce2c833b2fa913f88f548bb6d840e55b716224e0b5499","src/ir/memflags.rs":"dbcf3798ab66dc764b73fb7f139a621c54cc6bcc683f1f70a33ed7e8c3486bfd","src/ir/mod.rs":"37685305acb21dc24896e5d7977784988fe723c09bdf8ab8cc7830ccabd76a11","src/ir/progpoint.rs":"49433f22bd6ff3a96ad0733ff612f3617b312e4492b6b663187141966f6aa701","src/ir/sourceloc.rs":"37ef5fd8cef1de99620797d7d5aba3630e737171853c8471495c685dafac19b6","src/ir/stackslot.rs":"2f54359339837bb1d0d817d3af21bb4b1b050c31703885dfaced29f6e41153c2","src/ir/table.rs":"dcc3b663a989b2b084402b08dc9a0e928dbd052e194a46a1886cc6f0cf1a5f2c","src/ir/trapcode.rs":"59e223193617b8c1043ddd3a907c6131f2987e8fe0965ebfd9f7c056c064b7c5","src/ir/types.rs":"1f644beba2c797f7bd89378d930c3eca1491ec5f82c4715945ac63a0a5754473","src/ir/valueloc.rs":"4c676c2d21d75611ef922a230ee82846afb565ce0f55bc71e33c70e1a1d92a07","src/isa/arm32/abi.rs":"74775c5f1eb95764e46815fa8b31891416a616fdd212972eb77aead43b3345a9","src/isa/arm32/binemit.rs":"52b2f4b3c6d8683ed6963c1f53907ac57b6aab7cc149464c9a12d6875aa3b5c6","src/isa/arm32/enc_tables.rs":"b5b7f2fdcaf1d1878a357c54ab757e94f0d06e5bd391ac5d876e96f5b30d6b7a","src/isa/arm32/mod.rs":"239eb819224af2c2edaa44355f5491cbab780b7427289a607162f5e0df500da8","src/isa/arm32/registers.rs":"254b568a02480f46bb4967a24a438390231014258f0c159f0a41dbafe8e66d56","src/isa/arm32/settings.rs":"188f3cc445168b472b488e73b011e83edd31ac17e3841dacda07a55ccf923468","src/isa/arm64/abi.rs":"52353ed2e2133dacddaad70a876ecebb9c179c19b911ffa823b5b89d3ee7a17c","src/isa/arm64/binemit.rs":"4465cceb68d03ae4d0fdf188c9b86870fb57b3617d67f0bb7d476e5afb581e81","src/isa/arm64/enc_tables.rs":"8c829c544daeed9adc8458891614a0be6f149e775bd22651465f2c165d4a9e56","src/isa/arm64/mod.rs":"46bc796d3420b252b7af843d60e16e0f51de524b0842c6e6fe1adcbadbb70752","src/isa/arm64/registers.rs":"308cfcfd9ff2191d7656e7350bb36e41803664eb86ae490fb4b4d3549b25b6a2","src/isa/arm64/settings.rs":"0dff47e995e5d9740deb0116b59e91fbcb725a7fa1bdbd802bf83c13381b17f7","src/isa/call_conv.rs":"833ac811ff78ab8d3a5052165e76c51c6da7686020d95462c18074750fb790ed","src/isa/constraints.rs":"bddb5c68e56b122a53d8be215e41d22ccf8c4563630b1486e6eb31c0d3337565","src/isa/enc_tables.rs":"3497f3d701f21d6f952424abf31515fde9e67aea1cde26236c9ee8b033c61ae6","src/isa/encoding.rs":"7ea5b4400530172f96e263561682886ea6c67e706398d44a83933ef7f0ac98a5","src/isa/mod.rs":"d9019b94d415113c782202a48d6c79d333fa6591539771cdc19e6dbee0047041","src/isa/registers.rs":"4a91d4888df5eeed1802f34c43a42b82aaf1f9928a58329b0cbc9c3c57c75485","src/isa/riscv/abi.rs":"36557b91ad16a1344c80fbb16a62b46eac88500d76cb9ebcd4eae224dd67b2de","src/isa/riscv/binemit.rs":"0bd76b005b53b71bdb59057a20671fbcd8ab1c37d767bfd4ab0a92d05e192d9a","src/isa/riscv/enc_tables.rs":"ab73c80fef6b1256fbd3c0e1bdd8e43a20f7d132a32236f6bfc028e9003adfe0","src/isa/riscv/mod.rs":"44932e33e3a6090bebe3c77e0237378d7808c61a331a7cc84ea22ec2f7f52ccb","src/isa/riscv/registers.rs":"666c2abe1a93db5f1573d1603db6c13c37f3fc877c0c93b64d1b971921bfa950","src/isa/riscv/settings.rs":"d018d23418ff3fb98571bcdeeddde3277bf213b4b8ac1e55b6573e128b3931ce","src/isa/stack.rs":"d023c57feb944c94c4dc8b7138dcbc9d37ff18ca23c23d83e9bab3c88299ffa0","src/isa/x86/abi.rs":"c36d9143f018af42c8c19f44e91510ccbcfa7be927357aff20ebd357de185fca","src/isa/x86/binemit.rs":"9b7a3a5aacbf382145ac39c2bfd767bdfa92a8d0447a84dcc19672f1db34d047","src/isa/x86/enc_tables.rs":"073fd2b33c412575e651d696c438429e53601a782d200470ffb86ee8249ac6b5","src/isa/x86/mod.rs":"c813127526b450f806b74837551deb0e7faae1e3cf74e618a4120c90eae59156","src/isa/x86/registers.rs":"bed70bbe1f56f3ef03ea7cd1bea68eb911913cb4c8b93167e044dfc639f7f461","src/isa/x86/settings.rs":"cd8f8c5255663f6e247f0634088b16b53d785ee8c62cb5c0926b3d27597c12ff","src/iterators.rs":"f85f52d3fa707a0eb974c92215b3e976923ce8f9481219f7812e0f2869c2bd37","src/legalizer/boundary.rs":"70a6819cbb116f07d0a09f8e5b0e2fe91145f423ad02e10225f8879ff4e61351","src/legalizer/call.rs":"be6074c64c1a00e5e81159dd94c8401fef62205b22c15e07e0c56cf922554d00","src/legalizer/globalvalue.rs":"59ab09a0faf593c7f228500b3fd3bacfc0412bdcb2864ec3621aa65adc4a5693","src/legalizer/heap.rs":"b83dc83a5876b024db058023692f71d8f910f6b212f34200e9bcf61a19daeb8e","src/legalizer/libcall.rs":"5c5a79709322a6562496c30af775ad255b27af67f7541fc1615f7deb891f8cff","src/legalizer/mod.rs":"d7ac361390308b605ee02d12d9bd6c0d46e36cf852115c0a71ddd88e8c7bd2bd","src/legalizer/split.rs":"13fe4d2cecea166ecdc1ebb11f5254374ee170518f1a61de7ac0a921bc8fb25d","src/legalizer/table.rs":"c36d03525312e3191aba8ee00c26a87c1ea200f9a9a0370f0cc84eeacff71786","src/lib.rs":"1e3a026f3ab6a1d133722227f1f9b8d2cd214e576e31c6c68d252326984dafc5","src/licm.rs":"1c14deeb4c86ef7bde39b16758825a774156609359724583ff8788be658abd8e","src/loop_analysis.rs":"58fc3cc0e700f05e3131ff1b16ff975d4f32a68c790f095d8445bd300356d3c0","src/nan_canonicalization.rs":"9619bb5554791bd1be75ecd98564d6c9f5b65132bc07c5c4d8c210cd79b66f82","src/partition_slice.rs":"bc13504e7658aab565918d965a0b67e941eb572e583870571bc6dbb2b9aad272","src/postopt.rs":"d4c487f0299fb905bb5a5822e38dea6f70afa4d4577288988b5bec8660bc1ba0","src/predicates.rs":"44bbc09ae0c7d5b54c05eb6061b062e92d1893edc7dda43ae2bccfedc6bb25e3","src/print_errors.rs":"3fbd77a01b5404a4bbcf2970e44299ad33948c71f4014d92026415daa8325314","src/ref_slice.rs":"421a61323c11858a596d50220487f399e1bcedeff0e8d1b716dd4b3531eb01a5","src/regalloc/affinity.rs":"19cec5495c8bddc1fcc8f3c8659d527a5a3ea373ffcc130e3fbd5b462ef15930","src/regalloc/coalescing.rs":"d83be1c1067eb56f2f8f16380450a327d6495b4c6f1f489ded68271c055aec07","src/regalloc/coloring.rs":"cd64fdf547e1c1a1ddcdf345d27b4ec6dfeaf6d34f69cab70082fb2b47c8e860","src/regalloc/context.rs":"e08cbd0dabaee5d9f78e8c6e3750ef61489c6517da7521043cad8dbb23f31581","src/regalloc/diversion.rs":"d46d733f6d00a8f536d5c7c8b8fc6f348c3d0605dd0ee77e1d8359367ba53347","src/regalloc/live_value_tracker.rs":"28823003dc72e8a4702776a8ab5ffd878712700a272b64376b0de2022e0ee31a","src/regalloc/liveness.rs":"a59673fda65d1e3c0e5b3f4468686d05a389c877bee7b10323264595c3c54677","src/regalloc/liverange.rs":"7a28454e5f70d570db439b966a01ead759b65eb65c5845f9c58bf2f230a5f2ab","src/regalloc/mod.rs":"6254df639f9289fd578e01b7dca99bc9c9e3c6680c6d031405e8df8d0cff31ad","src/regalloc/pressure.rs":"04738e95418f0f858885dfc45183efc3dfb59c8d2ad2fd88bbd9a73a62907730","src/regalloc/register_set.rs":"bc58f93f22f0adbe43260fe20c6089be1fca64f5bcc4acff85dc0a5ec5b61937","src/regalloc/reload.rs":"ccccb716a694b53103bd4d55efb2323e788c1127469233c17b648fa06baa67b1","src/regalloc/solver.rs":"43eebe2ae7f7e8b5510d161428152503ec37661f5083a36d925b4a247e1bd28a","src/regalloc/spilling.rs":"dff4af64409c9a1db7697423576826c3920c26c892fbdde89ee31c680d672e03","src/regalloc/virtregs.rs":"e5c8da6860ba9495f9396621530347e1dd6fc5b2fae2eb23c171ea77429356f1","src/result.rs":"c10354d615f93caa446c3c8c49d6ba3af762816af470f9c4accf04315cce9753","src/scoped_hash_map.rs":"5afafb3a4039094c3a2aad1582354220d21f399aa50046e7f4a1259e1976597e","src/settings.rs":"263d88ef1f976ecb5ee5656d95e77ca9cc49d91e9865f44d040d070a41a1bbfb","src/simple_gvn.rs":"c8feb380d4831badc59aa1e65efeafa6702711585817fe5f6b31de6b265fac24","src/simple_preopt.rs":"d2800d1345dc02e2ff5ef5c8b3d1bf9fcaee8f62e78df9f1681338ffc780d520","src/stack_layout.rs":"c5de271e296fc424f1a30017620bc88500369c8e553fef6e95beccb9c6640e7c","src/timing.rs":"a6808943eec68f5d3ff32132d40c07c142e6aa8073473561573a013978883e4f","src/topo_order.rs":"b01ed68a7300691f41ac434e58a5267b10a8b4a7056d65035e24aa8a6722122a","src/unreachable_code.rs":"40cc71a02887ee4065c76ce96dda0a363a8cc134ec784fe5ed1f276db76596ce","src/value_label.rs":"b860f1a5a35fbd562d9cce4ac38852139bd4f1d7425cda53c2529b0a361bd21c","src/verifier/cssa.rs":"e3e1d77b763c0ba82d3b59ab5b4667fd3152d5a08be50b58b0c82f86376bb062","src/verifier/flags.rs":"cac8ba7ed5fe621eaa425112b931423cb5f3523d580fcf0b7536deb252e96186","src/verifier/liveness.rs":"ac3413b464ee8b5aa5928bee724799b9a1e0cbbdce433c819b9d870483ed070a","src/verifier/locations.rs":"04635edc12bc741a23c9318611aac4abcb42f01effbebee6d858f108f9393a44","src/verifier/mod.rs":"a0ee43ae2f160936ab5ed05c6cea7111bd175aebe4058850060bfb5e1ded8a29","src/write.rs":"e067ac97dffcace67545525c631d6df6930e96700019a1e4723f98e31333fc9a"},"package":null}
\ No newline at end of file
--- a/third_party/rust/cranelift-codegen/meta-python/base/instructions.py
+++ b/third_party/rust/cranelift-codegen/meta-python/base/instructions.py
@@ -159,17 +159,17 @@ jump_table_entry = Instruction(
 
     Load a serialized ``entry`` from a jump table ``JT`` at a given index
     ``addr`` with a specific ``Size``. The retrieved entry may need to be
     decoded after loading, depending upon the jump table type used.
 
     Currently, the only type supported is entries which are relative to the
     base of the jump table.
     """,
-    ins=(x, addr, Size, JT), outs=entry)
+    ins=(x, addr, Size, JT), outs=entry, can_load=True)
 
 jump_table_base = Instruction(
     'jump_table_base', r"""
     Get the absolute base address of a jump table.
 
     This is used for jump tables wherein the entries are stored relative to
     the base of jump table. In order to use these, generated code should first
     load an entry using ``jump_table_entry``, then use this instruction to add
--- a/third_party/rust/cranelift-codegen/meta-python/isa/riscv/encodings.py
+++ b/third_party/rust/cranelift-codegen/meta-python/isa/riscv/encodings.py
@@ -1,19 +1,20 @@
 """
 RISC-V Encodings.
 """
 from __future__ import absolute_import
 from base import instructions as base
+from base import types
 from base.immediates import intcc
 from .defs import RV32, RV64
 from .recipes import OPIMM, OPIMM32, OP, OP32, LUI, BRANCH, JALR, JAL
 from .recipes import LOAD, STORE
 from .recipes import R, Rshamt, Ricmp, Ii, Iz, Iicmp, Iret, Icall, Icopy
-from .recipes import U, UJ, UJcall, SB, SBzero, GPsp, GPfi, Irmov
+from .recipes import U, UJ, UJcall, SB, SBzero, GPsp, GPfi, Irmov, stacknull
 from .settings import use_m
 from cdsl.ast import Var
 from base.legalize import narrow, expand
 
 RV32.legalize_monomorphic(expand)
 RV32.legalize_type(
         default=narrow,
         i32=expand,
@@ -155,8 +156,14 @@ RV64.enc(base.copy.i32, Icopy, OPIMM32(0
 RV32.enc(base.regmove.i32, Irmov, OPIMM(0b000))
 RV64.enc(base.regmove.i64, Irmov, OPIMM(0b000))
 RV64.enc(base.regmove.i32, Irmov, OPIMM32(0b000))
 
 RV32.enc(base.copy.b1, Icopy, OPIMM(0b000))
 RV64.enc(base.copy.b1, Icopy, OPIMM(0b000))
 RV32.enc(base.regmove.b1, Irmov, OPIMM(0b000))
 RV64.enc(base.regmove.b1, Irmov, OPIMM(0b000))
+
+# Stack-slot-to-the-same-stack-slot copy, which is guaranteed to turn
+# into a no-op.
+for ty in [types.i64, types.i32, types.i16, types.i8, types.f64, types.f32]:
+    RV64.enc(base.copy_nop.bind(ty), stacknull, 0)
+    RV32.enc(base.copy_nop.bind(ty), stacknull, 0)
--- a/third_party/rust/cranelift-codegen/meta-python/isa/riscv/recipes.py
+++ b/third_party/rust/cranelift-codegen/meta-python/isa/riscv/recipes.py
@@ -218,8 +218,13 @@ GPsp = EncRecipe(
         ins=GPR, outs=Stack(GPR),
         emit='unimplemented!();')
 
 # Fill of a GPR.
 GPfi = EncRecipe(
         'GPfi', Unary, base_size=4,
         ins=Stack(GPR), outs=GPR,
         emit='unimplemented!();')
+
+# Stack-slot-to-the-same-stack-slot copy, which is guaranteed to turn
+# into a no-op.
+stacknull = EncRecipe('stacknull', Unary, base_size=0,
+                      ins=Stack(GPR), outs=Stack(GPR), emit='')
--- a/third_party/rust/cranelift-codegen/meta-python/isa/x86/encodings.py
+++ b/third_party/rust/cranelift-codegen/meta-python/isa/x86/encodings.py
@@ -337,21 +337,33 @@ enc_x86_64(x86.pop.i64, r.popq, 0x58)
 
 # Copy Special
 # For x86-64, only define REX forms for now, since we can't describe the
 # special regunit immediate operands with the current constraint language.
 X86_64.enc(base.copy_special, *r.copysp.rex(0x89, w=1))
 X86_32.enc(base.copy_special, *r.copysp(0x89))
 
 # Stack-slot-to-the-same-stack-slot copy, which is guaranteed to turn
-# into a no-op.
-X86_64.enc(base.copy_nop.i64, r.stacknull, 0)
-X86_64.enc(base.copy_nop.i32, r.stacknull, 0)
-X86_64.enc(base.copy_nop.f64, r.stacknull, 0)
-X86_64.enc(base.copy_nop.f32, r.stacknull, 0)
+# into a no-op.  Ideally we could to make this encoding available for
+# all types, and write `base.copy_nop.any`, but it appears that the
+# controlling type variable must not polymorphic.  So we make do with
+# the following limited set, and guard the generating transformation in
+# regalloc/reload.rs accordingly.
+#
+# The same encoding is generated for both the 64- and 32-bit architectures.
+# Note that we can't use `enc_both` here, because that attempts to create a
+# variant with a REX prefix in the 64-bit-architecture case.  But since
+# there's no actual instruction for the REX prefix to modify the meaning of,
+# it will modify the meaning of whatever instruction happens to follow this
+# one, which is obviously wrong.  Note also that we can and indeed *must*
+# claim that there's a 64-bit encoding for the 32-bit arch case, even though
+# no such single instruction actually exists for the 32-bit arch case.
+for ty in [types.i64, types.i32, types.i16, types.i8, types.f64, types.f32]:
+    X86_64.enc(base.copy_nop.bind(ty), r.stacknull, 0)
+    X86_32.enc(base.copy_nop.bind(ty), r.stacknull, 0)
 
 # Adjust SP down by a dynamic value (or up, with a negative operand).
 X86_32.enc(base.adjust_sp_down.i32, *r.adjustsp(0x29))
 X86_64.enc(base.adjust_sp_down.i64, *r.adjustsp.rex(0x29, w=1))
 
 # Adjust SP up by an immediate (or down, with a negative immediate)
 X86_32.enc(base.adjust_sp_up_imm, *r.adjustsp_ib(0x83))
 X86_32.enc(base.adjust_sp_up_imm, *r.adjustsp_id(0x81))
--- a/third_party/rust/cranelift-codegen/src/binemit/memorysink.rs
+++ b/third_party/rust/cranelift-codegen/src/binemit/memorysink.rs
@@ -29,28 +29,32 @@ use core::ptr::write_unaligned;
 ///
 /// Note that `MemoryCodeSink` writes multi-byte values in the native byte order of the host. This
 /// is not the right thing to do for cross compilation.
 pub struct MemoryCodeSink<'a> {
     /// Pointer to start of sink's preallocated memory.
     data: *mut u8,
     /// Offset is isize because its major consumer needs it in that form.
     offset: isize,
-    relocs: &'a mut RelocSink,
-    traps: &'a mut TrapSink,
+    relocs: &'a mut dyn RelocSink,
+    traps: &'a mut dyn TrapSink,
     /// Information about the generated code and read-only data.
     pub info: CodeInfo,
 }
 
 impl<'a> MemoryCodeSink<'a> {
     /// Create a new memory code sink that writes a function to the memory pointed to by `data`.
     ///
     /// This function is unsafe since `MemoryCodeSink` does not perform bounds checking on the
     /// memory buffer, and it can't guarantee that the `data` pointer is valid.
-    pub unsafe fn new(data: *mut u8, relocs: &'a mut RelocSink, traps: &'a mut TrapSink) -> Self {
+    pub unsafe fn new(
+        data: *mut u8,
+        relocs: &'a mut dyn RelocSink,
+        traps: &'a mut dyn TrapSink,
+    ) -> Self {
         Self {
             data,
             offset: 0,
             info: CodeInfo {
                 code_size: 0,
                 jumptables_size: 0,
                 rodata_size: 0,
                 total_size: 0,
@@ -137,17 +141,17 @@ impl<'a> CodeSink for MemoryCodeSink<'a>
         self.info.code_size = self.offset();
     }
 
     fn begin_rodata(&mut self) {
         self.info.jumptables_size = self.offset() - self.info.code_size;
     }
 
     fn end_codegen(&mut self) {
-        self.info.rodata_size = self.offset() - self.info.jumptables_size;
+        self.info.rodata_size = self.offset() - (self.info.jumptables_size + self.info.code_size);
         self.info.total_size = self.offset();
     }
 }
 
 /// A `TrapSink` implementation that does nothing, which is convenient when
 /// compiling code that does not rely on trapping semantics.
 pub struct NullTrapSink {}
 
--- a/third_party/rust/cranelift-codegen/src/binemit/relaxation.rs
+++ b/third_party/rust/cranelift-codegen/src/binemit/relaxation.rs
@@ -35,17 +35,17 @@ use crate::iterators::IteratorExtras;
 use crate::regalloc::RegDiversions;
 use crate::timing;
 use crate::CodegenResult;
 use log::debug;
 
 /// Relax branches and compute the final layout of EBB headers in `func`.
 ///
 /// Fill in the `func.offsets` table so the function is ready for binary emission.
-pub fn relax_branches(func: &mut Function, isa: &TargetIsa) -> CodegenResult<CodeInfo> {
+pub fn relax_branches(func: &mut Function, isa: &dyn TargetIsa) -> CodegenResult<CodeInfo> {
     let _tt = timing::relax_branches();
 
     let encinfo = isa.encoding_info();
 
     // Clear all offsets so we can recognize EBBs that haven't been visited yet.
     func.offsets.clear();
     func.offsets.resize(func.dfg.num_ebbs());
 
@@ -169,17 +169,17 @@ fn fallthroughs(func: &mut Function) {
 /// Return the size of the replacement instructions up to and including the location where `cur` is
 /// left.
 fn relax_branch(
     cur: &mut FuncCursor,
     divert: &RegDiversions,
     offset: CodeOffset,
     dest_offset: CodeOffset,
     encinfo: &EncInfo,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) -> CodeOffset {
     let inst = cur.current_inst().unwrap();
     debug!(
         "Relaxing [{}] {} for {:#x}-{:#x} range",
         encinfo.display(cur.func.encodings[inst]),
         cur.func.dfg.display_inst(inst, isa),
         offset,
         dest_offset
--- a/third_party/rust/cranelift-codegen/src/binemit/shrink.rs
+++ b/third_party/rust/cranelift-codegen/src/binemit/shrink.rs
@@ -8,17 +8,17 @@
 use crate::ir::instructions::InstructionData;
 use crate::ir::Function;
 use crate::isa::TargetIsa;
 use crate::regalloc::RegDiversions;
 use crate::timing;
 use log::debug;
 
 /// Pick the smallest valid encodings for instructions.
-pub fn shrink_instructions(func: &mut Function, isa: &TargetIsa) {
+pub fn shrink_instructions(func: &mut Function, isa: &dyn TargetIsa) {
     let _tt = timing::shrink_instructions();
 
     let encinfo = isa.encoding_info();
     let mut divert = RegDiversions::new();
 
     for ebb in func.layout.ebbs() {
         divert.clear();
         for inst in func.layout.ebb_insts(ebb) {
--- a/third_party/rust/cranelift-codegen/src/cfg_printer.rs
+++ b/third_party/rust/cranelift-codegen/src/cfg_printer.rs
@@ -18,32 +18,32 @@ impl<'a> CFGPrinter<'a> {
     pub fn new(func: &'a Function) -> Self {
         Self {
             func,
             cfg: ControlFlowGraph::with_function(func),
         }
     }
 
     /// Write the CFG for this function to `w`.
-    pub fn write(&self, w: &mut Write) -> Result {
+    pub fn write(&self, w: &mut dyn Write) -> Result {
         self.header(w)?;
         self.ebb_nodes(w)?;
         self.cfg_connections(w)?;
         writeln!(w, "}}")
     }
 
-    fn header(&self, w: &mut Write) -> Result {
+    fn header(&self, w: &mut dyn Write) -> Result {
         writeln!(w, "digraph \"{}\" {{", self.func.name)?;
         if let Some(entry) = self.func.layout.entry_block() {
             writeln!(w, "    {{rank=min; {}}}", entry)?;
         }
         Ok(())
     }
 
-    fn ebb_nodes(&self, w: &mut Write) -> Result {
+    fn ebb_nodes(&self, w: &mut dyn Write) -> Result {
         for ebb in &self.func.layout {
             write!(w, "    {} [shape=record, label=\"{{{}", ebb, ebb)?;
             // Add all outgoing branch instructions to the label.
             for inst in self.func.layout.ebb_insts(ebb) {
                 let idata = &self.func.dfg[inst];
                 match idata.analyze_branch(&self.func.dfg.value_lists) {
                     BranchInfo::SingleDest(dest, _) => {
                         write!(w, " | <{}>{} {}", inst, idata.opcode(), dest)?
@@ -57,17 +57,17 @@ impl<'a> CFGPrinter<'a> {
                     BranchInfo::NotABranch => {}
                 }
             }
             writeln!(w, "}}\"]")?
         }
         Ok(())
     }
 
-    fn cfg_connections(&self, w: &mut Write) -> Result {
+    fn cfg_connections(&self, w: &mut dyn Write) -> Result {
         for ebb in &self.func.layout {
             for BasicBlock { ebb: parent, inst } in self.cfg.pred_iter(ebb) {
                 writeln!(w, "    {}:{} -> {}", parent, inst, ebb)?;
             }
         }
         Ok(())
     }
 }
--- a/third_party/rust/cranelift-codegen/src/context.rs
+++ b/third_party/rust/cranelift-codegen/src/context.rs
@@ -91,20 +91,20 @@ impl Context {
     /// into `relocs`.
     ///
     /// This function calls `compile` and `emit_to_memory`, taking care to resize `mem` as
     /// needed, so it provides a safe interface.
     ///
     /// Returns information about the function's code and read-only data.
     pub fn compile_and_emit(
         &mut self,
-        isa: &TargetIsa,
+        isa: &dyn TargetIsa,
         mem: &mut Vec<u8>,
-        relocs: &mut RelocSink,
-        traps: &mut TrapSink,
+        relocs: &mut dyn RelocSink,
+        traps: &mut dyn TrapSink,
     ) -> CodegenResult<CodeInfo> {
         let info = self.compile(isa)?;
         let old_len = mem.len();
         mem.resize(old_len + info.total_size as usize, 0);
         let new_info =
             unsafe { self.emit_to_memory(isa, mem.as_mut_ptr().add(old_len), relocs, traps) };
         debug_assert!(new_info == info);
         Ok(info)
@@ -112,17 +112,17 @@ impl Context {
 
     /// Compile the function.
     ///
     /// Run the function through all the passes necessary to generate code for the target ISA
     /// represented by `isa`. This does not include the final step of emitting machine code into a
     /// code sink.
     ///
     /// Returns information about the function's code and read-only data.
-    pub fn compile(&mut self, isa: &TargetIsa) -> CodegenResult<CodeInfo> {
+    pub fn compile(&mut self, isa: &dyn TargetIsa) -> CodegenResult<CodeInfo> {
         let _tt = timing::compile();
         self.verify_if(isa)?;
 
         self.compute_cfg();
         if isa.flags().opt_level() != OptLevel::Fastest {
             self.preopt(isa)?;
         }
         if isa.flags().enable_nan_canonicalization() {
@@ -159,20 +159,20 @@ impl Context {
     /// The machine code is not relocated. Instead, any relocations are emitted into `relocs`.
     ///
     /// This function is unsafe since it does not perform bounds checking on the memory buffer,
     /// and it can't guarantee that the `mem` pointer is valid.
     ///
     /// Returns information about the emitted code and data.
     pub unsafe fn emit_to_memory(
         &self,
-        isa: &TargetIsa,
+        isa: &dyn TargetIsa,
         mem: *mut u8,
-        relocs: &mut RelocSink,
-        traps: &mut TrapSink,
+        relocs: &mut dyn RelocSink,
+        traps: &mut dyn TrapSink,
     ) -> CodeInfo {
         let _tt = timing::binemit();
         let mut sink = MemoryCodeSink::new(mem, relocs, traps);
         isa.emit_function_to_memory(&self.func, &mut sink);
         sink.info
     }
 
     /// Run the verifier on the function.
@@ -194,67 +194,67 @@ impl Context {
         let fisa = fisa.into();
         if fisa.flags.enable_verifier() {
             self.verify(fisa)?;
         }
         Ok(())
     }
 
     /// Run the locations verifier on the function.
-    pub fn verify_locations(&self, isa: &TargetIsa) -> VerifierResult<()> {
+    pub fn verify_locations(&self, isa: &dyn TargetIsa) -> VerifierResult<()> {
         let mut errors = VerifierErrors::default();
         let _ = verify_locations(isa, &self.func, None, &mut errors);
 
         if errors.is_empty() {
             Ok(())
         } else {
             Err(errors)
         }
     }
 
     /// Run the locations verifier only if the `enable_verifier` setting is true.
-    pub fn verify_locations_if(&self, isa: &TargetIsa) -> CodegenResult<()> {
+    pub fn verify_locations_if(&self, isa: &dyn TargetIsa) -> CodegenResult<()> {
         if isa.flags().enable_verifier() {
             self.verify_locations(isa)?;
         }
         Ok(())
     }
 
     /// Perform dead-code elimination on the function.
     pub fn dce<'a, FOI: Into<FlagsOrIsa<'a>>>(&mut self, fisa: FOI) -> CodegenResult<()> {
         do_dce(&mut self.func, &mut self.domtree);
         self.verify_if(fisa)?;
         Ok(())
     }
 
     /// Perform pre-legalization rewrites on the function.
-    pub fn preopt(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
+    pub fn preopt(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
         do_preopt(&mut self.func, &mut self.cfg);
         self.verify_if(isa)?;
         Ok(())
     }
 
     /// Perform NaN canonicalizing rewrites on the function.
-    pub fn canonicalize_nans(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
+    pub fn canonicalize_nans(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
         do_nan_canonicalization(&mut self.func);
         self.verify_if(isa)
     }
 
     /// Run the legalizer for `isa` on the function.
-    pub fn legalize(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
+    pub fn legalize(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
         // Legalization invalidates the domtree and loop_analysis by mutating the CFG.
         // TODO: Avoid doing this when legalization doesn't actually mutate the CFG.
         self.domtree.clear();
         self.loop_analysis.clear();
         legalize_function(&mut self.func, &mut self.cfg, isa);
         self.verify_if(isa)
     }
 
     /// Perform post-legalization rewrites on the function.
-    pub fn postopt(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
+    pub fn postopt(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
         do_postopt(&mut self.func, isa);
         self.verify_if(isa)?;
         Ok(())
     }
 
     /// Compute the control flow graph.
     pub fn compute_cfg(&mut self) {
         self.cfg.compute(&self.func)
@@ -279,17 +279,17 @@ impl Context {
 
     /// Perform simple GVN on the function.
     pub fn simple_gvn<'a, FOI: Into<FlagsOrIsa<'a>>>(&mut self, fisa: FOI) -> CodegenResult<()> {
         do_simple_gvn(&mut self.func, &mut self.domtree);
         self.verify_if(fisa)
     }
 
     /// Perform LICM on the function.
-    pub fn licm(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
+    pub fn licm(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
         do_licm(
             isa,
             &mut self.func,
             &mut self.cfg,
             &mut self.domtree,
             &mut self.loop_analysis,
         );
         self.verify_if(isa)
@@ -300,47 +300,50 @@ impl Context {
     where
         FOI: Into<FlagsOrIsa<'a>>,
     {
         eliminate_unreachable_code(&mut self.func, &mut self.cfg, &self.domtree);
         self.verify_if(fisa)
     }
 
     /// Run the register allocator.
-    pub fn regalloc(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
+    pub fn regalloc(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
         self.regalloc
             .run(isa, &mut self.func, &self.cfg, &mut self.domtree)
     }
 
     /// Insert prologue and epilogues after computing the stack frame layout.
-    pub fn prologue_epilogue(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
+    pub fn prologue_epilogue(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
         isa.prologue_epilogue(&mut self.func)?;
         self.verify_if(isa)?;
         self.verify_locations_if(isa)?;
         Ok(())
     }
 
     /// Run the instruction shrinking pass.
-    pub fn shrink_instructions(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
+    pub fn shrink_instructions(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
         shrink_instructions(&mut self.func, isa);
         self.verify_if(isa)?;
         self.verify_locations_if(isa)?;
         Ok(())
     }
 
     /// Run the branch relaxation pass and return information about the function's code and
     /// read-only data.
-    pub fn relax_branches(&mut self, isa: &TargetIsa) -> CodegenResult<CodeInfo> {
+    pub fn relax_branches(&mut self, isa: &dyn TargetIsa) -> CodegenResult<CodeInfo> {
         let info = relax_branches(&mut self.func, isa)?;
         self.verify_if(isa)?;
         self.verify_locations_if(isa)?;
         Ok(info)
     }
 
     /// Builds ranges and location for specified value labels.
-    pub fn build_value_labels_ranges(&self, isa: &TargetIsa) -> CodegenResult<ValueLabelsRanges> {
+    pub fn build_value_labels_ranges(
+        &self,
+        isa: &dyn TargetIsa,
+    ) -> CodegenResult<ValueLabelsRanges> {
         Ok(build_value_labels_ranges::<ComparableSourceLoc>(
             &self.func,
             &self.regalloc,
             isa,
         ))
     }
 }
--- a/third_party/rust/cranelift-codegen/src/cursor.rs
+++ b/third_party/rust/cranelift-codegen/src/cursor.rs
@@ -652,22 +652,22 @@ pub struct EncCursor<'f> {
     pos: CursorPosition,
     srcloc: ir::SourceLoc,
     built_inst: Option<ir::Inst>,
 
     /// The referenced function.
     pub func: &'f mut ir::Function,
 
     /// The target ISA that will be used to encode instructions.
-    pub isa: &'f TargetIsa,
+    pub isa: &'f dyn TargetIsa,
 }
 
 impl<'f> EncCursor<'f> {
     /// Create a new `EncCursor` pointing nowhere.
-    pub fn new(func: &'f mut ir::Function, isa: &'f TargetIsa) -> Self {
+    pub fn new(func: &'f mut ir::Function, isa: &'f dyn TargetIsa) -> Self {
         Self {
             pos: CursorPosition::Nowhere,
             srcloc: Default::default(),
             built_inst: None,
             func,
             isa,
         }
     }
--- a/third_party/rust/cranelift-codegen/src/ir/dfg.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/dfg.rs
@@ -421,17 +421,17 @@ impl DataFlowGraph {
     /// multiple results, also call `make_inst_results` to allocate value table entries.
     pub fn make_inst(&mut self, data: InstructionData) -> Inst {
         let n = self.num_insts() + 1;
         self.results.resize(n);
         self.insts.push(data)
     }
 
     /// Returns an object that displays `inst`.
-    pub fn display_inst<'a, I: Into<Option<&'a TargetIsa>>>(
+    pub fn display_inst<'a, I: Into<Option<&'a dyn TargetIsa>>>(
         &'a self,
         inst: Inst,
         isa: I,
     ) -> DisplayInst<'a> {
         DisplayInst(self, isa.into(), inst)
     }
 
     /// Get all value arguments on `inst` as a slice.
@@ -904,17 +904,17 @@ impl EbbData {
     fn new() -> Self {
         Self {
             params: ValueList::new(),
         }
     }
 }
 
 /// Object that can display an instruction.
-pub struct DisplayInst<'a>(&'a DataFlowGraph, Option<&'a TargetIsa>, Inst);
+pub struct DisplayInst<'a>(&'a DataFlowGraph, Option<&'a dyn TargetIsa>, Inst);
 
 impl<'a> fmt::Display for DisplayInst<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let dfg = self.0;
         let isa = self.1;
         let inst = self.2;
 
         if let Some((first, rest)) = dfg.inst_results(inst).split_first() {
--- a/third_party/rust/cranelift-codegen/src/ir/entities.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/entities.rs
@@ -233,17 +233,17 @@ impl fmt::Display for AnyEntity {
             AnyEntity::Heap(r) => r.fmt(f),
             AnyEntity::Table(r) => r.fmt(f),
         }
     }
 }
 
 impl fmt::Debug for AnyEntity {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        (self as &fmt::Display).fmt(f)
+        (self as &dyn fmt::Display).fmt(f)
     }
 }
 
 impl From<Ebb> for AnyEntity {
     fn from(r: Ebb) -> Self {
         AnyEntity::Ebb(r)
     }
 }
--- a/third_party/rust/cranelift-codegen/src/ir/function.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/function.rs
@@ -150,17 +150,20 @@ impl Function {
     }
 
     /// Declares a table accessible to the function.
     pub fn create_table(&mut self, data: TableData) -> Table {
         self.tables.push(data)
     }
 
     /// Return an object that can display this function with correct ISA-specific annotations.
-    pub fn display<'a, I: Into<Option<&'a TargetIsa>>>(&'a self, isa: I) -> DisplayFunction<'a> {
+    pub fn display<'a, I: Into<Option<&'a dyn TargetIsa>>>(
+        &'a self,
+        isa: I,
+    ) -> DisplayFunction<'a> {
         DisplayFunction(self, isa.into().into())
     }
 
     /// Return an object that can display this function with correct ISA-specific annotations.
     pub fn display_with<'a>(
         &'a self,
         annotations: DisplayFunctionAnnotations<'a>,
     ) -> DisplayFunction<'a> {
@@ -197,53 +200,53 @@ impl Function {
             divert: RegDiversions::new(),
             encodings: &self.encodings,
             offset: self.offsets[ebb],
             iter: self.layout.ebb_insts(ebb),
         }
     }
 
     /// Wrapper around `encode` which assigns `inst` the resulting encoding.
-    pub fn update_encoding(&mut self, inst: ir::Inst, isa: &TargetIsa) -> Result<(), Legalize> {
+    pub fn update_encoding(&mut self, inst: ir::Inst, isa: &dyn TargetIsa) -> Result<(), Legalize> {
         self.encode(inst, isa).map(|e| self.encodings[inst] = e)
     }
 
     /// Wrapper around `TargetIsa::encode` for encoding an existing instruction
     /// in the `Function`.
-    pub fn encode(&self, inst: ir::Inst, isa: &TargetIsa) -> Result<Encoding, Legalize> {
+    pub fn encode(&self, inst: ir::Inst, isa: &dyn TargetIsa) -> Result<Encoding, Legalize> {
         isa.encode(&self, &self.dfg[inst], self.dfg.ctrl_typevar(inst))
     }
 
     /// Starts collection of debug information.
     pub fn collect_debug_info(&mut self) {
         self.dfg.collect_debug_info();
     }
 }
 
 /// Additional annotations for function display.
 pub struct DisplayFunctionAnnotations<'a> {
     /// Enable ISA annotations.
-    pub isa: Option<&'a TargetIsa>,
+    pub isa: Option<&'a dyn TargetIsa>,
 
     /// Enable value labels annotations.
     pub value_ranges: Option<&'a ValueLabelsRanges>,
 }
 
 impl<'a> DisplayFunctionAnnotations<'a> {
     /// Create a DisplayFunctionAnnotations with all fields set to None.
     pub fn default() -> Self {
         DisplayFunctionAnnotations {
             isa: None,
             value_ranges: None,
         }
     }
 }
 
-impl<'a> From<Option<&'a TargetIsa>> for DisplayFunctionAnnotations<'a> {
-    fn from(isa: Option<&'a TargetIsa>) -> DisplayFunctionAnnotations {
+impl<'a> From<Option<&'a dyn TargetIsa>> for DisplayFunctionAnnotations<'a> {
+    fn from(isa: Option<&'a dyn TargetIsa>) -> DisplayFunctionAnnotations {
         DisplayFunctionAnnotations {
             isa,
             value_ranges: None,
         }
     }
 }
 
 /// Wrapper type capable of displaying a `Function` with correct ISA annotations.
--- a/third_party/rust/cranelift-codegen/src/ir/globalvalue.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/globalvalue.rs
@@ -71,17 +71,17 @@ impl GlobalValueData {
     pub fn symbol_name(&self) -> &ExternalName {
         match *self {
             GlobalValueData::Symbol { ref name, .. } => name,
             _ => panic!("only symbols have names"),
         }
     }
 
     /// Return the type of this global.
-    pub fn global_type(&self, isa: &TargetIsa) -> Type {
+    pub fn global_type(&self, isa: &dyn TargetIsa) -> Type {
         match *self {
             GlobalValueData::VMContext { .. } | GlobalValueData::Symbol { .. } => {
                 isa.pointer_type()
             }
             GlobalValueData::IAddImm { global_type, .. }
             | GlobalValueData::Load { global_type, .. } => global_type,
         }
     }
--- a/third_party/rust/cranelift-codegen/src/ir/libcall.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/libcall.rs
@@ -102,29 +102,29 @@ impl LibCall {
 /// Get a function reference for `libcall` in `func`, following the signature
 /// for `inst`.
 ///
 /// If there is an existing reference, use it, otherwise make a new one.
 pub fn get_libcall_funcref(
     libcall: LibCall,
     func: &mut Function,
     inst: Inst,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) -> FuncRef {
     find_funcref(libcall, func).unwrap_or_else(|| make_funcref_for_inst(libcall, func, inst, isa))
 }
 
 /// Get a function reference for the probestack function in `func`.
 ///
 /// If there is an existing reference, use it, otherwise make a new one.
 pub fn get_probestack_funcref(
     func: &mut Function,
     reg_type: Type,
     arg_reg: RegUnit,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) -> FuncRef {
     find_funcref(LibCall::Probestack, func)
         .unwrap_or_else(|| make_funcref_for_probestack(func, reg_type, arg_reg, isa))
 }
 
 /// Get the existing function reference for `libcall` in `func` if it exists.
 fn find_funcref(libcall: LibCall, func: &Function) -> Option<FuncRef> {
     // We're assuming that all libcall function decls are at the end.
@@ -142,47 +142,52 @@ fn find_funcref(libcall: LibCall, func: 
     None
 }
 
 /// Create a funcref for `LibCall::Probestack`.
 fn make_funcref_for_probestack(
     func: &mut Function,
     reg_type: Type,
     arg_reg: RegUnit,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) -> FuncRef {
     let mut sig = Signature::new(CallConv::Probestack);
     let rax = AbiParam::special_reg(reg_type, ArgumentPurpose::Normal, arg_reg);
     sig.params.push(rax);
     if !isa.flags().probestack_func_adjusts_sp() {
         sig.returns.push(rax);
     }
     make_funcref(LibCall::Probestack, func, sig, isa)
 }
 
 /// Create a funcref for `libcall` with a signature matching `inst`.
 fn make_funcref_for_inst(
     libcall: LibCall,
     func: &mut Function,
     inst: Inst,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) -> FuncRef {
     let mut sig = Signature::new(isa.default_call_conv());
     for &v in func.dfg.inst_args(inst) {
         sig.params.push(AbiParam::new(func.dfg.value_type(v)));
     }
     for &v in func.dfg.inst_results(inst) {
         sig.returns.push(AbiParam::new(func.dfg.value_type(v)));
     }
 
     make_funcref(libcall, func, sig, isa)
 }
 
 /// Create a funcref for `libcall`.
-fn make_funcref(libcall: LibCall, func: &mut Function, sig: Signature, isa: &TargetIsa) -> FuncRef {
+fn make_funcref(
+    libcall: LibCall,
+    func: &mut Function,
+    sig: Signature,
+    isa: &dyn TargetIsa,
+) -> FuncRef {
     let sigref = func.import_signature(sig);
 
     func.import_function(ExtFuncData {
         name: ExternalName::LibCall(libcall),
         signature: sigref,
         colocated: isa.flags().colocated_libcalls(),
     })
 }
--- a/third_party/rust/cranelift-codegen/src/isa/arm32/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/arm32/mod.rs
@@ -35,17 +35,17 @@ pub fn isa_builder(triple: Triple) -> Is
         constructor: isa_constructor,
     }
 }
 
 fn isa_constructor(
     triple: Triple,
     shared_flags: shared_settings::Flags,
     builder: shared_settings::Builder,
-) -> Box<TargetIsa> {
+) -> Box<dyn TargetIsa> {
     let level1 = match triple.architecture {
         Architecture::Thumbv6m | Architecture::Thumbv7em | Architecture::Thumbv7m => {
             &enc_tables::LEVEL1_T32[..]
         }
         Architecture::Arm
         | Architecture::Armv4t
         | Architecture::Armv5te
         | Architecture::Armv7
@@ -114,17 +114,17 @@ impl TargetIsa for Isa {
     }
 
     #[cfg(feature = "testing_hooks")]
     fn emit_inst(
         &self,
         func: &ir::Function,
         inst: ir::Inst,
         divert: &mut regalloc::RegDiversions,
-        sink: &mut CodeSink,
+        sink: &mut dyn CodeSink,
     ) {
         binemit::emit_inst(func, inst, divert, sink)
     }
 
     fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
         emit_function(func, binemit::emit_inst, sink)
     }
 }
--- a/third_party/rust/cranelift-codegen/src/isa/arm64/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/arm64/mod.rs
@@ -34,17 +34,17 @@ pub fn isa_builder(triple: Triple) -> Is
         constructor: isa_constructor,
     }
 }
 
 fn isa_constructor(
     triple: Triple,
     shared_flags: shared_settings::Flags,
     builder: shared_settings::Builder,
-) -> Box<TargetIsa> {
+) -> Box<dyn TargetIsa> {
     Box::new(Isa {
         triple,
         isa_flags: settings::Flags::new(&shared_flags, builder),
         shared_flags,
     })
 }
 
 impl TargetIsa for Isa {
@@ -101,17 +101,17 @@ impl TargetIsa for Isa {
     }
 
     #[cfg(feature = "testing_hooks")]
     fn emit_inst(
         &self,
         func: &ir::Function,
         inst: ir::Inst,
         divert: &mut regalloc::RegDiversions,
-        sink: &mut CodeSink,
+        sink: &mut dyn CodeSink,
     ) {
         binemit::emit_inst(func, inst, divert, sink)
     }
 
     fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
         emit_function(func, binemit::emit_inst, sink)
     }
 }
--- a/third_party/rust/cranelift-codegen/src/isa/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/mod.rs
@@ -136,23 +136,23 @@ pub enum LookupError {
     Unsupported,
 }
 
 /// Builder for a `TargetIsa`.
 /// Modify the ISA-specific settings before creating the `TargetIsa` trait object with `finish`.
 pub struct Builder {
     triple: Triple,
     setup: settings::Builder,
-    constructor: fn(Triple, settings::Flags, settings::Builder) -> Box<TargetIsa>,
+    constructor: fn(Triple, settings::Flags, settings::Builder) -> Box<dyn TargetIsa>,
 }
 
 impl Builder {
     /// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a
     /// fully configured `TargetIsa` trait object.
-    pub fn finish(self, shared_flags: settings::Flags) -> Box<TargetIsa> {
+    pub fn finish(self, shared_flags: settings::Flags) -> Box<dyn TargetIsa> {
         (self.constructor)(self.triple, shared_flags, self.setup)
     }
 }
 
 impl settings::Configurable for Builder {
     fn set(&mut self, name: &str, value: &str) -> SetResult<()> {
         self.setup.set(name, value)
     }
@@ -162,17 +162,17 @@ impl settings::Configurable for Builder 
     }
 }
 
 /// After determining that an instruction doesn't have an encoding, how should we proceed to
 /// legalize it?
 ///
 /// The `Encodings` iterator returns a legalization function to call.
 pub type Legalize =
-    fn(ir::Inst, &mut ir::Function, &mut flowgraph::ControlFlowGraph, &TargetIsa) -> bool;
+    fn(ir::Inst, &mut ir::Function, &mut flowgraph::ControlFlowGraph, &dyn TargetIsa) -> bool;
 
 /// This struct provides information that a frontend may need to know about a target to
 /// produce Cranelift IR for the target.
 #[derive(Clone, Copy)]
 pub struct TargetFrontendConfig {
     /// The default calling convention of the target.
     pub default_call_conv: CallConv,
 
@@ -362,14 +362,14 @@ pub trait TargetIsa: fmt::Display + Sync
     /// This function is under the "testing_hooks" feature, and is only suitable for use by
     /// test harnesses. It increases code size, and is inefficient.
     #[cfg(feature = "testing_hooks")]
     fn emit_inst(
         &self,
         func: &ir::Function,
         inst: ir::Inst,
         divert: &mut regalloc::RegDiversions,
-        sink: &mut binemit::CodeSink,
+        sink: &mut dyn binemit::CodeSink,
     );
 
     /// Emit a whole function into memory.
     fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut binemit::MemoryCodeSink);
 }
--- a/third_party/rust/cranelift-codegen/src/isa/riscv/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/riscv/mod.rs
@@ -35,17 +35,17 @@ pub fn isa_builder(triple: Triple) -> Is
         constructor: isa_constructor,
     }
 }
 
 fn isa_constructor(
     triple: Triple,
     shared_flags: shared_settings::Flags,
     builder: shared_settings::Builder,
-) -> Box<TargetIsa> {
+) -> Box<dyn TargetIsa> {
     let level1 = match triple.pointer_width().unwrap() {
         PointerWidth::U16 => panic!("16-bit RISC-V unrecognized"),
         PointerWidth::U32 => &enc_tables::LEVEL1_RV32[..],
         PointerWidth::U64 => &enc_tables::LEVEL1_RV64[..],
     };
     Box::new(Isa {
         triple,
         isa_flags: settings::Flags::new(&shared_flags, builder),
@@ -108,17 +108,17 @@ impl TargetIsa for Isa {
     }
 
     #[cfg(feature = "testing_hooks")]
     fn emit_inst(
         &self,
         func: &ir::Function,
         inst: ir::Inst,
         divert: &mut regalloc::RegDiversions,
-        sink: &mut CodeSink,
+        sink: &mut dyn CodeSink,
     ) {
         binemit::emit_inst(func, inst, divert, sink)
     }
 
     fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
         emit_function(func, binemit::emit_inst, sink)
     }
 }
@@ -128,17 +128,17 @@ mod tests {
     use crate::ir::{immediates, types};
     use crate::ir::{Function, InstructionData, Opcode};
     use crate::isa;
     use crate::settings::{self, Configurable};
     use core::str::FromStr;
     use std::string::{String, ToString};
     use target_lexicon::triple;
 
-    fn encstr(isa: &isa::TargetIsa, enc: Result<isa::Encoding, isa::Legalize>) -> String {
+    fn encstr(isa: &dyn isa::TargetIsa, enc: Result<isa::Encoding, isa::Legalize>) -> String {
         match enc {
             Ok(e) => isa.encoding_info().display(e).to_string(),
             Err(_) => "no encoding".to_string(),
         }
     }
 
     #[test]
     fn test_64bitenc() {
--- a/third_party/rust/cranelift-codegen/src/isa/x86/abi.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/x86/abi.rs
@@ -194,17 +194,17 @@ pub fn allocatable_registers(_func: &ir:
             regs.take(FPR, FPR.unit(i));
         }
     }
 
     regs
 }
 
 /// Get the set of callee-saved registers.
-fn callee_saved_gprs(isa: &TargetIsa, call_conv: CallConv) -> &'static [RU] {
+fn callee_saved_gprs(isa: &dyn TargetIsa, call_conv: CallConv) -> &'static [RU] {
     match isa.triple().pointer_width().unwrap() {
         PointerWidth::U16 => panic!(),
         PointerWidth::U32 => &[RU::rbx, RU::rsi, RU::rdi],
         PointerWidth::U64 => {
             if call_conv == CallConv::WindowsFastcall {
                 // "registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15 are considered nonvolatile
                 //  and must be saved and restored by a function that uses them."
                 // as per https://msdn.microsoft.com/en-us/library/6t169e9c.aspx
@@ -222,17 +222,17 @@ fn callee_saved_gprs(isa: &TargetIsa, ca
             } else {
                 &[RU::rbx, RU::r12, RU::r13, RU::r14, RU::r15]
             }
         }
     }
 }
 
 /// Get the set of callee-saved registers that are used.
-fn callee_saved_gprs_used(isa: &TargetIsa, func: &ir::Function) -> RegisterSet {
+fn callee_saved_gprs_used(isa: &dyn TargetIsa, func: &ir::Function) -> RegisterSet {
     let mut all_callee_saved = RegisterSet::empty();
     for reg in callee_saved_gprs(isa, func.signature.call_conv) {
         all_callee_saved.free(GPR, *reg as RegUnit);
     }
 
     let mut used = RegisterSet::empty();
     for value_loc in func.locations.values() {
         // Note that `value_loc` here contains only a single unit of a potentially multi-unit
@@ -264,29 +264,29 @@ fn callee_saved_gprs_used(isa: &TargetIs
             }
         }
     }
 
     used.intersect(&all_callee_saved);
     used
 }
 
-pub fn prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenResult<()> {
+pub fn prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> CodegenResult<()> {
     match func.signature.call_conv {
         // For now, just translate fast and cold as system_v.
         CallConv::Fast | CallConv::Cold | CallConv::SystemV => {
             system_v_prologue_epilogue(func, isa)
         }
         CallConv::WindowsFastcall => fastcall_prologue_epilogue(func, isa),
         CallConv::Baldrdash => baldrdash_prologue_epilogue(func, isa),
         CallConv::Probestack => unimplemented!("probestack calling convention"),
     }
 }
 
-fn baldrdash_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenResult<()> {
+fn baldrdash_prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> CodegenResult<()> {
     debug_assert!(
         !isa.flags().probestack_enabled(),
         "baldrdash does not expect cranelift to emit stack probes"
     );
 
     // Baldrdash on 32-bit x86 always aligns its stack pointer to 16 bytes.
     let stack_align = 16;
     let word_size = StackSize::from(isa.pointer_bytes());
@@ -297,17 +297,17 @@ fn baldrdash_prologue_epilogue(func: &mu
     func.stack_slots.push(ss);
 
     layout_stack(&mut func.stack_slots, stack_align)?;
     Ok(())
 }
 
 /// Implementation of the fastcall-based Win64 calling convention described at [1]
 /// [1] https://msdn.microsoft.com/en-us/library/ms235286.aspx
-fn fastcall_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenResult<()> {
+fn fastcall_prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> CodegenResult<()> {
     if isa.triple().pointer_width().unwrap() != PointerWidth::U64 {
         panic!("TODO: windows-fastcall: x86-32 not implemented yet");
     }
 
     // [1] "The primary exceptions are the stack pointer and malloc or alloca memory,
     // which are aligned to 16 bytes in order to aid performance"
     let stack_align = 16;
 
@@ -369,17 +369,17 @@ fn fastcall_prologue_epilogue(func: &mut
     // Reset the cursor and insert the epilogue
     let mut pos = pos.at_position(CursorPosition::Nowhere);
     insert_common_epilogues(&mut pos, local_stack_size, reg_type, &csrs);
 
     Ok(())
 }
 
 /// Insert a System V-compatible prologue and epilogue.
-fn system_v_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenResult<()> {
+fn system_v_prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> CodegenResult<()> {
     // The original 32-bit x86 ELF ABI had a 4-byte aligned stack pointer, but
     // newer versions use a 16-byte aligned stack pointer.
     let stack_align = 16;
     let pointer_width = isa.triple().pointer_width().unwrap();
     let word_size = pointer_width.bytes() as usize;
     let reg_type = ir::Type::int(u16::from(pointer_width.bits())).unwrap();
 
     let csrs = callee_saved_gprs_used(isa, func);
@@ -430,17 +430,17 @@ fn system_v_prologue_epilogue(func: &mut
 
 /// Insert the prologue for a given function.
 /// This is used by common calling conventions such as System V.
 fn insert_common_prologue(
     pos: &mut EncCursor,
     stack_size: i64,
     reg_type: ir::types::Type,
     csrs: &RegisterSet,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     if stack_size > 0 {
         // Check if there is a special stack limit parameter. If so insert stack check.
         if let Some(stack_limit_arg) = pos.func.special_param(ArgumentPurpose::StackLimit) {
             // Total stack size is the size of all stack area used by the function, including
             // pushed CSRs, frame pointer.
             // Also, the size of a return address, implicitly pushed by a x86 `call` instruction,
             // also should be accounted for.
--- a/third_party/rust/cranelift-codegen/src/isa/x86/enc_tables.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/x86/enc_tables.rs
@@ -110,17 +110,17 @@ fn maybe_iconst_imm(pos: &FuncCursor, va
     }
 }
 
 /// Expand the `sdiv` and `srem` instructions using `x86_sdivmodx`.
 fn expand_sdivrem(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    isa: &isa::TargetIsa,
+    isa: &dyn isa::TargetIsa,
 ) {
     let (x, y, is_srem) = match func.dfg[inst] {
         ir::InstructionData::Binary {
             opcode: ir::Opcode::Sdiv,
             args,
         } => (args[0], args[1], false),
         ir::InstructionData::Binary {
             opcode: ir::Opcode::Srem,
@@ -220,17 +220,17 @@ fn expand_sdivrem(
     cfg.recompute_ebb(pos.func, done);
 }
 
 /// Expand the `udiv` and `urem` instructions using `x86_udivmodx`.
 fn expand_udivrem(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
-    isa: &isa::TargetIsa,
+    isa: &dyn isa::TargetIsa,
 ) {
     let (x, y, is_urem) = match func.dfg[inst] {
         ir::InstructionData::Binary {
             opcode: ir::Opcode::Udiv,
             args,
         } => (args[0], args[1], false),
         ir::InstructionData::Binary {
             opcode: ir::Opcode::Urem,
@@ -273,17 +273,17 @@ fn expand_udivrem(
 }
 
 /// Expand the `fmin` and `fmax` instructions using the x86 `x86_fmin` and `x86_fmax`
 /// instructions.
 fn expand_minmax(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &isa::TargetIsa,
+    _isa: &dyn isa::TargetIsa,
 ) {
     let (x, y, x86_opc, bitwise_opc) = match func.dfg[inst] {
         ir::InstructionData::Binary {
             opcode: ir::Opcode::Fmin,
             args,
         } => (args[0], args[1], ir::Opcode::X86Fmin, ir::Opcode::Bor),
         ir::InstructionData::Binary {
             opcode: ir::Opcode::Fmax,
@@ -365,17 +365,17 @@ fn expand_minmax(
 }
 
 /// x86 has no unsigned-to-float conversions. We handle the easy case of zero-extending i32 to
 /// i64 with a pattern, the rest needs more code.
 fn expand_fcvt_from_uint(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &isa::TargetIsa,
+    _isa: &dyn isa::TargetIsa,
 ) {
     let x;
     match func.dfg[inst] {
         ir::InstructionData::Unary {
             opcode: ir::Opcode::FcvtFromUint,
             arg,
         } => x = arg,
         _ => panic!("Need fcvt_from_uint: {}", func.dfg.display_inst(inst, None)),
@@ -436,17 +436,17 @@ fn expand_fcvt_from_uint(
     cfg.recompute_ebb(pos.func, neg_ebb);
     cfg.recompute_ebb(pos.func, done);
 }
 
 fn expand_fcvt_to_sint(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &isa::TargetIsa,
+    _isa: &dyn isa::TargetIsa,
 ) {
     use crate::ir::immediates::{Ieee32, Ieee64};
 
     let x = match func.dfg[inst] {
         ir::InstructionData::Unary {
             opcode: ir::Opcode::FcvtToSint,
             arg,
         } => arg,
@@ -531,17 +531,17 @@ fn expand_fcvt_to_sint(
     cfg.recompute_ebb(pos.func, old_ebb);
     cfg.recompute_ebb(pos.func, done);
 }
 
 fn expand_fcvt_to_sint_sat(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &isa::TargetIsa,
+    _isa: &dyn isa::TargetIsa,
 ) {
     use crate::ir::immediates::{Ieee32, Ieee64};
 
     let x = match func.dfg[inst] {
         ir::InstructionData::Unary {
             opcode: ir::Opcode::FcvtToSintSat,
             arg,
         } => arg,
@@ -650,17 +650,17 @@ fn expand_fcvt_to_sint_sat(
     cfg.recompute_ebb(pos.func, old_ebb);
     cfg.recompute_ebb(pos.func, done_ebb);
 }
 
 fn expand_fcvt_to_uint(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &isa::TargetIsa,
+    _isa: &dyn isa::TargetIsa,
 ) {
     use crate::ir::immediates::{Ieee32, Ieee64};
 
     let x = match func.dfg[inst] {
         ir::InstructionData::Unary {
             opcode: ir::Opcode::FcvtToUint,
             arg,
         } => arg,
@@ -731,17 +731,17 @@ fn expand_fcvt_to_uint(
     cfg.recompute_ebb(pos.func, large);
     cfg.recompute_ebb(pos.func, done);
 }
 
 fn expand_fcvt_to_uint_sat(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &isa::TargetIsa,
+    _isa: &dyn isa::TargetIsa,
 ) {
     use crate::ir::immediates::{Ieee32, Ieee64};
 
     let x = match func.dfg[inst] {
         ir::InstructionData::Unary {
             opcode: ir::Opcode::FcvtToUintSat,
             arg,
         } => arg,
--- a/third_party/rust/cranelift-codegen/src/isa/x86/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/x86/mod.rs
@@ -37,17 +37,17 @@ pub fn isa_builder(triple: Triple) -> Is
         constructor: isa_constructor,
     }
 }
 
 fn isa_constructor(
     triple: Triple,
     shared_flags: shared_settings::Flags,
     builder: shared_settings::Builder,
-) -> Box<TargetIsa> {
+) -> Box<dyn TargetIsa> {
     let level1 = match triple.pointer_width().unwrap() {
         PointerWidth::U16 => unimplemented!("x86-16"),
         PointerWidth::U32 => &enc_tables::LEVEL1_I32[..],
         PointerWidth::U64 => &enc_tables::LEVEL1_I64[..],
     };
     Box::new(Isa {
         triple,
         isa_flags: settings::Flags::new(&shared_flags, builder),
@@ -118,17 +118,17 @@ impl TargetIsa for Isa {
     }
 
     #[cfg(feature = "testing_hooks")]
     fn emit_inst(
         &self,
         func: &ir::Function,
         inst: ir::Inst,
         divert: &mut regalloc::RegDiversions,
-        sink: &mut CodeSink,
+        sink: &mut dyn CodeSink,
     ) {
         binemit::emit_inst(func, inst, divert, sink)
     }
 
     fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
         emit_function(func, binemit::emit_inst, sink)
     }
 
--- a/third_party/rust/cranelift-codegen/src/legalizer/boundary.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/boundary.rs
@@ -30,38 +30,38 @@ use crate::legalizer::split::{isplit, vs
 use log::debug;
 use std::vec::Vec;
 
 /// Legalize all the function signatures in `func`.
 ///
 /// This changes all signatures to be ABI-compliant with full `ArgumentLoc` annotations. It doesn't
 /// change the entry block arguments, calls, or return instructions, so this can leave the function
 /// in a state with type discrepancies.
-pub fn legalize_signatures(func: &mut Function, isa: &TargetIsa) {
+pub fn legalize_signatures(func: &mut Function, isa: &dyn TargetIsa) {
     legalize_signature(&mut func.signature, true, isa);
     for sig_data in func.dfg.signatures.values_mut() {
         legalize_signature(sig_data, false, isa);
     }
 
     if let Some(entry) = func.layout.entry_block() {
         legalize_entry_params(func, entry);
         spill_entry_params(func, entry);
     }
 }
 
 /// Legalize the libcall signature, which we may generate on the fly after
 /// `legalize_signatures` has been called.
-pub fn legalize_libcall_signature(signature: &mut Signature, isa: &TargetIsa) {
+pub fn legalize_libcall_signature(signature: &mut Signature, isa: &dyn TargetIsa) {
     legalize_signature(signature, false, isa);
 }
 
 /// Legalize the given signature.
 ///
 /// `current` is true if this is the signature for the current function.
-fn legalize_signature(signature: &mut Signature, current: bool, isa: &TargetIsa) {
+fn legalize_signature(signature: &mut Signature, current: bool, isa: &dyn TargetIsa) {
     isa.legalize_signature(signature, current);
 }
 
 /// Legalize the entry block parameters after `func`'s signature has been legalized.
 ///
 /// The legalized signature may contain more parameters than the original signature, and the
 /// parameter types have been changed. This function goes through the parameters of the entry EBB
 /// and replaces them with parameters of the right type for the ABI.
--- a/third_party/rust/cranelift-codegen/src/legalizer/call.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/call.rs
@@ -9,17 +9,17 @@ use crate::ir::{self, InstBuilder};
 use crate::isa::TargetIsa;
 
 /// Expand a `call` instruction. This lowers it to a `call_indirect`, which
 /// is only done if the ABI doesn't support direct calls.
 pub fn expand_call(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     // Unpack the instruction.
     let (func_ref, old_args) = match func.dfg[inst] {
         ir::InstructionData::Call {
             opcode,
             ref args,
             func_ref,
         } => {
--- a/third_party/rust/cranelift-codegen/src/legalizer/globalvalue.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/globalvalue.rs
@@ -8,17 +8,17 @@ use crate::flowgraph::ControlFlowGraph;
 use crate::ir::{self, InstBuilder};
 use crate::isa::TargetIsa;
 
 /// Expand a `global_value` instruction according to the definition of the global value.
 pub fn expand_global_value(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     // Unpack the instruction.
     let gv = match func.dfg[inst] {
         ir::InstructionData::UnaryGlobalValue {
             opcode,
             global_value,
         } => {
             debug_assert_eq!(opcode, ir::Opcode::GlobalValue);
@@ -85,17 +85,17 @@ fn iadd_imm_addr(
 /// Expand a `global_value` instruction for a load global.
 fn load_addr(
     inst: ir::Inst,
     func: &mut ir::Function,
     base: ir::GlobalValue,
     offset: ir::immediates::Offset32,
     global_type: ir::Type,
     readonly: bool,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     // We need to load a pointer from the `base` global value, so insert a new `global_value`
     // instruction. This depends on the iterative legalization loop. Note that the IR verifier
     // detects any cycles in the `load` globals.
     let ptr_ty = isa.pointer_type();
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
 
@@ -118,12 +118,12 @@ fn load_addr(
     // Perform the load.
     pos.func
         .dfg
         .replace(inst)
         .load(global_type, mflags, base_addr, offset);
 }
 
 /// Expand a `global_value` instruction for a symbolic name global.
-fn symbol(inst: ir::Inst, func: &mut ir::Function, gv: ir::GlobalValue, isa: &TargetIsa) {
+fn symbol(inst: ir::Inst, func: &mut ir::Function, gv: ir::GlobalValue, isa: &dyn TargetIsa) {
     let ptr_ty = isa.pointer_type();
     func.dfg.replace(inst).symbol_value(ptr_ty, gv);
 }
--- a/third_party/rust/cranelift-codegen/src/legalizer/heap.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/heap.rs
@@ -9,17 +9,17 @@ use crate::ir::condcodes::IntCC;
 use crate::ir::{self, InstBuilder};
 use crate::isa::TargetIsa;
 
 /// Expand a `heap_addr` instruction according to the definition of the heap.
 pub fn expand_heap_addr(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &TargetIsa,
+    _isa: &dyn TargetIsa,
 ) {
     // Unpack the instruction.
     let (heap, offset, access_size) = match func.dfg[inst] {
         ir::InstructionData::HeapAddr {
             opcode,
             heap,
             arg,
             imm,
--- a/third_party/rust/cranelift-codegen/src/legalizer/libcall.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/libcall.rs
@@ -2,17 +2,17 @@
 
 use crate::ir;
 use crate::ir::{get_libcall_funcref, InstBuilder};
 use crate::isa::TargetIsa;
 use crate::legalizer::boundary::legalize_libcall_signature;
 use std::vec::Vec;
 
 /// Try to expand `inst` as a library call, returning true is successful.
-pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function, isa: &TargetIsa) -> bool {
+pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function, isa: &dyn TargetIsa) -> bool {
     // Does the opcode/ctrl_type combo even have a well-known runtime library name.
     let libcall = match ir::LibCall::for_inst(func.dfg[inst].opcode(), func.dfg.ctrl_typevar(inst))
     {
         Some(lc) => lc,
         None => return false,
     };
 
     // Now we convert `inst` to a call. First save the arguments.
--- a/third_party/rust/cranelift-codegen/src/legalizer/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/mod.rs
@@ -36,17 +36,17 @@ use self::libcall::expand_as_libcall;
 use self::table::expand_table_addr;
 
 /// Legalize `inst` for `isa`. Return true if any changes to the code were
 /// made; return false if the instruction was successfully encoded as is.
 fn legalize_inst(
     inst: ir::Inst,
     pos: &mut FuncCursor,
     cfg: &mut ControlFlowGraph,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) -> bool {
     let opcode = pos.func.dfg[inst].opcode();
 
     // Check for ABI boundaries that need to be converted to the legalized signature.
     if opcode.is_call() {
         if boundary::handle_call_abi(inst, pos.func, cfg) {
             return true;
         }
@@ -78,17 +78,17 @@ fn legalize_inst(
     }
 }
 
 /// Legalize `func` for `isa`.
 ///
 /// - Transform any instructions that don't have a legal representation in `isa`.
 /// - Fill out `func.encodings`.
 ///
-pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: &TargetIsa) {
+pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: &dyn TargetIsa) {
     let _tt = timing::legalize();
     debug_assert!(cfg.is_valid());
 
     boundary::legalize_signatures(func, isa);
 
     func.encodings.resize(func.dfg.num_insts());
 
     let mut pos = FuncCursor::new(func);
@@ -124,17 +124,17 @@ pub fn legalize_function(func: &mut ir::
 include!(concat!(env!("OUT_DIR"), "/legalizer.rs"));
 
 /// Custom expansion for conditional trap instructions.
 /// TODO: Add CFG support to the Python patterns so we won't have to do this.
 fn expand_cond_trap(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &TargetIsa,
+    _isa: &dyn TargetIsa,
 ) {
     // Parse the instruction.
     let trapz;
     let (arg, code) = match func.dfg[inst] {
         ir::InstructionData::CondTrap { opcode, arg, code } => {
             // We want to branch *over* an unconditional trap.
             trapz = match opcode {
                 ir::Opcode::Trapz => true,
@@ -174,31 +174,31 @@ fn expand_cond_trap(
     cfg.recompute_ebb(pos.func, new_ebb);
 }
 
 /// Jump tables.
 fn expand_br_table(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     if isa.flags().jump_tables_enabled() {
         expand_br_table_jt(inst, func, cfg, isa);
     } else {
         expand_br_table_conds(inst, func, cfg, isa);
     }
 }
 
 /// Expand br_table to jump table.
 fn expand_br_table_jt(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     use crate::ir::condcodes::IntCC;
 
     let (arg, default_ebb, table) = match func.dfg[inst] {
         ir::InstructionData::BranchTable {
             opcode: ir::Opcode::BrTable,
             arg,
             destination,
@@ -234,17 +234,17 @@ fn expand_br_table_jt(
     cfg.recompute_ebb(pos.func, ebb);
 }
 
 /// Expand br_table to series of conditionals.
 fn expand_br_table_conds(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &TargetIsa,
+    _isa: &dyn TargetIsa,
 ) {
     use crate::ir::condcodes::IntCC;
 
     let (arg, default_ebb, table) = match func.dfg[inst] {
         ir::InstructionData::BranchTable {
             opcode: ir::Opcode::BrTable,
             arg,
             destination,
@@ -275,17 +275,17 @@ fn expand_br_table_conds(
 /// Expand the select instruction.
 ///
 /// Conditional moves are available in some ISAs for some register classes. The remaining selects
 /// are handled by a branch.
 fn expand_select(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &TargetIsa,
+    _isa: &dyn TargetIsa,
 ) {
     let (ctrl, tval, fval) = match func.dfg[inst] {
         ir::InstructionData::Ternary {
             opcode: ir::Opcode::Select,
             args,
         } => (args[0], args[1], args[2]),
         _ => panic!("Expected select: {}", func.dfg.display_inst(inst, None)),
     };
@@ -310,17 +310,17 @@ fn expand_select(
     cfg.recompute_ebb(pos.func, new_ebb);
     cfg.recompute_ebb(pos.func, old_ebb);
 }
 
 fn expand_br_icmp(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
-    _isa: &TargetIsa,
+    _isa: &dyn TargetIsa,
 ) {
     let (cond, a, b, destination, ebb_args) = match func.dfg[inst] {
         ir::InstructionData::BranchIcmp {
             cond,
             destination,
             ref args,
             ..
         } => (
@@ -345,17 +345,17 @@ fn expand_br_icmp(
     cfg.recompute_ebb(pos.func, old_ebb);
 }
 
 /// Expand illegal `f32const` and `f64const` instructions.
 fn expand_fconst(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
-    _isa: &TargetIsa,
+    _isa: &dyn TargetIsa,
 ) {
     let ty = func.dfg.value_type(func.dfg.first_result(inst));
     debug_assert!(!ty.is_vector(), "Only scalar fconst supported: {}", ty);
 
     // In the future, we may want to generate constant pool entries for these constants, but for
     // now use an `iconst` and a bit cast.
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
@@ -373,17 +373,17 @@ fn expand_fconst(
     pos.func.dfg.replace(inst).bitcast(ty, ival);
 }
 
 /// Expand illegal `stack_load` instructions.
 fn expand_stack_load(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     let ty = func.dfg.value_type(func.dfg.first_result(inst));
     let addr_ty = isa.pointer_type();
 
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
 
     let (stack_slot, offset) = match pos.func.dfg[inst] {
@@ -405,17 +405,17 @@ fn expand_stack_load(
     pos.func.dfg.replace(inst).load(ty, mflags, addr, 0);
 }
 
 /// Expand illegal `stack_store` instructions.
 fn expand_stack_store(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     let addr_ty = isa.pointer_type();
 
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
 
     let (val, stack_slot, offset) = match pos.func.dfg[inst] {
         ir::InstructionData::StackStore {
--- a/third_party/rust/cranelift-codegen/src/legalizer/table.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/table.rs
@@ -10,17 +10,17 @@ use crate::ir::immediates::Offset32;
 use crate::ir::{self, InstBuilder};
 use crate::isa::TargetIsa;
 
 /// Expand a `table_addr` instruction according to the definition of the table.
 pub fn expand_table_addr(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
-    _isa: &TargetIsa,
+    _isa: &dyn TargetIsa,
 ) {
     // Unpack the instruction.
     let (table, index, element_offset) = match func.dfg[inst] {
         ir::InstructionData::TableAddr {
             opcode,
             table,
             arg,
             offset,
--- a/third_party/rust/cranelift-codegen/src/licm.rs
+++ b/third_party/rust/cranelift-codegen/src/licm.rs
@@ -12,17 +12,17 @@ use crate::isa::TargetIsa;
 use crate::loop_analysis::{Loop, LoopAnalysis};
 use crate::timing;
 use std::vec::Vec;
 
 /// Performs the LICM pass by detecting loops within the CFG and moving
 /// loop-invariant instructions out of them.
 /// Changes the CFG and domtree in-place during the operation.
 pub fn do_licm(
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
     func: &mut Function,
     cfg: &mut ControlFlowGraph,
     domtree: &mut DominatorTree,
     loop_analysis: &mut LoopAnalysis,
 ) {
     let _tt = timing::licm();
     debug_assert!(cfg.is_valid());
     debug_assert!(domtree.is_valid());
@@ -59,17 +59,17 @@ pub fn do_licm(
     // We have to recompute the domtree to account for the changes
     cfg.compute(func);
     domtree.compute(func, cfg);
 }
 
 // Insert a pre-header before the header, modifying the function layout and CFG to reflect it.
 // A jump instruction to the header is placed at the end of the pre-header.
 fn create_pre_header(
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
     header: Ebb,
     func: &mut Function,
     cfg: &mut ControlFlowGraph,
     domtree: &DominatorTree,
 ) -> Ebb {
     let pool = &mut ListPool::<Value>::new();
     let header_args_values: Vec<Value> = func.dfg.ebb_params(header).into_iter().cloned().collect();
     let header_args_types: Vec<Type> = header_args_values
--- a/third_party/rust/cranelift-codegen/src/postopt.rs
+++ b/third_party/rust/cranelift-codegen/src/postopt.rs
@@ -40,17 +40,17 @@ enum CmpBrKind {
 /// in integer registers.
 ///
 /// For example, optimize icmp/fcmp brz/brnz sequences into ifcmp/ffcmp brif/brff
 /// sequences.
 fn optimize_cpu_flags(
     pos: &mut EncCursor,
     inst: Inst,
     last_flags_clobber: Option<Inst>,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     // Look for compare and branch patterns.
     // This code could be considerably simplified with non-lexical lifetimes.
     let info = match pos.func.dfg[inst] {
         InstructionData::Branch {
             opcode,
             destination,
             ref args,
@@ -174,17 +174,17 @@ struct MemOpInfo {
     opcode: Opcode,
     itype: Type,
     arg: Value,
     st_arg: Option<Value>,
     flags: MemFlags,
     offset: Offset32,
 }
 
-fn optimize_complex_addresses(pos: &mut EncCursor, inst: Inst, isa: &TargetIsa) {
+fn optimize_complex_addresses(pos: &mut EncCursor, inst: Inst, isa: &dyn TargetIsa) {
     // Look for simple loads and stores we can optimize.
     let info = match pos.func.dfg[inst] {
         InstructionData::Load {
             opcode,
             arg,
             flags,
             offset,
         } => MemOpInfo {
@@ -352,17 +352,17 @@ fn optimize_complex_addresses(pos: &mut 
     let ok = pos.func.update_encoding(inst, isa).is_ok();
     debug_assert!(ok);
 }
 
 //----------------------------------------------------------------------
 //
 // The main post-opt pass.
 
-pub fn do_postopt(func: &mut Function, isa: &TargetIsa) {
+pub fn do_postopt(func: &mut Function, isa: &dyn TargetIsa) {
     let _tt = timing::postopt();
     let mut pos = EncCursor::new(func, isa);
     while let Some(_ebb) = pos.next_ebb() {
         let mut last_flags_clobber = None;
         while let Some(inst) = pos.next_inst() {
             if isa.uses_cpu_flags() {
                 // Optimize instructions to make use of flags.
                 optimize_cpu_flags(&mut pos, inst, last_flags_clobber, isa);
--- a/third_party/rust/cranelift-codegen/src/print_errors.rs
+++ b/third_party/rust/cranelift-codegen/src/print_errors.rs
@@ -12,18 +12,18 @@ use core::fmt;
 use core::fmt::Write;
 use std::boxed::Box;
 use std::string::{String, ToString};
 use std::vec::Vec;
 
 /// Pretty-print a verifier error.
 pub fn pretty_verifier_error<'a>(
     func: &ir::Function,
-    isa: Option<&TargetIsa>,
-    func_w: Option<Box<FuncWriter + 'a>>,
+    isa: Option<&dyn TargetIsa>,
+    func_w: Option<Box<dyn FuncWriter + 'a>>,
     errors: VerifierErrors,
 ) -> String {
     let mut errors = errors.0;
     let mut w = String::new();
     let num_errors = errors.len();
 
     decorate_function(
         &mut PrettyVerifierError(func_w.unwrap_or_else(|| Box::new(PlainWriter)), &mut errors),
@@ -39,61 +39,61 @@ pub fn pretty_verifier_error<'a>(
         num_errors,
         if num_errors == 1 { "" } else { "s" }
     )
     .unwrap();
 
     w
 }
 
-struct PrettyVerifierError<'a>(Box<FuncWriter + 'a>, &'a mut Vec<VerifierError>);
+struct PrettyVerifierError<'a>(Box<dyn FuncWriter + 'a>, &'a mut Vec<VerifierError>);
 
 impl<'a> FuncWriter for PrettyVerifierError<'a> {
     fn write_ebb_header(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
-        isa: Option<&TargetIsa>,
+        isa: Option<&dyn TargetIsa>,
         ebb: Ebb,
         indent: usize,
     ) -> fmt::Result {
         pretty_ebb_header_error(w, func, isa, ebb, indent, &mut *self.0, self.1)
     }
 
     fn write_instruction(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
         aliases: &SecondaryMap<Value, Vec<Value>>,
-        isa: Option<&TargetIsa>,
+        isa: Option<&dyn TargetIsa>,
         inst: Inst,
         indent: usize,
     ) -> fmt::Result {
         pretty_instruction_error(w, func, aliases, isa, inst, indent, &mut *self.0, self.1)
     }
 
     fn write_entity_definition(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
         entity: AnyEntity,
-        value: &fmt::Display,
+        value: &dyn fmt::Display,
     ) -> fmt::Result {
         pretty_preamble_error(w, func, entity, value, &mut *self.0, self.1)
     }
 }
 
 /// Pretty-print a function verifier error for a given EBB.
 fn pretty_ebb_header_error(
-    w: &mut Write,
+    w: &mut dyn Write,
     func: &Function,
-    isa: Option<&TargetIsa>,
+    isa: Option<&dyn TargetIsa>,
     cur_ebb: Ebb,
     indent: usize,
-    func_w: &mut FuncWriter,
+    func_w: &mut dyn FuncWriter,
     errors: &mut Vec<VerifierError>,
 ) -> fmt::Result {
     let mut s = String::new();
     func_w.write_ebb_header(&mut s, func, isa, cur_ebb, indent)?;
     write!(w, "{}", s)?;
 
     // TODO: Use drain_filter here when it gets stabilized
     let mut i = 0;
@@ -116,23 +116,23 @@ fn pretty_ebb_header_error(
         w.write_char('\n')?;
     }
 
     Ok(())
 }
 
 /// Pretty-print a function verifier error for a given instruction.
 fn pretty_instruction_error(
-    w: &mut Write,
+    w: &mut dyn Write,
     func: &Function,
     aliases: &SecondaryMap<Value, Vec<Value>>,
-    isa: Option<&TargetIsa>,
+    isa: Option<&dyn TargetIsa>,
     cur_inst: Inst,
     indent: usize,
-    func_w: &mut FuncWriter,
+    func_w: &mut dyn FuncWriter,
     errors: &mut Vec<VerifierError>,
 ) -> fmt::Result {
     let mut s = String::new();
     func_w.write_instruction(&mut s, func, aliases, isa, cur_inst, indent)?;
     write!(w, "{}", s)?;
 
     // TODO: Use drain_filter here when it gets stabilized
     let mut i = 0;
@@ -154,21 +154,21 @@ fn pretty_instruction_error(
     if printed_error {
         w.write_char('\n')?;
     }
 
     Ok(())
 }
 
 fn pretty_preamble_error(
-    w: &mut Write,
+    w: &mut dyn Write,
     func: &Function,
     entity: AnyEntity,
-    value: &fmt::Display,
-    func_w: &mut FuncWriter,
+    value: &dyn fmt::Display,
+    func_w: &mut dyn FuncWriter,
     errors: &mut Vec<VerifierError>,
 ) -> fmt::Result {
     let mut s = String::new();
     func_w.write_entity_definition(&mut s, func, entity, value)?;
     write!(w, "{}", s)?;
 
     // TODO: Use drain_filter here when it gets stabilized
     let mut i = 0;
@@ -190,38 +190,38 @@ fn pretty_preamble_error(
         w.write_char('\n')?;
     }
 
     Ok(())
 }
 
 /// Prints:
 ///    ;   ^~~~~~
-fn print_arrow(w: &mut Write, entity: &str) -> fmt::Result {
+fn print_arrow(w: &mut dyn Write, entity: &str) -> fmt::Result {
     write!(w, ";")?;
 
     let indent = entity.len() - entity.trim_start().len();
     if indent != 0 {
         write!(w, "{1:0$}^", indent - 1, "")?;
     }
 
     for _ in 0..entity.trim().len() - 1 {
         write!(w, "~")?;
     }
 
     writeln!(w)
 }
 
 /// Prints:
 ///    ; error: [ERROR BODY]
-fn print_error(w: &mut Write, err: VerifierError) -> fmt::Result {
+fn print_error(w: &mut dyn Write, err: VerifierError) -> fmt::Result {
     writeln!(w, "; error: {}", err.to_string())?;
     Ok(())
 }
 
 /// Pretty-print a Cranelift error.
-pub fn pretty_error(func: &ir::Function, isa: Option<&TargetIsa>, err: CodegenError) -> String {
+pub fn pretty_error(func: &ir::Function, isa: Option<&dyn TargetIsa>, err: CodegenError) -> String {
     if let CodegenError::Verifier(e) = err {
         pretty_verifier_error(func, isa, None, e)
     } else {
         err.to_string()
     }
 }
--- a/third_party/rust/cranelift-codegen/src/regalloc/affinity.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/affinity.rs
@@ -43,17 +43,17 @@ impl Affinity {
         if constraint.kind == ConstraintKind::Stack {
             Affinity::Stack
         } else {
             Affinity::Reg(constraint.regclass.into())
         }
     }
 
     /// Create an affinity that matches an ABI argument for `isa`.
-    pub fn abi(arg: &AbiParam, isa: &TargetIsa) -> Self {
+    pub fn abi(arg: &AbiParam, isa: &dyn TargetIsa) -> Self {
         match arg.location {
             ArgumentLoc::Unassigned => Affinity::Unassigned,
             ArgumentLoc::Reg(_) => Affinity::Reg(isa.regclass_for_abi_type(arg.value_type).into()),
             ArgumentLoc::Stack(_) => Affinity::Stack,
         }
     }
 
     /// Is this the `Unassigned` affinity?
--- a/third_party/rust/cranelift-codegen/src/regalloc/coalescing.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/coalescing.rs
@@ -61,17 +61,17 @@ pub struct Coalescing {
     vcopies: VirtualCopies,
     values: Vec<Value>,
     predecessors: Vec<Inst>,
     backedges: Vec<Inst>,
 }
 
 /// One-shot context created once per invocation.
 struct Context<'a> {
-    isa: &'a TargetIsa,
+    isa: &'a dyn TargetIsa,
     encinfo: EncInfo,
 
     func: &'a mut Function,
     cfg: &'a ControlFlowGraph,
     domtree: &'a DominatorTree,
     preorder: &'a DominatorTreePreorder,
     liveness: &'a mut Liveness,
     virtregs: &'a mut VirtRegs,
@@ -103,17 +103,17 @@ impl Coalescing {
         self.values.clear();
         self.predecessors.clear();
         self.backedges.clear();
     }
 
     /// Convert `func` to Conventional SSA form and build virtual registers in the process.
     pub fn conventional_ssa(
         &mut self,
-        isa: &TargetIsa,
+        isa: &dyn TargetIsa,
         func: &mut Function,
         cfg: &ControlFlowGraph,
         domtree: &DominatorTree,
         liveness: &mut Liveness,
         virtregs: &mut VirtRegs,
     ) {
         let _tt = timing::ra_cssa();
         debug!("Coalescing for:\n{}", func.display(isa));
--- a/third_party/rust/cranelift-codegen/src/regalloc/coloring.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/coloring.rs
@@ -113,17 +113,17 @@ impl Coloring {
     pub fn clear(&mut self) {
         self.divert.clear();
         self.solver.clear();
     }
 
     /// Run the coloring algorithm over `func`.
     pub fn run(
         &mut self,
-        isa: &TargetIsa,
+        isa: &dyn TargetIsa,
         func: &mut Function,
         domtree: &DominatorTree,
         liveness: &mut Liveness,
         tracker: &mut LiveValueTracker,
     ) {
         let _tt = timing::ra_coloring();
         debug!("Coloring for:\n{}", func.display(isa));
         let mut ctx = Context {
--- a/third_party/rust/cranelift-codegen/src/regalloc/context.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/context.rs
@@ -70,17 +70,17 @@ impl Context {
     }
 
     /// Allocate registers in `func`.
     ///
     /// After register allocation, all values in `func` have been assigned to a register or stack
     /// location that is consistent with instruction encoding constraints.
     pub fn run(
         &mut self,
-        isa: &TargetIsa,
+        isa: &dyn TargetIsa,
         func: &mut Function,
         cfg: &ControlFlowGraph,
         domtree: &mut DominatorTree,
     ) -> CodegenResult<()> {
         let _tt = timing::regalloc();
         debug_assert!(domtree.is_valid());
 
         let mut errors = VerifierErrors::default();
--- a/third_party/rust/cranelift-codegen/src/regalloc/liveness.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/liveness.rs
@@ -190,17 +190,17 @@ use std::vec::Vec;
 /// A set of live ranges, indexed by value number.
 type LiveRangeSet = SparseMap<Value, LiveRange>;
 
 /// Get a mutable reference to the live range for `value`.
 /// Create it if necessary.
 fn get_or_create<'a>(
     lrset: &'a mut LiveRangeSet,
     value: Value,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
     func: &Function,
     encinfo: &EncInfo,
 ) -> &'a mut LiveRange {
     // It would be better to use `get_mut()` here, but that leads to borrow checker fighting
     // which can probably only be resolved by non-lexical lifetimes.
     // https://github.com/rust-lang/rfcs/issues/811
     if lrset.get(value).is_none() {
         // Create a live range for value. We need the program point that defines it.
@@ -384,17 +384,17 @@ impl Liveness {
     /// Change the affinity of `value` to `Stack` and return the previous affinity.
     pub fn spill(&mut self, value: Value) -> Affinity {
         let lr = self.ranges.get_mut(value).expect("Value has no live range");
         mem::replace(&mut lr.affinity, Affinity::Stack)
     }
 
     /// Compute the live ranges of all SSA values used in `func`.
     /// This clears out any existing analysis stored in this data structure.
-    pub fn compute(&mut self, isa: &TargetIsa, func: &mut Function, cfg: &ControlFlowGraph) {
+    pub fn compute(&mut self, isa: &dyn TargetIsa, func: &mut Function, cfg: &ControlFlowGraph) {
         let _tt = timing::ra_liveness();
         self.ranges.clear();
 
         // Get ISA data structures used for computing live range affinities.
         let encinfo = isa.encoding_info();
         let reginfo = isa.register_info();
 
         // The liveness computation needs to visit all uses, but the order doesn't matter.
--- a/third_party/rust/cranelift-codegen/src/regalloc/pressure.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/pressure.rs
@@ -276,30 +276,30 @@ mod tests {
     use crate::isa::{RegClass, TargetIsa};
     use crate::regalloc::RegisterSet;
     use core::borrow::Borrow;
     use core::str::FromStr;
     use std::boxed::Box;
     use target_lexicon::triple;
 
     // Make an arm32 `TargetIsa`, if possible.
-    fn arm32() -> Option<Box<TargetIsa>> {
+    fn arm32() -> Option<Box<dyn TargetIsa>> {
         use crate::isa;
         use crate::settings;
 
         let shared_builder = settings::builder();
         let shared_flags = settings::Flags::new(shared_builder);
 
         isa::lookup(triple!("arm"))
             .ok()
             .map(|b| b.finish(shared_flags))
     }
 
     // Get a register class by name.
-    fn rc_by_name(isa: &TargetIsa, name: &str) -> RegClass {
+    fn rc_by_name(isa: &dyn TargetIsa, name: &str) -> RegClass {
         isa.register_info()
             .classes
             .iter()
             .find(|rc| rc.name == name)
             .expect("Can't find named register class.")
     }
 
     #[test]
--- a/third_party/rust/cranelift-codegen/src/regalloc/reload.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/reload.rs
@@ -60,17 +60,17 @@ impl Reload {
     pub fn clear(&mut self) {
         self.candidates.clear();
         self.reloads.clear();
     }
 
     /// Run the reload algorithm over `func`.
     pub fn run(
         &mut self,
-        isa: &TargetIsa,
+        isa: &dyn TargetIsa,
         func: &mut Function,
         domtree: &DominatorTree,
         liveness: &mut Liveness,
         topo: &mut TopoOrder,
         tracker: &mut LiveValueTracker,
     ) {
         let _tt = timing::ra_reload();
         debug!("Reload for:\n{}", func.display(isa));
@@ -217,28 +217,39 @@ impl<'a> Context<'a> {
         // has a zero-length encoding, so will disappear at emission time.
         if let InstructionData::Unary {
             opcode: Opcode::Copy,
             arg,
         } = self.cur.func.dfg[inst]
         {
             let dst_vals = self.cur.func.dfg.inst_results(inst);
             if dst_vals.len() == 1 {
+                let dst_val = dst_vals[0];
                 let can_transform = match (
                     self.cur.func.locations[arg],
-                    self.cur.func.locations[dst_vals[0]],
+                    self.cur.func.locations[dst_val],
                 ) {
-                    (ValueLoc::Stack(src_slot), ValueLoc::Stack(dst_slot)) => src_slot == dst_slot,
+                    (ValueLoc::Stack(src_slot), ValueLoc::Stack(dst_slot)) => {
+                        src_slot == dst_slot && {
+                            let src_ty = self.cur.func.dfg.value_type(arg);
+                            let dst_ty = self.cur.func.dfg.value_type(dst_val);
+                            debug_assert!(src_ty == dst_ty);
+                            // This limits the transformation to copies of the
+                            // types: I64 I32 I16 I8 F64 and F32, since that's
+                            // the set of `copy_nop` encodings available.
+                            src_ty.is_int() || src_ty.is_float()
+                        }
+                    }
                     _ => false,
                 };
                 if can_transform {
                     // Convert the instruction into a `copy_nop`.
                     self.cur.func.dfg.replace(inst).copy_nop(arg);
                     let ok = self.cur.func.update_encoding(inst, self.cur.isa).is_ok();
-                    debug_assert!(ok);
+                    debug_assert!(ok, "copy_nop encoding missing for this type");
 
                     // And move on to the next insn.
                     self.reloads.clear();
                     let _ = tracker.process_inst(inst, &self.cur.func.dfg, self.liveness);
                     self.cur.next_inst();
                     self.candidates.clear();
                     return;
                 }
@@ -450,17 +461,17 @@ impl<'a> Context<'a> {
 
 /// Find reload candidates in the instruction's ABI variable arguments. This handles both
 /// return values and call arguments.
 fn handle_abi_args(
     candidates: &mut Vec<ReloadCandidate>,
     abi_types: &[AbiParam],
     var_args: &[Value],
     offset: usize,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
     liveness: &Liveness,
 ) {
     debug_assert_eq!(abi_types.len(), var_args.len());
     for ((abi, &arg), argidx) in abi_types.iter().zip(var_args).zip(offset..) {
         if abi.location.is_reg() {
             let lv = liveness.get(arg).expect("Missing live range for ABI arg");
             if lv.affinity.is_stack() {
                 candidates.push(ReloadCandidate {
--- a/third_party/rust/cranelift-codegen/src/regalloc/solver.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/solver.rs
@@ -401,17 +401,17 @@ impl fmt::Display for Move {
                 rc.info.display_regunit(to)
             ),
         }
     }
 }
 
 impl fmt::Debug for Move {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let as_display: &fmt::Display = self;
+        let as_display: &dyn fmt::Display = self;
         as_display.fmt(f)
     }
 }
 
 /// Constraint solver for register allocation around a single instruction.
 ///
 /// Start by programming in the instruction constraints.
 ///
@@ -1134,17 +1134,17 @@ mod tests {
     use crate::ir::Value;
     use crate::isa::{RegClass, RegInfo, RegUnit, TargetIsa};
     use crate::regalloc::RegisterSet;
     use core::str::FromStr;
     use std::boxed::Box;
     use target_lexicon::triple;
 
     // Make an arm32 `TargetIsa`, if possible.
-    fn arm32() -> Option<Box<TargetIsa>> {
+    fn arm32() -> Option<Box<dyn TargetIsa>> {
         use crate::isa;
         use crate::settings;
 
         let shared_builder = settings::builder();
         let shared_flags = settings::Flags::new(shared_builder);
 
         isa::lookup(triple!("arm"))
             .ok()
--- a/third_party/rust/cranelift-codegen/src/regalloc/spilling.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/spilling.rs
@@ -86,17 +86,17 @@ impl Spilling {
     pub fn clear(&mut self) {
         self.spills.clear();
         self.reg_uses.clear();
     }
 
     /// Run the spilling algorithm over `func`.
     pub fn run(
         &mut self,
-        isa: &TargetIsa,
+        isa: &dyn TargetIsa,
         func: &mut Function,
         domtree: &DominatorTree,
         liveness: &mut Liveness,
         virtregs: &VirtRegs,
         topo: &mut TopoOrder,
         tracker: &mut LiveValueTracker,
     ) {
         let _tt = timing::ra_spilling();
--- a/third_party/rust/cranelift-codegen/src/settings.rs
+++ b/third_party/rust/cranelift-codegen/src/settings.rs
@@ -341,27 +341,27 @@ include!(concat!(env!("OUT_DIR"), "/sett
 /// A few passes need to access the flags but only optionally a target ISA. The `FlagsOrIsa`
 /// wrapper can be used to pass either, and extract the flags so they are always accessible.
 #[derive(Clone, Copy)]
 pub struct FlagsOrIsa<'a> {
     /// Flags are always present.
     pub flags: &'a Flags,
 
     /// The ISA may not be present.
-    pub isa: Option<&'a TargetIsa>,
+    pub isa: Option<&'a dyn TargetIsa>,
 }
 
 impl<'a> From<&'a Flags> for FlagsOrIsa<'a> {
     fn from(flags: &'a Flags) -> FlagsOrIsa {
         FlagsOrIsa { flags, isa: None }
     }
 }
 
-impl<'a> From<&'a TargetIsa> for FlagsOrIsa<'a> {
-    fn from(isa: &'a TargetIsa) -> FlagsOrIsa {
+impl<'a> From<&'a dyn TargetIsa> for FlagsOrIsa<'a> {
+    fn from(isa: &'a dyn TargetIsa) -> FlagsOrIsa {
         FlagsOrIsa {
             flags: isa.flags(),
             isa: Some(isa),
         }
     }
 }
 
 #[cfg(test)]
--- a/third_party/rust/cranelift-codegen/src/value_label.rs
+++ b/third_party/rust/cranelift-codegen/src/value_label.rs
@@ -76,17 +76,17 @@ where
     sorted
 }
 
 /// Builds ranges and location for specified value labels.
 /// The labels specified at DataFlowGraph's values_labels collection.
 pub fn build_value_labels_ranges<T>(
     func: &Function,
     regalloc: &Context,
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
 ) -> ValueLabelsRanges
 where
     T: From<SourceLoc> + Deref<Target = SourceLoc> + Ord + Copy,
 {
     let values_labels = build_value_labels_index::<T>(func);
 
     let mut ebbs = func.layout.ebbs().collect::<Vec<_>>();
     ebbs.sort_by_key(|ebb| func.offsets[*ebb]); // Ensure inst offsets always increase
--- a/third_party/rust/cranelift-codegen/src/verifier/flags.rs
+++ b/third_party/rust/cranelift-codegen/src/verifier/flags.rs
@@ -19,17 +19,17 @@ use crate::verifier::{VerifierErrors, Ve
 ///
 /// - At most one flags value can be live at a time.
 /// - A flags value can not be live across an instruction that clobbers the flags.
 ///
 ///
 pub fn verify_flags(
     func: &ir::Function,
     cfg: &ControlFlowGraph,
-    isa: Option<&isa::TargetIsa>,
+    isa: Option<&dyn isa::TargetIsa>,
     errors: &mut VerifierErrors,
 ) -> VerifierStepResult<()> {
     let _tt = timing::verify_flags();
     let mut verifier = FlagsVerifier {
         func,
         cfg,
         encinfo: isa.map(|isa| isa.encoding_info()),
         livein: SecondaryMap::new(),
--- a/third_party/rust/cranelift-codegen/src/verifier/liveness.rs
+++ b/third_party/rust/cranelift-codegen/src/verifier/liveness.rs
@@ -18,17 +18,17 @@ use core::cmp::Ordering;
 /// - The live range def point must match where the value is defined.
 /// - The live range must reach all uses.
 /// - When a live range is live-in to an EBB, it must be live at all the predecessors.
 /// - The live range affinity must be compatible with encoding constraints.
 ///
 /// We don't verify that live ranges are minimal. This would require recomputing live ranges for
 /// all values.
 pub fn verify_liveness(
-    isa: &TargetIsa,
+    isa: &dyn TargetIsa,
     func: &Function,
     cfg: &ControlFlowGraph,
     liveness: &Liveness,
     errors: &mut VerifierErrors,
 ) -> VerifierStepResult<()> {
     let _tt = timing::verify_liveness();
     let verifier = LivenessVerifier {
         isa,
@@ -37,17 +37,17 @@ pub fn verify_liveness(
         liveness,
     };
     verifier.check_ebbs(errors)?;
     verifier.check_insts(errors)?;
     Ok(())
 }
 
 struct LivenessVerifier<'a> {
-    isa: &'a TargetIsa,
+    isa: &'a dyn TargetIsa,
     func: &'a Function,
     cfg: &'a ControlFlowGraph,
     liveness: &'a Liveness,
 }
 
 impl<'a> LivenessVerifier<'a> {
     /// Check all EBB arguments.
     fn check_ebbs(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
--- a/third_party/rust/cranelift-codegen/src/verifier/locations.rs
+++ b/third_party/rust/cranelift-codegen/src/verifier/locations.rs
@@ -14,17 +14,17 @@ use crate::verifier::{VerifierErrors, Ve
 /// instruction encoding recipes.
 ///
 /// Values can be temporarily diverted to a different location by using the `regmove`, `regspill`,
 /// and `regfill` instructions, but only inside an EBB.
 ///
 /// If a liveness analysis is provided, it is used to verify that there are no active register
 /// diversions across control flow edges.
 pub fn verify_locations(
-    isa: &isa::TargetIsa,
+    isa: &dyn isa::TargetIsa,
     func: &ir::Function,
     liveness: Option<&Liveness>,
     errors: &mut VerifierErrors,
 ) -> VerifierStepResult<()> {
     let _tt = timing::verify_locations();
     let verifier = LocationVerifier {
         isa,
         func,
@@ -32,17 +32,17 @@ pub fn verify_locations(
         encinfo: isa.encoding_info(),
         liveness,
     };
     verifier.check_constraints(errors)?;
     Ok(())
 }
 
 struct LocationVerifier<'a> {
-    isa: &'a isa::TargetIsa,
+    isa: &'a dyn isa::TargetIsa,
     func: &'a ir::Function,
     reginfo: isa::RegInfo,
     encinfo: isa::EncInfo,
     liveness: Option<&'a Liveness>,
 }
 
 impl<'a> LocationVerifier<'a> {
     /// Check that the assigned value locations match the operand constraints of their uses.
--- a/third_party/rust/cranelift-codegen/src/verifier/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/verifier/mod.rs
@@ -261,17 +261,17 @@ pub fn verify_context<'a, FOI: Into<Flag
     }
     verifier.run(errors)
 }
 
 struct Verifier<'a> {
     func: &'a Function,
     expected_cfg: ControlFlowGraph,
     expected_domtree: DominatorTree,
-    isa: Option<&'a TargetIsa>,
+    isa: Option<&'a dyn TargetIsa>,
 }
 
 impl<'a> Verifier<'a> {
     pub fn new(func: &'a Function, fisa: FlagsOrIsa<'a>) -> Self {
         let expected_cfg = ControlFlowGraph::with_function(func);
         let expected_domtree = DominatorTree::with_function(func, &expected_cfg);
         Self {
             func,
@@ -575,17 +575,17 @@ impl<'a> Verifier<'a> {
                     "argument {} -> {} is not attached",
                     arg,
                     original
                 );
             }
         }
 
         for &res in self.func.dfg.inst_results(inst) {
-            self.verify_inst_result(inst, res, errors).is_ok();
+            self.verify_inst_result(inst, res, errors)?;
         }
 
         match self.func.dfg[inst] {
             MultiAry { ref args, .. } => {
                 self.verify_value_list(inst, args, errors)?;
             }
             Jump {
                 destination,
@@ -1068,21 +1068,21 @@ impl<'a> Verifier<'a> {
             ctrl_type
         } else {
             // Non-polymorphic instructions don't check the controlling type variable, so `Option`
             // is unnecessary and we can just make it `INVALID`.
             types::INVALID
         };
 
         // Typechecking instructions is never fatal
-        self.typecheck_results(inst, ctrl_type, errors).is_ok();
-        self.typecheck_fixed_args(inst, ctrl_type, errors).is_ok();
-        self.typecheck_variable_args(inst, errors).is_ok();
-        self.typecheck_return(inst, errors).is_ok();
-        self.typecheck_special(inst, ctrl_type, errors).is_ok();
+        let _ = self.typecheck_results(inst, ctrl_type, errors);
+        let _ = self.typecheck_fixed_args(inst, ctrl_type, errors);
+        let _ = self.typecheck_variable_args(inst, errors);
+        let _ = self.typecheck_return(inst, errors);
+        let _ = self.typecheck_special(inst, ctrl_type, errors);
 
         // Misuses of copy_nop instructions are fatal
         self.typecheck_copy_nop(inst, errors)?;
 
         Ok(())
     }
 
     fn typecheck_results(
--- a/third_party/rust/cranelift-codegen/src/write.rs
+++ b/third_party/rust/cranelift-codegen/src/write.rs
@@ -17,48 +17,48 @@ use std::collections::HashSet;
 use std::string::String;
 use std::vec::Vec;
 
 /// A `FuncWriter` used to decorate functions during printing.
 pub trait FuncWriter {
     /// Write the extended basic block header for the current function.
     fn write_ebb_header(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
-        isa: Option<&TargetIsa>,
+        isa: Option<&dyn TargetIsa>,
         ebb: Ebb,
         indent: usize,
     ) -> fmt::Result;
 
     /// Write the given `inst` to `w`.
     fn write_instruction(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
         aliases: &SecondaryMap<Value, Vec<Value>>,
-        isa: Option<&TargetIsa>,
+        isa: Option<&dyn TargetIsa>,
         inst: Inst,
         indent: usize,
     ) -> fmt::Result;
 
     /// Write the preamble to `w`. By default, this uses `write_entity_definition`.
     fn write_preamble(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
         regs: Option<&RegInfo>,
     ) -> Result<bool, fmt::Error> {
         self.super_preamble(w, func, regs)
     }
 
     /// Default impl of `write_preamble`
     fn super_preamble(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
         regs: Option<&RegInfo>,
     ) -> Result<bool, fmt::Error> {
         let mut any = false;
 
         for (ss, slot) in func.stack_slots.iter() {
             any = true;
             self.write_entity_definition(w, func, ss.into(), slot)?;
@@ -103,69 +103,69 @@ pub trait FuncWriter {
         }
 
         Ok(any)
     }
 
     /// Write an entity definition defined in the preamble to `w`.
     fn write_entity_definition(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
         entity: AnyEntity,
-        value: &fmt::Display,
+        value: &dyn fmt::Display,
     ) -> fmt::Result {
         self.super_entity_definition(w, func, entity, value)
     }
 
     /// Default impl of `write_entity_definition`
     #[allow(unused_variables)]
     fn super_entity_definition(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
         entity: AnyEntity,
-        value: &fmt::Display,
+        value: &dyn fmt::Display,
     ) -> fmt::Result {
         writeln!(w, "    {} = {}", entity, value)
     }
 }
 
 /// A `PlainWriter` that doesn't decorate the function.
 pub struct PlainWriter;
 
 impl FuncWriter for PlainWriter {
     fn write_instruction(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
         aliases: &SecondaryMap<Value, Vec<Value>>,
-        isa: Option<&TargetIsa>,
+        isa: Option<&dyn TargetIsa>,
         inst: Inst,
         indent: usize,
     ) -> fmt::Result {
         write_instruction(w, func, aliases, isa, inst, indent)
     }
 
     fn write_ebb_header(
         &mut self,
-        w: &mut Write,
+        w: &mut dyn Write,
         func: &Function,
-        isa: Option<&TargetIsa>,
+        isa: Option<&dyn TargetIsa>,
         ebb: Ebb,
         indent: usize,
     ) -> fmt::Result {
         write_ebb_header(w, func, isa, ebb, indent)
     }
 }
 
 /// Write `func` to `w` as equivalent text.
 /// Use `isa` to emit ISA-dependent annotations.
 pub fn write_function(
-    w: &mut Write,
+    w: &mut dyn Write,
     func: &Function,
     annotations: &DisplayFunctionAnnotations,
 ) -> fmt::Result {
     decorate_function(&mut PlainWriter, w, func, annotations)
 }
 
 /// Create a reverse-alias map from a value to all aliases having that value as a direct target
 fn alias_map(func: &Function) -> SecondaryMap<Value, Vec<Value>> {
@@ -179,17 +179,17 @@ fn alias_map(func: &Function) -> Seconda
     aliases
 }
 
 /// Writes `func` to `w` as text.
 /// write_function_plain is passed as 'closure' to print instructions as text.
 /// pretty_function_error is passed as 'closure' to add error decoration.
 pub fn decorate_function<FW: FuncWriter>(
     func_w: &mut FW,
-    w: &mut Write,
+    w: &mut dyn Write,
     func: &Function,
     annotations: &DisplayFunctionAnnotations,
 ) -> fmt::Result {
     let regs = annotations.isa.map(TargetIsa::register_info);
     let regs = regs.as_ref();
 
     write!(w, "function ")?;
     write_spec(w, func, regs)?;
@@ -205,44 +205,49 @@ pub fn decorate_function<FW: FuncWriter>
     }
     writeln!(w, "}}")
 }
 
 //----------------------------------------------------------------------
 //
 // Function spec.
 
-fn write_spec(w: &mut Write, func: &Function, regs: Option<&RegInfo>) -> fmt::Result {
+fn write_spec(w: &mut dyn Write, func: &Function, regs: Option<&RegInfo>) -> fmt::Result {
     write!(w, "{}{}", func.name, func.signature.display(regs))
 }
 
 //----------------------------------------------------------------------
 //
 // Basic blocks
 
-fn write_arg(w: &mut Write, func: &Function, regs: Option<&RegInfo>, arg: Value) -> fmt::Result {
+fn write_arg(
+    w: &mut dyn Write,
+    func: &Function,
+    regs: Option<&RegInfo>,
+    arg: Value,
+) -> fmt::Result {
     write!(w, "{}: {}", arg, func.dfg.value_type(arg))?;
     let loc = func.locations[arg];
     if loc.is_assigned() {
         write!(w, " [{}]", loc.display(regs))?
     }
 
     Ok(())
 }
 
 /// Write out the basic block header, outdented:
 ///
 ///    ebb1:
 ///    ebb1(v1: i32):
 ///    ebb10(v4: f64, v5: b1):
 ///
 pub fn write_ebb_header(
-    w: &mut Write,
+    w: &mut dyn Write,
     func: &Function,
-    isa: Option<&TargetIsa>,
+    isa: Option<&dyn TargetIsa>,
     ebb: Ebb,
     indent: usize,
 ) -> fmt::Result {
     // The `indent` is the instruction indentation. EBB headers are 4 spaces out from that.
     write!(w, "{1:0$}{2}", indent - 4, "", ebb)?;
 
     let regs = isa.map(TargetIsa::register_info);
     let regs = regs.as_ref();
@@ -258,26 +263,26 @@ pub fn write_ebb_header(
     // Remaining arguments.
     for arg in args {
         write!(w, ", ")?;
         write_arg(w, func, regs, arg)?;
     }
     writeln!(w, "):")
 }
 
-fn write_valueloc(w: &mut Write, loc: &ValueLoc, regs: &RegInfo) -> fmt::Result {
+fn write_valueloc(w: &mut dyn Write, loc: &ValueLoc, regs: &RegInfo) -> fmt::Result {
     match loc {
         ValueLoc::Reg(r) => write!(w, "{}", regs.display_regunit(*r)),
         ValueLoc::Stack(ss) => write!(w, "{}", ss),
         ValueLoc::Unassigned => write!(w, "?"),
     }
 }
 
 fn write_value_range_markers(
-    w: &mut Write,
+    w: &mut dyn Write,
     val_ranges: &ValueLabelsRanges,
     regs: &RegInfo,
     offset: u32,
     indent: usize,
 ) -> fmt::Result {
     let mut result = String::new();
     let mut shown = HashSet::new();
     for (val, rng) in val_ranges {
@@ -301,17 +306,17 @@ fn write_value_range_markers(
     if result.len() > 0 {
         writeln!(w, ";{1:0$}; {2}", indent + 24, "", result)?;
     }
     Ok(())
 }
 
 fn decorate_ebb<FW: FuncWriter>(
     func_w: &mut FW,
-    w: &mut Write,
+    w: &mut dyn Write,
     func: &Function,
     aliases: &SecondaryMap<Value, Vec<Value>>,
     annotations: &DisplayFunctionAnnotations,
     ebb: Ebb,
 ) -> fmt::Result {
     // Indent all instructions if any encodings are present.
     let indent = if func.encodings.is_empty() && func.srclocs.is_empty() {
         4
@@ -380,37 +385,37 @@ fn type_suffix(func: &Function, inst: In
         !rtype.is_invalid(),
         "Polymorphic instruction must produce a result"
     );
     Some(rtype)
 }
 
 /// Write out any aliases to the given target, including indirect aliases
 fn write_value_aliases(
-    w: &mut Write,
+    w: &mut dyn Write,
     aliases: &SecondaryMap<Value, Vec<Value>>,
     target: Value,
     indent: usize,
 ) -> fmt::Result {
     let mut todo_stack = vec![target];
     while let Some(target) = todo_stack.pop() {
         for &a in &aliases[target] {
             writeln!(w, "{1:0$}{2} -> {3}", indent, "", a, target)?;
             todo_stack.push(a);
         }
     }
 
     Ok(())
 }
 
 fn write_instruction(
-    w: &mut Write,
+    w: &mut dyn Write,
     func: &Function,
     aliases: &SecondaryMap<Value, Vec<Value>>,
-    isa: Option<&TargetIsa>,
+    isa: Option<&dyn TargetIsa>,
     inst: Inst,
     indent: usize,
 ) -> fmt::Result {
     // Prefix containing source location, encoding, and value locations.
     let mut s = String::with_capacity(16);
 
     // Source location goes first.
     let srcloc = func.srclocs[inst];
@@ -467,19 +472,19 @@ fn write_instruction(
     for r in func.dfg.inst_results(inst) {
         write_value_aliases(w, aliases, *r, indent)?;
     }
     Ok(())
 }
 
 /// Write the operands of `inst` to `w` with a prepended space.
 pub fn write_operands(
-    w: &mut Write,
+    w: &mut dyn Write,
     dfg: &DataFlowGraph,
-    isa: Option<&TargetIsa>,
+    isa: Option<&dyn TargetIsa>,
     inst: Inst,
 ) -> fmt::Result {
     let pool = &dfg.value_lists;
     use crate::ir::instructions::InstructionData::*;
     match dfg[inst] {
         Unary { arg, .. } => write!(w, " {}", arg),
         UnaryImm { imm, .. } => write!(w, " {}", imm),
         UnaryIeee32 { imm, .. } => write!(w, " {}", imm),
@@ -682,17 +687,17 @@ pub fn write_operands(
         } => write!(w, " {} {}, {}", cond, arg, code),
         FloatCondTrap {
             cond, arg, code, ..
         } => write!(w, " {} {}, {}", cond, arg, code),
     }
 }
 
 /// Write EBB args using optional parantheses.
-fn write_ebb_args(w: &mut Write, args: &[Value]) -> fmt::Result {
+fn write_ebb_args(w: &mut dyn Write, args: &[Value]) -> fmt::Result {
     if args.is_empty() {
         Ok(())
     } else {
         write!(w, "({})", DisplayValues(args))
     }
 }
 
 /// Displayable slice of values.
--- a/third_party/rust/cranelift-entity/.cargo-checksum.json
+++ b/third_party/rust/cranelift-entity/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"48e037bea5be27018e3f98bfba7ca7b0af1322c2083c69a137ab3320cd64b9fb","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/boxed_slice.rs":"687428ee0442013c0d5962dd78d0964830233bc4cb19aa530d30da0f1dc437a9","src/iter.rs":"4a4d3309fe9aad14fd7702f02459f4277b4ddb50dba700e58dcc75665ffebfb3","src/keys.rs":"b8c2fba26dee15bf3d1880bb2b41e8d66fe1428d242ee6d9fd30ee94bbd0407d","src/lib.rs":"139fc0eeed2e8cde2b82b8b7402e8c7cd079a9fbbf1ec692622e5ad0c10d9faf","src/list.rs":"fc3decc81bcef92e106aae53e586a0ef21d70916fa53a48f7b813c5da44b8dc2","src/map.rs":"f35031459aca446734726c132c0a571482f1ec2ca8221b352d2e18c74950e977","src/packed_option.rs":"9d47f5b8302ee685c096817e376144e363507d1c77ef562d3ae4dbddae568195","src/primary.rs":"e95e4b2ed36413d80c4c0dcfc19dcf8a9f52e34467aaec196c774fd639747028","src/set.rs":"ec0ff7a9ee674c90ff9d06ea1fd4ab05039369146c2d259f476c6f612417933f","src/sparse.rs":"cf345a81d69a5dddaed4778b6aaaf06c70da2c1fd4cd21e366ed6ca5906ffdab"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"48e037bea5be27018e3f98bfba7ca7b0af1322c2083c69a137ab3320cd64b9fb","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/boxed_slice.rs":"687428ee0442013c0d5962dd78d0964830233bc4cb19aa530d30da0f1dc437a9","src/iter.rs":"4a4d3309fe9aad14fd7702f02459f4277b4ddb50dba700e58dcc75665ffebfb3","src/keys.rs":"b8c2fba26dee15bf3d1880bb2b41e8d66fe1428d242ee6d9fd30ee94bbd0407d","src/lib.rs":"f83cdc6c4a2cd0d75e85c355ee2c8b19b25194c86468c2285bde1f725656062f","src/list.rs":"fc3decc81bcef92e106aae53e586a0ef21d70916fa53a48f7b813c5da44b8dc2","src/map.rs":"f35031459aca446734726c132c0a571482f1ec2ca8221b352d2e18c74950e977","src/packed_option.rs":"9d47f5b8302ee685c096817e376144e363507d1c77ef562d3ae4dbddae568195","src/primary.rs":"e95e4b2ed36413d80c4c0dcfc19dcf8a9f52e34467aaec196c774fd639747028","src/set.rs":"ec0ff7a9ee674c90ff9d06ea1fd4ab05039369146c2d259f476c6f612417933f","src/sparse.rs":"cf345a81d69a5dddaed4778b6aaaf06c70da2c1fd4cd21e366ed6ca5906ffdab"},"package":null}
\ No newline at end of file
--- a/third_party/rust/cranelift-entity/src/lib.rs
+++ b/third_party/rust/cranelift-entity/src/lib.rs
@@ -121,17 +121,17 @@ macro_rules! entity_impl {
         impl $crate::__core::fmt::Display for $entity {
             fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result {
                 write!(f, concat!($display_prefix, "{}"), self.0)
             }
         }
 
         impl $crate::__core::fmt::Debug for $entity {
             fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result {
-                (self as &$crate::__core::fmt::Display).fmt(f)
+                (self as &dyn $crate::__core::fmt::Display).fmt(f)
             }
         }
     };
 }
 
 pub mod packed_option;
 
 mod boxed_slice;
--- a/third_party/rust/cranelift-frontend/.cargo-checksum.json
+++ b/third_party/rust/cranelift-frontend/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"c92f07d9959d10331c6b4770a4db12f706927a18897dfed45472abcd6e58190e","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"149ccdd1fdbdff42693720b14f9077dfbaa5c54ad6cae097d68756678a7486e2","src/lib.rs":"1cc2e7aaffa45bccea9e59fcc9d9c5d295a9f7adacd6bd55933834e20e969aef","src/ssa.rs":"88cb07071943f3e72a91c91afb58960689b4d9c56352b3bb7cd5d69288066190","src/switch.rs":"b8f337966b540254feb5f979b4a146f5ef69ae199864da6332c9d7513ff3ec8b","src/variable.rs":"f082efaa4b2d3c5eb48f6344149408074e1e15cb581f7a63f549313c7a1037be"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"c92f07d9959d10331c6b4770a4db12f706927a18897dfed45472abcd6e58190e","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"f2fcd908b6a3c9b4a925702a578c9b2f0c6af6ed53cfc3cd7070b6fa3b7d58cb","src/lib.rs":"1cc2e7aaffa45bccea9e59fcc9d9c5d295a9f7adacd6bd55933834e20e969aef","src/ssa.rs":"88cb07071943f3e72a91c91afb58960689b4d9c56352b3bb7cd5d69288066190","src/switch.rs":"b8f337966b540254feb5f979b4a146f5ef69ae199864da6332c9d7513ff3ec8b","src/variable.rs":"f082efaa4b2d3c5eb48f6344149408074e1e15cb581f7a63f549313c7a1037be"},"package":null}
\ No newline at end of file
--- a/third_party/rust/cranelift-frontend/src/frontend.rs
+++ b/third_party/rust/cranelift-frontend/src/frontend.rs
@@ -566,17 +566,17 @@ impl<'a> FunctionBuilder<'a> {
         self.func_ctx.ebbs[self.position.ebb.unwrap()].filled
     }
 
     /// Returns a displayable object for the function as it is.
     ///
     /// Useful for debug purposes. Use it with `None` for standard printing.
     // Clippy thinks the lifetime that follows is needless, but rustc needs it
     #[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_lifetimes))]
-    pub fn display<'b, I: Into<Option<&'b TargetIsa>>>(&'b self, isa: I) -> DisplayFunction {
+    pub fn display<'b, I: Into<Option<&'b dyn TargetIsa>>>(&'b self, isa: I) -> DisplayFunction {
         self.func.display(isa)
     }
 }
 
 /// Helper functions
 impl<'a> FunctionBuilder<'a> {
     /// Calls libc.memcpy
     ///
--- a/third_party/rust/cranelift-wasm/.cargo-checksum.json
+++ b/third_party/rust/cranelift-wasm/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"6065884c733b5e4ae101f38771c52bff0ba7b9984bf9438dde102aa68e4b9b5c","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"87679cdb53e8cbec3b1aa45afb2124727c1c059f8bd10363d27daf318a9f9a36","src/code_translator.rs":"56a399a242c9b59c25104e5c3faa81d289d0d441d17617a20b0061fbd9297aa3","src/environ/dummy.rs":"ee4d8d4924b4b04027f8af07968d5098ecd72ee62b53622d30334d1a38b227b8","src/environ/mod.rs":"617c147485038dfd797ab0ea71b4cfa9574d95d5d5b1ca362c6b7b6a462cf577","src/environ/spec.rs":"f45b20f6f9e60d94eb13829168ce8f7078ac61282689d43f58e1fccf9815d488","src/func_translator.rs":"07e1ebda4949f744e7d7b5a679bf1951fbefd807a0f0748231353cf1ef536d82","src/lib.rs":"0897b0270e746961db3d4dc74e5f766aced0ef23f870399aa9e685f1ec62ea83","src/module_translator.rs":"ac54c24aaa3775f72ccd16d1781be648bb0e83ea83909f933d07e86ef1879213","src/sections_translator.rs":"b7313a25c4e95917f8e87103fa8613166b25c040933979a0ff293c89eb3f99dc","src/state.rs":"9e4f67900439f6aa18cfa3f16c694487374ddf42530db4504bccab0ebc360c96","src/translation_utils.rs":"72ccd5bed655f1a215873218d004b087f692b0d060af0f57773b961b75214cac","tests/wasm_testsuite.rs":"9b4e008587c61377cf38f9d0e4635418ee38e32a865db8da5dfc6e0fae047436"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"1988715f39ef56d0e40ffcb2ffde965a1753a8ed15375e8a30fccabba16bd701","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"87679cdb53e8cbec3b1aa45afb2124727c1c059f8bd10363d27daf318a9f9a36","src/code_translator.rs":"77040f6e49784aafce63a04057a3464651ed7a817ba055226d40ef5755914989","src/environ/dummy.rs":"ee4d8d4924b4b04027f8af07968d5098ecd72ee62b53622d30334d1a38b227b8","src/environ/mod.rs":"617c147485038dfd797ab0ea71b4cfa9574d95d5d5b1ca362c6b7b6a462cf577","src/environ/spec.rs":"f45b20f6f9e60d94eb13829168ce8f7078ac61282689d43f58e1fccf9815d488","src/func_translator.rs":"07e1ebda4949f744e7d7b5a679bf1951fbefd807a0f0748231353cf1ef536d82","src/lib.rs":"0897b0270e746961db3d4dc74e5f766aced0ef23f870399aa9e685f1ec62ea83","src/module_translator.rs":"2345a4ee009eb59a90898795f939b9c7b241604a44abb27278610257cce84156","src/sections_translator.rs":"8ad698652ec7741feea8c10badfd6891d27d9b5b2b06819b08ec009afa584e81","src/state.rs":"9e4f67900439f6aa18cfa3f16c694487374ddf42530db4504bccab0ebc360c96","src/translation_utils.rs":"cb6b1ab91b4dd4739e5282989c61e6778cd1150319c8c7466b32f6ecc5db7afe","tests/wasm_testsuite.rs":"9b4e008587c61377cf38f9d0e4635418ee38e32a865db8da5dfc6e0fae047436"},"package":null}
\ No newline at end of file
--- a/third_party/rust/cranelift-wasm/Cargo.toml
+++ b/third_party/rust/cranelift-wasm/Cargo.toml
@@ -6,17 +6,17 @@ description = "Translator from WebAssemb
 repository = "https://github.com/CraneStation/cranelift"
 license = "Apache-2.0 WITH LLVM-exception"
 categories = ["no-std", "wasm"]
 readme = "README.md"
 keywords = ["webassembly", "wasm"]
 edition = "2018"
 
 [dependencies]
-wasmparser = { version = "0.29.2", default-features = false }
+wasmparser = { version = "0.31.0", default-features = false }
 cranelift-codegen = { path = "../cranelift-codegen", version = "0.30.0", default-features = false }
 cranelift-entity = { path = "../cranelift-entity", version = "0.30.0", default-features = false }
 cranelift-frontend = { path = "../cranelift-frontend", version = "0.30.0", default-features = false }
 hashmap_core = { version = "0.1.9", optional = true }
 failure = { version = "0.1.1", default-features = false, features = ["derive"] }
 failure_derive = { version = "0.1.1", default-features = false }
 log = { version = "0.4.6", default-features = false }
 
--- a/third_party/rust/cranelift-wasm/src/code_translator.rs
+++ b/third_party/rust/cranelift-wasm/src/code_translator.rs
@@ -20,17 +20,19 @@
 //! - `call_indirect` has to translate the function index into the address of where this
 //!    is;
 //!
 //! That is why `translate_function_body` takes an object having the `WasmRuntime` trait as
 //! argument.
 use super::{hash_map, HashMap};
 use crate::environ::{FuncEnvironment, GlobalVariable, ReturnMode, WasmError, WasmResult};
 use crate::state::{ControlStackFrame, TranslationState};
-use crate::translation_utils::{f32_translation, f64_translation, num_return_values, type_to_type};
+use crate::translation_utils::{
+    blocktype_to_type, f32_translation, f64_translation, num_return_values,
+};
 use crate::translation_utils::{FuncIndex, MemoryIndex, SignatureIndex, TableIndex};
 use core::{i32, u32};
 use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
 use cranelift_codegen::ir::types::*;
 use cranelift_codegen::ir::{self, InstBuilder, JumpTableData, MemFlags, ValueLabel};
 use cranelift_codegen::packed_option::ReservedValue;
 use cranelift_frontend::{FunctionBuilder, Variable};
 use wasmparser::{MemoryImmediate, Operator};
@@ -125,25 +127,25 @@ pub fn translate_operator<FE: FuncEnviro
          *
          *  The `End` instruction pops the last control frame from the control stack, seals
          *  the destination block (since `br` instructions targeting it only appear inside the
          *  block and have already been translated) and modify the value stack to use the
          *  possible `Ebb`'s arguments values.
          ***********************************************************************************/
         Operator::Block { ty } => {
             let next = builder.create_ebb();
-            if let Ok(ty_cre) = type_to_type(ty) {
+            if let Ok(ty_cre) = blocktype_to_type(ty) {
                 builder.append_ebb_param(next, ty_cre);
             }
             state.push_block(next, num_return_values(ty));
         }
         Operator::Loop { ty } => {
             let loop_body = builder.create_ebb();
             let next = builder.create_ebb();
-            if let Ok(ty_cre) = type_to_type(ty) {
+            if let Ok(ty_cre) = blocktype_to_type(ty) {
                 builder.append_ebb_param(next, ty_cre);
             }
             builder.ins().jump(loop_body, &[]);
             state.push_loop(loop_body, next, num_return_values(ty));
             builder.switch_to_block(loop_body);
             environ.translate_loop_header(builder.cursor())?;
         }
         Operator::If { ty } => {
@@ -151,17 +153,17 @@ pub fn translate_operator<FE: FuncEnviro
             let if_not = builder.create_ebb();
             let jump_inst = builder.ins().brz(val, if_not, &[]);
             // Here we append an argument to an Ebb targeted by an argumentless jump instruction
             // But in fact there are two cases:
             // - either the If does not have a Else clause, in that case ty = EmptyBlock
             //   and we add nothing;
             // - either the If have an Else clause, in that case the destination of this jump
             //   instruction will be changed later when we translate the Else operator.
-            if let Ok(ty_cre) = type_to_type(ty) {
+            if let Ok(ty_cre) = blocktype_to_type(ty) {
                 builder.append_ebb_param(if_not, ty_cre);
             }
             state.push_if(jump_inst, if_not, num_return_values(ty));
         }
         Operator::Else => {
             // We take the control frame pushed by the if, use its ebb as the else body
             // and push a new control frame with a new ebb for the code after the if/then/else
             // At the end of the then clause we jump to the destination
--- a/third_party/rust/cranelift-wasm/src/module_translator.rs
+++ b/third_party/rust/cranelift-wasm/src/module_translator.rs
@@ -8,17 +8,17 @@ use crate::sections_translator::{
 };
 use cranelift_codegen::timing;
 use wasmparser::{ModuleReader, SectionCode};
 
 /// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cranelift IR
 /// [`Function`](../codegen/ir/function/struct.Function.html).
 pub fn translate_module<'data>(
     data: &'data [u8],
-    environ: &mut ModuleEnvironment<'data>,
+    environ: &mut dyn ModuleEnvironment<'data>,
 ) -> WasmResult<()> {
     let _tt = timing::wasm_translate_module();
     let mut reader = ModuleReader::new(data)?;
 
     reader.skip_custom_sections()?;
     if reader.eof() {
         return Ok(());
     }
--- a/third_party/rust/cranelift-wasm/src/sections_translator.rs
+++ b/third_party/rust/cranelift-wasm/src/sections_translator.rs
@@ -1,13 +1,13 @@
 //! Helper functions to gather information for each of the non-function sections of a
 //! WebAssembly module.
 //!
-//! The code of theses helper function is straightforward since it is only about reading metadata
-//! about linear memories, tables, globals, etc. and storing them for later use.
+//! The code of these helper functions is straightforward since they only read metadata
+//! about linear memories, tables, globals, etc. and store them for later use.
 //!
 //! The special case of the initialize expressions for table elements offsets or global variables
 //! is handled, according to the semantics of WebAssembly, to only specific expressions that are
 //! interpreted on the fly.
 use crate::environ::{ModuleEnvironment, WasmResult};
 use crate::translation_utils::{
     type_to_type, FuncIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex, SignatureIndex,
     Table, TableElementType, TableIndex,
@@ -22,17 +22,17 @@ use wasmparser::{
     FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
     ImportSectionReader, MemorySectionReader, MemoryType, Operator, TableSectionReader,
     TypeSectionReader,
 };
 
 /// Parses the Type section of the wasm module.
 pub fn parse_type_section(
     types: TypeSectionReader,
-    environ: &mut ModuleEnvironment,
+    environ: &mut dyn ModuleEnvironment,
 ) -> WasmResult<()> {
     environ.reserve_signatures(types.get_count());
 
     for entry in types {
         match entry? {
             FuncType {
                 form: wasmparser::Type::Func,
                 ref params,
@@ -55,17 +55,17 @@ pub fn parse_type_section(
         }
     }
     Ok(())
 }
 
 /// Parses the Import section of the wasm module.
 pub fn parse_import_section<'data>(
     imports: ImportSectionReader<'data>,
-    environ: &mut ModuleEnvironment<'data>,
+    environ: &mut dyn ModuleEnvironment<'data>,
 ) -> WasmResult<()> {
     environ.reserve_imports(imports.get_count());
 
     for entry in imports {
         let import = entry?;
         let module_name = import.module;
         let field_name = import.field;
 
@@ -117,32 +117,32 @@ pub fn parse_import_section<'data>(
 
     environ.finish_imports();
     Ok(())
 }
 
 /// Parses the Function section of the wasm module.
 pub fn parse_function_section(
     functions: FunctionSectionReader,
-    environ: &mut ModuleEnvironment,
+    environ: &mut dyn ModuleEnvironment,
 ) -> WasmResult<()> {
     environ.reserve_func_types(functions.get_count());
 
     for entry in functions {
         let sigindex = entry?;
         environ.declare_func_type(SignatureIndex::from_u32(sigindex));
     }
 
     Ok(())
 }
 
 /// Parses the Table section of the wasm module.
 pub fn parse_table_section(
     tables: TableSectionReader,
-    environ: &mut ModuleEnvironment,
+    environ: &mut dyn ModuleEnvironment,
 ) -> WasmResult<()> {
     environ.reserve_tables(tables.get_count());
 
     for entry in tables {
         let table = entry?;
         environ.declare_table(Table {
             ty: match type_to_type(table.element_type) {
                 Ok(t) => TableElementType::Val(t),
@@ -154,17 +154,17 @@ pub fn parse_table_section(
     }
 
     Ok(())
 }
 
 /// Parses the Memory section of the wasm module.
 pub fn parse_memory_section(
     memories: MemorySectionReader,
-    environ: &mut ModuleEnvironment,
+    environ: &mut dyn ModuleEnvironment,
 ) -> WasmResult<()> {
     environ.reserve_memories(memories.get_count());
 
     for entry in memories {
         let memory = entry?;
         environ.declare_memory(Memory {
             minimum: memory.limits.initial,
             maximum: memory.limits.maximum,
@@ -173,17 +173,17 @@ pub fn parse_memory_section(
     }
 
     Ok(())
 }
 
 /// Parses the Global section of the wasm module.
 pub fn parse_global_section(
     globals: GlobalSectionReader,
-    environ: &mut ModuleEnvironment,
+    environ: &mut dyn ModuleEnvironment,
 ) -> WasmResult<()> {
     environ.reserve_globals(globals.get_count());
 
     for entry in globals {
         let wasmparser::Global {
             ty: GlobalType {
                 content_type,
                 mutable,
@@ -210,17 +210,17 @@ pub fn parse_global_section(
     }
 
     Ok(())
 }
 
 /// Parses the Export section of the wasm module.
 pub fn parse_export_section<'data>(
     exports: ExportSectionReader<'data>,
-    environ: &mut ModuleEnvironment<'data>,
+    environ: &mut dyn ModuleEnvironment<'data>,
 ) -> WasmResult<()> {
     environ.reserve_exports(exports.get_count());
 
     for entry in exports {
         let Export {
             field,
             ref kind,
             index,
@@ -238,25 +238,25 @@ pub fn parse_export_section<'data>(
         }
     }
 
     environ.finish_exports();
     Ok(())
 }
 
 /// Parses the Start section of the wasm module.
-pub fn parse_start_section(index: u32, environ: &mut ModuleEnvironment) -> WasmResult<()> {
+pub fn parse_start_section(index: u32, environ: &mut dyn ModuleEnvironment) -> WasmResult<()> {
     environ.declare_start_func(FuncIndex::from_u32(index));
     Ok(())
 }
 
 /// Parses the Element section of the wasm module.
 pub fn parse_element_section<'data>(
     elements: ElementSectionReader<'data>,
-    environ: &mut ModuleEnvironment,
+    environ: &mut dyn ModuleEnvironment,
 ) -> WasmResult<()> {
     environ.reserve_table_elements(elements.get_count());
 
     for entry in elements {
         let Element { kind, items } = entry?;
         if let ElementKind::Active {
             table_index,
             init_expr,
@@ -287,31 +287,31 @@ pub fn parse_element_section<'data>(
         }
     }
     Ok(())
 }
 
 /// Parses the Code section of the wasm module.
 pub fn parse_code_section<'data>(
     code: CodeSectionReader<'data>,
-    environ: &mut ModuleEnvironment<'data>,
+    environ: &mut dyn ModuleEnvironment<'data>,
 ) -> WasmResult<()> {
     for body in code {
         let mut reader = body?.get_binary_reader();
         let size = reader.bytes_remaining();
         let offset = reader.original_position();
         environ.define_function_body(reader.read_bytes(size)?, offset)?;
     }
     Ok(())
 }
 
 /// Parses the Data section of the wasm module.
 pub fn parse_data_section<'data>(
     data: DataSectionReader<'data>,
-    environ: &mut ModuleEnvironment<'data>,
+    environ: &mut dyn ModuleEnvironment<'data>,
 ) -> WasmResult<()> {
     environ.reserve_data_initializers(data.get_count());
 
     for entry in data {
         let Data { kind, data } = entry?;
         if let DataKind::Active {
             memory_index,
             init_expr,
--- a/third_party/rust/cranelift-wasm/src/translation_utils.rs
+++ b/third_party/rust/cranelift-wasm/src/translation_utils.rs
@@ -114,35 +114,46 @@ pub fn type_to_type(ty: wasmparser::Type
         wasmparser::Type::I32 => ir::types::I32,
         wasmparser::Type::I64 => ir::types::I64,
         wasmparser::Type::F32 => ir::types::F32,
         wasmparser::Type::F64 => ir::types::F64,
         _ => return Err(()),
     })
 }
 
+/// Helper function translating wasmparser block signatures to Cranelift types when possible.
+pub fn blocktype_to_type(ty: wasmparser::TypeOrFuncType) -> Result<ir::Type, ()> {
+    match ty {
+        wasmparser::TypeOrFuncType::Type(ty) => type_to_type(ty),
+        wasmparser::TypeOrFuncType::FuncType(_) => unimplemented!("multi-value block signatures"),
+    }
+}
+
 /// Turns a `wasmparser` `f32` into a `Cranelift` one.
 pub fn f32_translation(x: wasmparser::Ieee32) -> ir::immediates::Ieee32 {
     ir::immediates::Ieee32::with_bits(x.bits())
 }
 
 /// Turns a `wasmparser` `f64` into a `Cranelift` one.
 pub fn f64_translation(x: wasmparser::Ieee64) -> ir::immediates::Ieee64 {
     ir::immediates::Ieee64::with_bits(x.bits())
 }
 
 /// Translate a `wasmparser` type into its `Cranelift` equivalent, when possible
-pub fn num_return_values(ty: wasmparser::Type) -> usize {
+pub fn num_return_values(ty: wasmparser::TypeOrFuncType) -> usize {
     match ty {
-        wasmparser::Type::EmptyBlockType => 0,
-        wasmparser::Type::I32
-        | wasmparser::Type::F32
-        | wasmparser::Type::I64
-        | wasmparser::Type::F64 => 1,
-        _ => panic!("unsupported return value type"),
+        wasmparser::TypeOrFuncType::Type(ty) => match ty {
+            wasmparser::Type::EmptyBlockType => 0,
+            wasmparser::Type::I32
+            | wasmparser::Type::F32
+            | wasmparser::Type::I64
+            | wasmparser::Type::F64 => 1,
+            _ => panic!("unsupported return value type"),
+        },
+        wasmparser::TypeOrFuncType::FuncType(_) => unimplemented!("multi-value block signatures"),
     }
 }
 
 /// Special VMContext value label. It is tracked as 0xffff_fffe label.
 pub fn get_vmctx_value_label() -> ir::ValueLabel {
     const VMCTX_LABEL: u32 = 0xffff_fffe;
     ir::ValueLabel::from_u32(VMCTX_LABEL)
 }
--- a/third_party/rust/wasmparser/.cargo-checksum.json
+++ b/third_party/rust/wasmparser/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"6f05ad46e7a84c8ae06ee90f29bb874acb68074a88aa31838554b9f9c07cd405","LICENSE":"a6c48161a09acc75a0e25503bab66a731eb5fba5392ed4bb4743e4ba5085327a","README.md":"13ea373a411dfa7371cd994736289bb000db51957da92315fecbcc9fe7dcab92","examples/dump.rs":"fdebf1af451d06691d011ba7220f3f9a483b2c54a851f06b610aaa5fcb3832df","examples/simple.rs":"c79ae542913e72cfcd03711543d173b2e8f62783e6c206459953bdb94dbb8c0c","format-all.sh":"6b02a40629ef3d2c0b9671222582a6217d526317a41262ae06c7a95de53bcbeb","src/binary_reader.rs":"e8d58f2ab57123955c680e9c9e790aec8e8a36732a77349bcdbadd7d8faf1c7d","src/lib.rs":"2fae91a32fe51183d5f9d4aab48665a0e617d6127a2031d6aaf4aa257e76dca1","src/limits.rs":"2cf22e266c2828d68bb521485b8bd604a2ecb7a023204d7874b3da5837ec44f9","src/parser.rs":"40624c94c125446b0c6106e7590b35c58df2a6ceafc85a72bb013eef2018eb58","src/primitives.rs":"4627647982376ea8519f931f09108d04c7080cf6b2a4b2d85e559ba7cfb6ad70","src/readers/code_section.rs":"2034c399b76428ac993c22f551f3c541b132d8b4ccc74e34f0043e25534d107b","src/readers/data_count_section.rs":"27ef37517b6beac21245008b14b5416b851c52d0af8e2ae85c1456674e1c9a9e","src/readers/data_section.rs":"e7e2a539d2d3049d4a8f68df9ea2f21d97e7061657bbd91845e1df3e9c1f2ebc","src/readers/element_section.rs":"e31e1d819c0b10acf58b8975238554245defe36db1c3206683b056c52978fb21","src/readers/export_section.rs":"7c74f7a11406a95c162f6ad4f77aafd0b1eee309f33b69f06bea12b23925e143","src/readers/function_section.rs":"57c0479ba8d7f61908ed74e86cbc26553fdd6d2d952f032ce29385a39f82efd3","src/readers/global_section.rs":"5fa18bed0fffadcc2dbdcbaedbe4e4398992fd1ce9e611b0319333a7681082ac","src/readers/import_section.rs":"1db4bf7290d04783d5cf526050d025b15a1daaf2bd97fca1a92ecb873d48f641","src/readers/init_expr.rs":"7020c80013dad4518a5f969c3ab4d624b46d778f03e632871cf343964f63441c","src/readers/linking_section.rs":"9df71f3ee5356f0d273c099212213353080001e261ca697caddf6b847fb5af09","src/readers/memory_section.rs":"83212f86cfc40d18fb392e9234c880afdf443f4af38a727ba346f9c740ef8718","src/readers/mod.rs":"13822fff4190b72f6ae14e29635d2c148a38ee972e148eb99a4688b0309bc2c9","src/readers/module.rs":"66473e7077b3d77ed01ed58d2796c8de7afdb2b90f2b0669c06fa90ca1b3434e","src/readers/name_section.rs":"297f57393d5fef745ec265438108aa6eb7ed2762c03c3beb539493612442f3da","src/readers/operators.rs":"da43ee8afcb0c1d6e7f1e19e8a10143101f0c598b1e533a394c7397f43881a82","src/readers/producers_section.rs":"674f402fc4545c94487f827153871b37adab44ed5eff4070a436eb18e514023a","src/readers/reloc_section.rs":"0ef818a8b83a4542c4c29c23642436a92d3e7c37bc0248e817ed5a9d65ec38ce","src/readers/section_reader.rs":"3d2260449fa0455d710ba6d97810372ec36cba70722c10dd236c3a18ca0eb56f","src/readers/sourcemappingurl_section.rs":"ababe84d51e4817ad19f827aa2b5239578e7f202e5ec06dd688b618885138434","src/readers/start_section.rs":"3eeae00e1aa0fcb2e0d93b7b0eaac30a60d3f1431c71c589cd3f73adb363d532","src/readers/table_section.rs":"e564876825a7b31df2b5dc850279b523e26dc50a08da935cc8d635a49e809951","src/readers/type_section.rs":"2fa33a7b793f3bfa01c259b5dbc38633b7343931886ab41f0cb96dd78db3bf6e","src/tests.rs":"ca486d82ffaa31370534d7d1475c0603f0e9d4888d3d07287b9d5458e6d11156","src/validator.rs":"ec0d1368f3b7833ff6d6178db50e3ffc6b2878d1d6ddab37728fdf21e8256896","test-all.sh":"ff894f4e5e34389ad6ef697bd4ade28a2483dd456eabba8b757945546568f4c9","test-no_std.sh":"f8bc939b378fe618b7ec6297152708e7c8740858eb94e5756464934a38796b8c"},"package":"981a8797cf89762e0233ec45fae731cb79a4dfaee12d9f0fe6cee01e4ac58d00"}
\ No newline at end of file
+{"files":{"Cargo.toml":"83c9345be6b7ac1c67bf7aa61e82fb440c299277dd02817a86e7dac7ba3ac7fa","LICENSE":"a6c48161a09acc75a0e25503bab66a731eb5fba5392ed4bb4743e4ba5085327a","README.md":"13ea373a411dfa7371cd994736289bb000db51957da92315fecbcc9fe7dcab92","benches/benchmark.rs":"25caa5e42e88412fdc443cdf1e870b100c9bf5e2907bbfd75f077757be3090bc","compare-master.sh":"165490eab36ef4eceb2913a6c5cdeff479a05e1e0119a7f4551b03dbcda51ad4","examples/dump.rs":"de2bbdba75e21b9ff92b32697b3d9941f8695b8f7e3a8dee8fc5d7f4c3a0649c","examples/simple.rs":"c79ae542913e72cfcd03711543d173b2e8f62783e6c206459953bdb94dbb8c0c","format-all.sh":"6b02a40629ef3d2c0b9671222582a6217d526317a41262ae06c7a95de53bcbeb","src/binary_reader.rs":"e523ef680480c5a106e0238b1fa4eb77ecaabc2652b65d5dc0f683ee0eed66d7","src/lib.rs":"bc786f619be99366d838c8837416c9008fa15beb873395e8b9ab98579a6b1c18","src/limits.rs":"4e4f9b7ed1d26e7a6727e36b136015cd9f4e38f596b3c8f82236789f45905cae","src/operators_validator.rs":"be295f7529ba863884a10d3236ee3e39c2b4b138ae5a1343b15612a367cd99ca","src/parser.rs":"9b1ab93de63117cfc43900cc99c9912dcd307b347ca982eb4e307331edab4ca2","src/primitives.rs":"9f1417b9dba839c548d9afd94488be7c1d179d243cfeca4f8b10c9805995af62","src/readers/code_section.rs":"2034c399b76428ac993c22f551f3c541b132d8b4ccc74e34f0043e25534d107b","src/readers/data_count_section.rs":"27ef37517b6beac21245008b14b5416b851c52d0af8e2ae85c1456674e1c9a9e","src/readers/data_section.rs":"e7e2a539d2d3049d4a8f68df9ea2f21d97e7061657bbd91845e1df3e9c1f2ebc","src/readers/element_section.rs":"e31e1d819c0b10acf58b8975238554245defe36db1c3206683b056c52978fb21","src/readers/export_section.rs":"7c74f7a11406a95c162f6ad4f77aafd0b1eee309f33b69f06bea12b23925e143","src/readers/function_section.rs":"57c0479ba8d7f61908ed74e86cbc26553fdd6d2d952f032ce29385a39f82efd3","src/readers/global_section.rs":"5fa18bed0fffadcc2dbdcbaedbe4e4398992fd1ce9e611b0319333a7681082ac","src/readers/import_section.rs":"1db4bf7290d04783d5cf526050d025b15a1daaf2bd97fca1a92ecb873d48f641","src/readers/init_expr.rs":"7020c80013dad4518a5f969c3ab4d624b46d778f03e632871cf343964f63441c","src/readers/linking_section.rs":"9df71f3ee5356f0d273c099212213353080001e261ca697caddf6b847fb5af09","src/readers/memory_section.rs":"83212f86cfc40d18fb392e9234c880afdf443f4af38a727ba346f9c740ef8718","src/readers/mod.rs":"13822fff4190b72f6ae14e29635d2c148a38ee972e148eb99a4688b0309bc2c9","src/readers/module.rs":"66473e7077b3d77ed01ed58d2796c8de7afdb2b90f2b0669c06fa90ca1b3434e","src/readers/name_section.rs":"297f57393d5fef745ec265438108aa6eb7ed2762c03c3beb539493612442f3da","src/readers/operators.rs":"da43ee8afcb0c1d6e7f1e19e8a10143101f0c598b1e533a394c7397f43881a82","src/readers/producers_section.rs":"674f402fc4545c94487f827153871b37adab44ed5eff4070a436eb18e514023a","src/readers/reloc_section.rs":"0ef818a8b83a4542c4c29c23642436a92d3e7c37bc0248e817ed5a9d65ec38ce","src/readers/section_reader.rs":"3d2260449fa0455d710ba6d97810372ec36cba70722c10dd236c3a18ca0eb56f","src/readers/sourcemappingurl_section.rs":"ababe84d51e4817ad19f827aa2b5239578e7f202e5ec06dd688b618885138434","src/readers/start_section.rs":"3eeae00e1aa0fcb2e0d93b7b0eaac30a60d3f1431c71c589cd3f73adb363d532","src/readers/table_section.rs":"e564876825a7b31df2b5dc850279b523e26dc50a08da935cc8d635a49e809951","src/readers/type_section.rs":"2fa33a7b793f3bfa01c259b5dbc38633b7343931886ab41f0cb96dd78db3bf6e","src/tests.rs":"927ed18fc70cf340a02b3e2f7f535a062003fcc3d6f66857093c431b88054dd3","src/validator.rs":"592db08da9b2f6a6cd658faac06d737434de98a09fd8bdc125e7a3c7f003d008","test-all.sh":"ff894f4e5e34389ad6ef697bd4ade28a2483dd456eabba8b757945546568f4c9","test-no_std.sh":"f8bc939b378fe618b7ec6297152708e7c8740858eb94e5756464934a38796b8c"},"package":"8a6f324afc05fd8282bbc49dae854a1c20f74aeff10a575b5a43453d1864db97"}
\ No newline at end of file
--- a/third_party/rust/wasmparser/Cargo.toml
+++ b/third_party/rust/wasmparser/Cargo.toml
@@ -1,31 +1,37 @@
 # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
 #
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
+# to registry (e.g., crates.io) dependencies
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "wasmparser"
-version = "0.29.2"
+version = "0.31.1"
 authors = ["Yury Delendik <ydelendik@mozilla.com>"]
 exclude = ["fuzz/**/*", "tests/**/*"]
 description = "A simple event-driven library for parsing WebAssembly binary files.\n"
 keywords = ["parser", "WebAssembly", "wasm"]
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/yurydelendik/wasmparser.rs"
+
+[[bench]]
+name = "benchmark"
+harness = false
 [dependencies.hashmap_core]
-version = "0.1.9"
+version = "0.1.10"
 optional = true
+[dev-dependencies.criterion]
+version = "0.2"
 
 [features]
 core = ["hashmap_core"]
 default = ["std"]
 std = []
 [badges.travis-ci]
 repository = "yurydelendik/wasmparser.rs"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/wasmparser/benches/benchmark.rs
@@ -0,0 +1,99 @@
+pub fn read_file_data(path: &PathBuf) -> Vec<u8> {
+    let mut data = Vec::new();
+    let mut f = File::open(path).ok().unwrap();
+    f.read_to_end(&mut data).unwrap();
+    data
+}
+
+const VALIDATOR_CONFIG: Option<ValidatingParserConfig> = Some(ValidatingParserConfig {
+    operator_config: OperatorValidatorConfig {
+        enable_threads: true,
+        enable_reference_types: true,
+        enable_simd: true,
+        enable_bulk_memory: true,
+    },
+    mutable_global_imports: true,
+});
+
+#[macro_use]
+extern crate criterion;
+extern crate wasmparser;
+
+use criterion::Criterion;
+use wasmparser::{
+    validate, OperatorValidatorConfig, Parser, ParserState, ValidatingParser,
+    ValidatingParserConfig, WasmDecoder,
+};
+
+use std::fs::{read_dir, File};
+use std::io::Read;
+use std::path::PathBuf;
+
+fn read_all_wasm<'a, T>(mut d: T)
+where
+    T: WasmDecoder<'a>,
+{
+    loop {
+        match *d.read() {
+            ParserState::Error(e) => panic!("unexpected error {:?}", e),
+            ParserState::EndWasm => return,
+            _ => (),
+        }
+    }
+}
+
+fn it_works_benchmark(c: &mut Criterion) {
+    let mut data: Vec<Vec<u8>> = vec![];
+    for entry in read_dir("tests").unwrap() {
+        let dir = entry.unwrap();
+        if !dir.file_type().unwrap().is_file() {
+            continue;
+        }
+        data.push(read_file_data(&dir.path()));
+    }
+    c.bench_function("it works benchmark", move |b| {
+        for d in &mut data {
+            b.iter(|| read_all_wasm(Parser::new(d.as_slice())));
+        }
+    });
+}
+
+fn validator_not_fails_benchmark(c: &mut Criterion) {
+    let mut data: Vec<Vec<u8>> = vec![];
+    for entry in read_dir("tests").unwrap() {
+        let dir = entry.unwrap();
+        if !dir.file_type().unwrap().is_file() {
+            continue;
+        }
+        data.push(read_file_data(&dir.path()));
+    }
+    c.bench_function("validator no fails benchmark", move |b| {
+        for d in &mut data {
+            b.iter(|| read_all_wasm(ValidatingParser::new(d.as_slice(), VALIDATOR_CONFIG)));
+        }
+    });
+}
+
+fn validate_benchmark(c: &mut Criterion) {
+    let mut data: Vec<Vec<u8>> = vec![vec![]];
+    for entry in read_dir("tests").unwrap() {
+        let dir = entry.unwrap();
+        if !dir.file_type().unwrap().is_file() {
+            continue;
+        }
+        data.push(read_file_data(&dir.path()));
+    }
+    c.bench_function("validate benchmark", move |b| {
+        for d in &mut data {
+            b.iter(|| validate(&d, VALIDATOR_CONFIG));
+        }
+    });
+}
+
+criterion_group!(
+    benchmark,
+    it_works_benchmark,
+    validator_not_fails_benchmark,
+    validate_benchmark
+);
+criterion_main!(benchmark);
new file mode 100755
--- /dev/null
+++ b/third_party/rust/wasmparser/compare-master.sh
@@ -0,0 +1,12 @@
+#/bin/bash
+
+# record current bench results
+cargo bench --bench benchmark -- --noplot --save-baseline after
+
+# switch to master and record its bench results
+git checkout master && \
+cargo bench --bench benchmark -- --noplot --save-baseline before
+
+# compare
+cargo install critcmp --force && \
+critcmp before after
--- a/third_party/rust/wasmparser/examples/dump.rs
+++ b/third_party/rust/wasmparser/examples/dump.rs
@@ -14,16 +14,17 @@ fn main() {
     if args.len() != 2 {
         println!("Usage: {} in.wasm", args[0]);
         return;
     }
 
     let buf: Vec<u8> = read_wasm(&args[1]).unwrap();
     let mut parser = Parser::new(&buf);
     loop {
+        print!("0x{:08x}\t", parser.current_position());
         let state = parser.read();
         match *state {
             ParserState::ExportSectionEntry {
                 field,
                 ref kind,
                 index,
             } => {
                 println!(
--- a/third_party/rust/wasmparser/src/binary_reader.rs
+++ b/third_party/rust/wasmparser/src/binary_reader.rs
@@ -20,17 +20,17 @@ use std::vec::Vec;
 use limits::{
     MAX_WASM_FUNCTION_LOCALS, MAX_WASM_FUNCTION_PARAMS, MAX_WASM_FUNCTION_RETURNS,
     MAX_WASM_FUNCTION_SIZE, MAX_WASM_STRING_SIZE,
 };
 
 use primitives::{
     BinaryReaderError, BrTable, CustomSectionKind, ExternalKind, FuncType, GlobalType, Ieee32,
     Ieee64, LinkingType, MemoryImmediate, MemoryType, NameType, Operator, RelocType,
-    ResizableLimits, Result, SIMDLineIndex, SectionCode, TableType, Type, V128,
+    ResizableLimits, Result, SIMDLineIndex, SectionCode, TableType, Type, TypeOrFuncType, V128,
 };
 
 const MAX_WASM_BR_TABLE_SIZE: usize = MAX_WASM_FUNCTION_SIZE;
 
 fn is_name(name: &str, expected: &'static str) -> bool {
     name == expected
 }
 
@@ -244,17 +244,17 @@ impl<'a> BinaryReader<'a> {
         }
         let mut params: Vec<Type> = Vec::with_capacity(params_len);
         for _ in 0..params_len {
             params.push(self.read_type()?);
         }
         let returns_len = self.read_var_u32()? as usize;
         if returns_len > MAX_WASM_FUNCTION_RETURNS {
             return Err(BinaryReaderError {
-                message: "function params size is out of bound",
+                message: "function returns size is out of bound",
                 offset: self.original_position() - 1,
             });
         }
         let mut returns: Vec<Type> = Vec::with_capacity(returns_len);
         for _ in 0..returns_len {
             returns.push(self.read_type()?);
         }
         Ok(FuncType {
@@ -512,16 +512,33 @@ impl<'a> BinaryReader<'a> {
             if (byte & 0x80) == 0 {
                 break;
             }
         }
         let ashift = 32 - shift;
         Ok((result << ashift) >> ashift)
     }
 
+    pub fn read_var_s33(&mut self) -> Result<i64> {
+        // Note: this is not quite spec compliant, in that it doesn't enforce
+        // that the number is encoded in ceil(N / 7) bytes. We should make a
+        // generic-over-N decoding function and replace all the various
+        // `read_var_{i,s}NN` methods with calls to instantiations of that.
+
+        let n = self.read_var_i64()?;
+        if n > (1 << 33 - 1) {
+            Err(BinaryReaderError {
+                message: "Invalid var_s33",
+                offset: self.original_position() - 1,
+            })
+        } else {
+            Ok(n)
+        }
+    }
+
     pub fn read_var_i64(&mut self) -> Result<i64> {
         let mut result: i64 = 0;
         let mut shift = 0;
         loop {
             let byte = self.read_u8()?;
             result |= i64::from(byte & 0x7F) << shift;
             if shift >= 57 {
                 let continuation_bit = (byte & 0x80) != 0;
@@ -785,29 +802,46 @@ impl<'a> BinaryReader<'a> {
                 return Err(BinaryReaderError {
                     message: "Unknown 0xFE opcode",
                     offset: self.original_position() - 1,
                 });
             }
         })
     }
 
+    fn read_blocktype(&mut self) -> Result<TypeOrFuncType> {
+        let position = self.position;
+        if let Ok(ty) = self.read_type() {
+            Ok(TypeOrFuncType::Type(ty))
+        } else {
+            self.position = position;
+            let idx = self.read_var_s33()?;
+            if idx < 0 || idx > (::std::u32::MAX as i64) {
+                return Err(BinaryReaderError {
+                    message: "invalid function type",
+                    offset: position,
+                });
+            }
+            Ok(TypeOrFuncType::FuncType(idx as u32))
+        }
+    }
+
     pub fn read_operator(&mut self) -> Result<Operator<'a>> {
         let code = self.read_u8()? as u8;
         Ok(match code {
             0x00 => Operator::Unreachable,
             0x01 => Operator::Nop,
             0x02 => Operator::Block {
-                ty: self.read_type()?,
+                ty: self.read_blocktype()?,
             },
             0x03 => Operator::Loop {
-                ty: self.read_type()?,
+                ty: self.read_blocktype()?,
             },
             0x04 => Operator::If {
-                ty: self.read_type()?,
+                ty: self.read_blocktype()?,
             },
             0x05 => Operator::Else,
             0x0b => Operator::End,
             0x0c => Operator::Br {
                 relative_depth: self.read_var_u32()?,
             },
             0x0d => Operator::BrIf {
                 relative_depth: self.read_var_u32()?,
--- a/third_party/rust/wasmparser/src/lib.rs
+++ b/third_party/rust/wasmparser/src/lib.rs
@@ -19,17 +19,16 @@
 //! The parser library reports events as they happend and only stores
 //! parsing information for a brief period of time, making it very fast
 //! and memory-efficient. The event-driven model, however, has some drawbacks.
 //! If you need random access to the entire WebAssembly data-structure,
 //! this is not the right library for you. You could however, build such
 //! a data-structure using this library.
 
 #![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 
 #[cfg(not(feature = "std"))]
 extern crate hashmap_core;
 
 #[cfg(not(feature = "std"))]
 #[macro_use]
 extern crate alloc;
 
@@ -61,24 +60,27 @@ pub use primitives::NameType;
 pub use primitives::Naming;
 pub use primitives::Operator;
 pub use primitives::RelocType;
 pub use primitives::ResizableLimits;
 pub use primitives::Result;
 pub use primitives::SectionCode;
 pub use primitives::TableType;
 pub use primitives::Type;
+pub use primitives::TypeOrFuncType;
 pub use primitives::V128;
 
 pub use validator::validate;
-pub use validator::OperatorValidatorConfig;
+pub use validator::validate_function_body;
 pub use validator::ValidatingOperatorParser;
 pub use validator::ValidatingParser;
 pub use validator::ValidatingParserConfig;
-pub use validator::WasmModuleResources;
+
+pub use operators_validator::OperatorValidatorConfig;
+pub use operators_validator::WasmModuleResources;
 
 pub use readers::CodeSectionReader;
 pub use readers::Data;
 pub use readers::DataKind;
 pub use readers::DataSectionReader;
 pub use readers::Element;
 pub use readers::ElementItems;
 pub use readers::ElementItemsReader;
@@ -111,22 +113,23 @@ pub use readers::SectionIterator;
 pub use readers::SectionIteratorLimited;
 pub use readers::SectionReader;
 pub use readers::SectionWithLimitedItems;
 pub use readers::TableSectionReader;
 pub use readers::TypeSectionReader;
 
 mod binary_reader;
 mod limits;
+mod operators_validator;
 mod parser;
 mod primitives;
 mod readers;
 mod tests;
 mod validator;
 
 #[cfg(not(feature = "std"))]
 mod std {
-    pub use alloc::{boxed, vec};
+    pub use alloc::{boxed, string, vec};
     pub use core::*;
     pub mod collections {
         pub use hashmap_core::HashSet;
     }
 }
--- a/third_party/rust/wasmparser/src/limits.rs
+++ b/third_party/rust/wasmparser/src/limits.rs
@@ -22,14 +22,13 @@ pub const _MAX_WASM_EXPORTS: usize = 100
 pub const MAX_WASM_GLOBALS: usize = 1000000;
 pub const _MAX_WASM_DATA_SEGMENTS: usize = 100000;
 pub const MAX_WASM_MEMORY_PAGES: usize = 65536;
 pub const MAX_WASM_STRING_SIZE: usize = 100000;
 pub const _MAX_WASM_MODULE_SIZE: usize = 1024 * 1024 * 1024; //= 1 GiB
 pub const MAX_WASM_FUNCTION_SIZE: usize = 128 * 1024;
 pub const MAX_WASM_FUNCTION_LOCALS: usize = 50000;
 pub const MAX_WASM_FUNCTION_PARAMS: usize = 1000;
-pub const _MAX_WASM_FUNCTION_MULTI_RETURNS: usize = 1000;
-pub const MAX_WASM_FUNCTION_RETURNS: usize = 1;
+pub const MAX_WASM_FUNCTION_RETURNS: usize = 1000;
 pub const _MAX_WASM_TABLE_SIZE: usize = 10000000;
 pub const MAX_WASM_TABLE_ENTRIES: usize = 10000000;
 pub const MAX_WASM_TABLES: usize = 1;
 pub const MAX_WASM_MEMORIES: usize = 1;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/wasmparser/src/operators_validator.rs
@@ -0,0 +1,1577 @@
+/* Copyright 2019 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use std::cmp::min;
+use std::result;
+use std::str;
+use std::vec::Vec;
+
+use primitives::{
+    FuncType, GlobalType, MemoryImmediate, MemoryType, Operator, SIMDLineIndex, TableType, Type,
+    TypeOrFuncType,
+};
+
+/// Test if `subtype` is a subtype of `supertype`.
+fn is_subtype_supertype(subtype: Type, supertype: Type) -> bool {
+    match supertype {
+        Type::AnyRef => subtype == Type::AnyRef || subtype == Type::AnyFunc,
+        _ => subtype == supertype,
+    }
+}
+
+#[derive(Debug)]
+struct BlockState {
+    start_types: Vec<Type>,
+    return_types: Vec<Type>,
+    stack_starts_at: usize,
+    jump_to_top: bool,
+    is_else_allowed: bool,
+    is_dead_code: bool,
+    polymorphic_values: Option<usize>,
+}
+
+impl BlockState {
+    fn is_stack_polymorphic(&self) -> bool {
+        self.polymorphic_values.is_some()
+    }
+}
+
+#[derive(Debug)]
+struct FuncState {
+    local_types: Vec<Type>,
+    blocks: Vec<BlockState>,
+    stack_types: Vec<Type>,
+    end_function: bool,
+}
+
+impl FuncState {
+    fn block_at(&self, depth: usize) -> &BlockState {
+        assert!(depth < self.blocks.len());
+        &self.blocks[self.blocks.len() - 1 - depth]
+    }
+    fn last_block(&self) -> &BlockState {
+        self.blocks.last().unwrap()
+    }
+    fn assert_stack_type_at(&self, index: usize, expected: Type) -> bool {
+        let stack_starts_at = self.last_block().stack_starts_at;
+        if self.last_block().is_stack_polymorphic()
+            && stack_starts_at + index >= self.stack_types.len()
+        {
+            return true;
+        }
+        assert!(stack_starts_at + index < self.stack_types.len());
+        is_subtype_supertype(
+            self.stack_types[self.stack_types.len() - 1 - index],
+            expected,
+        )
+    }
+    fn assert_block_stack_len(&self, depth: usize, minimal_len: usize) -> bool {
+        assert!(depth < self.blocks.len());
+        let blocks_end = self.blocks.len();
+        let block_offset = blocks_end - 1 - depth;
+        for i in block_offset..blocks_end {
+            if self.blocks[i].is_stack_polymorphic() {
+                return true;
+            }
+        }
+        let block_starts_at = self.blocks[block_offset].stack_starts_at;
+        self.stack_types.len() >= block_starts_at + minimal_len
+    }
+    fn assert_last_block_stack_len_exact(&self, len: usize) -> bool {
+        let block_starts_at = self.last_block().stack_starts_at;
+        if self.last_block().is_stack_polymorphic() {
+            let polymorphic_values = self.last_block().polymorphic_values.unwrap();
+            self.stack_types.len() + polymorphic_values <= block_starts_at + len
+        } else {
+            self.stack_types.len() == block_starts_at + len
+        }
+    }
+    fn remove_frame_stack_types(&mut self, remove_count: usize) -> OperatorValidatorResult<()> {
+        if remove_count == 0 {
+            return Ok(());
+        }
+        let last_block = self.blocks.last_mut().unwrap();
+        if last_block.is_stack_polymorphic() {
+            let len = self.stack_types.len();
+            let remove_non_polymorphic = len
+                .checked_sub(last_block.stack_starts_at)
+                .ok_or("invalid block signature")?
+                .min(remove_count);
+            self.stack_types.truncate(len - remove_non_polymorphic);
+            let polymorphic_values = last_block.polymorphic_values.unwrap();
+            let remove_polymorphic = min(remove_count - remove_non_polymorphic, polymorphic_values);
+            last_block.polymorphic_values = Some(polymorphic_values - remove_polymorphic);
+        } else {
+            assert!(self.stack_types.len() >= last_block.stack_starts_at + remove_count);
+            let keep = self.stack_types.len() - remove_count;
+            self.stack_types.truncate(keep);
+        }
+        Ok(())
+    }
+    fn push_block(
+        &mut self,
+        ty: TypeOrFuncType,
+        block_type: BlockType,
+        resources: &dyn WasmModuleResources,
+    ) -> OperatorValidatorResult<()> {
+        let (start_types, return_types) = match ty {
+            TypeOrFuncType::Type(Type::EmptyBlockType) => (vec![], vec![]),
+            TypeOrFuncType::Type(ty) => (vec![], vec![ty]),
+            TypeOrFuncType::FuncType(idx) => {
+                let ty = &resources.types()[idx as usize];
+                (ty.params.clone().into_vec(), ty.returns.clone().into_vec())
+            }
+        };
+        if block_type == BlockType::If {
+            self.stack_types.pop();
+        }
+        for (i, ty) in start_types.iter().rev().enumerate() {
+            if !self.assert_stack_type_at(i, *ty) {
+                return Err("stack operand type mismatch");
+            }
+        }
+        let stack_starts_at = self.stack_types.len() - start_types.len();
+        self.blocks.push(BlockState {
+            start_types,
+            return_types,
+            stack_starts_at,
+            jump_to_top: block_type == BlockType::Loop,
+            is_else_allowed: block_type == BlockType::If,
+            is_dead_code: false,
+            polymorphic_values: None,
+        });
+        Ok(())
+    }
+    fn pop_block(&mut self) {
+        assert!(self.blocks.len() > 1);
+        let last_block = self.blocks.pop().unwrap();
+        if last_block.is_stack_polymorphic() {
+            assert!(
+                self.stack_types.len()
+                    <= last_block.return_types.len() + last_block.stack_starts_at
+            );
+        } else {
+            assert!(
+                self.stack_types.len()
+                    == last_block.return_types.len() + last_block.stack_starts_at
+            );
+        }
+        let keep = last_block.stack_starts_at;
+        self.stack_types.truncate(keep);
+        self.stack_types.extend_from_slice(&last_block.return_types);
+    }
+    fn reset_block(&mut self) {
+        assert!(self.last_block().is_else_allowed);
+        let last_block = self.blocks.last_mut().unwrap();
+        let keep = last_block.stack_starts_at;
+        self.stack_types.truncate(keep);
+        self.stack_types
+            .extend(last_block.start_types.iter().cloned());
+        last_block.is_else_allowed = false;
+        last_block.polymorphic_values = None;
+    }
+    fn change_frame(&mut self, remove_count: usize) -> OperatorValidatorResult<()> {
+        self.remove_frame_stack_types(remove_count)
+    }
+    fn change_frame_with_type(
+        &mut self,
+        remove_count: usize,
+        ty: Type,
+    ) -> OperatorValidatorResult<()> {
+        self.remove_frame_stack_types(remove_count)?;
+        self.stack_types.push(ty);
+        Ok(())
+    }
+    fn change_frame_with_types(
+        &mut self,
+        remove_count: usize,
+        new_items: &[Type],
+    ) -> OperatorValidatorResult<()> {
+        self.remove_frame_stack_types(remove_count)?;
+        if new_items.is_empty() {
+            return Ok(());
+        }
+        self.stack_types.extend_from_slice(new_items);
+        Ok(())
+    }
+    fn change_frame_to_exact_types_from(&mut self, depth: usize) -> OperatorValidatorResult<()> {
+        let types = self.block_at(depth).return_types.clone();
+        let last_block = self.blocks.last_mut().unwrap();
+        let keep = last_block.stack_starts_at;
+        self.stack_types.truncate(keep);
+        self.stack_types.extend_from_slice(&types);
+        last_block.polymorphic_values = None;
+        Ok(())
+    }
+    fn change_frame_after_select(&mut self, ty: Option<Type>) -> OperatorValidatorResult<()> {
+        self.remove_frame_stack_types(3)?;
+        if ty.is_none() {
+            let last_block = self.blocks.last_mut().unwrap();
+            assert!(last_block.is_stack_polymorphic());
+            last_block.polymorphic_values = Some(last_block.polymorphic_values.unwrap() + 1);
+            return Ok(());
+        }
+        self.stack_types.push(ty.unwrap());
+        Ok(())
+    }
+    fn start_dead_code(&mut self) {
+        let last_block = self.blocks.last_mut().unwrap();
+        let keep = last_block.stack_starts_at;
+        self.stack_types.truncate(keep);
+        last_block.is_dead_code = true;
+        last_block.polymorphic_values = Some(0);
+    }
+    fn end_function(&mut self) {
+        self.end_function = true;
+    }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+enum BlockType {
+    Block,
+    Loop,
+    If,
+}
+
+pub trait WasmModuleResources {
+    fn types(&self) -> &[FuncType];
+    fn tables(&self) -> &[TableType];
+    fn memories(&self) -> &[MemoryType];
+    fn globals(&self) -> &[GlobalType];
+    fn func_type_indices(&self) -> &[u32];
+    fn element_count(&self) -> u32;
+    fn data_count(&self) -> u32;
+}
+
+pub enum FunctionEnd {
+    No,
+    Yes,
+}
+
+type OperatorValidatorResult<T> = result::Result<T, &'static str>;
+
+#[derive(Copy, Clone, Debug)]
+pub struct OperatorValidatorConfig {
+    pub enable_threads: bool,
+    pub enable_reference_types: bool,
+    pub enable_simd: bool,
+    pub enable_bulk_memory: bool,
+    pub enable_multi_value: bool,
+}
+
+pub(crate) const DEFAULT_OPERATOR_VALIDATOR_CONFIG: OperatorValidatorConfig =
+    OperatorValidatorConfig {
+        enable_threads: false,
+        enable_reference_types: false,
+        enable_simd: false,
+        enable_bulk_memory: false,
+        enable_multi_value: false,
+    };
+
+#[derive(Debug)]
+pub(crate) struct OperatorValidator {
+    func_state: FuncState,
+    config: OperatorValidatorConfig,
+}
+
+impl OperatorValidator {
+    pub fn new(
+        func_type: &FuncType,
+        locals: &[(u32, Type)],
+        config: OperatorValidatorConfig,
+    ) -> OperatorValidator {
+        let mut local_types = Vec::new();
+        local_types.extend_from_slice(&*func_type.params);
+        for local in locals {
+            for _ in 0..local.0 {
+                local_types.push(local.1);
+            }
+        }
+
+        let mut blocks = Vec::new();
+        let mut last_returns = Vec::new();
+        last_returns.extend_from_slice(&*func_type.returns);
+        blocks.push(BlockState {
+            start_types: vec![],
+            return_types: last_returns,
+            stack_starts_at: 0,
+            jump_to_top: false,
+            is_else_allowed: false,
+            is_dead_code: false,
+            polymorphic_values: None,
+        });
+
+        OperatorValidator {
+            func_state: FuncState {
+                local_types,
+                blocks,
+                stack_types: Vec::new(),
+                end_function: false,
+            },
+            config,
+        }
+    }
+
+    pub fn is_dead_code(&self) -> bool {
+        self.func_state.last_block().is_dead_code
+    }
+
+    fn check_frame_size(&self, require_count: usize) -> OperatorValidatorResult<()> {
+        if !self.func_state.assert_block_stack_len(0, require_count) {
+            Err("not enough operands")
+        } else {
+            Ok(())
+        }
+    }
+
+    fn check_operands_1(&self, operand: Type) -> OperatorValidatorResult<()> {
+        self.check_frame_size(1)?;
+        if !self.func_state.assert_stack_type_at(0, operand) {
+            return Err("stack operand type mismatch");
+        }
+        Ok(())
+    }
+
+    fn check_operands_2(&self, operand1: Type, operand2: Type) -> OperatorValidatorResult<()> {
+        self.check_frame_size(2)?;
+        if !self.func_state.assert_stack_type_at(1, operand1) {
+            return Err("stack operand type mismatch");
+        }
+        if !self.func_state.assert_stack_type_at(0, operand2) {
+            return Err("stack operand type mismatch");
+        }
+        Ok(())
+    }
+
+    fn check_operands(&self, expected_types: &[Type]) -> OperatorValidatorResult<()> {
+        let len = expected_types.len();
+        self.check_frame_size(len)?;
+        for i in 0..len {
+            if !self
+                .func_state
+                .assert_stack_type_at(len - 1 - i, expected_types[i])
+            {
+                return Err("stack operand type mismatch");
+            }
+        }
+        Ok(())
+    }
+
+    fn check_block_return_types(
+        &self,
+        block: &BlockState,
+        reserve_items: usize,
+    ) -> OperatorValidatorResult<()> {
+        if !self.config.enable_multi_value && block.return_types.len() > 1 {
+            return Err("blocks, loops, and ifs may only return at most one \
+                        value when multi-value is not enabled");
+        }
+        let len = block.return_types.len();
+        for i in 0..len {
+            if !self
+                .func_state
+                .assert_stack_type_at(len - 1 - i + reserve_items, block.return_types[i])
+            {
+                return Err("stack item type does not match block item type");
+            }
+        }
+        Ok(())
+    }
+
+    fn check_block_return(&self) -> OperatorValidatorResult<()> {
+        let len = self.func_state.last_block().return_types.len();
+        if !self.func_state.assert_last_block_stack_len_exact(len) {
+            return Err("stack size does not match block type");
+        }
+        self.check_block_return_types(self.func_state.last_block(), 0)
+    }
+
+    fn check_jump_from_block(
+        &self,
+        relative_depth: u32,
+        reserve_items: usize,
+    ) -> OperatorValidatorResult<()> {
+        if relative_depth as usize >= self.func_state.blocks.len() {
+            return Err("invalid block depth");
+        }
+        let block = self.func_state.block_at(relative_depth as usize);
+        if block.jump_to_top {
+            if !self.func_state.assert_block_stack_len(0, reserve_items) {
+                return Err("stack size does not match target loop type");
+            }
+            return Ok(());
+        }
+
+        let len = block.return_types.len();
+        if !self
+            .func_state
+            .assert_block_stack_len(0, len + reserve_items)
+        {
+            return Err("stack size does not match target block type");
+        }
+        self.check_block_return_types(block, reserve_items)
+    }
+
+    fn match_block_return(&self, depth1: u32, depth2: u32) -> OperatorValidatorResult<()> {
+        if depth1 as usize >= self.func_state.blocks.len() {
+            return Err("invalid block depth");
+        }
+        if depth2 as usize >= self.func_state.blocks.len() {
+            return Err("invalid block depth");
+        }
+        let block1 = self.func_state.block_at(depth1 as usize);
+        let block2 = self.func_state.block_at(depth2 as usize);
+        let return_types1 = &block1.return_types;
+        let return_types2 = &block2.return_types;
+        if block1.jump_to_top || block2.jump_to_top {
+            if block1.jump_to_top {
+                if !block2.jump_to_top && !return_types2.is_empty() {
+                    return Err("block types do not match");
+                }
+            } else if !return_types1.is_empty() {
+                return Err("block types do not match");
+            }
+        } else if *return_types1 != *return_types2 {
+            return Err("block types do not match");
+        }
+        Ok(())
+    }
+
+    fn check_memory_index(
+        &self,
+        memory_index: u32,
+        resources: &dyn WasmModuleResources,
+    ) -> OperatorValidatorResult<()> {
+        if memory_index as usize >= resources.memories().len() {
+            return Err("no liner memories are present");
+        }
+        Ok(())
+    }
+
+    fn check_shared_memory_index(
+        &self,
+        memory_index: u32,
+        resources: &dyn WasmModuleResources,
+    ) -> OperatorValidatorResult<()> {
+        if memory_index as usize >= resources.memories().len() {
+            return Err("no liner memories are present");
+        }
+        if !resources.memories()[memory_index as usize].shared {
+            return Err("atomic accesses require shared memory");
+        }
+        Ok(())
+    }
+
+    fn check_memarg(
+        &self,
+        memarg: &MemoryImmediate,
+        max_align: u32,
+        resources: &dyn WasmModuleResources,
+    ) -> OperatorValidatorResult<()> {
+        self.check_memory_index(0, resources)?;
+        let align = memarg.flags;
+        if align > max_align {
+            return Err("align is required to be at most the number of accessed bytes");
+        }
+        Ok(())
+    }
+
+    fn check_threads_enabled(&self) -> OperatorValidatorResult<()> {
+        if !self.config.enable_threads {
+            return Err("threads support is not enabled");
+        }
+        Ok(())
+    }
+
+    fn check_reference_types_enabled(&self) -> OperatorValidatorResult<()> {
+        if !self.config.enable_reference_types {
+            return Err("reference types support is not enabled");
+        }
+        Ok(())
+    }
+
+    fn check_simd_enabled(&self) -> OperatorValidatorResult<()> {
+        if !self.config.enable_simd {
+            return Err("SIMD support is not enabled");
+        }
+        Ok(())
+    }
+
+    fn check_bulk_memory_enabled(&self) -> OperatorValidatorResult<()> {
+        if !self.config.enable_bulk_memory {
+            return Err("bulk memory support is not enabled");
+        }
+        Ok(())
+    }
+
+    fn check_shared_memarg_wo_align(
+        &self,
+        _: &MemoryImmediate,
+        resources: &dyn WasmModuleResources,
+    ) -> OperatorValidatorResult<()> {
+        self.check_shared_memory_index(0, resources)?;
+        Ok(())
+    }
+
+    fn check_simd_line_index(&self, index: SIMDLineIndex, max: u8) -> OperatorValidatorResult<()> {
+        if index >= max {
+            return Err("SIMD index out of bounds");
+        }
+        Ok(())
+    }
+
+    fn check_block_type(
+        &self,
+        ty: TypeOrFuncType,
+        resources: &dyn WasmModuleResources,
+    ) -> OperatorValidatorResult<()> {
+        match ty {
+            TypeOrFuncType::Type(Type::EmptyBlockType)
+            | TypeOrFuncType::Type(Type::I32)
+            | TypeOrFuncType::Type(Type::I64)
+            | TypeOrFuncType::Type(Type::F32)
+            | TypeOrFuncType::Type(Type::F64) => Ok(()),
+            TypeOrFuncType::FuncType(idx) => {
+                let idx = idx as usize;
+                let types = resources.types();
+                if idx >= types.len() {
+                    return Err("type index out of bounds");
+                }
+                Ok(())
+            }
+            _ => Err("invalid block return type"),
+        }
+    }
+
+    fn check_select(&self) -> OperatorValidatorResult<Option<Type>> {
+        self.check_frame_size(3)?;
+        let func_state = &self.func_state;
+        let last_block = func_state.last_block();
+        Ok(if last_block.is_stack_polymorphic() {
+            match func_state.stack_types.len() - last_block.stack_starts_at {
+                0 => None,
+                1 => {
+                    self.check_operands_1(Type::I32)?;
+                    None
+                }
+                2 => {
+                    self.check_operands_1(Type::I32)?;
+                    Some(func_state.stack_types[func_state.stack_types.len() - 2])
+                }
+                _ => {
+                    let ty = func_state.stack_types[func_state.stack_types.len() - 3];
+                    self.check_operands_2(ty, Type::I32)?;
+                    Some(ty)
+                }
+            }
+        } else {
+            let ty = func_state.stack_types[func_state.stack_types.len() - 3];
+            self.check_operands_2(ty, Type::I32)?;
+            Some(ty)
+        })
+    }
+
+    pub(crate) fn process_operator(
+        &mut self,
+        operator: &Operator,
+        resources: &dyn WasmModuleResources,
+    ) -> OperatorValidatorResult<FunctionEnd> {
+        if self.func_state.end_function {
+            return Err("unexpected operator");
+        }
+        match *operator {
+            Operator::Unreachable => self.func_state.start_dead_code(),
+            Operator::Nop => (),
+            Operator::Block { ty } => {
+                self.check_block_type(ty, resources)?;
+                self.func_state
+                    .push_block(ty, BlockType::Block, resources)?;
+            }
+            Operator::Loop { ty } => {
+                self.check_block_type(ty, resources)?;
+                self.func_state.push_block(ty, BlockType::Loop, resources)?;
+            }
+            Operator::If { ty } => {
+                self.check_block_type(ty, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.push_block(ty, BlockType::If, resources)?;
+            }
+            Operator::Else => {
+                if !self.func_state.last_block().is_else_allowed {
+                    return Err("unexpected else: if block is not started");
+                }
+                self.check_block_return()?;
+                self.func_state.reset_block()
+            }
+            Operator::End => {
+                self.check_block_return()?;
+                if self.func_state.blocks.len() == 1 {
+                    self.func_state.end_function();
+                    return Ok(FunctionEnd::Yes);
+                }
+                if {
+                    let last_block = &self.func_state.last_block();
+                    last_block.is_else_allowed && !last_block.return_types.is_empty()
+                } {
+                    return Err("else is expected: if block has type");
+                }
+                self.func_state.pop_block()
+            }
+            Operator::Br { relative_depth } => {
+                self.check_jump_from_block(relative_depth, 0)?;
+                self.func_state.start_dead_code()
+            }
+            Operator::BrIf { relative_depth } => {
+                self.check_operands_1(Type::I32)?;
+                self.check_jump_from_block(relative_depth, 1)?;
+                if self.func_state.last_block().is_stack_polymorphic() {
+                    self.func_state
+                        .change_frame_to_exact_types_from(relative_depth as usize)?;
+                } else {
+                    self.func_state.change_frame(1)?;
+                }
+            }
+            Operator::BrTable { ref table } => {
+                self.check_operands_1(Type::I32)?;
+                let mut depth0: Option<u32> = None;
+                for relative_depth in table {
+                    if depth0.is_none() {
+                        self.check_jump_from_block(relative_depth, 1)?;
+                        depth0 = Some(relative_depth);
+                        continue;
+                    }
+                    self.match_block_return(relative_depth, depth0.unwrap())?;
+                }
+                self.func_state.start_dead_code()
+            }
+            Operator::Return => {
+                let depth = (self.func_state.blocks.len() - 1) as u32;
+                self.check_jump_from_block(depth, 0)?;
+                self.func_state.start_dead_code()
+            }
+            Operator::Call { function_index } => {
+                if function_index as usize >= resources.func_type_indices().len() {
+                    return Err("function index out of bounds");
+                }
+                let type_index = resources.func_type_indices()[function_index as usize];
+                let ty = &resources.types()[type_index as usize];
+                self.check_operands(&ty.params)?;
+                self.func_state
+                    .change_frame_with_types(ty.params.len(), &ty.returns)?;
+            }
+            Operator::CallIndirect { index, table_index } => {
+                if table_index as usize >= resources.tables().len() {
+                    return Err("table index out of bounds");
+                }
+                if index as usize >= resources.types().len() {
+                    return Err("type index out of bounds");
+                }
+                let ty = &resources.types()[index as usize];
+                let mut types = Vec::with_capacity(ty.params.len() + 1);
+                types.extend_from_slice(&ty.params);
+                types.push(Type::I32);
+                self.check_operands(&types)?;
+                self.func_state
+                    .change_frame_with_types(ty.params.len() + 1, &ty.returns)?;
+            }
+            Operator::Drop => {
+                self.check_frame_size(1)?;
+                self.func_state.change_frame(1)?;
+            }
+            Operator::Select => {
+                let ty = self.check_select()?;
+                self.func_state.change_frame_after_select(ty)?;
+            }
+            Operator::GetLocal { local_index } => {
+                if local_index as usize >= self.func_state.local_types.len() {
+                    return Err("local index out of bounds");
+                }
+                let local_type = self.func_state.local_types[local_index as usize];
+                self.func_state.change_frame_with_type(0, local_type)?;
+            }
+            Operator::SetLocal { local_index } => {
+                if local_index as usize >= self.func_state.local_types.len() {
+                    return Err("local index out of bounds");
+                }
+                let local_type = self.func_state.local_types[local_index as usize];
+                self.check_operands_1(local_type)?;
+                self.func_state.change_frame(1)?;
+            }
+            Operator::TeeLocal { local_index } => {
+                if local_index as usize >= self.func_state.local_types.len() {
+                    return Err("local index out of bounds");
+                }
+                let local_type = self.func_state.local_types[local_index as usize];
+                self.check_operands_1(local_type)?;
+                self.func_state.change_frame_with_type(1, local_type)?;
+            }
+            Operator::GetGlobal { global_index } => {
+                if global_index as usize >= resources.globals().len() {
+                    return Err("global index out of bounds");
+                }
+                let ty = &resources.globals()[global_index as usize];
+                self.func_state.change_frame_with_type(0, ty.content_type)?;
+            }
+            Operator::SetGlobal { global_index } => {
+                if global_index as usize >= resources.globals().len() {
+                    return Err("global index out of bounds");
+                }
+                let ty = &resources.globals()[global_index as usize];
+                // FIXME
+                //    if !ty.mutable {
+                //        return self.create_error("global expected to be mutable");
+                //    }
+                self.check_operands_1(ty.content_type)?;
+                self.func_state.change_frame(1)?;
+            }
+            Operator::I32Load { ref memarg } => {
+                self.check_memarg(memarg, 2, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I64Load { ref memarg } => {
+                self.check_memarg(memarg, 3, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::F32Load { ref memarg } => {
+                self.check_memarg(memarg, 2, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::F32)?;
+            }
+            Operator::F64Load { ref memarg } => {
+                self.check_memarg(memarg, 3, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::F64)?;
+            }
+            Operator::I32Load8S { ref memarg } => {
+                self.check_memarg(memarg, 0, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32Load8U { ref memarg } => {
+                self.check_memarg(memarg, 0, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32Load16S { ref memarg } => {
+                self.check_memarg(memarg, 1, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32Load16U { ref memarg } => {
+                self.check_memarg(memarg, 1, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I64Load8S { ref memarg } => {
+                self.check_memarg(memarg, 0, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64Load8U { ref memarg } => {
+                self.check_memarg(memarg, 0, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64Load16S { ref memarg } => {
+                self.check_memarg(memarg, 1, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64Load16U { ref memarg } => {
+                self.check_memarg(memarg, 1, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64Load32S { ref memarg } => {
+                self.check_memarg(memarg, 2, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64Load32U { ref memarg } => {
+                self.check_memarg(memarg, 2, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I32Store { ref memarg } => {
+                self.check_memarg(memarg, 2, resources)?;
+                self.check_operands_2(Type::I32, Type::I32)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::I64Store { ref memarg } => {
+                self.check_memarg(memarg, 3, resources)?;
+                self.check_operands_2(Type::I32, Type::I64)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::F32Store { ref memarg } => {
+                self.check_memarg(memarg, 2, resources)?;
+                self.check_operands_2(Type::I32, Type::F32)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::F64Store { ref memarg } => {
+                self.check_memarg(memarg, 3, resources)?;
+                self.check_operands_2(Type::I32, Type::F64)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::I32Store8 { ref memarg } => {
+                self.check_memarg(memarg, 0, resources)?;
+                self.check_operands_2(Type::I32, Type::I32)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::I32Store16 { ref memarg } => {
+                self.check_memarg(memarg, 1, resources)?;
+                self.check_operands_2(Type::I32, Type::I32)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::I64Store8 { ref memarg } => {
+                self.check_memarg(memarg, 0, resources)?;
+                self.check_operands_2(Type::I32, Type::I64)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::I64Store16 { ref memarg } => {
+                self.check_memarg(memarg, 1, resources)?;
+                self.check_operands_2(Type::I32, Type::I64)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::I64Store32 { ref memarg } => {
+                self.check_memarg(memarg, 2, resources)?;
+                self.check_operands_2(Type::I32, Type::I64)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::MemorySize {
+                reserved: memory_index,
+            } => {
+                self.check_memory_index(memory_index, resources)?;
+                self.func_state.change_frame_with_type(0, Type::I32)?;
+            }
+            Operator::MemoryGrow {
+                reserved: memory_index,
+            } => {
+                self.check_memory_index(memory_index, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32Const { .. } => self.func_state.change_frame_with_type(0, Type::I32)?,
+            Operator::I64Const { .. } => self.func_state.change_frame_with_type(0, Type::I64)?,
+            Operator::F32Const { .. } => self.func_state.change_frame_with_type(0, Type::F32)?,
+            Operator::F64Const { .. } => self.func_state.change_frame_with_type(0, Type::F64)?,
+            Operator::I32Eqz => {
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32Eq
+            | Operator::I32Ne
+            | Operator::I32LtS
+            | Operator::I32LtU
+            | Operator::I32GtS
+            | Operator::I32GtU
+            | Operator::I32LeS
+            | Operator::I32LeU
+            | Operator::I32GeS
+            | Operator::I32GeU => {
+                self.check_operands_2(Type::I32, Type::I32)?;
+                self.func_state.change_frame_with_type(2, Type::I32)?;
+            }
+            Operator::I64Eqz => {
+                self.check_operands_1(Type::I64)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I64Eq
+            | Operator::I64Ne
+            | Operator::I64LtS
+            | Operator::I64LtU
+            | Operator::I64GtS
+            | Operator::I64GtU
+            | Operator::I64LeS
+            | Operator::I64LeU
+            | Operator::I64GeS
+            | Operator::I64GeU => {
+                self.check_operands_2(Type::I64, Type::I64)?;
+                self.func_state.change_frame_with_type(2, Type::I32)?;
+            }
+            Operator::F32Eq
+            | Operator::F32Ne
+            | Operator::F32Lt
+            | Operator::F32Gt
+            | Operator::F32Le
+            | Operator::F32Ge => {
+                self.check_operands_2(Type::F32, Type::F32)?;
+                self.func_state.change_frame_with_type(2, Type::I32)?;
+            }
+            Operator::F64Eq
+            | Operator::F64Ne
+            | Operator::F64Lt
+            | Operator::F64Gt
+            | Operator::F64Le
+            | Operator::F64Ge => {
+                self.check_operands_2(Type::F64, Type::F64)?;
+                self.func_state.change_frame_with_type(2, Type::I32)?;
+            }
+            Operator::I32Clz | Operator::I32Ctz | Operator::I32Popcnt => {
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32Add
+            | Operator::I32Sub
+            | Operator::I32Mul
+            | Operator::I32DivS
+            | Operator::I32DivU
+            | Operator::I32RemS
+            | Operator::I32RemU
+            | Operator::I32And
+            | Operator::I32Or
+            | Operator::I32Xor
+            | Operator::I32Shl
+            | Operator::I32ShrS
+            | Operator::I32ShrU
+            | Operator::I32Rotl
+            | Operator::I32Rotr => {
+                self.check_operands_2(Type::I32, Type::I32)?;
+                self.func_state.change_frame_with_type(2, Type::I32)?;
+            }
+            Operator::I64Clz | Operator::I64Ctz | Operator::I64Popcnt => {
+                self.check_operands_1(Type::I64)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64Add
+            | Operator::I64Sub
+            | Operator::I64Mul
+            | Operator::I64DivS
+            | Operator::I64DivU
+            | Operator::I64RemS
+            | Operator::I64RemU
+            | Operator::I64And
+            | Operator::I64Or
+            | Operator::I64Xor
+            | Operator::I64Shl
+            | Operator::I64ShrS
+            | Operator::I64ShrU
+            | Operator::I64Rotl
+            | Operator::I64Rotr => {
+                self.check_operands_2(Type::I64, Type::I64)?;
+                self.func_state.change_frame_with_type(2, Type::I64)?;
+            }
+            Operator::F32Abs
+            | Operator::F32Neg
+            | Operator::F32Ceil
+            | Operator::F32Floor
+            | Operator::F32Trunc
+            | Operator::F32Nearest
+            | Operator::F32Sqrt => {
+                self.check_operands_1(Type::F32)?;
+                self.func_state.change_frame_with_type(1, Type::F32)?;
+            }
+            Operator::F32Add
+            | Operator::F32Sub
+            | Operator::F32Mul
+            | Operator::F32Div
+            | Operator::F32Min
+            | Operator::F32Max
+            | Operator::F32Copysign => {
+                self.check_operands_2(Type::F32, Type::F32)?;
+                self.func_state.change_frame_with_type(2, Type::F32)?;
+            }
+            Operator::F64Abs
+            | Operator::F64Neg
+            | Operator::F64Ceil
+            | Operator::F64Floor
+            | Operator::F64Trunc
+            | Operator::F64Nearest
+            | Operator::F64Sqrt => {
+                self.check_operands_1(Type::F64)?;
+                self.func_state.change_frame_with_type(1, Type::F64)?;
+            }
+            Operator::F64Add
+            | Operator::F64Sub
+            | Operator::F64Mul
+            | Operator::F64Div
+            | Operator::F64Min
+            | Operator::F64Max
+            | Operator::F64Copysign => {
+                self.check_operands_2(Type::F64, Type::F64)?;
+                self.func_state.change_frame_with_type(2, Type::F64)?;
+            }
+            Operator::I32WrapI64 => {
+                self.check_operands_1(Type::I64)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32TruncSF32 | Operator::I32TruncUF32 => {
+                self.check_operands_1(Type::F32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32TruncSF64 | Operator::I32TruncUF64 => {
+                self.check_operands_1(Type::F64)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I64ExtendSI32 | Operator::I64ExtendUI32 => {
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64TruncSF32 | Operator::I64TruncUF32 => {
+                self.check_operands_1(Type::F32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64TruncSF64 | Operator::I64TruncUF64 => {
+                self.check_operands_1(Type::F64)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::F32ConvertSI32 | Operator::F32ConvertUI32 => {
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::F32)?;
+            }
+            Operator::F32ConvertSI64 | Operator::F32ConvertUI64 => {
+                self.check_operands_1(Type::I64)?;
+                self.func_state.change_frame_with_type(1, Type::F32)?;
+            }
+            Operator::F32DemoteF64 => {
+                self.check_operands_1(Type::F64)?;
+                self.func_state.change_frame_with_type(1, Type::F32)?;
+            }
+            Operator::F64ConvertSI32 | Operator::F64ConvertUI32 => {
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::F64)?;
+            }
+            Operator::F64ConvertSI64 | Operator::F64ConvertUI64 => {
+                self.check_operands_1(Type::I64)?;
+                self.func_state.change_frame_with_type(1, Type::F64)?;
+            }
+            Operator::F64PromoteF32 => {
+                self.check_operands_1(Type::F32)?;
+                self.func_state.change_frame_with_type(1, Type::F64)?;
+            }
+            Operator::I32ReinterpretF32 => {
+                self.check_operands_1(Type::F32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I64ReinterpretF64 => {
+                self.check_operands_1(Type::F64)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::F32ReinterpretI32 => {
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::F32)?;
+            }
+            Operator::F64ReinterpretI64 => {
+                self.check_operands_1(Type::I64)?;
+                self.func_state.change_frame_with_type(1, Type::F64)?;
+            }
+            Operator::I32TruncSSatF32 | Operator::I32TruncUSatF32 => {
+                self.check_operands_1(Type::F32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32TruncSSatF64 | Operator::I32TruncUSatF64 => {
+                self.check_operands_1(Type::F64)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I64TruncSSatF32 | Operator::I64TruncUSatF32 => {
+                self.check_operands_1(Type::F32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64TruncSSatF64 | Operator::I64TruncUSatF64 => {
+                self.check_operands_1(Type::F64)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I32Extend16S | Operator::I32Extend8S => {
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+
+            Operator::I64Extend32S | Operator::I64Extend16S | Operator::I64Extend8S => {
+                self.check_operands_1(Type::I64)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+
+            Operator::I32AtomicLoad { ref memarg }
+            | Operator::I32AtomicLoad16U { ref memarg }
+            | Operator::I32AtomicLoad8U { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I64AtomicLoad { ref memarg }
+            | Operator::I64AtomicLoad32U { ref memarg }
+            | Operator::I64AtomicLoad16U { ref memarg }
+            | Operator::I64AtomicLoad8U { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I32AtomicStore { ref memarg }
+            | Operator::I32AtomicStore16 { ref memarg }
+            | Operator::I32AtomicStore8 { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands_2(Type::I32, Type::I32)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::I64AtomicStore { ref memarg }
+            | Operator::I64AtomicStore32 { ref memarg }
+            | Operator::I64AtomicStore16 { ref memarg }
+            | Operator::I64AtomicStore8 { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands_2(Type::I32, Type::I64)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::I32AtomicRmwAdd { ref memarg }
+            | Operator::I32AtomicRmwSub { ref memarg }
+            | Operator::I32AtomicRmwAnd { ref memarg }
+            | Operator::I32AtomicRmwOr { ref memarg }
+            | Operator::I32AtomicRmwXor { ref memarg }
+            | Operator::I32AtomicRmw16UAdd { ref memarg }
+            | Operator::I32AtomicRmw16USub { ref memarg }
+            | Operator::I32AtomicRmw16UAnd { ref memarg }
+            | Operator::I32AtomicRmw16UOr { ref memarg }
+            | Operator::I32AtomicRmw16UXor { ref memarg }
+            | Operator::I32AtomicRmw8UAdd { ref memarg }
+            | Operator::I32AtomicRmw8USub { ref memarg }
+            | Operator::I32AtomicRmw8UAnd { ref memarg }
+            | Operator::I32AtomicRmw8UOr { ref memarg }
+            | Operator::I32AtomicRmw8UXor { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands_2(Type::I32, Type::I32)?;
+                self.func_state.change_frame_with_type(2, Type::I32)?;
+            }
+            Operator::I64AtomicRmwAdd { ref memarg }
+            | Operator::I64AtomicRmwSub { ref memarg }
+            | Operator::I64AtomicRmwAnd { ref memarg }
+            | Operator::I64AtomicRmwOr { ref memarg }
+            | Operator::I64AtomicRmwXor { ref memarg }
+            | Operator::I64AtomicRmw32UAdd { ref memarg }
+            | Operator::I64AtomicRmw32USub { ref memarg }
+            | Operator::I64AtomicRmw32UAnd { ref memarg }
+            | Operator::I64AtomicRmw32UOr { ref memarg }
+            | Operator::I64AtomicRmw32UXor { ref memarg }
+            | Operator::I64AtomicRmw16UAdd { ref memarg }
+            | Operator::I64AtomicRmw16USub { ref memarg }
+            | Operator::I64AtomicRmw16UAnd { ref memarg }
+            | Operator::I64AtomicRmw16UOr { ref memarg }
+            | Operator::I64AtomicRmw16UXor { ref memarg }
+            | Operator::I64AtomicRmw8UAdd { ref memarg }
+            | Operator::I64AtomicRmw8USub { ref memarg }
+            | Operator::I64AtomicRmw8UAnd { ref memarg }
+            | Operator::I64AtomicRmw8UOr { ref memarg }
+            | Operator::I64AtomicRmw8UXor { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands_2(Type::I32, Type::I64)?;
+                self.func_state.change_frame_with_type(2, Type::I64)?;
+            }
+            Operator::I32AtomicRmwXchg { ref memarg }
+            | Operator::I32AtomicRmw16UXchg { ref memarg }
+            | Operator::I32AtomicRmw8UXchg { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands_2(Type::I32, Type::I32)?;
+                self.func_state.change_frame_with_type(2, Type::I32)?;
+            }
+            Operator::I32AtomicRmwCmpxchg { ref memarg }
+            | Operator::I32AtomicRmw16UCmpxchg { ref memarg }
+            | Operator::I32AtomicRmw8UCmpxchg { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands(&[Type::I32, Type::I32, Type::I32])?;
+                self.func_state.change_frame_with_type(3, Type::I32)?;
+            }
+            Operator::I64AtomicRmwXchg { ref memarg }
+            | Operator::I64AtomicRmw32UXchg { ref memarg }
+            | Operator::I64AtomicRmw16UXchg { ref memarg }
+            | Operator::I64AtomicRmw8UXchg { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands_2(Type::I32, Type::I64)?;
+                self.func_state.change_frame_with_type(2, Type::I64)?;
+            }
+            Operator::I64AtomicRmwCmpxchg { ref memarg }
+            | Operator::I64AtomicRmw32UCmpxchg { ref memarg }
+            | Operator::I64AtomicRmw16UCmpxchg { ref memarg }
+            | Operator::I64AtomicRmw8UCmpxchg { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands(&[Type::I32, Type::I64, Type::I64])?;
+                self.func_state.change_frame_with_type(3, Type::I64)?;
+            }
+            Operator::Wake { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands_2(Type::I32, Type::I32)?;
+                self.func_state.change_frame_with_type(2, Type::I32)?;
+            }
+            Operator::I32Wait { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands(&[Type::I32, Type::I32, Type::I64])?;
+                self.func_state.change_frame_with_type(3, Type::I32)?;
+            }
+            Operator::I64Wait { ref memarg } => {
+                self.check_threads_enabled()?;
+                self.check_shared_memarg_wo_align(memarg, resources)?;
+                self.check_operands(&[Type::I32, Type::I64, Type::I64])?;
+                self.func_state.change_frame_with_type(3, Type::I32)?;
+            }
+            Operator::RefNull => {
+                self.check_reference_types_enabled()?;
+                self.func_state.change_frame_with_type(0, Type::AnyRef)?;
+            }
+            Operator::RefIsNull => {
+                self.check_reference_types_enabled()?;
+                self.check_operands(&[Type::AnyRef])?;
+                self.func_state.change_frame_with_type(0, Type::I32)?;
+            }
+            Operator::V128Load { ref memarg } => {
+                self.check_simd_enabled()?;
+                self.check_memarg(memarg, 4, resources)?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::V128)?;
+            }
+            Operator::V128Store { ref memarg } => {
+                self.check_simd_enabled()?;
+                self.check_memarg(memarg, 4, resources)?;
+                self.check_operands_2(Type::I32, Type::V128)?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::V128Const { .. } => {
+                self.check_simd_enabled()?;
+                self.func_state.change_frame_with_type(0, Type::V128)?;
+            }
+            Operator::V8x16Shuffle { ref lines } => {
+                self.check_simd_enabled()?;
+                self.check_operands_2(Type::V128, Type::V128)?;
+                for i in lines {
+                    self.check_simd_line_index(*i, 32)?;
+                }
+                self.func_state.change_frame_with_type(2, Type::V128)?;
+            }
+            Operator::I8x16Splat | Operator::I16x8Splat | Operator::I32x4Splat => {
+                self.check_simd_enabled()?;
+                self.check_operands_1(Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::V128)?;
+            }
+            Operator::I64x2Splat => {
+                self.check_simd_enabled()?;
+                self.check_operands_1(Type::I64)?;
+                self.func_state.change_frame_with_type(1, Type::V128)?;
+            }
+            Operator::F32x4Splat => {
+                self.check_simd_enabled()?;
+                self.check_operands_1(Type::F32)?;
+                self.func_state.change_frame_with_type(1, Type::V128)?;
+            }
+            Operator::F64x2Splat => {
+                self.check_simd_enabled()?;
+                self.check_operands_1(Type::F64)?;
+                self.func_state.change_frame_with_type(1, Type::V128)?;
+            }
+            Operator::I8x16ExtractLaneS { line } | Operator::I8x16ExtractLaneU { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 16)?;
+                self.check_operands_1(Type::V128)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I16x8ExtractLaneS { line } | Operator::I16x8ExtractLaneU { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 8)?;
+                self.check_operands_1(Type::V128)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I32x4ExtractLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 4)?;
+                self.check_operands_1(Type::V128)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I8x16ReplaceLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 16)?;
+                self.check_operands_2(Type::V128, Type::I32)?;
+                self.func_state.change_frame_with_type(2, Type::V128)?;
+            }
+            Operator::I16x8ReplaceLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 8)?;
+                self.check_operands_2(Type::V128, Type::I32)?;
+                self.func_state.change_frame_with_type(2, Type::V128)?;
+            }
+            Operator::I32x4ReplaceLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 4)?;
+                self.check_operands_2(Type::V128, Type::I32)?;
+                self.func_state.change_frame_with_type(2, Type::V128)?;
+            }
+            Operator::I64x2ExtractLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 2)?;
+                self.check_operands_1(Type::V128)?;
+                self.func_state.change_frame_with_type(1, Type::I64)?;
+            }
+            Operator::I64x2ReplaceLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 2)?;
+                self.check_operands_2(Type::V128, Type::I64)?;
+                self.func_state.change_frame_with_type(2, Type::V128)?;
+            }
+            Operator::F32x4ExtractLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 4)?;
+                self.check_operands_1(Type::V128)?;
+                self.func_state.change_frame_with_type(1, Type::F32)?;
+            }
+            Operator::F32x4ReplaceLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 4)?;
+                self.check_operands_2(Type::V128, Type::F32)?;
+                self.func_state.change_frame_with_type(2, Type::V128)?;
+            }
+            Operator::F64x2ExtractLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 2)?;
+                self.check_operands_1(Type::V128)?;
+                self.func_state.change_frame_with_type(1, Type::F64)?;
+            }
+            Operator::F64x2ReplaceLane { line } => {
+                self.check_simd_enabled()?;
+                self.check_simd_line_index(line, 2)?;
+                self.check_operands_2(Type::V128, Type::F64)?;
+                self.func_state.change_frame_with_type(2, Type::V128)?;
+            }
+            Operator::I8x16Eq
+            | Operator::I8x16Ne
+            | Operator::I8x16LtS
+            | Operator::I8x16LtU
+            | Operator::I8x16GtS
+            | Operator::I8x16GtU
+            | Operator::I8x16LeS
+            | Operator::I8x16LeU
+            | Operator::I8x16GeS
+            | Operator::I8x16GeU
+            | Operator::I16x8Eq
+            | Operator::I16x8Ne
+            | Operator::I16x8LtS
+            | Operator::I16x8LtU
+            | Operator::I16x8GtS
+            | Operator::I16x8GtU
+            | Operator::I16x8LeS
+            | Operator::I16x8LeU
+            | Operator::I16x8GeS
+            | Operator::I16x8GeU
+            | Operator::I32x4Eq
+            | Operator::I32x4Ne
+            | Operator::I32x4LtS
+            | Operator::I32x4LtU
+            | Operator::I32x4GtS
+            | Operator::I32x4GtU
+            | Operator::I32x4LeS
+            | Operator::I32x4LeU
+            | Operator::I32x4GeS
+            | Operator::I32x4GeU
+            | Operator::F32x4Eq
+            | Operator::F32x4Ne
+            | Operator::F32x4Lt
+            | Operator::F32x4Gt
+            | Operator::F32x4Le
+            | Operator::F32x4Ge
+            | Operator::F64x2Eq
+            | Operator::F64x2Ne
+            | Operator::F64x2Lt
+            | Operator::F64x2Gt
+            | Operator::F64x2Le
+            | Operator::F64x2Ge
+            | Operator::V128And
+            | Operator::V128Or
+            | Operator::V128Xor
+            | Operator::I8x16Add
+            | Operator::I8x16AddSaturateS
+            | Operator::I8x16AddSaturateU
+            | Operator::I8x16Sub
+            | Operator::I8x16SubSaturateS
+            | Operator::I8x16SubSaturateU
+            | Operator::I8x16Mul
+            | Operator::I16x8Add
+            | Operator::I16x8AddSaturateS
+            | Operator::I16x8AddSaturateU
+            | Operator::I16x8Sub
+            | Operator::I16x8SubSaturateS
+            | Operator::I16x8SubSaturateU
+            | Operator::I16x8Mul
+            | Operator::I32x4Add
+            | Operator::I32x4Sub
+            | Operator::I32x4Mul
+            | Operator::I64x2Add
+            | Operator::I64x2Sub
+            | Operator::F32x4Add
+            | Operator::F32x4Sub
+            | Operator::F32x4Mul
+            | Operator::F32x4Div
+            | Operator::F32x4Min
+            | Operator::F32x4Max
+            | Operator::F64x2Add
+            | Operator::F64x2Sub
+            | Operator::F64x2Mul
+            | Operator::F64x2Div
+            | Operator::F64x2Min
+            | Operator::F64x2Max => {
+                self.check_simd_enabled()?;
+                self.check_operands_2(Type::V128, Type::V128)?;
+                self.func_state.change_frame_with_type(2, Type::V128)?;
+            }
+            Operator::V128Not
+            | Operator::I8x16Neg
+            | Operator::I16x8Neg
+            | Operator::I32x4Neg
+            | Operator::I64x2Neg
+            | Operator::F32x4Abs
+            | Operator::F32x4Neg
+            | Operator::F32x4Sqrt
+            | Operator::F64x2Abs
+            | Operator::F64x2Neg
+            | Operator::F64x2Sqrt
+            | Operator::I32x4TruncSF32x4Sat
+            | Operator::I32x4TruncUF32x4Sat
+            | Operator::I64x2TruncSF64x2Sat
+            | Operator::I64x2TruncUF64x2Sat
+            | Operator::F32x4ConvertSI32x4
+            | Operator::F32x4ConvertUI32x4
+            | Operator::F64x2ConvertSI64x2
+            | Operator::F64x2ConvertUI64x2 => {
+                self.check_simd_enabled()?;
+                self.check_operands_1(Type::V128)?;
+                self.func_state.change_frame_with_type(1, Type::V128)?;
+            }
+            Operator::V128Bitselect => {
+                self.check_simd_enabled()?;
+                self.check_operands(&[Type::V128, Type::V128, Type::V128])?;
+                self.func_state.change_frame_with_type(2, Type::V128)?;
+            }
+            Operator::I8x16AnyTrue
+            | Operator::I8x16AllTrue
+            | Operator::I16x8AnyTrue
+            | Operator::I16x8AllTrue
+            | Operator::I32x4AnyTrue
+            | Operator::I32x4AllTrue
+            | Operator::I64x2AnyTrue
+            | Operator::I64x2AllTrue => {
+                self.check_simd_enabled()?;
+                self.check_operands_1(Type::V128)?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::I8x16Shl
+            | Operator::I8x16ShrS
+            | Operator::I8x16ShrU
+            | Operator::I16x8Shl
+            | Operator::I16x8ShrS
+            | Operator::I16x8ShrU
+            | Operator::I32x4Shl
+            | Operator::I32x4ShrS
+            | Operator::I32x4ShrU
+            | Operator::I64x2Shl
+            | Operator::I64x2ShrS
+            | Operator::I64x2ShrU => {
+                self.check_simd_enabled()?;
+                self.check_operands_2(Type::V128, Type::I32)?;
+                self.func_state.change_frame_with_type(1, Type::V128)?;
+            }
+
+            Operator::MemoryInit { segment } => {
+                self.check_bulk_memory_enabled()?;
+                if segment >= resources.data_count() {
+                    return Err("segment index out of bounds");
+                }
+                self.check_memory_index(0, resources)?;
+                self.check_operands(&[Type::I32, Type::I32, Type::I32])?;
+                self.func_state.change_frame(3)?;
+            }
+            Operator::DataDrop { segment } => {
+                self.check_bulk_memory_enabled()?;
+                if segment >= resources.data_count() {
+                    return Err("segment index out of bounds");
+                }
+            }
+            Operator::MemoryCopy | Operator::MemoryFill => {
+                self.check_bulk_memory_enabled()?;
+                self.check_memory_index(0, resources)?;
+                self.check_operands(&[Type::I32, Type::I32, Type::I32])?;
+                self.func_state.change_frame(3)?;
+            }
+            Operator::TableInit { segment } => {
+                self.check_bulk_memory_enabled()?;
+                if segment >= resources.element_count() {
+                    return Err("segment index out of bounds");
+                }
+                if 0 >= resources.tables().len() {
+                    return Err("table index out of bounds");
+                }
+                self.check_operands(&[Type::I32, Type::I32, Type::I32])?;
+                self.func_state.change_frame(3)?;
+            }
+            Operator::ElemDrop { segment } => {
+                self.check_bulk_memory_enabled()?;
+                if segment >= resources.element_count() {
+                    return Err("segment index out of bounds");
+                }
+            }
+            Operator::TableCopy => {
+                self.check_bulk_memory_enabled()?;
+                if 0 >= resources.tables().len() {
+                    return Err("table index out of bounds");
+                }
+                self.check_operands(&[Type::I32, Type::I32, Type::I32])?;
+                self.func_state.change_frame(3)?;
+            }
+            Operator::TableGet { table } => {
+                self.check_reference_types_enabled()?;
+                if table as usize >= resources.tables().len() {
+                    return Err("table index out of bounds");
+                }
+                self.check_operands(&[Type::I32])?;
+                self.func_state.change_frame_with_type(1, Type::AnyRef)?;
+            }
+            Operator::TableSet { table } => {
+                self.check_reference_types_enabled()?;
+                if table as usize >= resources.tables().len() {
+                    return Err("table index out of bounds");
+                }
+                self.check_operands(&[Type::I32, Type::AnyRef])?;
+                self.func_state.change_frame(2)?;
+            }
+            Operator::TableGrow { table } => {
+                self.check_reference_types_enabled()?;
+                if table as usize >= resources.tables().len() {
+                    return Err("table index out of bounds");
+                }
+                self.check_operands(&[Type::I32])?;
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+            Operator::TableSize { table } => {
+                self.check_reference_types_enabled()?;
+                if table as usize >= resources.tables().len() {
+                    return Err("table index out of bounds");
+                }
+                self.func_state.change_frame_with_type(1, Type::I32)?;
+            }
+        }
+        Ok(FunctionEnd::No)
+    }
+
+    pub(crate) fn process_end_function(&self) -> OperatorValidatorResult<()> {
+        if !self.func_state.end_function {
+            return Err("expected end of function");
+        }
+        Ok(())
+    }
+}
--- a/third_party/rust/wasmparser/src/parser.rs
+++ b/third_party/rust/wasmparser/src/parser.rs
@@ -264,18 +264,22 @@ impl<'a> Parser<'a> {
         if self.operators_reader.is_some() {
             return self
                 .operators_reader
                 .as_ref()
                 .expect("operators reader")
                 .original_position();
         }
         match self.section_reader {
-            ParserSectionReader::CodeSectionReader(ref reader) => return reader.original_position(),
-            ParserSectionReader::DataSectionReader(ref reader) => return reader.original_position(),
+            ParserSectionReader::CodeSectionReader(ref reader) => {
+                return reader.original_position()
+            }
+            ParserSectionReader::DataSectionReader(ref reader) => {
+                return reader.original_position()
+            }
             ParserSectionReader::ElementSectionReader(ref reader) => {
                 return reader.original_position();
             }
             ParserSectionReader::ExportSectionReader(ref reader) => {
                 return reader.original_position();
             }
             ParserSectionReader::FunctionSectionReader(ref reader) => {
                 return reader.original_position();
@@ -287,18 +291,22 @@ impl<'a> Parser<'a> {
                 return reader.original_position();
             }
             ParserSectionReader::MemorySectionReader(ref reader) => {
                 return reader.original_position();
             }
             ParserSectionReader::TableSectionReader(ref reader) => {
                 return reader.original_position();
             }
-            ParserSectionReader::TypeSectionReader(ref reader) => return reader.original_position(),
-            ParserSectionReader::NameSectionReader(ref reader) => return reader.original_position(),
+            ParserSectionReader::TypeSectionReader(ref reader) => {
+                return reader.original_position()
+            }
+            ParserSectionReader::NameSectionReader(ref reader) => {
+                return reader.original_position()
+            }
             ParserSectionReader::LinkingSectionReader(ref reader) => {
                 return reader.original_position();
             }
             ParserSectionReader::RelocSectionReader(ref reader) => {
                 return reader.original_position();
             }
             _ => (),
         };
--- a/third_party/rust/wasmparser/src/primitives.rs
+++ b/third_party/rust/wasmparser/src/primitives.rs
@@ -9,28 +9,31 @@
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 use std::boxed::Box;
-use std::error::Error;
 use std::fmt;
 use std::result;
 
+#[cfg(feature = "std")]
+use std::error::Error;
+
 #[derive(Debug, Copy, Clone)]
 pub struct BinaryReaderError {
     pub message: &'static str,
     pub offset: usize,
 }
 
 pub type Result<T> = result::Result<T, BinaryReaderError>;
 
+#[cfg(feature = "std")]
 impl Error for BinaryReaderError {}
 
 impl fmt::Display for BinaryReaderError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{} (at offset {})", self.message, self.offset)
     }
 }
 
@@ -41,17 +44,17 @@ pub enum CustomSectionKind {
     Producers,
     SourceMappingURL,
     Reloc,
     Linking,
 }
 
 /// Section code as defined [here].
 ///
-/// [here]: https://webassembly.github.io/spec/binary/modules.html#sections
+/// [here]: https://webassembly.github.io/spec/core/binary/modules.html#sections
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub enum SectionCode<'a> {
     Custom {
         name: &'a str,
         kind: CustomSectionKind,
     },
     Type,      // Function signature declarations
     Import,    // Import declarations
@@ -64,33 +67,46 @@ pub enum SectionCode<'a> {
     Element,   // Elements section
     Code,      // Function bodies (code)
     Data,      // Data segments
     DataCount, // Count of passive data segments
 }
 
 /// Types as defined [here].
 ///
-/// [here]: https://webassembly.github.io/spec/syntax/types.html#types
+/// [here]: https://webassembly.github.io/spec/core/syntax/types.html#types
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum Type {
     I32,
     I64,
     F32,
     F64,
     V128,
     AnyFunc,
     AnyRef,
     Func,
     EmptyBlockType,
 }
 
+/// Either a value type or a function type.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum TypeOrFuncType {
+    /// A value type.
+    ///
+    /// When used as the type for a block, this type is the optional result
+    /// type: `[] -> [t?]`.
+    Type(Type),
+
+    /// A function type (referenced as an index into the types section).
+    FuncType(u32),
+}
+
 /// External types as defined [here].
 ///
-/// [here]: https://webassembly.github.io/spec/syntax/types.html#external-types
+/// [here]: https://webassembly.github.io/spec/core/syntax/types.html#external-types
 #[derive(Debug, Copy, Clone)]
 pub enum ExternalKind {
     Function,
     Table,
     Memory,
     Global,
 }
 
@@ -210,24 +226,24 @@ impl V128 {
         &self.0
     }
 }
 
 pub type SIMDLineIndex = u8;
 
 /// Instructions as defined [here].
 ///
-/// [here]: https://webassembly.github.io/spec/binary/instructions.html
+/// [here]: https://webassembly.github.io/spec/core/binary/instructions.html
 #[derive(Debug)]
 pub enum Operator<'a> {
     Unreachable,
     Nop,
-    Block { ty: Type },
-    Loop { ty: Type },
-    If { ty: Type },
+    Block { ty: TypeOrFuncType },
+    Loop { ty: TypeOrFuncType },
+    If { ty: TypeOrFuncType },
     Else,
     End,
     Br { relative_depth: u32 },
     BrIf { relative_depth: u32 },
     BrTable { table: BrTable<'a> },
     Return,
     Call { function_index: u32 },
     CallIndirect { index: u32, table_index: u32 },
--- a/third_party/rust/wasmparser/src/tests.rs
+++ b/third_party/rust/wasmparser/src/tests.rs
@@ -11,29 +11,31 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #[cfg(feature = "std")]
 #[cfg(test)]
 mod simple_tests {
+    use operators_validator::OperatorValidatorConfig;
     use parser::{Parser, ParserInput, ParserState, WasmDecoder};
     use primitives::{Operator, SectionCode};
     use std::fs::{read_dir, File};
     use std::io::prelude::*;
     use std::path::PathBuf;
-    use validator::{OperatorValidatorConfig, ValidatingParser, ValidatingParserConfig};
+    use validator::{ValidatingParser, ValidatingParserConfig};
 
     const VALIDATOR_CONFIG: Option<ValidatingParserConfig> = Some(ValidatingParserConfig {
         operator_config: OperatorValidatorConfig {
             enable_threads: true,
             enable_reference_types: true,
             enable_simd: true,
             enable_bulk_memory: true,
+            enable_multi_value: true,
         },
         mutable_global_imports: true,
     });
 
     fn read_file_data(path: &PathBuf) -> Vec<u8> {
         println!("Parsing {:?}", path);
         let mut data = Vec::new();
         let mut f = File::open(path).ok().unwrap();
--- a/third_party/rust/wasmparser/src/validator.rs
+++ b/third_party/rust/wasmparser/src/validator.rs
@@ -1,119 +1,51 @@
-/* Copyright 2017 Mozilla Foundation
+/* Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
-use std::boxed::Box;
-use std::cmp::min;
 use std::collections::HashSet;
 use std::result;
 use std::str;
+use std::string::String;
 use std::vec::Vec;
 
 use limits::{
-    MAX_WASM_FUNCTIONS, MAX_WASM_GLOBALS, MAX_WASM_MEMORIES, MAX_WASM_MEMORY_PAGES,
-    MAX_WASM_TABLES, MAX_WASM_TYPES,
+    MAX_WASM_FUNCTIONS, MAX_WASM_FUNCTION_LOCALS, MAX_WASM_GLOBALS, MAX_WASM_MEMORIES,
+    MAX_WASM_MEMORY_PAGES, MAX_WASM_TABLES, MAX_WASM_TYPES,
 };
 
 use binary_reader::BinaryReader;
 
 use primitives::{
-    BinaryReaderError, ExternalKind, FuncType, GlobalType, ImportSectionEntryType, MemoryImmediate,
-    MemoryType, Operator, ResizableLimits, Result, SIMDLineIndex, SectionCode, TableType, Type,
+    BinaryReaderError, ExternalKind, FuncType, GlobalType, ImportSectionEntryType, MemoryType,
+    Operator, ResizableLimits, Result, SectionCode, TableType, Type,
 };
 
 use parser::{Parser, ParserInput, ParserState, WasmDecoder};
 
-type ValidatorResult<'a, T> = result::Result<T, ParserState<'a>>;
-
-/// Test if `subtype` is a subtype of `supertype`.
-fn is_subtype_supertype(subtype: Type, supertype: Type) -> bool {
-    match supertype {
-        Type::AnyRef => subtype == Type::AnyRef || subtype == Type::AnyFunc,
-        _ => subtype == supertype,
-    }
-}
-
-struct BlockState {
-    return_types: Vec<Type>,
-    stack_starts_at: usize,
-    jump_to_top: bool,
-    is_else_allowed: bool,
-    is_dead_code: bool,
-    polymorphic_values: Option<usize>,
-}
-
-impl BlockState {
-    fn is_stack_polymorphic(&self) -> bool {
-        self.polymorphic_values.is_some()
-    }
-}
-
-struct FuncState {
-    local_types: Vec<Type>,
-    blocks: Vec<BlockState>,
-    stack_types: Vec<Type>,
-    end_function: bool,
-}
+use operators_validator::{
+    FunctionEnd, OperatorValidator, OperatorValidatorConfig, WasmModuleResources,
+    DEFAULT_OPERATOR_VALIDATOR_CONFIG,
+};
 
-impl FuncState {
-    fn block_at(&self, depth: usize) -> &BlockState {
-        assert!(depth < self.blocks.len());
-        &self.blocks[self.blocks.len() - 1 - depth]
-    }
-    fn last_block(&self) -> &BlockState {
-        self.blocks.last().unwrap()
-    }
-    fn assert_stack_type_at(&self, index: usize, expected: Type) -> bool {
-        let stack_starts_at = self.last_block().stack_starts_at;
-        if self.last_block().is_stack_polymorphic()
-            && stack_starts_at + index >= self.stack_types.len()
-        {
-            return true;
-        }
-        assert!(stack_starts_at + index < self.stack_types.len());
-        is_subtype_supertype(
-            self.stack_types[self.stack_types.len() - 1 - index],
-            expected,
-        )
-    }
-    fn assert_block_stack_len(&self, depth: usize, minimal_len: usize) -> bool {
-        assert!(depth < self.blocks.len());
-        let blocks_end = self.blocks.len();
-        let block_offset = blocks_end - 1 - depth;
-        for i in block_offset..blocks_end {
-            if self.blocks[i].is_stack_polymorphic() {
-                return true;
-            }
-        }
-        let block_starts_at = self.blocks[block_offset].stack_starts_at;
-        self.stack_types.len() >= block_starts_at + minimal_len
-    }
-    fn assert_last_block_stack_len_exact(&self, len: usize) -> bool {
-        let block_starts_at = self.last_block().stack_starts_at;
-        if self.last_block().is_stack_polymorphic() {
-            let polymorphic_values = self.last_block().polymorphic_values.unwrap();
-            self.stack_types.len() + polymorphic_values <= block_starts_at + len
-        } else {
-            self.stack_types.len() == block_starts_at + len
-        }
-    }
-}
+use readers::FunctionBody;
+
+type ValidatorResult<'a, T> = result::Result<T, ParserState<'a>>;
 
 struct InitExpressionState {
     ty: Type,
     global_count: usize,
     validated: bool,
 }
 
 #[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
@@ -148,1515 +80,40 @@ impl SectionOrderState {
             SectionCode::Code => Some(SectionOrderState::Code),
             SectionCode::Data => Some(SectionOrderState::Data),
             SectionCode::DataCount => Some(SectionOrderState::DataCount),
             _ => None,
         }
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq)]
-enum BlockType {
-    Block,
-    Loop,
-    If,
-}
-
-enum OperatorAction {
-    None,
-    ChangeFrame(usize),
-    ChangeFrameWithType(usize, Type),
-    ChangeFrameWithTypes(usize, Box<[Type]>),
-    ChangeFrameToExactTypes(Vec<Type>),
-    ChangeFrameAfterSelect(Option<Type>),
-    PushBlock(Type, BlockType),
-    PopBlock,
-    ResetBlock,
-    DeadCode,
-    EndFunction,
-}
-
-impl OperatorAction {
-    fn remove_frame_stack_types(
-        func_state: &mut FuncState,
-        remove_count: usize,
-    ) -> OperatorValidatorResult<()> {
-        if remove_count == 0 {
-            return Ok(());
-        }
-        let last_block = func_state.blocks.last_mut().unwrap();
-        if last_block.is_stack_polymorphic() {
-            let len = func_state.stack_types.len();
-            let remove_non_polymorphic = len
-                .checked_sub(last_block.stack_starts_at)
-                .ok_or("invalid block signature")?
-                .min(remove_count);
-            func_state
-                .stack_types
-                .truncate(len - remove_non_polymorphic);
-            let polymorphic_values = last_block.polymorphic_values.unwrap();
-            let remove_polymorphic = min(remove_count - remove_non_polymorphic, polymorphic_values);
-            last_block.polymorphic_values = Some(polymorphic_values - remove_polymorphic);
-        } else {
-            assert!(func_state.stack_types.len() >= last_block.stack_starts_at + remove_count);
-            let keep = func_state.stack_types.len() - remove_count;
-            func_state.stack_types.truncate(keep);
-        }
-        Ok(())
-    }
-    fn update(&self, func_state: &mut FuncState) -> OperatorValidatorResult<()> {
-        match *self {
-            OperatorAction::None => (),
-            OperatorAction::PushBlock(ty, block_type) => {
-                let return_types = match ty {
-                    Type::EmptyBlockType => Vec::with_capacity(0),
-                    _ => vec![ty],
-                };
-                if block_type == BlockType::If {
-                    func_state.stack_types.pop();
-                }
-                let stack_starts_at = func_state.stack_types.len();
-                func_state.blocks.push(BlockState {
-                    return_types,
-                    stack_starts_at,
-                    jump_to_top: block_type == BlockType::Loop,
-                    is_else_allowed: block_type == BlockType::If,
-                    is_dead_code: false,
-                    polymorphic_values: None,
-                });
-            }
-            OperatorAction::PopBlock => {
-                assert!(func_state.blocks.len() > 1);
-                let last_block = func_state.blocks.pop().unwrap();
-                if last_block.is_stack_polymorphic() {
-                    assert!(
-                        func_state.stack_types.len()
-                            <= last_block.return_types.len() + last_block.stack_starts_at
-                    );
-                } else {
-                    assert!(
-                        func_state.stack_types.len()
-                            == last_block.return_types.len() + last_block.stack_starts_at
-                    );
-                }
-                let keep = last_block.stack_starts_at;
-                func_state.stack_types.truncate(keep);
-                func_state
-                    .stack_types
-                    .extend_from_slice(&last_block.return_types);
-            }
-            OperatorAction::ResetBlock => {
-                assert!(func_state.last_block().is_else_allowed);
-                let last_block = func_state.blocks.last_mut().unwrap();
-                let keep = last_block.stack_starts_at;
-                func_state.stack_types.truncate(keep);
-                last_block.is_else_allowed = false;
-                last_block.polymorphic_values = None;
-            }
-            OperatorAction::ChangeFrame(remove_count) => {
-                OperatorAction::remove_frame_stack_types(func_state, remove_count)?
-            }
-            OperatorAction::ChangeFrameWithType(remove_count, ty) => {
-                OperatorAction::remove_frame_stack_types(func_state, remove_count)?;
-                func_state.stack_types.push(ty);
-            }
-            OperatorAction::ChangeFrameWithTypes(remove_count, ref new_items) => {
-                OperatorAction::remove_frame_stack_types(func_state, remove_count)?;
-                if new_items.is_empty() {
-                    return Ok(());
-                }
-                func_state.stack_types.extend_from_slice(new_items);
-            }
-            OperatorAction::ChangeFrameToExactTypes(ref items) => {
-                let last_block = func_state.blocks.last_mut().unwrap();
-                let keep = last_block.stack_starts_at;
-                func_state.stack_types.truncate(keep);
-                func_state.stack_types.extend_from_slice(items);
-                last_block.polymorphic_values = None;
-            }
-            OperatorAction::ChangeFrameAfterSelect(ty) => {
-                OperatorAction::remove_frame_stack_types(func_state, 3)?;
-                if ty.is_none() {
-                    let last_block = func_state.blocks.last_mut().unwrap();
-                    assert!(last_block.is_stack_polymorphic());
-                    last_block.polymorphic_values =
-                        Some(last_block.polymorphic_values.unwrap() + 1);
-                    return Ok(());
-                }
-                func_state.stack_types.push(ty.unwrap());
-            }
-            OperatorAction::DeadCode => {
-                let last_block = func_state.blocks.last_mut().unwrap();
-                let keep = last_block.stack_starts_at;
-                func_state.stack_types.truncate(keep);
-                last_block.is_dead_code = true;
-                last_block.polymorphic_values = Some(0);
-            }
-            OperatorAction::EndFunction => {
-                func_state.end_function = true;
-            }
-        }
-        Ok(())
-    }
-}
-
-pub trait WasmModuleResources {
-    fn types(&self) -> &[FuncType];
-    fn tables(&self) -> &[TableType];
-    fn memories(&self) -> &[MemoryType];
-    fn globals(&self) -> &[GlobalType];
-    fn func_type_indices(&self) -> &[u32];
-    fn element_count(&self) -> u32;
-    fn data_count(&self) -> u32;
-}
-
-type OperatorValidatorResult<T> = result::Result<T, &'static str>;
-
-#[derive(Copy, Clone)]
-pub struct OperatorValidatorConfig {
-    pub enable_threads: bool,
-    pub enable_reference_types: bool,
-    pub enable_simd: bool,
-    pub enable_bulk_memory: bool,
-}
-
-const DEFAULT_OPERATOR_VALIDATOR_CONFIG: OperatorValidatorConfig = OperatorValidatorConfig {
-    enable_threads: false,
-    enable_reference_types: false,
-    enable_simd: false,
-    enable_bulk_memory: false,
-};
-
-struct OperatorValidator {
-    func_state: FuncState,
-    config: OperatorValidatorConfig,
-}
-
-impl OperatorValidator {
-    pub fn new(
-        func_type: &FuncType,
-        locals: &[(u32, Type)],
-        config: OperatorValidatorConfig,
-    ) -> OperatorValidator {
-        let mut local_types = Vec::new();
-        local_types.extend_from_slice(&*func_type.params);
-        for local in locals {
-            for _ in 0..local.0 {
-                local_types.push(local.1);
-            }
-        }
-
-        let mut blocks = Vec::new();
-        let mut last_returns = Vec::new();
-        last_returns.extend_from_slice(&*func_type.returns);
-        blocks.push(BlockState {
-            return_types: last_returns,
-            stack_starts_at: 0,
-            jump_to_top: false,
-            is_else_allowed: false,
-            is_dead_code: false,
-            polymorphic_values: None,
-        });
-
-        OperatorValidator {
-            func_state: FuncState {
-                local_types,
-                blocks,
-                stack_types: Vec::new(),
-                end_function: false,
-            },
-            config,
-        }
-    }
-
-    pub fn is_dead_code(&self) -> bool {
-        self.func_state.last_block().is_dead_code
-    }
-
-    fn check_frame_size(
-        &self,
-        func_state: &FuncState,
-        require_count: usize,
-    ) -> OperatorValidatorResult<()> {
-        if !func_state.assert_block_stack_len(0, require_count) {
-            Err("not enough operands")
-        } else {
-            Ok(())
-        }
-    }
-
-    fn check_operands_1(
-        &self,
-        func_state: &FuncState,
-        operand: Type,
-    ) -> OperatorValidatorResult<()> {
-        self.check_frame_size(func_state, 1)?;
-        if !func_state.assert_stack_type_at(0, operand) {
-            return Err("stack operand type mismatch");
-        }
-        Ok(())
-    }
-
-    fn check_operands_2(
-        &self,
-        func_state: &FuncState,
-        operand1: Type,
-        operand2: Type,
-    ) -> OperatorValidatorResult<()> {
-        self.check_frame_size(func_state, 2)?;
-        if !func_state.assert_stack_type_at(1, operand1) {
-            return Err("stack operand type mismatch");
-        }
-        if !func_state.assert_stack_type_at(0, operand2) {
-            return Err("stack operand type mismatch");
-        }
-        Ok(())
-    }
-
-    fn check_operands(
-        &self,
-        func_state: &FuncState,
-        expected_types: &[Type],
-    ) -> OperatorValidatorResult<()> {
-        let len = expected_types.len();
-        self.check_frame_size(func_state, len)?;
-        for i in 0..len {
-            if !func_state.assert_stack_type_at(len - 1 - i, expected_types[i]) {
-                return Err("stack operand type mismatch");
-            }
-        }
-        Ok(())
-    }
-
-    fn check_block_return_types(
-        &self,
-        func_state: &FuncState,
-        block: &BlockState,
-        reserve_items: usize,
-    ) -> OperatorValidatorResult<()> {
-        let len = block.return_types.len();
-        for i in 0..len {
-            if !func_state.assert_stack_type_at(len - 1 - i + reserve_items, block.return_types[i])
-            {
-                return Err("stack item type does not match block item type");
-            }
-        }
-        Ok(())
-    }
-
-    fn check_block_return(&self, func_state: &FuncState) -> OperatorValidatorResult<()> {
-        let len = func_state.last_block().return_types.len();
-        if !func_state.assert_last_block_stack_len_exact(len) {
-            return Err("stack size does not match block type");
-        }
-        self.check_block_return_types(func_state, func_state.last_block(), 0)
-    }
-
-    fn check_jump_from_block(
-        &self,
-        func_state: &FuncState,
-        relative_depth: u32,
-        reserve_items: usize,
-    ) -> OperatorValidatorResult<()> {
-        if relative_depth as usize >= func_state.blocks.len() {
-            return Err("invalid block depth");
-        }
-        let block = func_state.block_at(relative_depth as usize);
-        if block.jump_to_top {
-            if !func_state.assert_block_stack_len(0, reserve_items) {
-                return Err("stack size does not match target loop type");
-            }
-            return Ok(());
-        }
-
-        let len = block.return_types.len();
-        if !func_state.assert_block_stack_len(0, len + reserve_items) {
-            return Err("stack size does not match target block type");
-        }
-        self.check_block_return_types(func_state, block, reserve_items)
-    }
-
-    fn match_block_return(
-        &self,
-        func_state: &FuncState,
-        depth1: u32,
-        depth2: u32,
-    ) -> OperatorValidatorResult<()> {
-        if depth1 as usize >= func_state.blocks.len() {
-            return Err("invalid block depth");
-        }
-        if depth2 as usize >= func_state.blocks.len() {
-            return Err("invalid block depth");
-        }
-        let block1 = func_state.block_at(depth1 as usize);
-        let block2 = func_state.block_at(depth2 as usize);
-        let return_types1 = &block1.return_types;
-        let return_types2 = &block2.return_types;
-        if block1.jump_to_top || block2.jump_to_top {
-            if block1.jump_to_top {
-                if !block2.jump_to_top && !return_types2.is_empty() {
-                    return Err("block types do not match");
-                }
-            } else if !return_types1.is_empty() {
-                return Err("block types do not match");
-            }
-        } else if *return_types1 != *return_types2 {
-            return Err("block types do not match");
-        }
-        Ok(())
-    }
-
-    fn check_memory_index(
-        &self,
-        memory_index: u32,
-        resources: &WasmModuleResources,
-    ) -> OperatorValidatorResult<()> {
-        if memory_index as usize >= resources.memories().len() {
-            return Err("no liner memories are present");
-        }
-        Ok(())
-    }
-
-    fn check_shared_memory_index(
-        &self,
-        memory_index: u32,
-        resources: &WasmModuleResources,
-    ) -> OperatorValidatorResult<()> {
-        if memory_index as usize >= resources.memories().len() {
-            return Err("no liner memories are present");
-        }
-        if !resources.memories()[memory_index as usize].shared {
-            return Err("atomic accesses require shared memory");
-        }
-        Ok(())
-    }
-
-    fn check_memarg(
-        &self,
-        memarg: &MemoryImmediate,
-        max_align: u32,
-        resources: &WasmModuleResources,
-    ) -> OperatorValidatorResult<()> {
-        self.check_memory_index(0, resources)?;
-        let align = memarg.flags;
-        if align > max_align {
-            return Err("align is required to be at most the number of accessed bytes");
-        }
-        Ok(())
-    }
-
-    fn check_threads_enabled(&self) -> OperatorValidatorResult<()> {
-        if !self.config.enable_threads {
-            return Err("threads support is not enabled");
-        }
-        Ok(())
-    }
-
-    fn check_reference_types_enabled(&self) -> OperatorValidatorResult<()> {
-        if !self.config.enable_reference_types {
-            return Err("reference types support is not enabled");
-        }
-        Ok(())
-    }
-
-    fn check_simd_enabled(&self) -> OperatorValidatorResult<()> {
-        if !self.config.enable_simd {
-            return Err("SIMD support is not enabled");
-        }
-        Ok(())
-    }
-
-    fn check_bulk_memory_enabled(&self) -> OperatorValidatorResult<()> {
-        if !self.config.enable_bulk_memory {
-            return Err("bulk memory support is not enabled");
-        }
-        Ok(())
-    }
-
-    fn check_shared_memarg_wo_align(
-        &self,
-        _: &MemoryImmediate,
-        resources: &WasmModuleResources,
-    ) -> OperatorValidatorResult<()> {
-        self.check_shared_memory_index(0, resources)?;
-        Ok(())
-    }
-
-    fn check_simd_line_index(&self, index: SIMDLineIndex, max: u8) -> OperatorValidatorResult<()> {
-        if index >= max {
-            return Err("SIMD index out of bounds");
-        }
-        Ok(())
-    }
-
-    fn check_block_type(&self, ty: Type) -> OperatorValidatorResult<()> {
-        match ty {
-            Type::EmptyBlockType | Type::I32 | Type::I64 | Type::F32 | Type::F64 => Ok(()),
-            _ => Err("invalid block return type"),
-        }
-    }
-
-    fn check_select(&self, func_state: &FuncState) -> OperatorValidatorResult<Option<Type>> {
-        self.check_frame_size(func_state, 3)?;
-        let last_block = func_state.last_block();
-        Ok(if last_block.is_stack_polymorphic() {
-            match func_state
-                .stack_types
-                .len()
-                .checked_sub(last_block.stack_starts_at)
-                .ok_or("invalid block signature")?
-            {
-                0 => None,
-                1 => {
-                    self.check_operands_1(func_state, Type::I32)?;
-                    None
-                }
-                2 => {
-                    self.check_operands_1(func_state, Type::I32)?;
-                    Some(func_state.stack_types[func_state.stack_types.len() - 2])
-                }
-                _ => {
-                    let ty = func_state.stack_types[func_state.stack_types.len() - 3];
-                    self.check_operands_2(func_state, ty, Type::I32)?;
-                    Some(ty)
-                }
-            }
-        } else {
-            let ty = func_state.stack_types[func_state.stack_types.len() - 3];
-            self.check_operands_2(func_state, ty, Type::I32)?;
-            Some(ty)
-        })
-    }
-
-    fn process_operator(
-        &self,
-        operator: &Operator,
-        resources: &WasmModuleResources,
-    ) -> OperatorValidatorResult<OperatorAction> {
-        let func_state = &self.func_state;
-        if func_state.end_function {
-            return Err("unexpected operator");
-        }
-        Ok(match *operator {
-            Operator::Unreachable => OperatorAction::DeadCode,
-            Operator::Nop => OperatorAction::None,
-            Operator::Block { ty } => {
-                self.check_block_type(ty)?;
-                OperatorAction::PushBlock(ty, BlockType::Block)
-            }
-            Operator::Loop { ty } => {
-                self.check_block_type(ty)?;
-                OperatorAction::PushBlock(ty, BlockType::Loop)
-            }
-            Operator::If { ty } => {
-                self.check_block_type(ty)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::PushBlock(ty, BlockType::If)
-            }
-            Operator::Else => {
-                if !func_state.last_block().is_else_allowed {
-                    return Err("unexpected else: if block is not started");
-                }
-                self.check_block_return(func_state)?;
-                OperatorAction::ResetBlock
-            }
-            Operator::End => {
-                self.check_block_return(func_state)?;
-                let last_block = &func_state.last_block();
-                if func_state.blocks.len() == 1 {
-                    OperatorAction::EndFunction
-                } else {
-                    if last_block.is_else_allowed && !last_block.return_types.is_empty() {
-                        return Err("else is expected: if block has type");
-                    }
-                    OperatorAction::PopBlock
-                }
-            }
-            Operator::Br { relative_depth } => {
-                self.check_jump_from_block(func_state, relative_depth, 0)?;
-                OperatorAction::DeadCode
-            }
-            Operator::BrIf { relative_depth } => {
-                self.check_operands_1(func_state, Type::I32)?;
-                self.check_jump_from_block(func_state, relative_depth, 1)?;
-                if func_state.last_block().is_stack_polymorphic() {
-                    let block = func_state.block_at(relative_depth as usize);
-                    OperatorAction::ChangeFrameToExactTypes(block.return_types.clone())
-                } else {
-                    OperatorAction::ChangeFrame(1)
-                }
-            }
-            Operator::BrTable { ref table } => {
-                self.check_operands_1(func_state, Type::I32)?;
-                let mut depth0: Option<u32> = None;
-                for relative_depth in table {
-                    if depth0.is_none() {
-                        self.check_jump_from_block(func_state, relative_depth, 1)?;
-                        depth0 = Some(relative_depth);
-                        continue;
-                    }
-                    self.match_block_return(func_state, relative_depth, depth0.unwrap())?;
-                }
-                OperatorAction::DeadCode
-            }
-            Operator::Return => {
-                let depth = (func_state.blocks.len() - 1) as u32;
-                self.check_jump_from_block(func_state, depth, 0)?;
-                OperatorAction::DeadCode
-            }
-            Operator::Call { function_index } => {
-                if function_index as usize >= resources.func_type_indices().len() {
-                    return Err("function index out of bounds");
-                }
-                let type_index = resources.func_type_indices()[function_index as usize];
-                let ty = &resources.types()[type_index as usize];
-                self.check_operands(func_state, &ty.params)?;
-                OperatorAction::ChangeFrameWithTypes(ty.params.len(), ty.returns.clone())
-            }
-            Operator::CallIndirect { index, table_index } => {
-                if table_index as usize >= resources.tables().len() {
-                    return Err("table index out of bounds");
-                }
-                if index as usize >= resources.types().len() {
-                    return Err("type index out of bounds");
-                }
-                let ty = &resources.types()[index as usize];
-                let mut types = Vec::with_capacity(ty.params.len() + 1);
-                types.extend_from_slice(&ty.params);
-                types.push(Type::I32);
-                self.check_operands(func_state, &types)?;
-                OperatorAction::ChangeFrameWithTypes(ty.params.len() + 1, ty.returns.clone())
-            }
-            Operator::Drop => {
-                self.check_frame_size(func_state, 1)?;
-                OperatorAction::ChangeFrame(1)
-            }
-            Operator::Select => {
-                let ty = self.check_select(func_state)?;
-                OperatorAction::ChangeFrameAfterSelect(ty)
-            }
-            Operator::GetLocal { local_index } => {
-                if local_index as usize >= func_state.local_types.len() {
-                    return Err("local index out of bounds");
-                }
-                let local_type = func_state.local_types[local_index as usize];
-                OperatorAction::ChangeFrameWithType(0, local_type)
-            }
-            Operator::SetLocal { local_index } => {
-                if local_index as usize >= func_state.local_types.len() {
-                    return Err("local index out of bounds");
-                }
-                let local_type = func_state.local_types[local_index as usize];
-                self.check_operands_1(func_state, local_type)?;
-                OperatorAction::ChangeFrame(1)
-            }
-            Operator::TeeLocal { local_index } => {
-                if local_index as usize >= func_state.local_types.len() {
-                    return Err("local index out of bounds");
-                }
-                let local_type = func_state.local_types[local_index as usize];
-                self.check_operands_1(func_state, local_type)?;
-                OperatorAction::ChangeFrameWithType(1, local_type)
-            }
-            Operator::GetGlobal { global_index } => {
-                if global_index as usize >= resources.globals().len() {
-                    return Err("global index out of bounds");
-                }
-                let ty = &resources.globals()[global_index as usize];
-                OperatorAction::ChangeFrameWithType(0, ty.content_type)
-            }
-            Operator::SetGlobal { global_index } => {
-                if global_index as usize >= resources.globals().len() {
-                    return Err("global index out of bounds");
-                }
-                let ty = &resources.globals()[global_index as usize];
-                // FIXME
-                //    if !ty.mutable {
-                //        return self.create_error("global expected to be mutable");
-                //    }
-                self.check_operands_1(func_state, ty.content_type)?;
-                OperatorAction::ChangeFrame(1)
-            }
-            Operator::I32Load { ref memarg } => {
-                self.check_memarg(memarg, 2, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I64Load { ref memarg } => {
-                self.check_memarg(memarg, 3, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::F32Load { ref memarg } => {
-                self.check_memarg(memarg, 2, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F32)
-            }
-            Operator::F64Load { ref memarg } => {
-                self.check_memarg(memarg, 3, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F64)
-            }
-            Operator::I32Load8S { ref memarg } => {
-                self.check_memarg(memarg, 0, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32Load8U { ref memarg } => {
-                self.check_memarg(memarg, 0, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32Load16S { ref memarg } => {
-                self.check_memarg(memarg, 1, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32Load16U { ref memarg } => {
-                self.check_memarg(memarg, 1, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I64Load8S { ref memarg } => {
-                self.check_memarg(memarg, 0, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64Load8U { ref memarg } => {
-                self.check_memarg(memarg, 0, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64Load16S { ref memarg } => {
-                self.check_memarg(memarg, 1, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64Load16U { ref memarg } => {
-                self.check_memarg(memarg, 1, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64Load32S { ref memarg } => {
-                self.check_memarg(memarg, 2, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64Load32U { ref memarg } => {
-                self.check_memarg(memarg, 2, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I32Store { ref memarg } => {
-                self.check_memarg(memarg, 2, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I32)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::I64Store { ref memarg } => {
-                self.check_memarg(memarg, 3, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I64)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::F32Store { ref memarg } => {
-                self.check_memarg(memarg, 2, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::F32)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::F64Store { ref memarg } => {
-                self.check_memarg(memarg, 3, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::F64)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::I32Store8 { ref memarg } => {
-                self.check_memarg(memarg, 0, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I32)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::I32Store16 { ref memarg } => {
-                self.check_memarg(memarg, 1, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I32)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::I64Store8 { ref memarg } => {
-                self.check_memarg(memarg, 0, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I64)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::I64Store16 { ref memarg } => {
-                self.check_memarg(memarg, 1, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I64)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::I64Store32 { ref memarg } => {
-                self.check_memarg(memarg, 2, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I64)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::MemorySize {
-                reserved: memory_index,
-            } => {
-                self.check_memory_index(memory_index, resources)?;
-                OperatorAction::ChangeFrameWithType(0, Type::I32)
-            }
-            Operator::MemoryGrow {
-                reserved: memory_index,
-            } => {
-                self.check_memory_index(memory_index, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32Const { .. } => OperatorAction::ChangeFrameWithType(0, Type::I32),
-            Operator::I64Const { .. } => OperatorAction::ChangeFrameWithType(0, Type::I64),
-            Operator::F32Const { .. } => OperatorAction::ChangeFrameWithType(0, Type::F32),
-            Operator::F64Const { .. } => OperatorAction::ChangeFrameWithType(0, Type::F64),
-            Operator::I32Eqz => {
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32Eq
-            | Operator::I32Ne
-            | Operator::I32LtS
-            | Operator::I32LtU
-            | Operator::I32GtS
-            | Operator::I32GtU
-            | Operator::I32LeS
-            | Operator::I32LeU
-            | Operator::I32GeS
-            | Operator::I32GeU => {
-                self.check_operands_2(func_state, Type::I32, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I32)
-            }
-            Operator::I64Eqz => {
-                self.check_operands_1(func_state, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I64Eq
-            | Operator::I64Ne
-            | Operator::I64LtS
-            | Operator::I64LtU
-            | Operator::I64GtS
-            | Operator::I64GtU
-            | Operator::I64LeS
-            | Operator::I64LeU
-            | Operator::I64GeS
-            | Operator::I64GeU => {
-                self.check_operands_2(func_state, Type::I64, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I32)
-            }
-            Operator::F32Eq
-            | Operator::F32Ne
-            | Operator::F32Lt
-            | Operator::F32Gt
-            | Operator::F32Le
-            | Operator::F32Ge => {
-                self.check_operands_2(func_state, Type::F32, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I32)
-            }
-            Operator::F64Eq
-            | Operator::F64Ne
-            | Operator::F64Lt
-            | Operator::F64Gt
-            | Operator::F64Le
-            | Operator::F64Ge => {
-                self.check_operands_2(func_state, Type::F64, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I32)
-            }
-            Operator::I32Clz | Operator::I32Ctz | Operator::I32Popcnt => {
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32Add
-            | Operator::I32Sub
-            | Operator::I32Mul
-            | Operator::I32DivS
-            | Operator::I32DivU
-            | Operator::I32RemS
-            | Operator::I32RemU
-            | Operator::I32And
-            | Operator::I32Or
-            | Operator::I32Xor
-            | Operator::I32Shl
-            | Operator::I32ShrS
-            | Operator::I32ShrU
-            | Operator::I32Rotl
-            | Operator::I32Rotr => {
-                self.check_operands_2(func_state, Type::I32, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I32)
-            }
-            Operator::I64Clz | Operator::I64Ctz | Operator::I64Popcnt => {
-                self.check_operands_1(func_state, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64Add
-            | Operator::I64Sub
-            | Operator::I64Mul
-            | Operator::I64DivS
-            | Operator::I64DivU
-            | Operator::I64RemS
-            | Operator::I64RemU
-            | Operator::I64And
-            | Operator::I64Or
-            | Operator::I64Xor
-            | Operator::I64Shl
-            | Operator::I64ShrS
-            | Operator::I64ShrU
-            | Operator::I64Rotl
-            | Operator::I64Rotr => {
-                self.check_operands_2(func_state, Type::I64, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I64)
-            }
-            Operator::F32Abs
-            | Operator::F32Neg
-            | Operator::F32Ceil
-            | Operator::F32Floor
-            | Operator::F32Trunc
-            | Operator::F32Nearest
-            | Operator::F32Sqrt => {
-                self.check_operands_1(func_state, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F32)
-            }
-            Operator::F32Add
-            | Operator::F32Sub
-            | Operator::F32Mul
-            | Operator::F32Div
-            | Operator::F32Min
-            | Operator::F32Max
-            | Operator::F32Copysign => {
-                self.check_operands_2(func_state, Type::F32, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::F32)
-            }
-            Operator::F64Abs
-            | Operator::F64Neg
-            | Operator::F64Ceil
-            | Operator::F64Floor
-            | Operator::F64Trunc
-            | Operator::F64Nearest
-            | Operator::F64Sqrt => {
-                self.check_operands_1(func_state, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F64)
-            }
-            Operator::F64Add
-            | Operator::F64Sub
-            | Operator::F64Mul
-            | Operator::F64Div
-            | Operator::F64Min
-            | Operator::F64Max
-            | Operator::F64Copysign => {
-                self.check_operands_2(func_state, Type::F64, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(2, Type::F64)
-            }
-            Operator::I32WrapI64 => {
-                self.check_operands_1(func_state, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32TruncSF32 | Operator::I32TruncUF32 => {
-                self.check_operands_1(func_state, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32TruncSF64 | Operator::I32TruncUF64 => {
-                self.check_operands_1(func_state, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I64ExtendSI32 | Operator::I64ExtendUI32 => {
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64TruncSF32 | Operator::I64TruncUF32 => {
-                self.check_operands_1(func_state, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64TruncSF64 | Operator::I64TruncUF64 => {
-                self.check_operands_1(func_state, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::F32ConvertSI32 | Operator::F32ConvertUI32 => {
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F32)
-            }
-            Operator::F32ConvertSI64 | Operator::F32ConvertUI64 => {
-                self.check_operands_1(func_state, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F32)
-            }
-            Operator::F32DemoteF64 => {
-                self.check_operands_1(func_state, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F32)
-            }
-            Operator::F64ConvertSI32 | Operator::F64ConvertUI32 => {
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F64)
-            }
-            Operator::F64ConvertSI64 | Operator::F64ConvertUI64 => {
-                self.check_operands_1(func_state, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F64)
-            }
-            Operator::F64PromoteF32 => {
-                self.check_operands_1(func_state, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F64)
-            }
-            Operator::I32ReinterpretF32 => {
-                self.check_operands_1(func_state, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I64ReinterpretF64 => {
-                self.check_operands_1(func_state, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::F32ReinterpretI32 => {
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F32)
-            }
-            Operator::F64ReinterpretI64 => {
-                self.check_operands_1(func_state, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F64)
-            }
-            Operator::I32TruncSSatF32 | Operator::I32TruncUSatF32 => {
-                self.check_operands_1(func_state, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32TruncSSatF64 | Operator::I32TruncUSatF64 => {
-                self.check_operands_1(func_state, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I64TruncSSatF32 | Operator::I64TruncUSatF32 => {
-                self.check_operands_1(func_state, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64TruncSSatF64 | Operator::I64TruncUSatF64 => {
-                self.check_operands_1(func_state, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I32Extend16S | Operator::I32Extend8S => {
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-
-            Operator::I64Extend32S | Operator::I64Extend16S | Operator::I64Extend8S => {
-                self.check_operands_1(func_state, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-
-            Operator::I32AtomicLoad { ref memarg }
-            | Operator::I32AtomicLoad16U { ref memarg }
-            | Operator::I32AtomicLoad8U { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I64AtomicLoad { ref memarg }
-            | Operator::I64AtomicLoad32U { ref memarg }
-            | Operator::I64AtomicLoad16U { ref memarg }
-            | Operator::I64AtomicLoad8U { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I32AtomicStore { ref memarg }
-            | Operator::I32AtomicStore16 { ref memarg }
-            | Operator::I32AtomicStore8 { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I32)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::I64AtomicStore { ref memarg }
-            | Operator::I64AtomicStore32 { ref memarg }
-            | Operator::I64AtomicStore16 { ref memarg }
-            | Operator::I64AtomicStore8 { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I64)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::I32AtomicRmwAdd { ref memarg }
-            | Operator::I32AtomicRmwSub { ref memarg }
-            | Operator::I32AtomicRmwAnd { ref memarg }
-            | Operator::I32AtomicRmwOr { ref memarg }
-            | Operator::I32AtomicRmwXor { ref memarg }
-            | Operator::I32AtomicRmw16UAdd { ref memarg }
-            | Operator::I32AtomicRmw16USub { ref memarg }
-            | Operator::I32AtomicRmw16UAnd { ref memarg }
-            | Operator::I32AtomicRmw16UOr { ref memarg }
-            | Operator::I32AtomicRmw16UXor { ref memarg }
-            | Operator::I32AtomicRmw8UAdd { ref memarg }
-            | Operator::I32AtomicRmw8USub { ref memarg }
-            | Operator::I32AtomicRmw8UAnd { ref memarg }
-            | Operator::I32AtomicRmw8UOr { ref memarg }
-            | Operator::I32AtomicRmw8UXor { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I32)
-            }
-            Operator::I64AtomicRmwAdd { ref memarg }
-            | Operator::I64AtomicRmwSub { ref memarg }
-            | Operator::I64AtomicRmwAnd { ref memarg }
-            | Operator::I64AtomicRmwOr { ref memarg }
-            | Operator::I64AtomicRmwXor { ref memarg }
-            | Operator::I64AtomicRmw32UAdd { ref memarg }
-            | Operator::I64AtomicRmw32USub { ref memarg }
-            | Operator::I64AtomicRmw32UAnd { ref memarg }
-            | Operator::I64AtomicRmw32UOr { ref memarg }
-            | Operator::I64AtomicRmw32UXor { ref memarg }
-            | Operator::I64AtomicRmw16UAdd { ref memarg }
-            | Operator::I64AtomicRmw16USub { ref memarg }
-            | Operator::I64AtomicRmw16UAnd { ref memarg }
-            | Operator::I64AtomicRmw16UOr { ref memarg }
-            | Operator::I64AtomicRmw16UXor { ref memarg }
-            | Operator::I64AtomicRmw8UAdd { ref memarg }
-            | Operator::I64AtomicRmw8USub { ref memarg }
-            | Operator::I64AtomicRmw8UAnd { ref memarg }
-            | Operator::I64AtomicRmw8UOr { ref memarg }
-            | Operator::I64AtomicRmw8UXor { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I64)
-            }
-            Operator::I32AtomicRmwXchg { ref memarg }
-            | Operator::I32AtomicRmw16UXchg { ref memarg }
-            | Operator::I32AtomicRmw8UXchg { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I32)
-            }
-            Operator::I32AtomicRmwCmpxchg { ref memarg }
-            | Operator::I32AtomicRmw16UCmpxchg { ref memarg }
-            | Operator::I32AtomicRmw8UCmpxchg { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands(func_state, &[Type::I32, Type::I32, Type::I32])?;
-                OperatorAction::ChangeFrameWithType(3, Type::I32)
-            }
-            Operator::I64AtomicRmwXchg { ref memarg }
-            | Operator::I64AtomicRmw32UXchg { ref memarg }
-            | Operator::I64AtomicRmw16UXchg { ref memarg }
-            | Operator::I64AtomicRmw8UXchg { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I64)
-            }
-            Operator::I64AtomicRmwCmpxchg { ref memarg }
-            | Operator::I64AtomicRmw32UCmpxchg { ref memarg }
-            | Operator::I64AtomicRmw16UCmpxchg { ref memarg }
-            | Operator::I64AtomicRmw8UCmpxchg { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands(func_state, &[Type::I32, Type::I64, Type::I64])?;
-                OperatorAction::ChangeFrameWithType(3, Type::I64)
-            }
-            Operator::Wake { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::I32)
-            }
-            Operator::I32Wait { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands(func_state, &[Type::I32, Type::I32, Type::I64])?;
-                OperatorAction::ChangeFrameWithType(3, Type::I32)
-            }
-            Operator::I64Wait { ref memarg } => {
-                self.check_threads_enabled()?;
-                self.check_shared_memarg_wo_align(memarg, resources)?;
-                self.check_operands(func_state, &[Type::I32, Type::I64, Type::I64])?;
-                OperatorAction::ChangeFrameWithType(3, Type::I32)
-            }
-            Operator::RefNull => {
-                self.check_reference_types_enabled()?;
-                OperatorAction::ChangeFrameWithType(0, Type::AnyRef)
-            }
-            Operator::RefIsNull => {
-                self.check_reference_types_enabled()?;
-                self.check_operands(func_state, &[Type::AnyRef])?;
-                OperatorAction::ChangeFrameWithType(0, Type::I32)
-            }
-            Operator::V128Load { ref memarg } => {
-                self.check_simd_enabled()?;
-                self.check_memarg(memarg, 4, resources)?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::V128)
-            }
-            Operator::V128Store { ref memarg } => {
-                self.check_simd_enabled()?;
-                self.check_memarg(memarg, 4, resources)?;
-                self.check_operands_2(func_state, Type::I32, Type::V128)?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::V128Const { .. } => {
-                self.check_simd_enabled()?;
-                OperatorAction::ChangeFrameWithType(0, Type::V128)
-            }
-            Operator::V8x16Shuffle { ref lines } => {
-                self.check_simd_enabled()?;
-                self.check_operands_2(func_state, Type::V128, Type::V128)?;
-                for i in lines {
-                    self.check_simd_line_index(*i, 32)?;
-                }
-                OperatorAction::ChangeFrameWithType(2, Type::V128)
-            }
-            Operator::I8x16Splat | Operator::I16x8Splat | Operator::I32x4Splat => {
-                self.check_simd_enabled()?;
-                self.check_operands_1(func_state, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::V128)
-            }
-            Operator::I64x2Splat => {
-                self.check_simd_enabled()?;
-                self.check_operands_1(func_state, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::V128)
-            }
-            Operator::F32x4Splat => {
-                self.check_simd_enabled()?;
-                self.check_operands_1(func_state, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::V128)
-            }
-            Operator::F64x2Splat => {
-                self.check_simd_enabled()?;
-                self.check_operands_1(func_state, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(1, Type::V128)
-            }
-            Operator::I8x16ExtractLaneS { line } | Operator::I8x16ExtractLaneU { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 16)?;
-                self.check_operands_1(func_state, Type::V128)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I16x8ExtractLaneS { line } | Operator::I16x8ExtractLaneU { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 8)?;
-                self.check_operands_1(func_state, Type::V128)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I32x4ExtractLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 4)?;
-                self.check_operands_1(func_state, Type::V128)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I8x16ReplaceLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 16)?;
-                self.check_operands_2(func_state, Type::V128, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::V128)
-            }
-            Operator::I16x8ReplaceLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 8)?;
-                self.check_operands_2(func_state, Type::V128, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::V128)
-            }
-            Operator::I32x4ReplaceLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 4)?;
-                self.check_operands_2(func_state, Type::V128, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::V128)
-            }
-            Operator::I64x2ExtractLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 2)?;
-                self.check_operands_1(func_state, Type::V128)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I64)
-            }
-            Operator::I64x2ReplaceLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 2)?;
-                self.check_operands_2(func_state, Type::V128, Type::I64)?;
-                OperatorAction::ChangeFrameWithType(2, Type::V128)
-            }
-            Operator::F32x4ExtractLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 4)?;
-                self.check_operands_1(func_state, Type::V128)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F32)
-            }
-            Operator::F32x4ReplaceLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 4)?;
-                self.check_operands_2(func_state, Type::V128, Type::F32)?;
-                OperatorAction::ChangeFrameWithType(2, Type::V128)
-            }
-            Operator::F64x2ExtractLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 2)?;
-                self.check_operands_1(func_state, Type::V128)?;
-                OperatorAction::ChangeFrameWithType(1, Type::F64)
-            }
-            Operator::F64x2ReplaceLane { line } => {
-                self.check_simd_enabled()?;
-                self.check_simd_line_index(line, 2)?;
-                self.check_operands_2(func_state, Type::V128, Type::F64)?;
-                OperatorAction::ChangeFrameWithType(2, Type::V128)
-            }
-            Operator::I8x16Eq
-            | Operator::I8x16Ne
-            | Operator::I8x16LtS
-            | Operator::I8x16LtU
-            | Operator::I8x16GtS
-            | Operator::I8x16GtU
-            | Operator::I8x16LeS
-            | Operator::I8x16LeU
-            | Operator::I8x16GeS
-            | Operator::I8x16GeU
-            | Operator::I16x8Eq
-            | Operator::I16x8Ne
-            | Operator::I16x8LtS
-            | Operator::I16x8LtU
-            | Operator::I16x8GtS
-            | Operator::I16x8GtU
-            | Operator::I16x8LeS
-            | Operator::I16x8LeU
-            | Operator::I16x8GeS
-            | Operator::I16x8GeU
-            | Operator::I32x4Eq
-            | Operator::I32x4Ne
-            | Operator::I32x4LtS
-            | Operator::I32x4LtU
-            | Operator::I32x4GtS
-            | Operator::I32x4GtU
-            | Operator::I32x4LeS
-            | Operator::I32x4LeU
-            | Operator::I32x4GeS
-            | Operator::I32x4GeU
-            | Operator::F32x4Eq
-            | Operator::F32x4Ne
-            | Operator::F32x4Lt
-            | Operator::F32x4Gt
-            | Operator::F32x4Le
-            | Operator::F32x4Ge
-            | Operator::F64x2Eq
-            | Operator::F64x2Ne
-            | Operator::F64x2Lt
-            | Operator::F64x2Gt
-            | Operator::F64x2Le
-            | Operator::F64x2Ge
-            | Operator::V128And
-            | Operator::V128Or
-            | Operator::V128Xor
-            | Operator::I8x16Add
-            | Operator::I8x16AddSaturateS
-            | Operator::I8x16AddSaturateU
-            | Operator::I8x16Sub
-            | Operator::I8x16SubSaturateS
-            | Operator::I8x16SubSaturateU
-            | Operator::I8x16Mul
-            | Operator::I16x8Add
-            | Operator::I16x8AddSaturateS
-            | Operator::I16x8AddSaturateU
-            | Operator::I16x8Sub
-            | Operator::I16x8SubSaturateS
-            | Operator::I16x8SubSaturateU
-            | Operator::I16x8Mul
-            | Operator::I32x4Add
-            | Operator::I32x4Sub
-            | Operator::I32x4Mul
-            | Operator::I64x2Add
-            | Operator::I64x2Sub
-            | Operator::F32x4Add
-            | Operator::F32x4Sub
-            | Operator::F32x4Mul
-            | Operator::F32x4Div
-            | Operator::F32x4Min
-            | Operator::F32x4Max
-            | Operator::F64x2Add
-            | Operator::F64x2Sub
-            | Operator::F64x2Mul
-            | Operator::F64x2Div
-            | Operator::F64x2Min
-            | Operator::F64x2Max => {
-                self.check_simd_enabled()?;
-                self.check_operands_2(func_state, Type::V128, Type::V128)?;
-                OperatorAction::ChangeFrameWithType(2, Type::V128)
-            }
-            Operator::V128Not
-            | Operator::I8x16Neg
-            | Operator::I16x8Neg
-            | Operator::I32x4Neg
-            | Operator::I64x2Neg
-            | Operator::F32x4Abs
-            | Operator::F32x4Neg
-            | Operator::F32x4Sqrt
-            | Operator::F64x2Abs
-            | Operator::F64x2Neg
-            | Operator::F64x2Sqrt
-            | Operator::I32x4TruncSF32x4Sat
-            | Operator::I32x4TruncUF32x4Sat
-            | Operator::I64x2TruncSF64x2Sat
-            | Operator::I64x2TruncUF64x2Sat
-            | Operator::F32x4ConvertSI32x4
-            | Operator::F32x4ConvertUI32x4
-            | Operator::F64x2ConvertSI64x2
-            | Operator::F64x2ConvertUI64x2 => {
-                self.check_simd_enabled()?;
-                self.check_operands_1(func_state, Type::V128)?;
-                OperatorAction::ChangeFrameWithType(1, Type::V128)
-            }
-            Operator::V128Bitselect => {
-                self.check_simd_enabled()?;
-                self.check_operands(func_state, &[Type::V128, Type::V128, Type::V128])?;
-                OperatorAction::ChangeFrameWithType(2, Type::V128)
-            }
-            Operator::I8x16AnyTrue
-            | Operator::I8x16AllTrue
-            | Operator::I16x8AnyTrue
-            | Operator::I16x8AllTrue
-            | Operator::I32x4AnyTrue
-            | Operator::I32x4AllTrue
-            | Operator::I64x2AnyTrue
-            | Operator::I64x2AllTrue => {
-                self.check_simd_enabled()?;
-                self.check_operands_1(func_state, Type::V128)?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::I8x16Shl
-            | Operator::I8x16ShrS
-            | Operator::I8x16ShrU
-            | Operator::I16x8Shl
-            | Operator::I16x8ShrS
-            | Operator::I16x8ShrU
-            | Operator::I32x4Shl
-            | Operator::I32x4ShrS
-            | Operator::I32x4ShrU
-            | Operator::I64x2Shl
-            | Operator::I64x2ShrS
-            | Operator::I64x2ShrU => {
-                self.check_simd_enabled()?;
-                self.check_operands_2(func_state, Type::V128, Type::I32)?;
-                OperatorAction::ChangeFrameWithType(1, Type::V128)
-            }
-
-            Operator::MemoryInit { segment } => {
-                self.check_bulk_memory_enabled()?;
-                if segment >= resources.data_count() {
-                    return Err("segment index out of bounds");
-                }
-                self.check_memory_index(0, resources)?;
-                self.check_operands(func_state, &[Type::I32, Type::I32, Type::I32])?;
-                OperatorAction::ChangeFrame(3)
-            }
-            Operator::DataDrop { segment } => {
-                self.check_bulk_memory_enabled()?;
-                if segment >= resources.data_count() {
-                    return Err("segment index out of bounds");
-                }
-                OperatorAction::None
-            }
-            Operator::MemoryCopy | Operator::MemoryFill => {
-                self.check_bulk_memory_enabled()?;
-                self.check_memory_index(0, resources)?;
-                self.check_operands(func_state, &[Type::I32, Type::I32, Type::I32])?;
-                OperatorAction::ChangeFrame(3)
-            }
-            Operator::TableInit { segment } => {
-                self.check_bulk_memory_enabled()?;
-                if segment >= resources.element_count() {
-                    return Err("segment index out of bounds");
-                }
-                if 0 >= resources.tables().len() {
-                    return Err("table index out of bounds");
-                }
-                self.check_operands(func_state, &[Type::I32, Type::I32, Type::I32])?;
-                OperatorAction::ChangeFrame(3)
-            }
-            Operator::ElemDrop { segment } => {
-                self.check_bulk_memory_enabled()?;
-                if segment >= resources.element_count() {
-                    return Err("segment index out of bounds");
-                }
-                OperatorAction::None
-            }
-            Operator::TableCopy => {
-                self.check_bulk_memory_enabled()?;
-                if 0 >= resources.tables().len() {
-                    return Err("table index out of bounds");
-                }
-                self.check_operands(func_state, &[Type::I32, Type::I32, Type::I32])?;
-                OperatorAction::ChangeFrame(3)
-            }
-            Operator::TableGet { table } => {
-                self.check_reference_types_enabled()?;
-                if table as usize >= resources.tables().len() {
-                    return Err("table index out of bounds");
-                }
-                self.check_operands(func_state, &[Type::I32])?;
-                OperatorAction::ChangeFrameWithType(1, Type::AnyRef)
-            }
-            Operator::TableSet { table } => {
-                self.check_reference_types_enabled()?;
-                if table as usize >= resources.tables().len() {
-                    return Err("table index out of bounds");
-                }
-                self.check_operands(func_state, &[Type::I32, Type::AnyRef])?;
-                OperatorAction::ChangeFrame(2)
-            }
-            Operator::TableGrow { table } => {
-                self.check_reference_types_enabled()?;
-                if table as usize >= resources.tables().len() {
-                    return Err("table index out of bounds");
-                }
-                self.check_operands(func_state, &[Type::I32])?;
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-            Operator::TableSize { table } => {
-                self.check_reference_types_enabled()?;
-                if table as usize >= resources.tables().len() {
-                    return Err("table index out of bounds");
-                }
-                OperatorAction::ChangeFrameWithType(1, Type::I32)
-            }
-        })
-    }
-
-    fn process_end_function(&self) -> OperatorValidatorResult<()> {
-        let func_state = &self.func_state;
-        if !func_state.end_function {
-            return Err("expected end of function");
-        }
-        Ok(())
-    }
-}
-
 #[derive(Copy, Clone)]
 pub struct ValidatingParserConfig {
     pub operator_config: OperatorValidatorConfig,
 
     pub mutable_global_imports: bool,
 }
 
 const DEFAULT_VALIDATING_PARSER_CONFIG: ValidatingParserConfig = ValidatingParserConfig {
     operator_config: DEFAULT_OPERATOR_VALIDATOR_CONFIG,
 
     mutable_global_imports: false,
 };
 
-pub struct ValidatingParser<'a> {
-    parser: Parser<'a>,
-    validation_error: Option<ParserState<'a>>,
-    read_position: Option<usize>,
-    section_order_state: SectionOrderState,
+struct ValidatingParserResources {
     types: Vec<FuncType>,
     tables: Vec<TableType>,
     memories: Vec<MemoryType>,
     globals: Vec<GlobalType>,
     element_count: u32,
     data_count: Option<u32>,
-    data_found: u32,
     func_type_indices: Vec<u32>,
-    current_func_index: u32,
-    func_imports_count: u32,
-    init_expression_state: Option<InitExpressionState>,
-    exported_names: HashSet<String>,
-    current_operator_validator: Option<OperatorValidator>,
-    config: ValidatingParserConfig,
 }
 
-impl<'a> WasmModuleResources for ValidatingParser<'a> {
+impl<'a> WasmModuleResources for ValidatingParserResources {
     fn types(&self) -> &[FuncType] {
         &self.types
     }
 
     fn tables(&self) -> &[TableType] {
         &self.tables
     }
 
@@ -1676,40 +133,61 @@ impl<'a> WasmModuleResources for Validat
         self.element_count
     }
 
     fn data_count(&self) -> u32 {
         self.data_count.unwrap_or(0)
     }
 }
 
+pub struct ValidatingParser<'a> {
+    parser: Parser<'a>,
+    validation_error: Option<ParserState<'a>>,
+    read_position: Option<usize>,
+    section_order_state: SectionOrderState,
+    resources: ValidatingParserResources,
+    current_func_index: u32,
+    func_imports_count: u32,
+    init_expression_state: Option<InitExpressionState>,
+    data_found: u32,
+    exported_names: HashSet<String>,
+    current_operator_validator: Option<OperatorValidator>,
+    config: ValidatingParserConfig,
+}
+
 impl<'a> ValidatingParser<'a> {
     pub fn new(bytes: &[u8], config: Option<ValidatingParserConfig>) -> ValidatingParser {
         ValidatingParser {
             parser: Parser::new(bytes),
             validation_error: None,
             read_position: None,
             section_order_state: SectionOrderState::Initial,
-            types: Vec::new(),
-            tables: Vec::new(),
-            memories: Vec::new(),
-            globals: Vec::new(),
-            func_type_indices: Vec::new(),
+            resources: ValidatingParserResources {
+                types: Vec::new(),
+                tables: Vec::new(),
+                memories: Vec::new(),
+                globals: Vec::new(),
+                element_count: 0,
+                data_count: None,
+                func_type_indices: Vec::new(),
+            },
             current_func_index: 0,
             func_imports_count: 0,
             current_operator_validator: None,
             init_expression_state: None,
+            data_found: 0,
             exported_names: HashSet::new(),
             config: config.unwrap_or(DEFAULT_VALIDATING_PARSER_CONFIG),
-            element_count: 0,
-            data_count: None,
-            data_found: 0,
         }
     }
 
+    pub fn get_resources(&self) -> &dyn WasmModuleResources {
+        &self.resources
+    }
+
     fn create_validation_error(&self, message: &'static str) -> Option<ParserState<'a>> {
         Some(ParserState::Error(BinaryReaderError {
             message,
             offset: self.read_position.unwrap(),
         }))
     }
 
     fn create_error<T>(&self, message: &'static str) -> ValidatorResult<'a, T> {
@@ -1739,19 +217,16 @@ impl<'a> ValidatingParser<'a> {
         }
         Ok(())
     }
 
     fn check_func_type(&self, func_type: &FuncType) -> ValidatorResult<'a, ()> {
         if let Type::Func = func_type.form {
             self.check_value_types(&*func_type.params)?;
             self.check_value_types(&*func_type.returns)?;
-            if func_type.returns.len() > 1 {
-                return self.create_error("too many returns, expected 0 or 1");
-            }
             Ok(())
         } else {
             self.create_error("type signature is not a func")
         }
     }
 
     fn check_table_type(&self, table_type: &TableType) -> ValidatorResult<'a, ()> {
         if let Type::AnyFunc = table_type.element_type {
@@ -1776,38 +251,38 @@ impl<'a> ValidatingParser<'a> {
 
     fn check_global_type(&self, global_type: GlobalType) -> ValidatorResult<'a, ()> {
         self.check_value_type(global_type.content_type)
     }
 
     fn check_import_entry(&self, import_type: &ImportSectionEntryType) -> ValidatorResult<'a, ()> {
         match *import_type {
             ImportSectionEntryType::Function(type_index) => {
-                if self.func_type_indices.len() >= MAX_WASM_FUNCTIONS {
+                if self.resources.func_type_indices.len() >= MAX_WASM_FUNCTIONS {
                     return self.create_error("functions count out of bounds");
                 }
-                if type_index as usize >= self.types.len() {
+                if type_index as usize >= self.resources.types.len() {
                     return self.create_error("type index out of bounds");
                 }
                 Ok(())
             }
             ImportSectionEntryType::Table(ref table_type) => {
-                if self.tables.len() >= MAX_WASM_TABLES {
+                if self.resources.tables.len() >= MAX_WASM_TABLES {
                     return self.create_error("tables count must be at most 1");
                 }
                 self.check_table_type(table_type)
             }
             ImportSectionEntryType::Memory(ref memory_type) => {
-                if self.memories.len() >= MAX_WASM_MEMORIES {
+                if self.resources.memories.len() >= MAX_WASM_MEMORIES {
                     return self.create_error("memory count must be at most 1");
                 }
                 self.check_memory_type(memory_type)
             }
             ImportSectionEntryType::Global(global_type) => {
-                if self.globals.len() >= MAX_WASM_GLOBALS {
+                if self.resources.globals.len() >= MAX_WASM_GLOBALS {
                     return self.create_error("functions count out of bounds");
                 }
                 if global_type.mutable && !self.config.mutable_global_imports {
                     return self.create_error("global imports are required to be immutable");
                 }
                 self.check_global_type(global_type)
             }
         }
@@ -1822,17 +297,17 @@ impl<'a> ValidatingParser<'a> {
             Operator::I32Const { .. } => Type::I32,
             Operator::I64Const { .. } => Type::I64,
             Operator::F32Const { .. } => Type::F32,
             Operator::F64Const { .. } => Type::F64,
             Operator::GetGlobal { global_index } => {
                 if global_index as usize >= state.global_count {
                     return self.create_error("init_expr global index out of bounds");
                 }
-                self.globals[global_index as usize].content_type
+                self.resources.globals[global_index as usize].content_type
             }
             _ => return self.create_error("invalid init_expr operator"),
         };
         if ty != state.ty {
             return self.create_error("invalid init_expr type");
         }
         Ok(())
     }
@@ -1843,49 +318,49 @@ impl<'a> ValidatingParser<'a> {
         kind: ExternalKind,
         index: u32,
     ) -> ValidatorResult<'a, ()> {
         if self.exported_names.contains(field) {
             return self.create_error("non-unique export name");
         }
         match kind {
             ExternalKind::Function => {
-                if index as usize >= self.func_type_indices.len() {
+                if index as usize >= self.resources.func_type_indices.len() {
                     return self.create_error("exported function index out of bounds");
                 }
             }
             ExternalKind::Table => {
-                if index as usize >= self.tables.len() {
+                if index as usize >= self.resources.tables.len() {
                     return self.create_error("exported table index out of bounds");
                 }
             }
             ExternalKind::Memory => {
-                if index as usize >= self.memories.len() {
+                if index as usize >= self.resources.memories.len() {
                     return self.create_error("exported memory index out of bounds");
                 }
             }
             ExternalKind::Global => {
-                if index as usize >= self.globals.len() {
+                if index as usize >= self.resources.globals.len() {
                     return self.create_error("exported global index out of bounds");
                 }
-                let global = &self.globals[index as usize];
+                let global = &self.resources.globals[index as usize];
                 if global.mutable && !self.config.mutable_global_imports {
                     return self.create_error("exported global must be const");
                 }
             }
         };
         Ok(())
     }
 
     fn check_start(&self, func_index: u32) -> ValidatorResult<'a, ()> {
-        if func_index as usize >= self.func_type_indices.len() {
+        if func_index as usize >= self.resources.func_type_indices.len() {
             return self.create_error("start function index out of bounds");
         }
-        let type_index = self.func_type_indices[func_index as usize];
-        let ty = &self.types[type_index as usize];
+        let type_index = self.resources.func_type_indices[func_index as usize];
+        let ty = &self.resources.types[type_index as usize];
         if !ty.params.is_empty() || !ty.returns.is_empty() {
             return self.create_error("invlid start function type");
         }
         Ok(())
     }
 
     fn process_begin_section(&self, code: &SectionCode) -> ValidatorResult<'a, SectionOrderState> {
         let order_state = SectionOrderState::from_section_code(code);
@@ -1924,86 +399,86 @@ impl<'a> ValidatingParser<'a> {
                 } else {
                     self.section_order_state = check.ok().unwrap();
                 }
             }
             ParserState::TypeSectionEntry(ref func_type) => {
                 let check = self.check_func_type(func_type);
                 if check.is_err() {
                     self.validation_error = check.err();
-                } else if self.types.len() > MAX_WASM_TYPES {
+                } else if self.resources.types.len() > MAX_WASM_TYPES {
                     self.validation_error =
                         self.create_validation_error("types count is out of bounds");
                 } else {
-                    self.types.push(func_type.clone());
+                    self.resources.types.push(func_type.clone());
                 }
             }
             ParserState::ImportSectionEntry { ref ty, .. } => {
                 let check = self.check_import_entry(ty);
                 if check.is_err() {
                     self.validation_error = check.err();
                 } else {
                     match *ty {
                         ImportSectionEntryType::Function(type_index) => {
                             self.func_imports_count += 1;
-                            self.func_type_indices.push(type_index);
+                            self.resources.func_type_indices.push(type_index);
                         }
                         ImportSectionEntryType::Table(ref table_type) => {
-                            self.tables.push(table_type.clone());
+                            self.resources.tables.push(table_type.clone());
                         }
                         ImportSectionEntryType::Memory(ref memory_type) => {
-                            self.memories.push(memory_type.clone());
+                            self.resources.memories.push(memory_type.clone());
                         }
                         ImportSectionEntryType::Global(ref global_type) => {
-                            self.globals.push(global_type.clone());
+                            self.resources.globals.push(global_type.clone());
                         }
                     }
                 }
             }
             ParserState::FunctionSectionEntry(type_index) => {
-                if type_index as usize >= self.types.len() {
+                if type_index as usize >= self.resources.types.len() {
                     self.validation_error =
                         self.create_validation_error("func type index out of bounds");
-                } else if self.func_type_indices.len() >= MAX_WASM_FUNCTIONS {
+                } else if self.resources.func_type_indices.len() >= MAX_WASM_FUNCTIONS {
                     self.validation_error =
                         self.create_validation_error("functions count out of bounds");
                 } else {
-                    self.func_type_indices.push(type_index);
+                    self.resources.func_type_indices.push(type_index);
                 }
             }
             ParserState::TableSectionEntry(ref table_type) => {
-                if self.tables.len() >= MAX_WASM_TABLES {
+                if self.resources.tables.len() >= MAX_WASM_TABLES {
                     self.validation_error =
                         self.create_validation_error("tables count must be at most 1");
                 } else {
                     self.validation_error = self.check_table_type(table_type).err();
-                    self.tables.push(table_type.clone());
+                    self.resources.tables.push(table_type.clone());
                 }
             }
             ParserState::MemorySectionEntry(ref memory_type) => {
-                if self.memories.len() >= MAX_WASM_MEMORIES {
+                if self.resources.memories.len() >= MAX_WASM_MEMORIES {
                     self.validation_error =
                         self.create_validation_error("memories count must be at most 1");
                 } else {
                     self.validation_error = self.check_memory_type(memory_type).err();
-                    self.memories.push(memory_type.clone());
+                    self.resources.memories.push(memory_type.clone());
                 }
             }
             ParserState::BeginGlobalSectionEntry(global_type) => {
-                if self.globals.len() >= MAX_WASM_GLOBALS {
+                if self.resources.globals.len() >= MAX_WASM_GLOBALS {
                     self.validation_error =
                         self.create_validation_error("globals count out of bounds");
                 } else {
                     self.validation_error = self.check_global_type(global_type).err();
                     self.init_expression_state = Some(InitExpressionState {
                         ty: global_type.content_type,
-                        global_count: self.globals.len(),
+                        global_count: self.resources.globals.len(),
                         validated: false,
                     });
-                    self.globals.push(global_type);
+                    self.resources.globals.push(global_type);
                 }
             }
             ParserState::BeginInitExpressionBody => {
                 assert!(self.init_expression_state.is_some());
             }
             ParserState::InitExpressionOperator(ref operator) => {
                 self.validation_error = self.check_init_expression_operator(operator).err();
                 self.init_expression_state.as_mut().unwrap().validated = true;
@@ -2011,78 +486,75 @@ impl<'a> ValidatingParser<'a> {
             ParserState::EndInitExpressionBody => {
                 if !self.init_expression_state.as_ref().unwrap().validated {
                     self.validation_error = self.create_validation_error("init_expr is empty");
                 }
                 self.init_expression_state = None;
             }
             ParserState::ExportSectionEntry { field, kind, index } => {
                 self.validation_error = self.check_export_entry(field, kind, index).err();
-                self.exported_names.insert(field.to_string());
+                self.exported_names.insert(String::from(field));
             }
             ParserState::StartSectionEntry(func_index) => {
                 self.validation_error = self.check_start(func_index).err();
             }
             ParserState::DataCountSectionEntry(count) => {
-                self.data_count = Some(count);
+                self.resources.data_count = Some(count);
             }
             ParserState::BeginPassiveElementSectionEntry(_ty) => {
-                self.element_count += 1;
+                self.resources.element_count += 1;
             }
             ParserState::BeginActiveElementSectionEntry(table_index) => {
-                self.element_count += 1;
-                if table_index as usize >= self.tables.len() {
+                self.resources.element_count += 1;
+                if table_index as usize >= self.resources.tables.len() {
                     self.validation_error =
                         self.create_validation_error("element section table index out of bounds");
                 } else {
-                    assert!(self.tables[table_index as usize].element_type == Type::AnyFunc);
+                    assert!(
+                        self.resources.tables[table_index as usize].element_type == Type::AnyFunc
+                    );
                     self.init_expression_state = Some(InitExpressionState {
                         ty: Type::I32,
-                        global_count: self.globals.len(),
+                        global_count: self.resources.globals.len(),
                         validated: false,
                     });
                 }
             }
             ParserState::ElementSectionEntryBody(ref indices) => {
                 for func_index in &**indices {
-                    if *func_index as usize >= self.func_type_indices.len() {
+                    if *func_index as usize >= self.resources.func_type_indices.len() {
                         self.validation_error =
                             self.create_validation_error("element func index out of bounds");
                         break;
                     }
                 }
             }
             ParserState::BeginFunctionBody { .. } => {
                 let index = (self.current_func_index + self.func_imports_count) as usize;
-                if index as usize >= self.func_type_indices.len() {
+                if index as usize >= self.resources.func_type_indices.len() {
                     self.validation_error =
                         self.create_validation_error("func type is not defined");
                 }
             }
             ParserState::FunctionBodyLocals { ref locals } => {
                 let index = (self.current_func_index + self.func_imports_count) as usize;
-                let func_type = &self.types[self.func_type_indices[index] as usize];
+                let func_type =
+                    &self.resources.types[self.resources.func_type_indices[index] as usize];
                 let operator_config = self.config.operator_config;
                 self.current_operator_validator =
                     Some(OperatorValidator::new(func_type, locals, operator_config));
             }
             ParserState::CodeOperator(ref operator) => {
                 let check = self
                     .current_operator_validator
-                    .as_ref()
+                    .as_mut()
                     .unwrap()
-                    .process_operator(operator, self);
+                    .process_operator(operator, &self.resources);
                 match check {
-                    Ok(action) => {
-                        if let Err(err) = action.update(
-                            &mut self.current_operator_validator.as_mut().unwrap().func_state,
-                        ) {
-                            self.create_validation_error(err);
-                        }
-                    }
+                    Ok(_) => (),
                     Err(err) => {
                         self.validation_error = self.create_validation_error(err);
                     }
                 }
             }
             ParserState::EndFunctionBody => {
                 let check = self
                     .current_operator_validator
@@ -2094,36 +566,36 @@ impl<'a> ValidatingParser<'a> {
                 }
                 self.current_func_index += 1;
                 self.current_operator_validator = None;
             }
             ParserState::BeginDataSectionEntryBody(_) => {
                 self.data_found += 1;
             }
             ParserState::BeginActiveDataSectionEntry(memory_index) => {
-                if memory_index as usize >= self.memories.len() {
+                if memory_index as usize >= self.resources.memories.len() {
                     self.validation_error =
                         self.create_validation_error("data section memory index out of bounds");
                 } else {
                     self.init_expression_state = Some(InitExpressionState {
                         ty: Type::I32,
-                        global_count: self.globals.len(),
+                        global_count: self.resources.globals.len(),
                         validated: false,
                     });
                 }
             }
             ParserState::EndWasm => {
-                if self.func_type_indices.len()
+                if self.resources.func_type_indices.len()
                     != self.current_func_index as usize + self.func_imports_count as usize
                 {
                     self.validation_error = self.create_validation_error(
                         "function and code section have inconsistent lengths",
                     );
                 }
-                if let Some(data_count) = self.data_count {
+                if let Some(data_count) = self.resources.data_count {
                     if data_count != self.data_found {
                         self.validation_error = self.create_validation_error(
                             "data count section and passive data mismatch",
                         );
                     }
                 }
             }
             _ => (),
@@ -2137,29 +609,25 @@ impl<'a> ValidatingParser<'a> {
         let func_body_offset = match *self.last_state() {
             ParserState::BeginFunctionBody { .. } => self.parser.current_position(),
             _ => panic!("Invalid reader state"),
         };
         self.read();
         let operator_validator = match *self.last_state() {
             ParserState::FunctionBodyLocals { ref locals } => {
                 let index = (self.current_func_index + self.func_imports_count) as usize;
-                let func_type = &self.types[self.func_type_indices[index] as usize];
+                let func_type =
+                    &self.resources.types[self.resources.func_type_indices[index] as usize];
                 let operator_config = self.config.operator_config;
                 OperatorValidator::new(func_type, locals, operator_config)
             }
             _ => panic!("Invalid reader state"),
         };
         let reader = self.create_binary_reader();
-        ValidatingOperatorParser {
-            operator_validator,
-            reader,
-            func_body_offset,
-            end_function: false,
-        }
+        ValidatingOperatorParser::new(operator_validator, reader, func_body_offset)
     }
 }
 
 impl<'a> WasmDecoder<'a> for ValidatingParser<'a> {
     fn read(&mut self) -> &ParserState<'a> {
         if self.validation_error.is_some() {
             panic!("Parser in error state: validation");
         }
@@ -2168,16 +636,20 @@ impl<'a> WasmDecoder<'a> for ValidatingP
         self.process_state();
         self.last_state()
     }
 
     fn push_input(&mut self, input: ParserInput) {
         match input {
             ParserInput::SkipSection => panic!("Not supported"),
             ParserInput::ReadSectionRawData => panic!("Not supported"),
+            ParserInput::SkipFunctionBody => {
+                self.current_func_index += 1;
+                self.parser.push_input(input);
+            }
             _ => self.parser.push_input(input),
         }
     }
 
     fn read_with_input(&mut self, input: ParserInput) -> &ParserState<'a> {
         self.push_input(input);
         self.read()
     }
@@ -2204,16 +676,32 @@ impl<'a> WasmDecoder<'a> for ValidatingP
 pub struct ValidatingOperatorParser<'b> {
     operator_validator: OperatorValidator,
     reader: BinaryReader<'b>,
     func_body_offset: usize,
     end_function: bool,
 }
 
 impl<'b> ValidatingOperatorParser<'b> {
+    pub(crate) fn new<'c>(
+        operator_validator: OperatorValidator,
+        reader: BinaryReader<'c>,
+        func_body_offset: usize,
+    ) -> ValidatingOperatorParser<'c>
+    where
+        'b: 'c,
+    {
+        ValidatingOperatorParser {
+            operator_validator,
+            reader,
+            func_body_offset,
+            end_function: false,
+        }
+    }
+
     pub fn eof(&self) -> bool {
         self.end_function
     }
 
     pub fn current_position(&self) -> usize {
         self.reader.current_position()
     }
 
@@ -2229,75 +717,161 @@ impl<'b> ValidatingOperatorParser<'b> {
     /// # let data = &[0x0, 0x61, 0x73, 0x6d, 0x1, 0x0, 0x0, 0x0, 0x1, 0x84,
     /// #              0x80, 0x80, 0x80, 0x0, 0x1, 0x60, 0x0, 0x0, 0x3, 0x83,
     /// #              0x80, 0x80, 0x80, 0x0, 0x2, 0x0, 0x0, 0x6, 0x81, 0x80,
     /// #              0x80, 0x80, 0x0, 0x0, 0xa, 0x91, 0x80, 0x80, 0x80, 0x0,
     /// #              0x2, 0x83, 0x80, 0x80, 0x80, 0x0, 0x0, 0x1, 0xb, 0x83,
     /// #              0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0xb];
     /// use wasmparser::{WasmDecoder, ParserState, ValidatingParser};
     /// let mut parser = ValidatingParser::new(data, None);
-    /// let mut validating_parsers = Vec::new();
+    /// let mut i = 0;
     /// loop {
     ///     {
     ///         match *parser.read() {
     ///             ParserState::Error(_) |
     ///             ParserState::EndWasm => break,
     ///             ParserState::BeginFunctionBody {..} => (),
     ///             _ => continue
     ///         }
     ///     }
-    ///     let reader = parser.create_validating_operator_parser();
-    ///     validating_parsers.push(reader);
-    /// }
-    /// for (i, reader) in validating_parsers.iter_mut().enumerate() {
+    ///     let mut reader = parser.create_validating_operator_parser();
     ///     println!("Function {}", i);
+    ///     i += 1;
     ///     while !reader.eof() {
-    ///       let read = reader.next(&parser);
+    ///       let read = reader.next(parser.get_resources());
     ///       if let Ok(ref op) = read {
     ///           println!("  {:?}", op);
     ///       } else {
     ///           panic!("  Bad wasm code {:?}", read.err());
     ///       }
     ///     }
     /// }
     /// ```
-    pub fn next(&mut self, resources: &WasmModuleResources) -> Result<Operator<'b>> {
+    pub fn next<'c>(&mut self, resources: &dyn WasmModuleResources) -> Result<Operator<'c>>
+    where
+        'b: 'c,
+    {
         let op = self.reader.read_operator()?;
-        let check = self.operator_validator.process_operator(&op, resources);
-        if check.is_err() {
-            return Err(BinaryReaderError {
-                message: check.err().unwrap(),
-                offset: self.func_body_offset + self.reader.current_position(),
-            });
-        }
-        if let OperatorAction::EndFunction = check.ok().unwrap() {
-            self.end_function = true;
-            if !self.reader.eof() {
+        match self.operator_validator.process_operator(&op, resources) {
+            Err(err) => {
                 return Err(BinaryReaderError {
-                    message: "unexpected end of function",
+                    message: err,
                     offset: self.func_body_offset + self.reader.current_position(),
                 });
             }
-        }
+            Ok(FunctionEnd::Yes) => {
+                self.end_function = true;
+                if !self.reader.eof() {
+                    return Err(BinaryReaderError {
+                        message: "unexpected end of function",
+                        offset: self.func_body_offset + self.reader.current_position(),
+                    });
+                }
+            }
+            _ => (),
+        };
         Ok(op)
     }
 }
 
+/// Test whether the given buffer contains a valid WebAssembly function.
+/// The resources parameter contains all needed data to validate the operators.
+pub fn validate_function_body(
+    bytes: &[u8],
+    func_index: u32,
+    resources: &dyn WasmModuleResources,
+    operator_config: Option<OperatorValidatorConfig>,
+) -> bool {
+    let operator_config = operator_config.unwrap_or(DEFAULT_OPERATOR_VALIDATOR_CONFIG);
+    let function_body = FunctionBody::new(0, bytes);
+    let mut locals_reader = if let Ok(r) = function_body.get_locals_reader() {
+        r
+    } else {
+        return false;
+    };
+    let local_count = locals_reader.get_count() as usize;
+    if local_count > MAX_WASM_FUNCTION_LOCALS {
+        return false;
+    }
+    let mut locals: Vec<(u32, Type)> = Vec::with_capacity(local_count);
+    let mut locals_total: usize = 0;
+    for _ in 0..local_count {
+        let (count, ty) = if let Ok(r) = locals_reader.read() {
+            r
+        } else {
+            return false;
+        };
+        locals_total = if let Some(r) = locals_total.checked_add(count as usize) {
+            r
+        } else {
+            return false;
+        };
+        if locals_total > MAX_WASM_FUNCTION_LOCALS {
+            return false;
+        }
+        locals.push((count, ty));
+    }
+    let operators_reader = if let Ok(r) = function_body.get_operators_reader() {
+        r
+    } else {
+        return false;
+    };
+    let func_type_index = resources.func_type_indices()[func_index as usize];
+    let func_type = &resources.types()[func_type_index as usize];
+    let mut operator_validator = OperatorValidator::new(func_type, &locals, operator_config);
+    let mut eof_found = false;
+    for op in operators_reader.into_iter() {
+        let op = match op {
+            Err(_) => return false,
+            Ok(ref op) => op,
+        };
+        match operator_validator.process_operator(op, resources) {
+            Err(_) => return false,
+            Ok(FunctionEnd::Yes) => {
+                eof_found = true;
+            }
+            Ok(FunctionEnd::No) => (),
+        }
+    }
+    eof_found
+}
+
 /// Test whether the given buffer contains a valid WebAssembly module,
 /// analogous to WebAssembly.validate in the JS API.
 pub fn validate(bytes: &[u8], config: Option<ValidatingParserConfig>) -> bool {
     let mut parser = ValidatingParser::new(bytes, config);
+    let mut parser_input = None;
+    let mut func_ranges = Vec::new();
     loop {
-        let state = parser.read();
+        let next_input = parser_input.take().unwrap_or(ParserInput::Default);
+        let state = parser.read_with_input(next_input);
         match *state {
-            ParserState::EndWasm => return true,
+            ParserState::EndWasm => break,
             ParserState::Error(_) => return false,
+            ParserState::BeginFunctionBody { range } => {
+                parser_input = Some(ParserInput::SkipFunctionBody);
+                func_ranges.push(range);
+            }
             _ => (),
         }
     }
+    let operator_config = config.map(|c| c.operator_config);
+    for (i, range) in func_ranges.into_iter().enumerate() {
+        let function_body = range.slice(bytes);
+        let function_index = i as u32 + parser.func_imports_count;
+        if !validate_function_body(
+            function_body,
+            function_index,
+            &parser.resources,
+            operator_config,
+        ) {
+            return false;
+        }
+    }
+    true
 }
 
 #[test]
 fn test_validate() {
     assert!(validate(&[0x0, 0x61, 0x73, 0x6d, 0x1, 0x0, 0x0, 0x0], None));
     assert!(!validate(
         &[0x0, 0x61, 0x73, 0x6d, 0x2, 0x0, 0x0, 0x0],
         None