Skip to content

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

Open
@andykais

Description

@andykais

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: #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:

import Context from 'https://deno.land/[email protected]/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:

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions