Reputation: 91
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 ?
Upvotes: 9
Views: 9268
Reputation: 101
you should write importObject like this
const importObject = {
env: {
__memory_base: 0,
__table_base: 0,
memory: new WebAssembly.Memory({initial: 1})
}
}
Upvotes: 5
Reputation: 16217
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
Upvotes: 6