Wasm: Uncaught (in promise) TypeError: Import #0 module="env" error: module is not an object or function Promise.then (async) (anonymous) @ (index):9
Asked Answered
E

2

9

I'm new to emscripten and find it very hard... I have obligation to work on windows because i have to test .exe versions of my apps. I'm on windows 7.

I can compile wasm but javascript cannot read it. Here's my code.

C code:

char * HelloWorld ()
{
    return "Hello World !";
}

Emscripten command-line:

emcc hello.c -O2 -s ONLY_MY_CODE=1 -s WASM=1 -s SIDE_MODULE=1 -s EXPORTED_FUNCTIONS="['_HelloWorld']" -o hello.wasm

Wat result:

(module
  (type $t0 (func (result i32)))
  (type $t1 (func))
  (import "env" "memory" (memory $env.memory 256))
  (import "env" "memoryBase" (global $env.memoryBase i32))
  (func $_HelloWorld (export "_HelloWorld") (type $t0) (result i32)
    (get_global $env.memoryBase))
  (func $__post_instantiate (export "__post_instantiate") (type $t1)
    (set_global $g1
      (i32.add
        (get_global $env.memoryBase)
        (i32.const 16)))
    (set_global $g2
      (i32.add
        (get_global $g1)
        (i32.const 5242880))))
  (global $g1 (mut i32) (i32.const 0))
  (global $g2 (mut i32) (i32.const 0))
  (data (get_global $env.memoryBase) "Hello World !"))

Javascript:

importObject = {};

fetch('hello.wasm').then(response =>
  response.arrayBuffer()
).then(bytes =>
  WebAssembly.instantiate(bytes, importObject)
).then(results => {
  console.log("loaded");
});

Error message:

Uncaught (in promise) TypeError: Import #0 module="env" error: module is not an object or function
Promise.then (async)
(anonymous) @ (index):9

Can you tell me what's wrong in my code ?

Elsey answered 3/10, 2018 at 9:20 Comment(1)
I know this question is very old but does nobody see the undefined behavior caused from the C code?Phenix
V
6

I think the challenge is this: WebAssembly isn't fully baked yet.

The examples show their loader from what looks like an NPM package. In that package, importObj is optional.

You and I are trying to use WebAssembly.instantiate() - I'm using a web worker.

So we need to pass a more complete imports - specifically an env with an abort methoed. Here's an example from https://webassembly.studio 's assemblyscript starter project:

main.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body style="background: #fff">
  <span id="container"></span>
  <script src="./main.js"></script>
</body>
</html>

main.js

WebAssembly.instantiateStreaming(fetch("../out/main.wasm"), {
  main: {
    sayHello() {
      console.log("Hello from WebAssembly!");
    }
  },
  env: {
    abort(_msg, _file, line, column) {
      console.error("abort called at main.ts:" + line + ":" + column);
    }
  },
}).then(result => {
  const exports = result.instance.exports;
  document.getElementById("container").textContent = "Result: " + exports.add(19, 23);
}).catch(console.error);

main.ts

declare function sayHello(): void;

sayHello();

export function add(x: i32, y: i32): i32 {
  return x + y;
}

Note the env.abort function in importObject

Vigen answered 14/9, 2019 at 19:48 Comment(3)
Question relate to C and emscripten)Stedmann
I guess this question is not actual anymore due its ageStedmann
Search for that error brings this article. This error is the same as when trying to use an example for the AssemblyScript loader with the WebAssembly browser instantiate. The problem wasn't C/emscripten, it's not filling in the importObj correctly. It would be super helpful if there were more examples to work from.Vigen
R
5

you should write importObject like this

const importObject = {
  env: {
    __memory_base: 0,
    __table_base: 0,
    memory: new WebAssembly.Memory({initial: 1})
  }
}
Rattler answered 5/8, 2021 at 8:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.