Skip to content

Commit

Permalink
Merge pull request #819 from alexcrichton/add-wit-tooling
Browse files Browse the repository at this point in the history
Merge the `wit-parser` and `wit-component` crates into this repository
  • Loading branch information
alexcrichton committed Nov 16, 2022
2 parents 40f8469 + 50b8626 commit 001e5fc
Show file tree
Hide file tree
Showing 266 changed files with 18,077 additions and 29 deletions.
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ wasmparser-dump = { version = "0.1.11", path = "crates/dump" }
wasmprinter = { version = "0.2.43", path = "crates/wasmprinter" }
wast = { version = "49.0.0", path = "crates/wast" }
wat = { version = "1.0.51", path = "crates/wat" }
wit-component = { version = "0.3.0", path = "crates/wit-component" }
wit-parser = { version = "0.3.0", path = "crates/wit-parser" }

[dependencies]
anyhow = { workspace = true }
Expand Down Expand Up @@ -93,6 +95,10 @@ wasm-compose = { workspace = true, optional = true, features = ['cli'] }
rustc-demangle = { version = "0.1.21", optional = true }
cpp_demangle = { version = "0.4.0", optional = true }

# Dependencies of `component`
wit-component = { workspace = true, optional = true }
wit-parser = { workspace = true, optional = true }

[dev-dependencies]
serde_json = "1.0"
tempfile = "3.1"
Expand Down Expand Up @@ -122,6 +128,7 @@ default = [
'strip',
'compose',
'demangle',
'component',
]

# Each subcommand is gated behind a feature and lists the dependencies it needs
Expand All @@ -136,3 +143,4 @@ objdump = ['wasmparser']
strip = ['wasm-encoder', 'wasmparser', 'regex']
compose = ['wasm-compose']
demangle = ['rustc-demangle', 'cpp_demangle', 'wasmparser', 'wasm-encoder']
component = ['wit-component', 'wit-parser']
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ programmatically as well:
| `wasm-tools objdump` | | Print debugging information about section headers |
| `wasm-tools strip` | | Remove custom sections from a WebAssembly file |
| `wasm-tools demangle` | | Demangle Rust and C++ symbol names in the `name` section |
| `wasm-tools compose` | | Compose wasm components together |
| `wasm-tools compose` | [wasm-compose] | Compose wasm components together |
| `wasm-tools component new` | [wit-component] | Create a component from a core wasm binary |
| `wasm-tools component wit` | | Extract a `*.wit` interface from a component |

[wasmparser]: https://crates.io/crates/wasmparser
[wat]: https://crates.io/crates/wat
Expand All @@ -55,6 +57,8 @@ programmatically as well:
[wasm-smith]: https://crates.io/crates/wasm-smith
[wasm-mutate]: https://crates.io/crates/wasm-mutate
[wasm-shrink]: https://crates.io/crates/wasm-shrink
[wit-component]: https://crates.io/crates/wit-component
[wasm-compose]: https://crates.io/crates/wasm-compose

The `wasm-tools` CLI is primarily intended to be a debugging aid. The various
subcommands all have `--help` explainer texts to describe more about their
Expand All @@ -75,6 +79,10 @@ implemented in this repository as well. These libraries are:
* [**`wasm-smith`**](crates/wasm-smith) - a WebAssembly test case generator
* [**`wasm-encoder`**](crates/wasm-encoder) - a crate to generate a binary
WebAssembly module
* [**`wit-parser`**](crates/wit-parser) - a crate to parse and manage `*.wit`
files and interfaces.
* [**`wit-component`**](crates/wit-component) - a crate to create components
from core wasm modules.

It's recommended to use the libraries directly rather than the CLI tooling when
embedding into a separate project.
Expand Down
22 changes: 22 additions & 0 deletions crates/wit-component/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "wit-component"
authors = ["Peter Huene <peter@huene.dev>"]
version = "0.3.0"
edition.workspace = true

[dependencies]
wasmparser = { workspace = true }
wasm-encoder = { workspace = true }
wat = { workspace = true }
wit-parser = { workspace = true }
anyhow = { workspace = true }
log = "0.4.17"
bitflags = "1.3.2"
indexmap = { workspace = true }

[dev-dependencies]
wasmprinter = { workspace = true }
glob = "0.3.0"
pretty_assertions = "1.3.0"
env_logger = { workspace = true }
#test-helpers = { path = '../test-helpers', default-features = false }
93 changes: 93 additions & 0 deletions crates/wit-component/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# `wit-component`

`wit-component` is a crate for creating and interacting with WebAssembly
components based on the [component model proposal][model].

## CLI usage

The `wit-component` crate is available through the `wasm-tools` CLI suite under
two subcommands:

```
# Create a component from the input core wasm module
$ wasm-tools component new core.wasm -o component.wasm
# Extract a `*.wit` interface from a component
$ wasm-tools component wit component.wasm
```

## Features

* Creates WebAssembly [component binaries][model] from input core WebAssembly
modules. Input modules communicate with the [canonical ABI] to imported and
exported interfaces described with [`*.wit` files][wit]. The wit interface is
either embedded directly in the core wasm binary if it was generated with
[`wit-bindgen`] or it can be manually specified with a `--wit` flag.

* Supports "adapters" which can be used to bridge legacy core WebAssembly
imported functions into [component model][model] functions. Adapters are
themselves core wasm binaries which will be embedded into the final component.
An adapter's exports can be imported by the main core wasm binary and the
adapter can then call component model imports.

* A [`*.wit`][wit] interface can be extracted from an existing component to
see the interface that it exports and intends to import.

[model]: https://github.com/webassembly/component-model
[canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
[wit]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md
[`wit-bindgen`]: https://github.com/bytecodealliance/wit-bindgen

## Usage

Note that this crate is intended to be a low-level detail of tooling for
components. Developers will not necessarily interact with this tooling
day-to-day, instead using wrappers such as
[`cargo-component`](https://github.com/bytecodealliance/cargo-component) which
will automatically execute `wit-component` to produce component binaries.

First `wit-component` supports a "types only" mode where a core wasm input is
not necessary. This mode is used when embedding type information in a core wasm
binary, for example:

```sh
$ cat demo.wit
interface host {
hello: func()
}
world demo {
import host: host
}

$ wasm-tools component new --types-only --wit demo.wit -o demo.wasm

# The output `demo.wasm` is a valid component binary
$ wasm-tools validate --features component-model demo.wasm
$ wasm-tools print demo.wasm

# The `*.wit` file can be recovered from the `demo.wasm` as well
$ wasm-tools component wit demo.wasm
```

Toolchain authors can use `wit-component` to embed this "types only" section
into a core wasm binary. For a small demo here a raw `*.wat` wasm text file will
be used where the `demo.wit` argument is specified manually, however.

```sh
$ cat demo.core.wat
(module
(import "host" "hello" (func))
)

$ wasm-tools component new --wit demo.wit demo.core.wat -o demo.wasm

# Like before the output `demo.wasm` is a valid component binary
$ wasm-tools validate --features component-model demo.wasm
$ wasm-tools print demo.wasm

# Additionally like before the `*.wit` interface can still be extracted
$ wasm-tools component wit demo.wasm
```

Here the `demo.wasm` can now be shipped to a component runtime or embedded into
hosts.

0 comments on commit 001e5fc

Please sign in to comment.