emscripten-core / emscripten-core/emscripten

compile wasm binary without javascript imports.env (for deno support)

Open
#13,190 11 comments 0 reactions 0 assignees View on GitHub
JavaScript
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Hi, just looking for a general guide on how to compile wasm programs ready for deno. The only issue I found related to deno support is this one: https://github.com/emscripten-core/emscripten/issues/12203 does emscripten not support deno currently?

I am currently trying my luck at compiling opencv to deno using their wasm compilation guide: https://docs.opencv.org/master/d4/da1/tutorial_js_setup.html.

I cannot use the resulting js with deno out of the box though.
```
✘ andrew  ~/Code/scratchwork/opencv  deno run build_js/bin/opencv.js
error: Uncaught ReferenceError: Module is not defined
Module = {};
^
at file:///Users/andrew/Code/scratchwork/opencv/build_js/bin/opencv.js:46:12
at file:///Users/andrew/Code/scratchwork/opencv/build_js/bin/opencv.js:14:15
at file:///Users/andrew/Code/scratchwork/opencv/build_js/bin/opencv.js:22:2
```

I have attempted running just the extracted wasm binary from the opencv.js emscripten output. I can run that with the following deno code:
```ts
import Context from 'https://deno.land/std@0.83.0/wasi/snapshot_preview1.ts'

const context = new Context({
args: Deno.args,
env: Deno.env.toObject()
})
const wasmCode = await Deno.readFile('./opencv.wasm')
const module = await WebAssembly.compile(wasmCode)
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })

const instance = await WebAssembly.instantiate(module, {
wasi_snapshot_preview1: context.exports
})
```
this still expects some emscripten javascsript code:
```
$ deno run --allow-read --v8-flags="--experimental-wasm-threads" --allow-env deno-wasm.ts
Check file:///Users/andrew/Code/scratchwork/opencv/deno-wasm.ts
error: Uncaught (in promise) TypeError: WebAssembly.instantiate(): Import #0 module="env" error: module is not an object or function
const instance = await WebAssembly.instantiate(module, {
^
at deno-wasm.ts:11:36
```
I have seen a few issues specifying how to pass an env to Webassembly.instantiate that look like the following:
```ts
const instance = await WebAssembly.instantiate(module, {
env: {
abortStackOverflow: () => { throw new Error('overflow'); },
table: new WebAssembly.Table({ initial: 0, maximum: 0, element: 'anyfunc' }),
__table_base: 0,
memory: memory,
__memory_base: 1024,
STACKTOP: 0,
STACK_MAX: memory.buffer.byteLength,
},
wasi_snapshot_preview1: context.exports
})
```
however wasm appears to be expecting some emscripten specific functions
```
error: Uncaught (in promise) LinkError: WebAssembly.instantiate(): Import #0 module="env" function="_emval_new_array" error: function import requires a callable
```
Is there a way to either shove those allocation functions into the wasm binary, or import those functions independent of the compiled emscripten js output? I have tried the following flags: `-s STANDALONE`, `-s WASM=1`, `-s SINGLE_FILE=1`, `--no-entry` but none of them avoid the wasm binary relying on those functions.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.