Skip to content

Commit

Permalink
Enable specifying namespaces/packages in with (#8083)
Browse files Browse the repository at this point in the history
This commit implements bytecodealliance/wit-bindgen#840 for Wasmtime.
Currently `with` keys to bindgen only support either mapping resources
or interfaces. Now they additionally support mapping entire packages or
entire namespaces. This can help clean up some references to interfaces
through our own bindings to avoid listing all of them.
  • Loading branch information
alexcrichton committed Mar 12, 2024
1 parent 24c04a4 commit 77b0ae7
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 117 deletions.
151 changes: 151 additions & 0 deletions crates/component-macro/tests/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,154 @@ mod interface_name_with_rust_keyword {
"
});
}

mod with_works_with_hierarchy {
mod bindings {
wasmtime::component::bindgen!({
inline: "
package foo:foo;
interface a {
record t {
x: u32,
}
x: func() -> t;
}
interface b {
use a.{t};
x: func() -> t;
}
interface c {
use b.{t};
x: func() -> t;
}
world foo {
import c;
}
"
});
}

mod with_just_one_interface {
wasmtime::component::bindgen!({
inline: "
package foo:foo;
interface a {
record t {
x: u32,
}
x: func() -> t;
}
interface b {
use a.{t};
x: func() -> t;
}
interface c {
use b.{t};
x: func() -> t;
}
world foo {
use c.{t};
import x: func() -> t;
}
",
with: { "foo:foo/a": super::bindings::foo::foo::a }
});

struct X;

impl FooImports for X {
fn x(&mut self) -> wasmtime::Result<super::bindings::foo::foo::a::T> {
loop {}
}
}
}

mod with_whole_package {
wasmtime::component::bindgen!({
inline: "
package foo:foo;
interface a {
record t {
x: u32,
}
x: func() -> t;
}
interface b {
use a.{t};
x: func() -> t;
}
interface c {
use b.{t};
x: func() -> t;
}
world foo {
use c.{t};
import x: func() -> t;
}
",
with: { "foo:foo": super::bindings::foo::foo }
});

struct X;

impl FooImports for X {
fn x(&mut self) -> wasmtime::Result<super::bindings::foo::foo::a::T> {
loop {}
}
}
}

mod with_whole_namespace {
wasmtime::component::bindgen!({
inline: "
package foo:foo;
interface a {
record t {
x: u32,
}
x: func() -> t;
}
interface b {
use a.{t};
x: func() -> t;
}
interface c {
use b.{t};
x: func() -> t;
}
world foo {
use c.{t};
import x: func() -> t;
}
",
with: { "foo": super::bindings::foo }
});

struct X;

impl FooImports for X {
fn x(&mut self) -> wasmtime::Result<super::bindings::foo::foo::a::T> {
loop {}
}
}
}
}
7 changes: 4 additions & 3 deletions crates/wasi-http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ pub mod bindings {
tracing: true,
async: false,
with: {
"wasi:io/error": wasmtime_wasi::bindings::io::error,
"wasi:io/streams": wasmtime_wasi::bindings::io::streams,
"wasi:io/poll": wasmtime_wasi::bindings::io::poll,
// Upstream package dependencies
"wasi:io": wasmtime_wasi::bindings::io,

// Configure all WIT http resources to be defined types in this
// crate to use the `ResourceTable` helper methods.
"wasi:http/types/outgoing-body": super::body::HostOutgoingBody,
"wasi:http/types/future-incoming-response": super::types::HostFutureIncomingResponse,
"wasi:http/types/outgoing-response": super::types::HostOutgoingResponse,
Expand Down
29 changes: 5 additions & 24 deletions crates/wasi-http/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,8 @@ wasmtime::component::bindgen!({
tracing: true,
async: true,
with: {
"wasi:cli/stderr": wasmtime_wasi::bindings::cli::stderr,
"wasi:cli/stdin": wasmtime_wasi::bindings::cli::stdin,
"wasi:cli/stdout": wasmtime_wasi::bindings::cli::stdout,
"wasi:clocks/monotonic-clock": wasmtime_wasi::bindings::clocks::monotonic_clock,
"wasi:clocks/timezone": wasmtime_wasi::bindings::clocks::timezone,
"wasi:clocks/wall-clock": wasmtime_wasi::bindings::clocks::wall_clock,
"wasi:http/incoming-handler": bindings::http::incoming_handler,
"wasi:http/outgoing-handler": bindings::http::outgoing_handler,
"wasi:http/types": bindings::http::types,
"wasi:io/streams": wasmtime_wasi::bindings::io::streams,
"wasi:io/poll": wasmtime_wasi::bindings::io::poll,
"wasi:random/random": wasmtime_wasi::bindings::random::random,
"wasi:http": bindings::http,
"wasi": wasmtime_wasi::bindings,
},
});

Expand Down Expand Up @@ -56,18 +46,9 @@ pub mod sync {
tracing: true,
async: false,
with: {
"wasi:cli/stderr": wasmtime_wasi::bindings::cli::stderr,
"wasi:cli/stdin": wasmtime_wasi::bindings::cli::stdin,
"wasi:cli/stdout": wasmtime_wasi::bindings::cli::stdout,
"wasi:clocks/monotonic-clock": wasmtime_wasi::bindings::clocks::monotonic_clock,
"wasi:clocks/timezone": wasmtime_wasi::bindings::clocks::timezone,
"wasi:clocks/wall-clock": wasmtime_wasi::bindings::clocks::wall_clock,
"wasi:http/incoming-handler": bindings::http::incoming_handler,
"wasi:http/outgoing-handler": bindings::http::outgoing_handler,
"wasi:http/types": bindings::http::types,
"wasi:io/streams": wasmtime_wasi::bindings::io::streams,
"wasi:poll/poll": wasmtime_wasi::bindings::poll::poll,
"wasi:random/random": wasmtime_wasi::bindings::random::random,
"wasi:http": bindings::http, // http is in this crate
"wasi:io": wasmtime_wasi::bindings::sync_io, // io is sync
"wasi": wasmtime_wasi::bindings, // everything else
},
});

Expand Down
11 changes: 10 additions & 1 deletion crates/wasi/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ pub mod sync_io {
"wasi:filesystem/types/error-code" => FsError,
},
with: {
"wasi:clocks/wall-clock": crate::bindings::clocks::wall_clock,
// This interface comes from the outer module, as it's
// sync/async agnostic.
"wasi:clocks": crate::bindings::clocks,

// Configure the resource types of the bound interfaces here
// to be the same as the async versions of the resources, that
// way everything has the same type.
"wasi:filesystem/types/descriptor": super::super::filesystem::types::Descriptor,
"wasi:filesystem/types/directory-entry-stream": super::super::filesystem::types::DirectoryEntryStream,
"wasi:io/poll/pollable": super::super::io::poll::Pollable,
Expand Down Expand Up @@ -100,6 +106,9 @@ wasmtime::component::bindgen!({
"wasi:sockets/network/error-code" => crate::SocketError,
},
with: {
// Configure all resources to be concrete types defined in this crate,
// so that way we get to use nice typed helper methods with
// `ResourceTable`.
"wasi:sockets/network/network": super::network::Network,
"wasi:sockets/tcp/tcp-socket": super::tcp::TcpSocket,
"wasi:sockets/udp/udp-socket": super::udp::UdpSocket,
Expand Down
48 changes: 9 additions & 39 deletions crates/wasi/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,7 @@ wasmtime::component::bindgen!({
world: "wasi:cli/command",
tracing: true,
async: true,
with: {
"wasi:filesystem/types": crate::bindings::filesystem::types,
"wasi:filesystem/preopens": crate::bindings::filesystem::preopens,
"wasi:sockets/tcp": crate::bindings::sockets::tcp,
"wasi:clocks/monotonic_clock": crate::bindings::clocks::monotonic_clock,
"wasi:io/poll": crate::bindings::io::poll,
"wasi:io/streams": crate::bindings::io::streams,
"wasi:clocks/wall_clock": crate::bindings::clocks::wall_clock,
"wasi:random/random": crate::bindings::random::random,
"wasi:cli/environment": crate::bindings::cli::environment,
"wasi:cli/exit": crate::bindings::cli::exit,
"wasi:cli/stdin": crate::bindings::cli::stdin,
"wasi:cli/stdout": crate::bindings::cli::stdout,
"wasi:cli/stderr": crate::bindings::cli::stderr,
"wasi:cli/terminal-input": crate::bindings::cli::terminal_input,
"wasi:cli/terminal-output": crate::bindings::cli::terminal_output,
"wasi:cli/terminal-stdin": crate::bindings::cli::terminal_stdin,
"wasi:cli/terminal-stdout": crate::bindings::cli::terminal_stdout,
"wasi:cli/terminal-stderr": crate::bindings::cli::terminal_stderr,
},
with: { "wasi": crate::bindings },
});

pub fn add_to_linker<T: WasiView>(l: &mut wasmtime::component::Linker<T>) -> anyhow::Result<()> {
Expand Down Expand Up @@ -65,25 +46,14 @@ pub mod sync {
tracing: true,
async: false,
with: {
"wasi:filesystem/types": crate::bindings::sync_io::filesystem::types,
"wasi:filesystem/preopens": crate::bindings::filesystem::preopens,
"wasi:sockets/tcp": crate::bindings::sockets::tcp,
"wasi:sockets/udp": crate::bindings::sockets::udp,
"wasi:clocks/monotonic_clock": crate::bindings::clocks::monotonic_clock,
"wasi:io/poll": crate::bindings::sync_io::io::poll,
"wasi:io/streams": crate::bindings::sync_io::io::streams,
"wasi:clocks/wall_clock": crate::bindings::clocks::wall_clock,
"wasi:random/random": crate::bindings::random::random,
"wasi:cli/environment": crate::bindings::cli::environment,
"wasi:cli/exit": crate::bindings::cli::exit,
"wasi:cli/stdin": crate::bindings::cli::stdin,
"wasi:cli/stdout": crate::bindings::cli::stdout,
"wasi:cli/stderr": crate::bindings::cli::stderr,
"wasi:cli/terminal-input": crate::bindings::cli::terminal_input,
"wasi:cli/terminal-output": crate::bindings::cli::terminal_output,
"wasi:cli/terminal-stdin": crate::bindings::cli::terminal_stdin,
"wasi:cli/terminal-stdout": crate::bindings::cli::terminal_stdout,
"wasi:cli/terminal-stderr": crate::bindings::cli::terminal_stderr,
// Map interfaces with synchronous funtions to their synchronous
// counterparts...
"wasi:filesystem": crate::bindings::sync_io::filesystem,
"wasi:io": crate::bindings::sync_io::io,

// ... and everything else is not-async and so goes through the
// top-level bindings.
"wasi": crate::bindings
},
});

Expand Down
16 changes: 1 addition & 15 deletions crates/wasi/tests/all/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,21 +125,7 @@ fn api_proxy_streaming() {}
wasmtime::component::bindgen!({
world: "test-reactor",
async: true,
with: {
"wasi:io/streams": wasmtime_wasi::bindings::io::streams,
"wasi:filesystem/types": wasmtime_wasi::bindings::filesystem::types,
"wasi:filesystem/preopens": wasmtime_wasi::bindings::filesystem::preopens,
"wasi:cli/environment": wasmtime_wasi::bindings::cli::environment,
"wasi:cli/exit": wasmtime_wasi::bindings::cli::exit,
"wasi:cli/stdin": wasmtime_wasi::bindings::cli::stdin,
"wasi:cli/stdout": wasmtime_wasi::bindings::cli::stdout,
"wasi:cli/stderr": wasmtime_wasi::bindings::cli::stderr,
"wasi:cli/terminal_input": wasmtime_wasi::bindings::cli::terminal_input,
"wasi:cli/terminal_output": wasmtime_wasi::bindings::cli::terminal_output,
"wasi:cli/terminal_stdin": wasmtime_wasi::bindings::cli::terminal_stdin,
"wasi:cli/terminal_stdout": wasmtime_wasi::bindings::cli::terminal_stdout,
"wasi:cli/terminal_stderr": wasmtime_wasi::bindings::cli::terminal_stderr,
},
with: { "wasi": wasmtime_wasi::bindings },
ownership: Borrowing {
duplicate_if_necessary: false
}
Expand Down
20 changes: 19 additions & 1 deletion crates/wasmtime/src/runtime/component/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,25 @@ pub(crate) use self::store::ComponentStoreData;
/// // with an invocation of this macro. Resources need to be mapped to a
/// // Rust type name.
/// with: {
/// "wasi:random/random": some::other::wasi::random::random,
/// // This can be used to indicate that entire interfaces have
/// // bindings generated elsewhere with a path pointing to the
/// // bindinges-generated module.
/// "wasi:random/random": wasmtime_wasi::bindings::random::random,
///
/// // Similarly entire packages can also be specified.
/// "wasi:cli": wasmtime_wasi::bindings::cli,
///
/// // Or, if applicable, entire namespaces can additionally be mapped.
/// "wasi": wasmtime_wasi::bindings,
///
/// // Versions are supported if multiple versions are in play:
/// "wasi:http/types@0.2.0": wasmtime_wasi_http::bindings::http::types,
/// "wasi:http@0.2.0": wasmtime_wasi_http::bindings::http,
///
/// // The `with` key can also be used to specify the `T` used in
/// // import bindings of `Resource<T>`. This can be done to configure
/// // which typed resource shows up in generated bindings and can be
/// // useful when working with the typed methods of `ResourceTable`.
/// "wasi:filesystem/types/descriptor": MyDescriptorType,
/// },
/// });
Expand Down

0 comments on commit 77b0ae7

Please sign in to comment.