Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error instantiating WASM module: "module is not an object or function"

I'm trying to instantiate a .wasm file locally in node.js. The goal is to run the binary locally and reproduce the functionalities of the web page. Here's my minimum reproducible example:

const fetch = require("node-fetch");

const importObject = {
  imports: {
    imported_func: function(arg) {
      console.log(arg);
    }
  }
};

fetch('https://www.supremenewyork.com/ticket.wasm').then(response =>
  response.arrayBuffer()
).then(bytes => {
  let mod = new WebAssembly.Module(bytes);
  let instance = new WebAssembly.Instance(mod, importObject);
  instance.exports.exported_func();
})

The error I get is:

TypeError: WebAssembly.Instance(): Import #0 module="wasi_unstable" error: module is not an object or function

I saw some questions with similar problems but no real solutions were provided. This is my first time working with wasm so I'm pretty lost.

like image 669
Lucca Baumgärtner Avatar asked Jun 04 '20 12:06

Lucca Baumgärtner


People also ask

Is it possible to fetch and instantiate a Wasm module?

Warning: This method is not the most efficient way of fetching and instantiating wasm modules. If at all possible, you should use the newer WebAssembly.instantiateStreaming () method instead, which fetches, compiles, and instantiates a module all in one step, directly from the raw bytecode, so doesn't require conversion to an ArrayBuffer .

How do I import a module into a WebAssembly worker?

In the worker (see wasm_worker.js ) we define an import object for the module to use, then set up an event handler to receive the module from the main thread. When the module is received, we create an instance from it using the WebAssembly.instantiate () method and invoke an exported function from inside it.

How to instantiate a Wasm file in EMCC?

Instead, if you want to instantiate it yourself, you can look in the .wast at what it expects. However, you'll need to match the ABI expectations as well, like creating the stack, libc syscall imports if you print etc. In other words, emcc emits wasm files that are not standalone, they are designed to work with the .js file emcc emits for you.

Is it possible to use a Wasm file as a standalone file?

In theory a wasm file could be standalone, if you don't use any imports, manage your own stack, etc. and just provide exports that are called from outside. You can try to experiment with this using the ONLY_MY_CODE option to emcc, but it's not much tested yet-the main focus in emscripten has been to get C and C++ programs to "just work".


2 Answers

Your module seems to depend on the wasi_unstable API. If you want to load it you will need an implementation of that API.

To see exactly what imports you module needs you can use wasm2wat or wasmdis tools from wabt and binaryen projects respectively.

If you built your wasm module with emscripten then the recommended practice is to have the emscripten generate JS to that implenents these APIs and takes case of loading the module for you.

If you build your wasm module with the wasi-sdk then you need some kind of web polyfill for the WASI APIs.

like image 136
sbc100 Avatar answered Oct 29 '22 08:10

sbc100


This will make the error go away:

const importObject = {
  imports: {
    imported_func: function(arg) {
      console.log(arg);
    },
    wasi_unstable: () => {}
  }
};
like image 22
GirkovArpa Avatar answered Oct 29 '22 07:10

GirkovArpa