Skip to content

Commit

Permalink
Merge with upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
dhil committed Feb 9, 2024
2 parents a9e370e + c6dc35f commit b0c5692
Show file tree
Hide file tree
Showing 24 changed files with 344 additions and 173 deletions.
209 changes: 105 additions & 104 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wit-bindgen-cli"
authors = ["Alex Crichton <[email protected]>"]
version = "0.16.0"
version = "0.17.0"
edition = { workspace = true }
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
Expand All @@ -28,19 +28,20 @@ clap = { version = "4.3.19", features = ["derive"] }
env_logger = "0.10.0"
indexmap = "2.0.0"

wasmparser = { git = "https://github.com/wasmfx/wasmfx-tools", tag = "wasmfx-tools-1.0.57" }
wasm-metadata = { git = "https://github.com/wasmfx/wasmfx-tools", tag = "wasmfx-tools-1.0.57" }
wasm-encoder = { git = "https://github.com/wasmfx/wasmfx-tools", tag = "wasmfx-tools-1.0.57" }
wit-parser = { git = "https://github.com/wasmfx/wasmfx-tools", tag = "wasmfx-tools-1.0.57" }
wit-component = { git = "https://github.com/wasmfx/wasmfx-tools", tag = "wasmfx-tools-1.0.57" }

wit-bindgen-core = { path = 'crates/core', version = '0.16.0' }
wit-bindgen-c = { path = 'crates/c', version = '0.16.0' }
wit-bindgen-rust = { path = "crates/rust", version = "0.16.0" }
wit-bindgen-teavm-java = { path = 'crates/teavm-java', version = '0.16.0' }
wit-bindgen-go = { path = 'crates/go', version = '0.16.0' }
wit-bindgen-csharp = { path = 'crates/csharp', version = '0.16.0' }
wit-bindgen-markdown = { path = 'crates/markdown', version = '0.16.0' }
wit-bindgen = { path = 'crates/guest-rust', version = '0.16.0', default-features = false }
wit-bindgen-core = { path = 'crates/core', version = '0.17.0' }
wit-bindgen-c = { path = 'crates/c', version = '0.17.0' }
wit-bindgen-rust = { path = "crates/rust", version = "0.17.0" }
wit-bindgen-teavm-java = { path = 'crates/teavm-java', version = '0.17.0' }
wit-bindgen-go = { path = 'crates/go', version = '0.17.0' }
wit-bindgen-csharp = { path = 'crates/csharp', version = '0.17.0' }
wit-bindgen-markdown = { path = 'crates/markdown', version = '0.17.0' }
wit-bindgen = { path = 'crates/guest-rust', version = '0.17.0', default-features = false }

[[bin]]
name = "wit-bindgen"
Expand Down Expand Up @@ -82,5 +83,5 @@ wasmtime = { version = "17.0.0", features = ['component-model'] }
wasmtime-wasi = { version = "17.0.0" }
test-artifacts = { path = 'crates/test-rust-wasm/artifacts' }
wit-parser = { workspace = true }
wasmparser = "0.118.0"
wasmparser = { workspace = true }
wasm-encoder = { workspace = true }
78 changes: 42 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,23 @@

## About

> **Note**: this project is still relatively young and active development with
> large changes is still happening. If you're considering depending on this at
> this time it's recommended to reach out to the authors on [zulip] and get more
> information first.
[zulip]: https://bytecodealliance.zulipchat.com/#narrow/stream/327223-wit-bindgen

This project is a suite of bindings generators for languages that are compiled
to WebAssembly and use the [component model]. Bindings are described with
[`*.wit` files][WIT] which specify imports, exports, and facilitate reuse
between bindings definitions.

[WIT]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md
[WIT]: https://component-model.bytecodealliance.org/design/wit.html
[component model]: https://github.com/WebAssembly/component-model

The `wit-bindgen` repository is currently focused on **guest** programs which
are those compiled to WebAssembly. Executing a component in a host is not
managed in this repository, and some options of how to do so are [described
below][hosts].
below][hosts]. Languages developed in this repository are Rust, C, Java (TeaVM
Java), Go (TinyGo), and C#. If you encounter any problems feel free to [open an
issue](https://github.com/bytecodealliance/wit-bindgen/issues/new) or chat with
us on [Zulip][zulip].

## [WIT] as an IDL

Expand Down Expand Up @@ -97,8 +95,9 @@ etc. This can then be imported wholesale into the `my-game` world via the
`plugin` namespace. The structure of a [WIT] document and world will affect the
generated bindings per-language.

For more information about WIT and its syntax see the [upstream description of
WIT][WIT].
For more information about WIT and its syntax see the [online documentation for
WIT][WIT] as well as its [upstream
reference](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md).

## Creating a Component

Expand Down Expand Up @@ -139,23 +138,26 @@ that are using `wasi_snapshot_preview1` APIs.

The `wasm-tools component new` subcommand takes an `--adapt` argument which acts
as a way to polyfill non-component-model APIs, like `wasi_snapshot_preview1`,
with component model APIs. The [preview2-prototyping] project is the current
go-to location to acquire a polyfill from `wasi_snapshot_preview1` to an
in-development version of "wasi preview2" which is specified with [WIT]
and the component model.

Notably you'll want to download [one of the adapter modules][preview1-build]
and name it `wasi_snapshot_preview1.wasm` locally to pass as an `--adapt`
argument to `wasm-tools component new`. Note that there are two modules
provided on the downloads page, [one is for non-commands][non-command] which
don't have a `_start` entrypoint in the generated core wasm module (e.g. the
`cdylib` crate type in Rust) and [one that is for command modules][command]
which has a `_start` entrypoint (e.g. a `src/main.rs` in Rust).

[preview2-prototyping]: https://github.com/bytecodealliance/preview2-prototyping
with component model APIs. The [Wasmtime] runtime publishes [adapter
modules][preview1-build] with each release that are suitable to use with
`--adapt` to implement `wasi_snapshot_preview1` in terms of WASI 0.2. On
Wasmtime's releases page you'll see three modules to choose from:

* [`wasi_snapshot_preview1.command.wasm`] - use this for CLI applications.
* [`wasi_snapshot_preview1.reactor.wasm`] - use this for applications that don't
have a `main` function for example: for example a process that responds to an
event.
* [`wasi_snapshot_preview1.proxy.wasm`] - use this for applications fed into
`wasmtime serve` for example.

Only one adapter is necessary and be sure to look for the [latest
versions][preview1-build] as well.

[preview1-build]: https://github.com/bytecodealliance/wasmtime/releases/latest
[non-command]: https://github.com/bytecodealliance/wasmtime/releases/latest/download/wasi_snapshot_preview1.reactor.wasm
[command]: https://github.com/bytecodealliance/wasmtime/releases/latest/download/wasi_snapshot_preview1.command.wasm
[wasmtime]: https://github.com/bytecodealliance/wasmtime
[`wasi_snapshot_preview1.command.wasm`]: https://github.com/bytecodealliance/wasmtime/releases/download/v17.0.0/wasi_snapshot_preview1.command.wasm
[`wasi_snapshot_preview1.reactor.wasm`]: https://github.com/bytecodealliance/wasmtime/releases/download/v17.0.0/wasi_snapshot_preview1.reactor.wasm
[`wasi_snapshot_preview1.proxy.wasm`]: https://github.com/bytecodealliance/wasmtime/releases/download/v17.0.0/wasi_snapshot_preview1.proxy.wasm

## Supported Guest Languages

Expand Down Expand Up @@ -183,14 +185,15 @@ world host {

### Guest: Rust

The Rust compiler supports a native `wasm32-wasi` target and can be added to any
`rustup`-based toolchain with:
The Rust compiler supports a native `wasm32-wasi` target and can be added to
any `rustup`-based toolchain with:

```sh
rustup target add wasm32-wasi
```

In order to compile a wasi dynamic library, the following must be added to the `Cargo.toml` file:
In order to compile a wasi dynamic library, the following must be added to the
`Cargo.toml` file:

```toml
[lib]
Expand All @@ -200,7 +203,7 @@ crate-type = ["cdylib"]
Projects can then depend on `wit-bindgen` by executing:

```sh
cargo add --git https://github.com/bytecodealliance/wit-bindgen wit-bindgen
cargo add wit-bindgen
```

WIT files are currently added to a `wit/` folder adjacent to your `Cargo.toml`
Expand Down Expand Up @@ -237,14 +240,17 @@ impl Guest for MyHost {
```

By using [`cargo expand`](https://github.com/dtolnay/cargo-expand) or `cargo
doc` you can also explore the generated code.
doc` you can also explore the generated code. If there's a bug in `wit-bindgen`
and the generated bindings do not compile or if there's an error in the
generated code (which is probably also a bug in `wit-bindgen`), you can use
`WIT_BINDGEN_DEBUG=1` as an environment variable to help debug this.

This project can then be built with:

```sh
cargo build --target wasm32-wasi
wasm-tools component new ./target/wasm32-wasi/debug/my-project.wasm \
-o my-component.wasm --adapt ./wasi_snapshot_preview1.wasm
-o my-component.wasm --adapt ./wasi_snapshot_preview1.reactor.wasm
```

This creates a `my-component.wasm` file which is suitable to execute in any
Expand Down Expand Up @@ -370,7 +376,7 @@ This can then be compiled with `tinygo` and assembled into a component with:
go generate # generate bindings for Go
tinygo build -target=wasi -o main.wasm my-component.go # compile
wasm-tools component embed --world host ./wit main.wasm -o main.embed.wasm # create a component
wasm-tools component new main.embed.wasm --adapt wasi_snapshot_preview1.wasm -o main.component.wasm
wasm-tools component new main.embed.wasm --adapt wasi_snapshot_preview1.command.wasm -o main.component.wasm
wasm-tools validate main.component.wasm --features component-model
```

Expand All @@ -395,7 +401,7 @@ the following cargo command. This will let you generate the bindings for any
supported language.

```
cargo install --git https://github.com/bytecodealliance/wit-bindgen wit-bindgen-cli
cargo install wit-bindgen-cli
```

This CLI **IS NOT** stable and may change, do not expect it to be or rely on it
Expand All @@ -420,7 +426,7 @@ components:
takes a [WIT] package as input and generates `trait`-based bindings for the
runtime to implement and use.

- JS: the [`js-component-tools`] project can be used to execute components in JS
- JS: the [`jco`] project can be used to execute components in JS
either on the web or outside the browser in a runtime such as `node`. This
project generates a polyfill for a single concrete component to execute in a
JS environment by extracting the core WebAssembly modules that make up a
Expand All @@ -438,7 +444,7 @@ components:
inspect the WIT-based interface of a component with `wasm-tools component
wit`. You can link two components together with `wasm-tools compose` as well.

[`js-component-tools`]: https://github.com/bytecodealliance/js-component-tools
[`jco`]: https://github.com/bytecodealliance/jco

Note that the runtimes above are generally intended to work with arbitrary
components, not necessarily only those created by `wit-bindgen`. This is also
Expand All @@ -452,4 +458,4 @@ To build the cli:
cargo build
```

Learn more how to run the tests in the [testing document](tests/README.md).
Learn more how to run the tests in the [testing document](tests/README.md).
2 changes: 1 addition & 1 deletion crates/c/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wit-bindgen-c"
authors = ["Alex Crichton <[email protected]>"]
version = "0.16.0"
version = "0.17.0"
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
Expand Down
2 changes: 1 addition & 1 deletion crates/core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wit-bindgen-core"
authors = ["Alex Crichton <[email protected]>"]
version = "0.16.0"
version = "0.17.0"
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
Expand Down
4 changes: 2 additions & 2 deletions crates/csharp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wit-bindgen-csharp"
authors = ["Timmy Silesmo <[email protected]>"]
version = "0.16.0"
version = "0.17.0"
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
Expand All @@ -27,7 +27,7 @@ anyhow = { workspace = true }
[dev-dependencies]
test-helpers = { path = '../test-helpers' }
wasm-encoder = { workspace = true }
wasmparser = "0.118.0"
wasmparser = { workspace = true }

[features]
default = ["aot"]
Expand Down
2 changes: 1 addition & 1 deletion crates/go/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wit-bindgen-go"
authors = ["Mossaka <[email protected]>"]
version = "0.16.0"
version = "0.17.0"
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
Expand Down
4 changes: 2 additions & 2 deletions crates/guest-rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wit-bindgen"
authors = ["Alex Crichton <[email protected]>"]
version = "0.16.0"
version = "0.17.0"
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
Expand All @@ -12,7 +12,7 @@ Used when compiling Rust programs to the component model.
"""

[dependencies]
wit-bindgen-rust-macro = { path = "../rust-macro", optional = true, version = "0.16.0" }
wit-bindgen-rust-macro = { path = "../rust-macro", optional = true, version = "0.17.0" }
bitflags = { workspace = true }

[features]
Expand Down
2 changes: 1 addition & 1 deletion crates/markdown/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wit-bindgen-markdown"
version = "0.16.0"
version = "0.17.0"
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
Expand Down
2 changes: 1 addition & 1 deletion crates/rust-macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wit-bindgen-rust-macro"
authors = ["Alex Crichton <[email protected]>"]
version = "0.16.0"
version = "0.17.0"
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
Expand Down
5 changes: 5 additions & 0 deletions crates/rust-macro/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let out_dir = std::env::var("OUT_DIR").unwrap();
println!("cargo:rustc-env=DEBUG_OUTPUT_DIR={out_dir}");
}
27 changes: 26 additions & 1 deletion crates/rust-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use proc_macro2::{Span, TokenStream};
use quote::ToTokens;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use syn::parse::{Error, Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
use syn::{braced, token, Token};
Expand Down Expand Up @@ -154,7 +155,31 @@ impl Config {
.generate(&self.resolve, self.world, &mut files)
.map_err(|e| Error::new(Span::call_site(), e))?;
let (_, src) = files.iter().next().unwrap();
let src = std::str::from_utf8(src).unwrap();
let mut src = std::str::from_utf8(src).unwrap().to_string();

// If a magical `WIT_BINDGEN_DEBUG` environment variable is set then
// place a formatted version of the expanded code into a file. This file
// will then show up in rustc error messages for any codegen issues and can
// be inspected manually.
if std::env::var("WIT_BINDGEN_DEBUG").is_ok() {
static INVOCATION: AtomicUsize = AtomicUsize::new(0);
let root = Path::new(env!("DEBUG_OUTPUT_DIR"));
let world_name = &self.resolve.worlds[self.world].name;
let n = INVOCATION.fetch_add(1, Relaxed);
let path = root.join(format!("{world_name}{n}.rs"));

std::fs::write(&path, &src).unwrap();

// optimistically format the code but don't require success
drop(
std::process::Command::new("rustfmt")
.arg(&path)
.arg("--edition=2021")
.output(),
);

src = format!("include!({path:?});");
}
let mut contents = src.parse::<TokenStream>().unwrap();

// Include a dummy `include_str!` for any files we read so rustc knows that
Expand Down
2 changes: 1 addition & 1 deletion crates/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wit-bindgen-rust"
authors = ["Alex Crichton <[email protected]>"]
version = "0.16.0"
version = "0.17.0"
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
Expand Down
14 changes: 8 additions & 6 deletions crates/rust/src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,13 +432,15 @@ impl Bindgen for FunctionBindgen<'_, '_> {
Handle::Borrow(resource) => ("&", resource),
Handle::Own(resource) => ("", resource),
};
let resource = dealias(resolve, *resource);

let dealiased_resource = dealias(resolve, *resource);

results.push(
if let Direction::Export = self.gen.gen.resources[&resource].direction {
if let Direction::Export = self.gen.gen.resources[&dealiased_resource].direction
{
match handle {
Handle::Borrow(_) => {
let name = resolve.types[resource]
let name = resolve.types[*resource]
.name
.as_deref()
.unwrap()
Expand All @@ -449,17 +451,17 @@ impl Bindgen for FunctionBindgen<'_, '_> {
)
}
Handle::Own(_) => {
let name = self.gen.type_path(resource, true);
let name = self.gen.type_path(dealiased_resource, true);
format!("{name}::from_handle({op} as u32)")
}
}
} else if prefix == "" {
let name = self.gen.type_path(resource, true);
let name = self.gen.type_path(dealiased_resource, true);
format!("{name}::from_handle({op} as u32)")
} else {
let tmp = format!("handle{}", self.tmp());
self.handle_decls.push(format!("let {tmp};"));
let name = self.gen.type_path(resource, true);
let name = self.gen.type_path(dealiased_resource, true);
format!(
"{{\n
{tmp} = {name}::from_handle({op} as u32);
Expand Down
Loading

0 comments on commit b0c5692

Please sign in to comment.