Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error assertion left == right failed on Wasm module init in Rust-embedded Wasmtime #9714

Open
Tracked by #5032
epsylonix opened this issue Dec 3, 2024 · 3 comments
Assignees
Labels
bug Incorrect behavior in the current implementation that needs fixing wasm-proposal:gc Issues with the implementation of the gc wasm proposal

Comments

@epsylonix
Copy link

Test Case

I'm trying to run a Kotlin-produced Wasm module in Rust-embedded Wasmtime. Kotlin requires support for the Wasm GC proposal, which Wasmtime officially has since version 27.0.0. Unfortunately, when initializing the Kotlin-generated Wasm module, a Wasmtime assertion error occurs, seemingly related to the Wasm GC code.

I initially assumed some incompatibility between Wasmtime and Kotlin-produced Wasm but the same file can be executed successfully in the standalone mode with wasmtime -W function-references,gc.

The minimal Kotlin guest code that reproduces this issue looks like this:

fun main() {}

And this is the corresponding host code:

use wasmtime::*;
use wasi_common::sync::WasiCtxBuilder;

fn main() -> Result<()> {
    let mut config = Config::new();
    config
        .wasm_gc(true)
        .wasm_function_references(true);

    let engine = Engine::new(&mut config)?;
    let mut linker = Linker::new(&engine);
    wasi_common::sync::add_to_linker(&mut linker, |s| s)?;

    let wasi = WasiCtxBuilder::new()
        .inherit_stderr()
        .inherit_stdout()
        .build();
    let mut store = Store::new(&engine, wasi);

    let module = Module::from_file(&engine, "kotlin.wasm")?;
    linker.instantiate(&mut store, &module)?;

    Ok(())
}

This fails at linker.instantiate call with an error:

thread 'main' panicked at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/type_registry.rs:271:17:
assertion `left == right` failed
  left: WasmSubType { is_final: true, supertype: None, composite_type: WasmCompositeType { inner: Struct(WasmStructType { fields: [] }), shared: false } }
 right: WasmSubType { is_final: true, supertype: Some(Engine(VMSharedTypeIndex(19))), composite_type: WasmCompositeType { inner: Struct(WasmStructType { fields: [] }), shared: false } }

stack backtrace:
   0: rust_begin_unwind
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:662:5
   1: core::panicking::panic_fmt
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/panicking.rs:74:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/panicking.rs:367:5
   4: <wasmtime::runtime::type_registry::RegisteredType as core::cmp::PartialEq>::eq
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/type_registry.rs:271:17
   5: core::cmp::impls::<impl core::cmp::PartialEq<&B> for &A>::eq
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/cmp.rs:1661:13
   6: <Q as hashbrown::Equivalent<K>>::equivalent
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/lib.rs:172:9
   7: hashbrown::map::equivalent_key::{{closure}}
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/map.rs:229:14
   8: hashbrown::raw::inner::RawTable<T,A>::find_or_find_insert_slot::{{closure}}
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/raw/mod.rs:1425:68
   9: hashbrown::raw::inner::RawTableInner::find_or_find_insert_slot_inner
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/raw/mod.rs:1983:27
  10: hashbrown::raw::inner::RawTable<T,A>::find_or_find_insert_slot
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/raw/mod.rs:1423:19
  11: hashbrown::map::HashMap<K,V,S,A>::insert
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/map.rs:1754:15
  12: hashbrown::set::HashSet<T,S,A>::insert
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/set.rs:1115:9
  13: wasmtime::runtime::store::StoreOpaque::insert_gc_host_alloc_type
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/store.rs:1797:9
  14: wasmtime::runtime::gc::enabled::structref::StructRefPre::_new
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/gc/enabled/structref.rs:74:9
  15: wasmtime::runtime::vm::const_expr::ConstEvalContext::struct_new
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/vm/const_expr.rs:93:25
  16: wasmtime::runtime::vm::const_expr::ConstEvalContext::struct_new_default
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/vm/const_expr.rs:153:18
  17: wasmtime::runtime::vm::const_expr::ConstExprEvaluator::eval
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/vm/const_expr.rs:278:31
  18: wasmtime::runtime::vm::instance::allocator::initialize_globals
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/vm/instance/allocator.rs:779:13
  19: wasmtime::runtime::vm::instance::allocator::initialize_instance
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/vm/instance/allocator.rs:826:5
  20: wasmtime::runtime::vm::instance::InstanceHandle::initialize
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/vm/instance.rs:1541:9
  21: wasmtime::runtime::instance::Instance::new_raw
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/instance.rs:343:9
  22: wasmtime::runtime::instance::Instance::new_started_impl
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/instance.rs:206:33
  23: wasmtime::runtime::instance::Instance::new_started
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/instance.rs:194:9
  24: wasmtime::runtime::instance::InstancePre<T>::instantiate
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/instance.rs:876:18
  25: wasmtime::runtime::linker::Linker<T>::instantiate
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-27.0.0/src/runtime/linker.rs:1112:9
  26: jobexecutor::main
             at ./src/main.rs:25:5
  27: core::ops::function::FnOnce::call_once
             at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/ops/function.rs:250:5

Versions and Environment

Wasmtime version or commit: 27.0.0

Operating system: macOS

Architecture: arm64

@epsylonix epsylonix added the bug Incorrect behavior in the current implementation that needs fixing label Dec 3, 2024
@alexcrichton alexcrichton added the wasm-proposal:gc Issues with the implementation of the gc wasm proposal label Dec 3, 2024
@epsylonix
Copy link
Author

epsylonix commented Dec 4, 2024

I've also encountered a similar issue in the standalone mode with when added any non-trivial code. For example, using Kotlin's kotlinx.serialization json and a small code example from docs: https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/basic-serialization.md#json-decoding

import kotlinx.serialization.json.Json

fun main() {
    val data = Json.decodeFromString<HashMap<String, String>>("""
        {"name":"test"}
    """)
    println(data)
}

@WasmExport
fun dummy() {}

Execution results in this error:

thread 'main' panicked at crates/wasmtime/src/runtime/vm/gc/func_ref.rs:81:13:
assertion failed: types.is_subtype(actual_ty, expected_ty)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
[1]    11826 abort      ./wasmtime-v27.0.0/wasmtime -W function-references,gc

I tested it with WasmEdge and it this works there so I assume this is a Wasmtime issue, not Kotlin.

@fitzgen
Copy link
Member

fitzgen commented Dec 4, 2024

Thanks for filing an issue! Can you attach the .wasm or .wat instead of the Kotlin source? That will greatly help us debug and diagnose the issue. Thanks!

@epsylonix
Copy link
Author

epsylonix commented Dec 5, 2024

Thank you for looking into this!

Here are two wasm files for both issues I've mentined.

  1. The first one is an empty main case (fun main() {}) that can be executed by the standalone Wasmtime version but fails with assertion left == right failed when the module is initialized when Wasmtime is embedded in Rust. I'm new to Rust so it might be something I'm doing wrong here but the code is mostly taken from docs.
    assertion_failed__left_eq_right.wasm.zip

  2. The second one is the case with the serialization. It fails even in the standalone version of Wasmtime with assertion failed: types.is_subtype(actual_ty, expected_ty) error.
    assertion_failed__types_is_subtype.wasm.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Incorrect behavior in the current implementation that needs fixing wasm-proposal:gc Issues with the implementation of the gc wasm proposal
Projects
None yet
Development

No branches or pull requests

3 participants