wasmerio / wai

A language binding generator for `wai` (a precursor to WebAssembly interface types)
Apache License 2.0
114 stars 13 forks source link

WebAssembly Interfaces

A language bindings generator for wai

A Wasmer project building on wai

build status supported rustc stable

About

Note: Unfortunately, the maintainers behind wit-bindgen didn’t want to add support for Wasmer upstream, so we had to do a hard-fork in order to make things work with Wasmer.

This project is a bindings generator framework for WebAssembly programs and embeddings of WebAssembly. This works with *.wai files which describe the interface of a module, either imported or exported. For example this project can be used in cases such as:

This project is based on the interface types proposal. This repository will be following upstream changes. The purpose of wai is to provide a forwards-compatible toolchain and story for interface types and a canonical ABI. Generated language bindings all use the canonical ABI for communication, enabling WebAssembly modules to be written in any language with support and for WebAssembly modules to be consumed in any environment with language support.

Demo

View generated bindings online!

If you're curious to poke around and see what generated bindings look like for a given input *.wai, you can explore the generated code online to get an idea of what's being generated and what the glue code looks like.

Usage

At this time a CLI tool is provided mostly for debugging and exploratory purposes. It can be used easily with the wasmer CLI.

// browser.wai

record person {
  name: string,
  age: u32,
}

// Say hello to either the specified person or the current user
hello: func(who: option<person>) -> string
$ wasmer run wasmer/wai-bindgen-cli --dir=. -- js --import browser.wai
Generating "browser.d.ts"
Generating "browser.js"
Generating "intrinsics.js"

This tool is not necessarily intended to be integrated into toolchains. For example usage in Rust would more likely be done through procedural macros and Cargo dependencies. Usage in a Web application would probably use a version of wai-bindgen compiled to WebAssembly and published to NPM.

For now, though, you can explore what bindings look like in each language through the CLI. Again if you'd like to depend on this if you wouldn't mind please reach out on Slack so we can figure out a better story than relying on the CLI tool for your use case.

Supported Languages

First here's a list of supported languages for generating a WebAssembly binary which uses interface types. This means that these languages support *.wai-defined imports and exports.

This repository also supports a number of host languages/runtimes which can be used to consume WebAssembly modules that use interface types. These modules need to follow the canonical ABI for their exports/imports:

All generators support the --import and --export flags in the wai-bindgen CLI tool:

$ wasmer run wasmer/wai-bindgen-cli --dir=. -- js --import browser.wai
$ wasmer run wasmer/wai-bindgen-cli --dir=. -- rust-wasm --export my-interface.wai
$ wasmer run wasmer/wai-bindgen-cli --dir=. -- wasmer --import host-functions.wai

Here "import" means "I want to import and call the functions in this interface" and "export" means "I want to define the functions in this interface for others to call".

Finally in a sort of "miscellaneous" category the wai-bindgen CLI also supports:

Note that the list of supported languages here is a snapshot in time and is not final. The purpose of the interface-types proposal is to be language agnostic both in how WebAssembly modules are written as well as how they are consumed. If you have a runtime that isn't listed here or you're compiling to WebAssembly and your language isn't listed here, it doesn't mean that it will never be supported! A language binding generator is intended to be not the hardest thing in the world (but unfortunately also not the easiest) to write, and the crates and support in this repository mostly exist to make writing generators as easy as possible.

Some other languages and runtimes, for example, that don't have support in wai-bindgen today but are possible in the future (and may get written here too) are:

Note that this is not an exclusive list, only intended to give you an idea of what other bindings could look like. There's a plethora of runtimes and languages that compile to WebAssembly, and interface types should be able to work with all of them and it's theoretically just some work-hours away from having support in wai-bindgen.