Skip to content

Runtime crash with Rust + lto + simd + Emscripten EH #20414

@kleisauke

Description

@kleisauke

Given this example Rust program:
src/main.rs:

use std::collections::HashMap;

fn print_map(map: &HashMap<&str, &str>) {
    for (key, value) in map {
        println!("{}: {}", key, value);
    }
}

fn main() {
   let mut map = HashMap::new();
   map.insert("Hello", "world!");
   print_map(&map);
}

Fails at runtime when building with RUSTFLAGS="-Ctarget-feature=+simd128 -Clto -Cembed-bitcode=yes":

$ curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal --target wasm32-unknown-emscripten --default-toolchain nightly-2023-10-09 --component rust-src
$ source "$HOME/.cargo/env"
$ cargo new foo
$ cd foo
$ cat <<EOT > src/main.rs
use std::collections::HashMap;

fn print_map(map: &HashMap<&str, &str>) {
    for (key, value) in map {
        println!("{}: {}", key, value);
    }
}

fn main() {
   let mut map = HashMap::new();
   map.insert("Hello", "world!");
   print_map(&map);
}
EOT
$ RUSTFLAGS="-g -Ctarget-feature=+simd128 -Clto -Cembed-bitcode=yes" cargo build --release -Zbuild-std=panic_abort,std --target wasm32-unknown-emscripten
$ node target/wasm32-unknown-emscripten/release/foo.js
/home/kleisauke/foo/target/wasm32-unknown-emscripten/release/foo.js:114
      throw ex;
      ^

TypeError: type incompatibility when transforming from/to JS
    at foo.wasm.foo::main::h87ae4359dffc67a0 (wasm://wasm/foo.wasm-0055ddf2:wasm-function[35]:0x13a3)
    at foo.wasm.std::sys_common::backtrace::__rust_begin_short_backtrace::hbc269fb224856d88 (wasm://wasm/foo.wasm-0055ddf2:wasm-function[30]:0x65a)
    at invoke_vi (/home/kleisauke/foo/target/wasm32-unknown-emscripten/release/foo.js:3775:29)
    at foo.wasm.main (wasm://wasm/foo.wasm-0055ddf2:wasm-function[50]:0x2ea9)
    at Module._main (/home/kleisauke/foo/target/wasm32-unknown-emscripten/release/foo.js:3715:90)
    at callMain (/home/kleisauke/foo/target/wasm32-unknown-emscripten/release/foo.js:3903:15)
    at doRun (/home/kleisauke/foo/target/wasm32-unknown-emscripten/release/foo.js:3942:23)
    at run (/home/kleisauke/foo/target/wasm32-unknown-emscripten/release/foo.js:3957:5)
    at runCaller (/home/kleisauke/foo/target/wasm32-unknown-emscripten/release/foo.js:3882:19)
    at removeRunDependency (/home/kleisauke/foo/target/wasm32-unknown-emscripten/release/foo.js:409:7)

Node.js v20.5.1

While debugging this, I noticed that LLVM generates a invoke_iiV wrapper in WebAssemblyLowerEmscriptenEHSjLj.cpp, which would suggests that it attempts to transmit a V128 value to JavaScript, which isn't supported.
https://github.com/llvm/llvm-project/blob/32f719776552542691f14e786400fc222b7416f1/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp#L122-L123

Version of emscripten/emsdk:

$ emcc -v
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.47-git (a57ebdc55bae77a6b4f7dd05422b381ead72c3fd)
clang version 18.0.0 (https://github.com/llvm/llvm-project 18622fc2f4bcd58f9076301babdfbcca9c0a70d0)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/kleisauke/emsdk/upstream/bin

Context: kleisauke/wasm-vips#48.

(Feel free to transfer this issue if it doesn't belong here)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions