Running a .wasm file in node.js
Asked Answered
M

4

12

I've read many articles about running wasm files in node.js. Whenever I test the code, It throws this error

[TypeError: WebAssembly.instantiate(): Import #0 module="wasi_snapshot_preview1" error: module is not an object or function]

and then it does not show anything in the result. I am using this code:

const sp = {
  env: {
    memoryBase: 0,
    tableBase: 0,
    memory: new WebAssembly.Memory({
      initial: 256
    }),
    table: new WebAssembly.Table({
      initial: 0,
      element: 'anyfunc'
    })
  },
  imports: {
    imported_func: arg => {
      console.log(arg);
    }
  }
}

const fs = require('fs')
, wasm = WebAssembly.instantiate(new Uint8Array(fs.readFileSync('./test.wasm')), sp)
.then(result => console.log(result));

This code is throwing the above error.

Is there anything I am doing wrong?

SOLUTION:

There was nothing wrong with my code, rather here was something wrong with the way I was compiling my code. Instead of using

em++ test.cpp -o test.wasm

I should've used:

em++ -O1 test.cpp -o test.wasm -s WASM=1
Madelenemadelin answered 14/1, 2020 at 1:23 Comment(13)
But did you search Stackoverflow before posting? Because I searched by copy pasting your error message, and found https://mcmap.net/q/1010593/-typeerror-webassembly-instantiation-imports-argument-must-be-present-and-must-be-an-object (as well as two other questions). Also: always check MDN when using web APIs: the error literally tells you that you need an imports argument, and the documentation agrees.Your code only passes in a single argument instead of two.Arcuate
Yes I tried that but it is throwing an error: imports is not definedMadelenemadelin
So update your code to at least use the correct syntax, and then ask about that new error instead. Because right now your code is simply not using WebAssembly.instantiate() correctly.Arcuate
I think that the question you are referencing used browser javascript, while I am using nodeMadelenemadelin
That is entirely irrelevant: any implementation for WebAssembly has to follow the WebAssembly spec, so you'll need to make sure to pass two arguments into .instantiate().Arcuate
In my code, I put the second argument, which is the env. I got that from this tutorialMadelenemadelin
That is not what your code is showing. Please update your post, as a minimal reproducible example.Arcuate
I have updated my code. Sorry for the confusionMadelenemadelin
it's still missing the content of test.wasm, though, which is important for this new, completely different error =)Arcuate
test.wasm is just a file of bytecodeMadelenemadelin
Right, but it comes from somewhere; the error is implying that your code relies on wasi_snapshot_preview1, somehow (either your own code, or because your build chain added that). So the details about test.wasm and how its built are now important.Arcuate
I have actually realized my mistake. I was building the wasm file incorrectly. Thank you for the help thoughMadelenemadelin
in that case it might be worth deleting this question again, or updating it to explain what you did in the post, and then writing an answer that explains why that's wrong.Arcuate
M
8

Change test.wasm to test.js should work as well:

em++ -O1 test.cpp -o test.js -s WASM=1

Using .wasm as the output type or -s STANDALONE_WASM requires a runtime with wasi_snapshot_preview1 support.

Mcbee answered 7/7, 2020 at 14:53 Comment(2)
What does a runtime with wasi_snapshot_preview1 support a mean?Birdlime
Wasmtime, browser, or Node.js that supports WASI.Mcbee
M
2

The error reported is as follows:

[TypeError: WebAssembly.instantiate(): Import #0 module="wasi_snapshot_preview1" error: module is not an object or function]

This indicates that your WebAssembly module, test.wasm, is expecting an import named wasi_snapshot_preview1, which is required in order to instantiate it. This is nothing to do with the Node environment, you would see the same error in the browser.

How are you building and compiling your WebAssembly module? This import suggests you are using WASI.

I would recommend starting with a much simpler WebAssembly example.

Marcello answered 14/1, 2020 at 6:9 Comment(1)
all that i am doing is returning 0 inside a main function in my wasm code. I am using this command to build my wasm: em++ test.cpp -o test.wasmMadelenemadelin
N
1

Using this as second argument for WebAssembly instantiate worked for me:

const importObject = { wasi_snapshot_preview1: wasi.exports };
//more code
const instance = await WebAssembly.instantiate(wasm, importObject);
Nikolai answered 12/9, 2021 at 19:18 Comment(2)
Where does the wasi object come from ?Henryk
It depends on target environment. For example, wasi object is coming from a instance constructed with WASI for Node.js target environment. You can checkout WASI documentation for more details.@HenrykFredra
C
0

I was able to get rid of wasi_snapshot_preview1 error by recompiling with flags

emcc test.c -o test.wasm --no-entry -s EXPORTED_FUNCTIONS=_sum

Parameters: --no-entry means no main alike, sum is the function to be exported from test.c.

suggested by (long) blog post [1]

[1] https://habr.com/en/companies/otus/articles/693572/ (In Russian)

Ching answered 6/10, 2023 at 19:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.