Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions component-model/examples/tutorial/wat/adder/add.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(module
(func $add (param $lhs i32) (param $rhs i32) (result i32)
local.get $lhs
local.get $rhs
i32.add)
(export "docs:adder/add@0.1.0#add" (func $add))
)
3 changes: 2 additions & 1 deletion component-model/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@

# Using WebAssembly Components

- [Language Support for Components](./language-support.md)
- [Creating Components](./language-support.md)
- [C/C++](./language-support/c.md)
- [C#](./language-support/csharp.md)
- [Go](./language-support/go.md)
- [JavaScript](./language-support/javascript.md)
- [Python](./language-support/python.md)
- [Rust](./language-support/rust.md)
- [WebAssembly Text Format (WAT)](./language-support/wat.md)
- [Running Components](./running-components.md)
- [Wasmtime](./running-components/wasmtime.md)
- [jco](./running-components/jco.md)
Expand Down
74 changes: 12 additions & 62 deletions component-model/src/language-support.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Wasm Language Support
# Creating components

WebAssembly can be targeted by the majority of top programming
languages; however, the level of
support varies. This document details the subset of languages that target WASI and support
components.
Many popular programming languages can be compiled to WebAssembly,
but the level of support varies across languages.
This document details languages with compilers and runtimes
that support WebAssembly with WASI as a target platform.

> This is a living document, so if you are aware of advancements in a toolchain, please do
not hesitate to [contribute documentation](https://github.com/bytecodealliance/component-docs/blob/main/CONTRIBUTING.md). You can find more information about the development of support for specific languages in the [Guest Languages Special Interest Group Proposal](https://github.com/bytecodealliance/governance/blob/main/SIGs/SIG-guest-languages/proposal.md) document.
Expand All @@ -18,12 +18,11 @@ example host or from an application of that toolchain. This aims to provide a fu
components within and among toolchains.

Each section covers how to build and
run components for a given toolchain:
run components for a given toolchain.
The last section, on WebAssembly Text Format (WAT),
details how to write WebAssembly components by hand,
without using a higher-level language front-end.

- [Wasm Language Support](#wasm-language-support)
- [Language Agnostic Tooling](#language-agnostic-tooling)
- [Building a Component with `wasm-tools`](#building-a-component-with-wasm-tools)
- [Running a Component with Wasmtime](#running-a-component-with-wasmtime)
- [C/C++ Tooling](./language-support/c.md)
- [Building a Component with `wit-bindgen` and `wasm-tools`](./language-support/c.md#building-a-component-with-wit-bindgen-and-wasm-tools)
- [Running a Component from C/C++ Applications](./language-support/c.md#running-a-component-from-cc-applications)
Expand All @@ -38,55 +37,6 @@ run components for a given toolchain:
- [Rust Tooling](./language-support/rust.md)
- [Building a Component with `cargo component`](./language-support/rust.md#building-a-component-with-cargo-component)
- [Running a Component from Rust Applications](./language-support/rust.md#running-a-component-from-rust-appliacations)

## Language Agnostic Tooling

### Building a Component with `wasm-tools`

[`wasm-tools`](https://github.com/bytecodealliance/wasm-tools) provides a suite of subcommands for
working with WebAssembly modules and components.

`wasm-tools` can be used to create a component from WebAssembly Text (WAT). This walks through creating a component from WAT that implements the [`adder` world](https://github.com/bytecodealliance/component-docs/blob/main/component-model/examples/tutorial/wit/adder/world.wit) and simply adds two numbers.

1. Install [`wasm-tools`](https://github.com/bytecodealliance/wasm-tools/tree/main#installation), a
tool for low-level manipulation of Wasm modules and components.
2. The `add` function is defined inside the following `world` world:

```wit
package docs:adder@0.1.0;

interface add {
add: func(x: u32, y: u32) -> u32;
}

world adder {
export add;
}
```

3. Define an `add` core module in WAT that exports an `add` function that adds two parameters:

```wat
(module
(func $add (param $lhs i32) (param $rhs i32) (result i32)
local.get $lhs
local.get $rhs
i32.add)
(export "docs:adder/add@0.1.0" (func $add))
)
```

4. Use `wasm-tools` to create a component from the core module, first embedding component metadata
inside the core module and then encoding the WAT to a Wasm binary.

```sh
$ wasm-tools component embed adder/world.wit add.wat -o add.wasm
$ wasm-tools component new add.wasm -o add.component.wasm
```

### Running a Component with Wasmtime

You can "run" a component by calling one of its exports. Hosts and runtimes often only support
running components with certain exports. The [`wasmtime`](https://github.com/bytecodealliance/wasmtime) CLI can only run "command" components, so in
order to run the `add` function above, it first must be composed with a primary "command" component
that calls it. See [documentation on running components](./running-components/wasmtime.md) for more details.
- [WebAssembly Text Format (WAT)](./language-support/wat.md#wat-webassembly-text-format)
- [Building a Component from WAT with `wasm-tools`](./language-support/wat.md#building-a-component-with-wasm-tools)
- [Running a Component with Wasmtime](./language-support/wat.md#running-a-component-with-wasmtime)
115 changes: 115 additions & 0 deletions component-model/src/language-support/wat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
## Language Agnostic Tooling

[`wasm-tools`](https://github.com/bytecodealliance/wasm-tools) provides a suite of subcommands for
working with WebAssembly modules and components.

### WAT (WebAssembly Text Format)

WAT (WebAssembly Text Format) is a text-based language
that can be compiled to the WebAssembly binary format
by `wasm-tools` and other tools.
It's useful for writing small examples for testing and experimentation.

Here's an example of a module expressed in WAT:
```wat
{{#include ../../examples/tutorial/wat/adder/add.wat}}
```

The module contains two top-level declarations, a function and an export.

The function declaration declares a function named `$add`
with two arguments, `$lhs` and `$rhs`.
(Variable names in WAT always start with a `$`.)
Argument and result types need to be provided explicitly.
In this case, the types of both arguments and the result
are `i32` (32-bit integer).
The body of the function is a list of WebAssembly instructions.
The two `local.get` instructions push the values of `$lhs` and `$rhs`
onto the stack.
The `i32.add` instruction pops the two top values off the stack
and adds them, leaving the result on the stack.

The `export` declaration connects the function that was just declared
to a name that should be used for calling it externally.
We want to use this WAT code to implement the interface specified in a WIT file,
so the external name has to follow a certain convention.
The name `"docs:adder/add@0.1.0#add"` can be broken down as follows:
* `docs` is the package name.
* `adder` is the name of a world inside the `docs` package.
* `add` is the name of an interface defined in that world.
* 0.1.0 is a version number.
* Separately, `add` is the name of a function defined in the `add` interface.
All of these pieces come from the specific `.wit` file we are using
(see below).

There's much more than WAT can do;
see the Mozilla Developer Network's [a detailed guide to WAT](https://developer.mozilla.org/en-US/docs/WebAssembly/Guides/Understanding_the_text_format)
for more information.

The [wat2wasm](https://github.com/WebAssembly/wabt) tool converts
from WAT to the binary `.wasm` format,
but it does not create components.

### Building a Component from WAT with `wasm-tools`

`wasm-tools` can be used to create a component from WAT.
Here's how to create a component from WAT
that implements the [`adder` world](https://github.com/bytecodealliance/component-docs/blob/main/component-model/examples/tutorial/wit/adder/world.wit)
and simply adds two numbers.

1. Install [`wasm-tools`](https://github.com/bytecodealliance/wasm-tools/tree/main#installation), a
tool for low-level manipulation of Wasm modules and components.

2. The `add` function is defined inside the following world.
Create a file called `adder.wit` whose contents are as follows:

```wit
{{#include ../../examples/tutorial/wit/adder/world.wit}}
```

3. Define an `add` core module in WAT that exports an `add` function that adds two parameters.
Create a file called `add.wat` whose contents are as follows
(the same as the example in the WAT section):

```wat
{{#include ../../examples/tutorial/wat/adder/add.wat}}
```

4. Use `wasm-tools` to create a binary core module with component metadata embedded inside it:

```sh
wasm-tools component embed adder.wit add.wat -o add.wasm
```

5. Use `wasm-tools` to create a new component `.wasm` file
from the binary core module you just created:

```sh
wasm-tools component new add.wasm -o add.component.wasm
```

The suffix `.component.wasm` is just a convention.
You could also name the output file `add_component.wasm` or anything else
with the `.wasm` suffix.

### Running a Component with Wasmtime

You can "run" a component by calling one of its exports.
Hosts and runtimes often only support running components with certain exports.

Using the [`wasmtime`](https://github.com/bytecodealliance/wasmtime) CLI,
we can execute the `add` function in the component you just built,
passing in arguments:

```sh
wasmtime run --invoke 'add(1, 2)' add.component.wasm
```

The output is ```3```.
You can try passing other arguments to `add()`
by changing the arguments inside the parentheses.

This example was tested with `wasmtime` 34.0.1.
Earlier versions of `wasmtime` may not support the `--invoke` option.
Any other compliant WebAssembly runtime that supports components
can also run this component.