Skip to content
/ wapi Public

A minimal yet viable Web-first Wasm/JS bridge.

Notifications You must be signed in to change notification settings

dcodeIO/wapi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wapi

An experiment to create a minimal yet viable Web-first Wasm/JS bridge that works today. Similar to Emscripten's EM_ASM, but with most glue code contained in the Wasm binary for ease of use.

Usage

import wapi from "./index.js"

const wapiEnv = {
  getString(ptr) { ... }, // compiler-specific
  ...
}
const module = await WebAssembly.instantiate(theModule, { wapi: wapi(wapiEnv) })
...

How it works

Constructing a wapi environment creates an object to be imported into Wasm with two properties:

  • call, which executes the JS code given to it from within WebAssembly while caching it for further calls and
  • env, which is the common environment of all wapi calls

Upon construction, own properties of the initially provided wapiEnv (that then becomes env) are added to the scope of the JS code that will be executed, just as if these were globals:

// Init common environment
const wapiEnv = {
  hello() { ... }
  world(a) { ... }
}
WebAssembly.instantiate(theModule, { wapi: wapi(wapiEnv) })

// Within WebAssembly (pseudo-code)
wapi.call(`() => hello()`)
wapi.call(`(a) => world(a)`, a)

Works best with some level of compiler integration abstracting the wapi.calls away, but doesn't strictly require it as long as a compiler supports generating imports of the same name with multiple signatures.

How it performs

The JS magic used has some overhead, as it looks up the cached version of the code using a branch and then calls it indirectly, per call. Experiments indicate that a wapi.call (just the call, the code it executes is unaffected) is about 35-50% slower than a normal import call in V8. If the code being run performs non-trivial work anyway, this overhead seems to be neglectable. Otherwise it may depend.

How large is it

That large plus compiler-specific integration, e.g. to read strings from linear memory in the respective language's string encoding.

Building

npm install
npm run asbuild

Testing

npm test

About

A minimal yet viable Web-first Wasm/JS bridge.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published