Skip to content

Commit c4b4e11

Browse files
committed
reboot wit-bindgen-go
This re-introduces Go support, with a new implementation written from scratch. While the previous incarnation targeted TinyGo and reused the C generator for lifting and lowering, this one targets "big" Go and handles lifting and lowering itself. In addition, it supports idiomatic, goroutine-based concurrency on top of the component model async ABI, including streams and futures. This implementation is also distinct from the [go-modules](https://github.com/bytecodealliance/go-modules) project, which has a number of limitations (e.g. no async support, not safe for use with "big" Go) and is no longer being actively maintained. Note that the async support currently requires [a small patch](dicej/go@a1c8322) to the Go `runtime` library. I plan to work with the upstream project to make that patch unecessary in the future. Components that don't use async features should work with stock, unpatched Go. One of the tricky parts about lowering values and passing pointers to e.g. `{stream,future}.{read,write}` is that we must tell the Go garbage collector to pin the pointers (i.e. mark the pointee as both immovable and uncollectable) for as long as the host has access to them, but then unpin them promptly afterward to avoid leaks. We do this using `runtime.Pinner` instances, most of which are locally scoped and easy to reason about. However, we must use a couple of globally-scoped pinners as well: one for `cabi_realloc` allocations by the host when it lowers parameters (which we unpin after lifting those parameters) and another for returning values from sync-lifted exports (which we unpin in post-return functions). There are a couple of known missing features which I'll open GitHub issues for: 1. Resource handles are not being restored for unwritten items in the case of an incomplete stream or future write. 2. Importing and/or exporting multiple versions of the same package will cause name clashes. In addition, I plan to expand the test coverage beyond the basics covered in this commit. Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent ba933bd commit c4b4e11

File tree

57 files changed

+5488
-26
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+5488
-26
lines changed

Cargo.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ wit-bindgen-rust = { path = "crates/rust", version = "0.49.0" }
4848
wit-bindgen-csharp = { path = 'crates/csharp', version = '0.49.0' }
4949
wit-bindgen-markdown = { path = 'crates/markdown', version = '0.49.0' }
5050
wit-bindgen-moonbit = { path = 'crates/moonbit', version = '0.49.0' }
51+
wit-bindgen-go = { path = 'crates/go', version = '0.49.0' }
5152
wit-bindgen = { path = 'crates/guest-rust', version = '0.49.0', default-features = false }
5253
wit-bindgen-test = { path = 'crates/test', version = '0.49.0' }
5354

@@ -64,6 +65,7 @@ wit-bindgen-cpp = { workspace = true, features = ['clap'], optional = true }
6465
wit-bindgen-markdown = { workspace = true, features = ['clap'], optional = true }
6566
wit-bindgen-moonbit = { workspace = true, features = ['clap'], optional = true }
6667
wit-bindgen-csharp = { workspace = true, features = ['clap'], optional = true }
68+
wit-bindgen-go = { workspace = true, features = ['clap'], optional = true }
6769
wit-bindgen-test = { workspace = true }
6870
wit-component = { workspace = true }
6971
wasm-encoder = { workspace = true }
@@ -84,7 +86,7 @@ c = ['dep:wit-bindgen-c']
8486
cpp = ['dep:wit-bindgen-cpp']
8587
rust = ['dep:wit-bindgen-rust']
8688
markdown = ['dep:wit-bindgen-markdown']
87-
go = []
89+
go = ['dep:wit-bindgen-go']
8890
csharp = ['dep:wit-bindgen-csharp']
8991
csharp-mono = ['csharp']
9092
moonbit = ['dep:wit-bindgen-moonbit']

crates/core/src/abi.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,12 @@ pub fn guest_export_needs_post_return(resolve: &Resolve, func: &Function) -> boo
806806
.unwrap_or(false)
807807
}
808808

809+
pub fn guest_export_params_have_allocations(resolve: &Resolve, func: &Function) -> bool {
810+
func.params
811+
.iter()
812+
.any(|(_, t)| needs_deallocate(resolve, &t, Deallocate::Lists))
813+
}
814+
809815
fn needs_deallocate(resolve: &Resolve, ty: &Type, what: Deallocate) -> bool {
810816
match ty {
811817
Type::String => true,
@@ -1134,7 +1140,10 @@ impl<'a, B: Bindgen> Generator<'a, B> {
11341140
for (param_name, ty) in func.params.iter() {
11351141
let Some(types) = flat_types(self.resolve, ty, Some(max_flat_params))
11361142
else {
1137-
panic!("failed to flatten types during direct parameter lifting ('{param_name}' in func '{}')", func.name);
1143+
panic!(
1144+
"failed to flatten types during direct parameter lifting ('{param_name}' in func '{}')",
1145+
func.name
1146+
);
11381147
};
11391148
for _ in 0..types.len() {
11401149
self.emit(&Instruction::GetArg { nth: offset });

crates/core/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ pub trait InterfaceGenerator<'a> {
148148
fn type_record(&mut self, id: TypeId, name: &str, record: &Record, docs: &Docs);
149149
fn type_resource(&mut self, id: TypeId, name: &str, docs: &Docs);
150150
fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs);
151-
fn type_tuple(&mut self, id: TypeId, name: &str, flags: &Tuple, docs: &Docs);
151+
fn type_tuple(&mut self, id: TypeId, name: &str, tuple: &Tuple, docs: &Docs);
152152
fn type_variant(&mut self, id: TypeId, name: &str, variant: &Variant, docs: &Docs);
153153
fn type_option(&mut self, id: TypeId, name: &str, payload: &Type, docs: &Docs);
154154
fn type_result(&mut self, id: TypeId, name: &str, result: &Result_, docs: &Docs);

crates/go/Cargo.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "wit-bindgen-go"
3+
edition = "2024"
4+
version.workspace = true
5+
license.workspace = true
6+
repository.workspace = true
7+
rust-version = "1.85.0"
8+
9+
[dependencies]
10+
wit-bindgen-core = { workspace = true }
11+
wit-component = { workspace = true }
12+
wasm-encoder = { workspace = true }
13+
wasm-metadata = { workspace = true }
14+
anyhow = { workspace = true }
15+
heck = { workspace = true }
16+
clap = { workspace = true, optional = true }
17+
18+
[features]
19+
clap = ['dep:clap', 'wit-bindgen-core/clap']

0 commit comments

Comments
 (0)