Program Versions
$ rustc --version --verbose
rustc 1.65.0-nightly (0b79f758c 2022-08-18)
binary: rustc
commit-hash: 0b79f758c9aa6646606662a6d623a0752286cd17
commit-date: 2022-08-18
host: x86_64-unknown-linux-gnu
release: 1.65.0-nightly
LLVM version: 15.0.0
$ cargo --version
cargo 1.65.0-nightly (9809f8ff3 2022-08-16)
$ wasmtime --version
wasmtime-cli 0.39.1
$ nodejs --version
v12.22.9
Steps to Reproduce
I created a new Rust crate containing this source code:
use std::sync::atomic::{AtomicI32, Ordering};
static VALUE: AtomicI32 = AtomicI32::new(5);
fn basic_op() -> i32 {
VALUE.fetch_add(1, Ordering::SeqCst)
}
fn main() {
let v = basic_op() + basic_op() + basic_op();
}
Then, I compiled it to the target wasm32-unknown-unknown
, with the appropriate features enabled for atomics and global memory.
$ RUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+mutable-globals' cargo build --target wasm32-unknown-unknown -Z build-std=panic_abort,std
Then, I attempted to run the resulting .wasm
file in the wasmtime
runtime:
$ wasmtime run --wasm-features all target/wasm32-unknown-unknown/debug/simple-atomic.wasm
Error: failed to run main module `target/wasm32-unknown-unknown/debug/simple-atomic.wasm`
Caused by:
0: failed to instantiate "target/wasm32-unknown-unknown/debug/simple-atomic.wasm"
1: unknown import: `env::memory` has not been defined
Believing this to be a bug in wasmtime
, I then tried compiling the file in nodejs
.
$ nodejs --experimental-repl-await --experimental-wasm-anyref --experimental-wasm-bulk-memory --experimental-wasm-bigint --experimental-wasm-eh --experimental-wasm-mv --experimental-wasm-return-call --experimental-wasm-sat-f2i-conversions --experimental-wasm-se --experimental-wasm-simd --experimental-wasm-threads --experimental-wasm-type-reflection --experimental-wasm-anyref
Welcome to Node.js v12.22.9.
Type ".help" for more information.
> const fs = require("fs");
undefined
> let source = fs.readFileSync("target/wasm32-unknown-unknown/debug/simple-atomic.wasm")
undefined
> let instance = await WebAssembly.instantiate(source, {});
Uncaught:
TypeError: WebAssembly.instantiate(): Import #0 module="env" error: module is not an object or function
> let instance = await WebAssembly.instantiate(source, { env: { memory: [] } });
Uncaught:
LinkError: WebAssembly.instantiate(): Import #0 module="env" function="memory" error: memory import must be a WebAssembly.Memory object
It looks like the WASM file expects a "memory" object in its environment. I cannot find any documentation on this "memory" object. I assume it's supposed to be an object where global memory is stored. How should this be set from the JS end? Is there a way, within wasmtime
, to successfully invoke this code?