#witx #webassembly #wasm #generator #bindgen

app witx-codegen

WITX code generator for WebAssembly guest modules

20 unstable releases (3 breaking)

0.11.0 Jun 9, 2021
0.10.7 Oct 15, 2021
0.10.6 Jun 24, 2021
0.10.4 Apr 7, 2021
0.2.1 Apr 4, 2021

#13 in WebAssembly

Download history 25/week @ 2021-08-05 40/week @ 2021-08-12 12/week @ 2021-08-19 5/week @ 2021-08-26 1/week @ 2021-09-02 2/week @ 2021-09-09 21/week @ 2021-09-16 4/week @ 2021-09-23 19/week @ 2021-09-30 2/week @ 2021-10-07 64/week @ 2021-10-14 4/week @ 2021-10-21 5/week @ 2021-10-28 27/week @ 2021-11-04 13/week @ 2021-11-11 10/week @ 2021-11-18

55 downloads per month

MIT license

275KB
6K SLoC

Rust 5K SLoC // 0.0% comments TypeScript 428 SLoC // 0.6% comments Zig 354 SLoC // 0.6% comments

WITX code generator

CI status crates.io

WITX-CodeGen: A WITX code and documentation generator

WITX is a way to describe types and function interfaces for WebAssembly modules.

From this, code generators can produce code to access data and call functions from different languages using the same layout and calling conventions.

The generated code is compatible with the WebAssembly standard APIs (WASI).

This tool uses the next (as on June 9th, 2021) revision of the format definition, as implemented in the forthcoming version 0.10 of the Rust witx crate.

witx-codegen is written in Rust, but is language-agnostic. The output is meant to be simple to understand.

The tool can also produce different documentation formats.

witx-codegen supersedes as-witx, zig-witx, witx-docgen, witx-overview-docgen and witx-generate-raw.

Installation

  • Via cargo:
cargo install witx-codegen
  • Precompiled binaries: tarballs and Debian/Ubuntu packages are available here.

Usage

WITX code generator for WebAssembly guest modules

USAGE:
    witx-codegen [FLAGS] [OPTIONS] <witx_files>...

FLAGS:
    -h, --help            Prints help information
    -H, --skip-header     Do not generate a header
    -I, --skip-imports    Ignores imported types and functions
    -V, --version         Prints version information

OPTIONS:
    -m, --module-name <module_name>
            Set the module name to use instead of reading it from the witx file

    -o, --output <output_file>         Output file, or - for the standard output
    -t, --output-type <output_type>
            Output type. One in: {assemblyscript, zig, rust, overview, markdown}
            [default: assemblyscript]

ARGS:
    <witx_files>...    WITX files

Backends

Example inputs

See the test folder for examples of WITX input files.

Other input formats may also be eventually supported, as well as extensions to produce more structured documentation.

WITX format

See the test directory for some examples.

Basic types

bool, char, u8, u16, u32, u64, s8, s16, s32, s64

Other types

  • string: a read-only string.
  • (in-buffer u8): a read-only buffer whose elements are of type u8.
  • (out-buffer u8): a buffer whose elements are of type u8.
  • (@witx const_pointer u8): a read-only u8 pointer.
  • (@witx pointer u8): a u8 pointer.
  • (@witx usize): an object size.

Type aliases

  • (typename $status_code u16)
  • (typename $size (@witx usize))

Note that returned values from function must all be aliases, not raw types.

Handles

Handles are opaque references to objects managed by the host.

In order to use handles, a "resource" has to be declared:

(resource $http_handle)

A "resource" represent a group of handles. The same resource can be shared by all handle types from the same module.

Each handle type can then be declared as aliases:

(typename $query (handle $http_handle))
(typename $response_handle (handle $http_handle))

Constants

(typename $big_int u64)
(@witx const $big_int $zero 0)
(@witx const $big_int $a_hundred 100)
(@witx const $big_int $a_big_value 0xff00000000000000)
(@witx const $big_int $a_bigger_value 0xffffffffffffffff)

Structures

(typename $example_structure
  (record
    (field $first_member bool)
    (field $second_member u8)
    (field $third_member string)
  )
)

Structures that only contain booleans are encoded as bit sets.

Tuples

(typename $test_tuple (tuple $test_bool $test_medium_int $big_int))

Tagged unions

(typename $test_tagged_union
  (variant (@witx tag u16)
    (case $first_choice u8)
    (case $second_choice string)
    (case $third_choice f32)
    (case $empty_choice)
  )
)

This defines a union with a tag representing the active member. The example above generates a structure equivalent to:

struct {
    tag: u16,
    member: union {
        first_choice: u8,
        second_choice: string,
        third_choice: f32,
        empty_choice: (),
    }
}

Imports

Import some aliases, or all of them, from common.witx:

(use $some_type, $some_other_type from $common)
(use * from $common)

Modules

Only one module can be present in a file, whose name must match the module name. A module is defined as follows:

(module $module_name
...
)

It contains everything: types, handles, functions and imports.

Functions

(@interface func (export "symmetric_key_generate")
 (param $algorithm string)
 (param $options $opt_options)
 (result $error (expected $symmetric_key (error $crypto_errno)))
)

This declares a symmetric_key_generate function, with two input parameters (algorithm and options of type string and opt_options).

The function returns an error code of type $crypto_errno. Or, if no error occurred, the function returns a value of type $symmetric_key.

In Rust, an equivalent function would be:

fn symmetric_key_generate(algorithm: &str, options: OptOptions)
  -> Result<SymmetricKey, CryptoErrno>;

Returning multiple values:

(@interface func (export "symmetric_key_id")
  (param $key $symmetric_key)
  (param $key_id (@witx pointer u8))
  (param $key_id_max_len $size)
  (result $error (expected (tuple $size $version) (error $crypto_errno)))
)

The function returns either an error, or two values, of type $size and $version.

The above example is eauivalent to a declaration like that one in Rust:

fn symmetric_key_id(key: SymmetricKey, key_id: *mut u8, key_id_max_len: usize)
  -> Result<(Size, Version), CryptoErrno>;

Dependencies

~1.9–2.6MB
~51K SLoC