Repository: bytecodealliance/wasmtime (rust)

Issue:
Cranelift: Specifically formatted valid WASM panics with 'block Insertion point not in the layout'
I have been stuck on a WASM module failing to compile under Wasmtime (0.20 and main branch) for some time now.
After a lot of trial and error I have managed to construct a minimal example that fails:

```rust
use wasmtime::{Config, Engine, Linker, Module, Store};

fn main() {
    let mut config = Config::new();
    config.wasm_reference_types(true);
    let engine = Engine::new(&config);
    let module = Module::new(
        &engine,
        "
        (module
            (type (;0;) (func (param externref) (result i32)))
            (func $test (type 0) (param externref) (result i32)
                (local i32)
                i32.const 0
                local.tee 1
                i32.const 0
                i32.eq
                if                    
                else
                end
                local.get 1
                local.get 0
                table.set 0
                local.get 1
            )
            (table (;0;) 4 externref)
            (export \"test\" (func $test))
        )",
    )
    .unwrap();

    let store = Store::new(&engine.clone());
    let linker = Linker::new(&store);

    let _instance = linker.instantiate(&module.clone()).unwrap();
}
```

From my understanding this should be valid WASM, and tools like `wasm-validate --enable-all` also don't complain about anything, but trying to run this code with `RUST_BACKTRACE=1 cargo run` results in:

```
    Finished dev [unoptimized + debuginfo] target(s) in 0.11s
     Running `target/debug/wasmer-bug-report`
thread 'main' panicked at 'block Insertion point not in the layout', /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-codegen-0.67.0/src/ir/layout.rs:401:9
stack backtrace:
   0: std::panicking::begin_panic
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:505:12
   1: cranelift_codegen::ir::layout::Layout::insert_block_after
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-codegen-0.67.0/src/ir/layout.rs:401:9
   2: cranelift_frontend::frontend::FunctionBuilder::insert_block_after
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-frontend-0.67.0/src/frontend.rs:233:9
   3: <wasmtime_cranelift::func_environ::FuncEnvironment as cranelift_wasm::environ::spec::FuncEnvironment>::translate_table_set
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-cranelift-0.20.0/src/func_environ.rs:668:17
   4: cranelift_wasm::code_translator::translate_operator
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-wasm-0.67.0/src/code_translator.rs:1413:13
   5: cranelift_wasm::func_translator::parse_function_body
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-wasm-0.67.0/src/func_translator.rs:235:9
   6: cranelift_wasm::func_translator::FuncTranslator::translate_from_reader
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-wasm-0.67.0/src/func_translator.rs:111:9
   7: cranelift_wasm::func_translator::FuncTranslator::translate
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-wasm-0.67.0/src/func_translator.rs:64:9
   8: <wasmtime_cranelift::Cranelift as wasmtime_environ::compilation::Compiler>::compile_function
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-cranelift-0.20.0/src/lib.rs:354:22
   9: wasmtime_jit::compiler::Compiler::compile::{{closure}}
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-jit-0.20.0/src/compiler.rs:128:17
  10: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:247:13
  11: core::iter::adapters::map_try_fold::{{closure}}
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:912:28
  12: core::iter::traits::iterator::Iterator::try_fold
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1888:21
  13: <core::iter::adapters::Map<I,F> as core::iter::traits::iterator::Iterator>::try_fold
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:938:9
  14: <core::iter::adapters::Map<I,F> as core::iter::traits::iterator::Iterator>::try_fold
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:938:9
  15: <core::iter::adapters::TakeWhile<I,P> as core::iter::traits::iterator::Iterator>::try_fold
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:2078:13
  16: <core::iter::adapters::Map<I,F> as core::iter::traits::iterator::Iterator>::try_fold
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:938:9
  17: <core::iter::adapters::TakeWhile<I,P> as core::iter::traits::iterator::Iterator>::try_fold
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:2078:13
  18: <core::iter::adapters::TakeWhile<I,P> as core::iter::traits::iterator::Iterator>::fold
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:2093:9
  19: <rayon::iter::fold::FoldFolder<C,ID,F> as rayon::iter::plumbing::Folder<T>>::consume_iter
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/fold.rs:158:20
  20: <rayon::iter::while_some::WhileSomeFolder<C> as rayon::iter::plumbing::Folder<core::option::Option<T>>>::consume_iter
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/while_some.rs:139:21
  21: <rayon::iter::map::MapFolder<C,F> as rayon::iter::plumbing::Folder<T>>::consume_iter
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/map.rs:248:21
  22: <rayon::iter::map::MapFolder<C,F> as rayon::iter::plumbing::Folder<T>>::consume_iter
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/map.rs:248:21
  23: rayon::iter::plumbing::Producer::fold_with
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/plumbing/mod.rs:110:9
  24: rayon::iter::plumbing::bridge_producer_consumer::helper
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/plumbing/mod.rs:438:13
  25: rayon::iter::plumbing::bridge_producer_consumer
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/plumbing/mod.rs:397:12
  26: <rayon::iter::plumbing::bridge::Callback<C> as rayon::iter::plumbing::ProducerCallback<I>>::callback
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/plumbing/mod.rs:373:13
  27: <rayon::vec::Drain<T> as rayon::iter::IndexedParallelIterator>::with_producer
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/vec.rs:130:13
  28: <rayon::vec::IntoIter<T> as rayon::iter::IndexedParallelIterator>::with_producer
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/vec.rs:64:9
  29: rayon::iter::plumbing::bridge
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/plumbing/mod.rs:357:12
  30: <rayon::vec::IntoIter<T> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/vec.rs:39:9
  31: <rayon::iter::map::Map<I,F> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/map.rs:49:9
  32: <rayon::iter::map::Map<I,F> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/map.rs:49:9
  33: <rayon::iter::while_some::WhileSome<I> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/while_some.rs:44:9
  34: <rayon::iter::fold::Fold<I,ID,F> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/fold.rs:59:9
  35: <rayon::iter::map::Map<I,F> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/map.rs:49:9
  36: rayon::iter::reduce::reduce
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/reduce.rs:15:5
  37: rayon::iter::ParallelIterator::reduce
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/mod.rs:981:9
  38: rayon::iter::extend::collect
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/extend.rs:29:5
  39: rayon::iter::collect::<impl rayon::iter::ParallelExtend<T> for alloc::vec::Vec<T>>::par_extend
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/collect/mod.rs:163:28
  40: rayon::iter::from_par_iter::collect_extended
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/from_par_iter.rs:17:5
  41: rayon::iter::from_par_iter::<impl rayon::iter::FromParallelIterator<T> for alloc::vec::Vec<T>>::from_par_iter
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/from_par_iter.rs:30:9
  42: rayon::iter::ParallelIterator::collect
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/mod.rs:1973:9
  43: rayon::result::<impl rayon::iter::FromParallelIterator<core::result::Result<T,E>> for core::result::Result<C,E>>::from_par_iter
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/result.rs:121:26
  44: rayon::iter::ParallelIterator::collect
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.4.1/src/iter/mod.rs:1973:9
  45: wasmtime_jit::compiler::Compiler::compile
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-jit-0.20.0/src/compiler.rs:126:21
  46: wasmtime_jit::instantiate::CompilationArtifacts::build
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-jit-0.20.0/src/instantiate.rs:95:13
  47: wasmtime::module::Module::compile::{{closure}}
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-0.20.0/src/module.rs:308:17
  48: core::ops::function::FnOnce::call_once
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
  49: wasmtime_cache::ModuleCacheEntry::get_data
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-cache-0.20.0/src/lib.rs:59:28
  50: wasmtime::module::Module::compile
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-0.20.0/src/module.rs:306:25
  51: wasmtime::module::Module::from_binary_unchecked
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-0.20.0/src/module.rs:276:9
  52: wasmtime::module::Module::from_binary
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-0.20.0/src/module.rs:245:18
  53: wasmtime::module::Module::new
             at /Users/bkolobara/.cargo/registry/src/github.com-1ecc6299db9ec823/wasmtime-0.20.0/src/module.rs:156:9
  54: wasmer_bug_report::main
             at ./src/main.rs:7:18
  55: core::ops::function::FnOnce::call_once
             at /Users/bkolobara/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

Note that if the empty `if-else-end block` is removed it compiles fine. Or if the externref `table.set` is removed it also works fine. But this exact instruction sequence fails.

It could also be that I'm miss-understanding the WASM specification and that this is not valid WASM.

Pull request description:
Fix a panic in table-ops translation
This fixes an issue where `ensure_inserted_block()` wasn't called before
we do some block manipulation in the Wasmtime translation of some
table-related instructions. It looks like `ensure_inserted_block()` is
otherwise called on most instructions being added, so we just need to
call it explicitly it seems here.

Closes #2347


Patch:
diff --git a/crates/cranelift/src/func_environ.rs b/crates/cranelift/src/func_environ.rs
index efe1e5beb..99ebd0314 100644
--- a/crates/cranelift/src/func_environ.rs
+++ b/crates/cranelift/src/func_environ.rs
@@ -494,6 +494,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
 
                 let reference_type = self.reference_type(WasmType::ExternRef);
 
+                builder.ensure_inserted_block();
                 let continue_block = builder.create_block();
                 let non_null_elem_block = builder.create_block();
                 let gc_block = builder.create_block();
@@ -643,6 +644,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
                 //    drop the old table element *after* we've replaced it with
                 //    the new `value`!
 
+                builder.ensure_inserted_block();
                 let current_block = builder.current_block().unwrap();
                 let inc_ref_count_block = builder.create_block();
                 builder.insert_block_after(inc_ref_count_block, current_block);


Test patch:
diff --git a/tests/misc_testsuite/reference-types/no-panic.wast b/tests/misc_testsuite/reference-types/no-panic.wast
new file mode 100644
index 000000000..f6318ed6b
--- /dev/null
+++ b/tests/misc_testsuite/reference-types/no-panic.wast
@@ -0,0 +1,26 @@
+(module
+  (func $test (param i32) (result externref)
+        i32.const 0
+        if
+        else
+        end
+        local.get 0
+        table.get 0
+  )
+  (table 4 externref)
+  (export "test" (func $test))
+)
+
+(module
+  (func $test (param i32)
+        i32.const 0
+        if
+        else
+        end
+        local.get 0
+        ref.null extern
+        table.set 0
+  )
+  (table 4 externref)
+  (export "test" (func $test))
+)