runWasix fails, "memory import has 1 pages which is smaller than the declared initial of 17"
vexcat opened this issue · comments
Attempting to run a WASIX program using runWasix(module, {})
on @wasmer/sdk 0.6.0 fails with ok: false.
Using initializeLogger('trace');
to enable logging reveals the following:
DEBUG run_wasix_inner: wasmer_js::runtime: Initializing the global runtime
DEBUG run_wasix_inner: wasmer_js::tasks::scheduler: Spinning up the scheduler thread_id=0
DEBUG run_wasix_inner: wasmer_js::tasks::scheduler: Sending message to scheduler current_thread=0 msg=SpawnWithModule { module: Module { name: None }, task: _ }
DEBUG wait: wasmer_js::streams: Pipe closed
DEBUG wait:close: wasmer_js::streams: close
DEBUG wait: wasmer_js::instance: Closed stdin
DEBUG handle{worker.id=1}: wasmer_js::tasks::worker_message: Sending a worker message current_thread=1 msg=MarkBusy
DEBUG handle{worker.id=1}:run: wasmer_wasix::fs: Initializing WASI filesystem
DEBUG handle{worker.id=1}:run: wasmer_wasix::fs: Attempting to preopen / with alias None
DEBUG wasmer_js::tasks::scheduler: Sending message to scheduler current_thread=0 msg=WorkerBusy { worker_id: 1 }
DEBUG handle{worker.id=1}:run: wasmer::js::module: imported shared memory MemoryType { minimum: 1 pages, maximum: None, shared: false }
ERROR handle{worker.id=1}:run: wasmer_wasix::state::env: Instantiation failed pid=1 error=RuntimeError: js: WebAssembly.Instance(): Import #16 module="env" function="memory": memory import has 1 pages which is smaller than the declared initial of 17
DEBUG wasmer_js::streams: EOF
DEBUG wasmer_js::streams: EOF
DEBUG handle{worker.id=1}:run: wasmer_js::instance: Process exited unexpectedly error=Instantiation failed error.sources=[RuntimeError: js: WebAssembly.Instance(): Import #16 module="env" function="memory": memory import has 1 pages which is smaller than the declared initial of 17]
DEBUG handle{worker.id=1}:run: wasmer_js::run: close
DEBUG handle{worker.id=1}: wasmer_js::tasks::worker_message: Sending a worker message current_thread=1 msg=MarkIdle
DEBUG handle{worker.id=1}: wasmer_js::tasks::thread_pool_worker: close
INFO wait: wasmer_js::instance: close
DEBUG wasmer_js::tasks::scheduler: Sending message to scheduler current_thread=0 msg=WorkerIdle { worker_id: 1 }
Memory import in .wasm file:
(memory $env.memory (;0;) (import "env" "memory") 17 65536 shared)
Despite this being the only memory import, MemoryType { minimum: 1 pages, maximum: None, shared: false }
is logged, and wasmer attempts to initialize the module with only 1 page of memory.
Code to reproduce:
use rayon::prelude::*;
const NUM_THREADS: usize = 10;
fn thread_entry_point(id: usize) {
println!(" in thread {}", id);
}
fn main() {
let threads: Vec<_> = (0..NUM_THREADS).collect();
threads.into_par_iter().for_each(|i| {
thread_entry_point(i);
});
}
cargo wasix build -r
import { init, runWasix, Wasmer, initializeLogger } from '@wasmer/sdk';
await init();
initializeLogger('trace');
let module = await WebAssembly.compileStreaming(fetch('/rayon-threads.wasm'));
let instance = await runWasix(module, {});
const { code, stdout, stderr, ok } = await instance.wait();
console.log(`Wasix exited with ${code} (${ok}): ${stdout} ${stderr}`);
Hi @vexcat, this is a known limitation and happens because the browser doesn't expose a way for finding out how many pages a WebAssembly.Memory
import requires.
You can find the full explanation, code sample, and solution in the docs: Instantiation Failed Due to Memory Import Mismatch.
The solution is to give runWasix()
the *.wasm
file's bytes and let it handle the module compilation. We have a polyfill which will manually parse the *.wasm
file and extract the information needed to properly instantiate the WebAssembly module.
const response = await fetch("/rayon-threads.wasm");
const wasm = await response.arrayBuffer();
const instance = await runWasix(wasm);
...
Hi, thanks for the response.
let wasmReq = await fetch('/rayon-threads.wasm');
let wasmArr = new Uint8Array(await wasmReq.arrayBuffer());
let instance = await runWasix(wasmArr, {});
This does not work either, failing with the same error. Maybe this is a recent regression?