diff --git a/.gitmodules b/.gitmodules index ddc976053..baed4a9ae 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "tests/codegen/wasi-clocks"] path = tests/codegen/wasi-clocks url = https://github.com/WebAssembly/wasi-clocks +[submodule "crates/go/src/pkg"] + path = crates/go/src/pkg + url = https://github.com/bytecodealliance/go-pkg diff --git a/crates/go/README.md b/crates/go/README.md index a6be999a8..445fae147 100644 --- a/crates/go/README.md +++ b/crates/go/README.md @@ -2,8 +2,18 @@ This tool generates Go bindings for a chosen WIT world. +## Contributing + +If changes need to be made to `wit-bindgen-go`, here are the steps that need to be taken: +- Make the required changes to the [bytecodealliance/go-pkg](https://github.com/bytecodealliance/go-pkg) Go files and tag a release. +- Update the `crates/go/src/pkg` git submodule to reflect the most-recent release of `go-pkg`. +- Update the `REMOTE_PKG_VERSION` constant in [lib.rs](./src/lib.rs) to reflect the most-recent release of `go-pkg`. +- Make the required changes to `wit-bindgen-go`. + ## Usage +The easiest way to use `wit-bindgen-go` is through the [componentize-go](https://github.com/bytecodealliance/componentize-go) tool. See below for using `wit-bindgen-go` directly. + To generate bindings with this crate, issue the `go` subcommand to `wit-bindgen`: ```bash @@ -19,19 +29,20 @@ world provided: - You can replace this with your own version (e.g. referencing third party dependencies) if desired - `wit_bindings.go`: defines the `main` package for the module, including low-level, `//go:export`-annotated entrypoint functions corresponding to exported functions - These entrypoint functions in turn call high-level functions which must be provided by the application developer -- `wit_runtime/wit_runtime.go`: defines low-level functions for supporting the component model ABI +- `go.bytecodealliance.org/pkg/wit/runtime`: defines low-level functions for supporting the component model ABI - `/wit_bindings.go`: defines any types generated for the interface named `` (or `wit_world` for WIT types defined at the world level), plus any imported functions - Note that the types placed in these files include all types for both imported and exported interfaces, except for exported resource types and any types which depend on exported resource types - `export_/wit_bindings.go`: defines intrinsics for use with any exported resource types generated for the interface named `` (or `wit_world` for WIT types defined at the world level), plus any types which depend on those exported resource types, plus any exported functions - The exported resource type definitions must be provided by the application developer - The `export_` package is also the place to define any exported functions -- (if needed) `wit_types/wit_tuples.go`: defines `Tuple` types as required by the WIT world -- (if needed) `wit_types/wit_async.go`: defines low-level functions for integrating the Go scheduler with the component model async ABI -- (if needed) `wit_types/wit_option.go`: defines an `Option` type if required by the WIT world -- (if needed) `wit_types/wit_result.go`: defines an `Result` type if required by the WIT world -- (if needed) `wit_types/wit_unit.go`: defines an `Unit` type if required by the WIT world -- (if needed) `wit_types/wit_stream.go`: defines a `StreamReader` and `StreamWriter` types if required by the WIT world -- (if needed) `wit_types/wit_future.go`: defines a `FutureReader` and `FutureWriter` types if required by the WIT world +- (if needed) `go.bytecodealliance.org/pkg/wit/types`: + - defines `Tuple` types as required by the WIT world + - defines an `Option` type as required by the WIT world + - defines a `Result` type as required by the WIT world + - defines a `Unit` type as required by the WIT world + - defines a `StreamReader` and `StreamWriter` types as required by the WIT world + - defines a `FutureReader` and `FutureWriter` types as required by the WIT world +- (if needed) `go.bytecodealliance.org/pkg/wit/async`: defines low-level functions for integrating the Go scheduler with the component model async ABI Note that async support currently requires [a patched version of Go](https://github.com/dicej/go/releases/tag/go1.25.5-wasi-on-idle). Code @@ -60,7 +71,7 @@ interface foo { a: s32, b: string, } - + echo: func(x: thing) -> tuple; } @@ -89,6 +100,7 @@ func Echo(x Thing) (int32, string) { return x.A, x.B } EOF +go mod tidy GOARCH="wasm" GOOS="wasip1" go build -o core.wasm -buildmode=c-shared -ldflags=-checklinkname=0 wasm-tools component embed -w test ../world.wit core.wasm -o core-with-wit.wasm wasm-tools component new --adapt ../wasi_snapshot_preview1.reactor.wasm core-with-wit.wasm -o component.wasm @@ -106,6 +118,7 @@ func Run() (int32, string) { return Echo(Thing{42, "hello, world!"}) } EOF +go mod tidy GOARCH="wasm" GOOS="wasip1" go build -o core.wasm -buildmode=c-shared -ldflags=-checklinkname=0 wasm-tools component embed -w runner ../world.wit core.wasm -o core-with-wit.wasm wasm-tools component new --adapt ../wasi_snapshot_preview1.reactor.wasm core-with-wit.wasm -o component.wasm diff --git a/crates/go/src/lib.rs b/crates/go/src/lib.rs index 9467b1573..c8d01269c 100644 --- a/crates/go/src/lib.rs +++ b/crates/go/src/lib.rs @@ -33,9 +33,24 @@ const EXPORT_RETURN_AREA: &str = "exportReturnArea"; const SYNC_EXPORT_PINNER: &str = "syncExportPinner"; const PINNER: &str = "pinner"; -/// Adds the wit-bindgen GitHub repository prefix to a package name. +/// Adds the shared package repository prefix to a package name. fn remote_pkg(name: &str) -> String { - format!(r#""github.com/bytecodealliance/wit-bindgen/{name}""#) + let prefix = match name { + "types" => "witTypes", + "async" => "witAsync", + "runtime" => "witRuntime", + _ => unimplemented!(), + }; + format!(r#"{prefix} "go.bytecodealliance.org/pkg/wit/{name}""#) +} + +/// The version of github.com/bytecodealliance/go-pkg that's being used +const REMOTE_PKG_VERSION: &str = "v0.2.0"; + +/// If a user specifies the `pkg_name` flag, the required version for the +/// shared remote package isn't recorded. This enables downstream users to retrieve the version programmatically. +pub fn remote_pkg_version() -> String { + format!("go.bytecodealliance.org/pkg {REMOTE_PKG_VERSION}") } #[derive(Default, Debug, Copy, Clone)] @@ -100,6 +115,12 @@ pub struct Opts { /// standalone executable. #[cfg_attr(feature = "clap", clap(long))] pub pkg_name: Option, + + /// Print the version of the remote package being used for the shared WIT types. + /// + /// Must be specified in addition to the `pkg-name` flag. + #[cfg_attr(feature = "clap", clap(long))] + pub print_remote_pkg_version: bool, } impl Opts { @@ -283,34 +304,34 @@ impl Go { format!("*{name}") } TypeDefKind::Option(ty) => { - imports.insert(remote_pkg("wit_types")); + imports.insert(remote_pkg("types")); let ty = self.type_name(resolve, *ty, local, in_import, imports); - format!("wit_types.Option[{ty}]") + format!("witTypes.Option[{ty}]") } TypeDefKind::List(ty) => { let ty = self.type_name(resolve, *ty, local, in_import, imports); format!("[]{ty}") } TypeDefKind::Result(result) => { - imports.insert(remote_pkg("wit_types")); + imports.insert(remote_pkg("types")); let ok_type = result .ok .map(|ty| self.type_name(resolve, ty, local, in_import, imports)) .unwrap_or_else(|| { self.need_unit = true; - "wit_types.Unit".into() + "witTypes.Unit".into() }); let err_type = result .err .map(|ty| self.type_name(resolve, ty, local, in_import, imports)) .unwrap_or_else(|| { self.need_unit = true; - "wit_types.Unit".into() + "witTypes.Unit".into() }); - format!("wit_types.Result[{ok_type}, {err_type}]") + format!("witTypes.Result[{ok_type}, {err_type}]") } TypeDefKind::Tuple(tuple) => { - imports.insert(remote_pkg("wit_types")); + imports.insert(remote_pkg("types")); let count = tuple.types.len(); if count > 16 { todo!( @@ -325,29 +346,29 @@ impl Go { .map(|ty| self.type_name(resolve, *ty, local, in_import, imports)) .collect::>() .join(", "); - format!("wit_types.Tuple{count}[{types}]") + format!("witTypes.Tuple{count}[{types}]") } TypeDefKind::Future(ty) => { self.need_future = true; - imports.insert(remote_pkg("wit_types")); + imports.insert(remote_pkg("types")); let ty = ty .map(|ty| self.type_name(resolve, ty, local, in_import, imports)) .unwrap_or_else(|| { self.need_unit = true; - "wit_types.Unit".into() + "witTypes.Unit".into() }); - format!("*wit_types.FutureReader[{ty}]") + format!("*witTypes.FutureReader[{ty}]") } TypeDefKind::Stream(ty) => { self.need_stream = true; - imports.insert(remote_pkg("wit_types")); + imports.insert(remote_pkg("types")); let ty = ty .map(|ty| self.type_name(resolve, ty, local, in_import, imports)) .unwrap_or_else(|| { self.need_unit = true; - "wit_types.Unit".into() + "witTypes.Unit".into() }); - format!("*wit_types.StreamReader[{ty}]") + format!("*witTypes.StreamReader[{ty}]") } TypeDefKind::Type(ty) => { self.type_name(resolve, *ty, local, in_import, imports) @@ -392,7 +413,7 @@ impl Go { need_unsafe: true, ..InterfaceData::default() }; - data.imports.insert(remote_pkg("wit_types")); + data.imports.insert(remote_pkg("types")); let (payload, snake) = if let Some(ty) = payload_ty { ( @@ -401,7 +422,7 @@ impl Go { ) } else { self.need_unit = true; - ("wit_types.Unit".into(), "unit".into()) + ("witTypes.Unit".into(), "unit".into()) }; let camel = snake.to_upper_camel_case(); @@ -415,7 +436,7 @@ impl Go { None => ( format!( "func wasm_{kind}_lift_{snake}(src unsafe.Pointer) {payload} {{ - return wit_types.Unit{{}} + return witTypes.Unit{{}} }} " ), @@ -521,7 +542,7 @@ func wasm_{kind}_drop_writable_{snake}(handle int32) {lower} -var wasm_{kind}_vtable_{snake} = wit_types.{upper_kind}Vtable[{payload}]{{ +var wasm_{kind}_vtable_{snake} = witTypes.{upper_kind}Vtable[{payload}]{{ {size}, {align}, wasm_{kind}_read_{snake}, @@ -534,14 +555,14 @@ var wasm_{kind}_vtable_{snake} = wit_types.{upper_kind}Vtable[{payload}]{{ {lower_name}, }} -func Make{upper_kind}{camel}() (*wit_types.{upper_kind}Writer[{payload}], *wit_types.{upper_kind}Reader[{payload}]) {{ +func Make{upper_kind}{camel}() (*witTypes.{upper_kind}Writer[{payload}], *witTypes.{upper_kind}Reader[{payload}]) {{ pair := wasm_{kind}_new_{snake}() - return wit_types.Make{upper_kind}Writer[{payload}](&wasm_{kind}_vtable_{snake}, int32(pair >> 32)), - wit_types.Make{upper_kind}Reader[{payload}](&wasm_{kind}_vtable_{snake}, int32(pair & 0xFFFFFFFF)) + return witTypes.Make{upper_kind}Writer[{payload}](&wasm_{kind}_vtable_{snake}, int32(pair >> 32)), + witTypes.Make{upper_kind}Reader[{payload}](&wasm_{kind}_vtable_{snake}, int32(pair & 0xFFFFFFFF)) }} -func Lift{upper_kind}{camel}(handle int32) *wit_types.{upper_kind}Reader[{payload}] {{ - return wit_types.Make{upper_kind}Reader[{payload}](&wasm_{kind}_vtable_{snake}, handle) +func Lift{upper_kind}{camel}(handle int32) *witTypes.{upper_kind}Reader[{payload}] {{ + return witTypes.Make{upper_kind}Reader[{payload}](&wasm_{kind}_vtable_{snake}, handle) }} "# ); @@ -672,7 +693,7 @@ impl WorldGenerator for Go { fn preprocess(&mut self, resolve: &Resolve, world: WorldId) { _ = world; self.sizes.fill(resolve); - self.imports.insert(remote_pkg("wit_runtime")); + self.imports.insert(remote_pkg("runtime")); } fn import_interface( @@ -853,21 +874,25 @@ impl WorldGenerator for Go { .join("\n"); let (exports_file_path, package_name, main_func) = if self.opts.pkg_name.is_some() { + if self.opts.print_remote_pkg_version { + println!("{}", remote_pkg_version()); + } // If a module name is specified, the generated files will be used as a library. ("wit_exports/wit_exports.go", "wit_exports", "") } else { - // This is the literal location of the Go package. - let replacement_pkg = concat!( - "github.com/bytecodealliance/wit-bindgen/crates/go/src/package v", - env!("CARGO_PKG_VERSION") - ); - files.push( "go.mod", format!( - "module {}\n\ngo 1.25\n\nreplace github.com/bytecodealliance/wit-bindgen => {}", + r#"module {} + +go 1.25 + +require ( + go.bytecodealliance.org/pkg {} +) +"#, self.opts.pkg_name.as_deref().unwrap_or("wit_component"), - replacement_pkg + REMOTE_PKG_VERSION, ) .as_bytes(), ); @@ -897,7 +922,7 @@ import ( ) var staticPinner = runtime.Pinner{{}} -var {EXPORT_RETURN_AREA} = uintptr(wit_runtime.Allocate(&staticPinner, {size}, {align})) +var {EXPORT_RETURN_AREA} = uintptr(witRuntime.Allocate(&staticPinner, {size}, {align})) var {SYNC_EXPORT_PINNER} = runtime.Pinner{{}} {src} @@ -1010,10 +1035,10 @@ impl Go { generator.imports = imports; let code = if async_ { - generator.imports.insert(remote_pkg("wit_async")); + generator.imports.insert(remote_pkg("async")); let (lower, wasm_params) = if sig.indirect_params { - generator.imports.insert(remote_pkg("wit_runtime")); + generator.imports.insert(remote_pkg("runtime")); let params_pointer = generator.locals.tmp("params"); let abi = generator @@ -1042,7 +1067,7 @@ impl Go { generator.need_pinner = true; ( format!( - "{params_pointer} := wit_runtime.Allocate({PINNER}, {size}, {align})\n{code}" + "{params_pointer} := witRuntime.Allocate({PINNER}, {size}, {align})\n{code}" ), vec![format!("uintptr({params_pointer})")], ) @@ -1097,7 +1122,7 @@ return {results}" format!( "{lower} -wit_async.SubtaskWait(uint32({raw_name}({wasm_params}))) +witAsync.SubtaskWait(uint32({raw_name}({wasm_params}))) {lift} " ) @@ -1116,12 +1141,12 @@ wit_async.SubtaskWait(uint32({raw_name}({wasm_params}))) let return_area = |generator: &mut FunctionGenerator<'_>, size: ArchitectureSize, align: Alignment| { - generator.imports.insert(remote_pkg("wit_runtime")); + generator.imports.insert(remote_pkg("runtime")); generator.need_pinner = true; let size = size.format(POINTER_SIZE_EXPRESSION); let align = align.format(POINTER_SIZE_EXPRESSION); format!( - "{IMPORT_RETURN_AREA} := uintptr(wit_runtime.Allocate({PINNER}, {size}, {align}))" + "{IMPORT_RETURN_AREA} := uintptr(witRuntime.Allocate({PINNER}, {size}, {align}))" ) }; @@ -1228,7 +1253,7 @@ func {camel}({go_params}) {go_results} {{ self.imports.extend(imports); let (pinner, other, start, end) = if async_ { - self.imports.insert(remote_pkg("wit_async")); + self.imports.insert(remote_pkg("async")); let module = match interface { Some(name) => resolve.name_world_key(name), @@ -1269,14 +1294,14 @@ func {camel}({go_params}) {go_results} {{ //go:wasmexport [callback]{prefix}{export_name} func wasm_export_callback_{name}(event0 uint32, event1 uint32, event2 uint32) uint32 {{ - return wit_async.Callback(event0, event1, event2) + return witAsync.Callback(event0, event1, event2) }} //go:wasmimport [export]{module} [task-return]{function} func wasm_export_task_return_{name}({task_return_params}) " ), - "return int32(wit_async.Run(func() {", + "return int32(witAsync.Run(func() {", "}))", ) } else if abi::guest_export_needs_post_return(resolve, func) { @@ -1568,7 +1593,7 @@ impl Bindgen for FunctionGenerator<'_> { if !self.return_area_size.is_empty() { self.need_pinner = true; - self.imports.insert(remote_pkg("wit_runtime")); + self.imports.insert(remote_pkg("runtime")); } IMPORT_RETURN_AREA.into() @@ -1677,7 +1702,7 @@ impl Bindgen for FunctionGenerator<'_> { Instruction::ListLower { element, .. } => { self.need_unsafe = true; self.need_pinner = true; - self.imports.insert(remote_pkg("wit_runtime")); + self.imports.insert(remote_pkg("runtime")); let (body, _) = self.blocks.pop().unwrap(); let value = &operands[0]; let slice = self.locals.tmp("slice"); @@ -1697,7 +1722,7 @@ impl Bindgen for FunctionGenerator<'_> { self.src, "{slice} := {value} {length} := uint32(len({slice})) -{result} := wit_runtime.Allocate({PINNER}, uintptr({length} * {size}), {align}) +{result} := witRuntime.Allocate({PINNER}, uintptr({length} * {size}), {align}) for index, {ITER_ELEMENT} := range {slice} {{ {ITER_BASE_POINTER} := unsafe.Add({result}, index * {size}) {body} @@ -1734,8 +1759,8 @@ for index := 0; index < int({length}); index++ {{ } Instruction::CallInterface { func, .. } => { if self.unpin_params { - self.imports.insert(remote_pkg("wit_runtime")); - uwriteln!(self.src, "wit_runtime.Unpin()"); + self.imports.insert(remote_pkg("runtime")); + uwriteln!(self.src, "witRuntime.Unpin()"); } let name = func.item_name().to_upper_camel_case(); @@ -1778,7 +1803,7 @@ for index := 0; index < int({length}); index++ {{ { let count = tuple.types.len(); self.generator.tuples.insert(count); - self.imports.insert(remote_pkg("wit_types")); + self.imports.insert(remote_pkg("types")); let results = (0..count) .map(|_| self.locals.tmp("result")) @@ -1795,7 +1820,7 @@ for index := 0; index < int({length}); index++ {{ uwriteln!( self.src, "{results} := {call} -{result} := wit_types.Tuple{count}[{types}]{{{results}}}" +{result} := witTypes.Tuple{count}[{types}]{{{results}}}" ); } else { uwriteln!(self.src, "{result} := {call}"); @@ -1972,8 +1997,8 @@ if {value} {{ .collect::>() .join(", "); let fields = operands.join(", "); - self.imports.insert(remote_pkg("wit_types")); - results.push(format!("wit_types.Tuple{count}[{types}]{{{fields}}}")); + self.imports.insert(remote_pkg("types")); + results.push(format!("witTypes.Tuple{count}[{types}]{{{fields}}}")); } Instruction::FlagsLower { .. } => { let value = operands.pop().unwrap(); @@ -2001,7 +2026,7 @@ if {value} {{ .. } => { self.generator.need_option = true; - self.imports.insert(remote_pkg("wit_types")); + self.imports.insert(remote_pkg("types")); let (some, some_results) = self.blocks.pop().unwrap(); let (none, none_results) = self.blocks.pop().unwrap(); let value = &operands[0]; @@ -2040,10 +2065,10 @@ if {value} {{ self.src, r#"{declarations} switch {value}.Tag() {{ -case wit_types.OptionNone: +case witTypes.OptionNone: {none} {none_result_assignments} -case wit_types.OptionSome: +case witTypes.OptionSome: {VARIANT_PAYLOAD_NAME} := {value}.Some() {some} {some_result_assignments} @@ -2054,7 +2079,7 @@ default: } Instruction::OptionLift { ty, payload } => { self.generator.need_option = true; - self.imports.insert(remote_pkg("wit_types")); + self.imports.insert(remote_pkg("types")); let (some, some_results) = self.blocks.pop().unwrap(); let (none, none_results) = self.blocks.pop().unwrap(); assert!(none_results.is_empty()); @@ -2070,10 +2095,10 @@ default: switch {tag} {{ case 0: {none} - {result} = wit_types.None[{some_type}]() + {result} = witTypes.None[{some_type}]() case 1: {some} - {result} = wit_types.Some[{some_type}]({some_result}) + {result} = witTypes.Some[{some_type}]({some_result}) default: panic("unreachable") }}"# @@ -2086,7 +2111,7 @@ default: .. } => { self.generator.need_result = true; - self.imports.insert(remote_pkg("wit_types")); + self.imports.insert(remote_pkg("types")); let (err, err_results) = self.blocks.pop().unwrap(); let (ok, ok_results) = self.blocks.pop().unwrap(); let value = &operands[0]; @@ -2139,11 +2164,11 @@ default: self.src, r#"{declarations} switch {value}.Tag() {{ -case wit_types.ResultOk: +case witTypes.ResultOk: {ok_set_payload} {ok} {ok_result_assignments} -case wit_types.ResultErr: +case witTypes.ResultErr: {err_set_payload} {err} {err_result_assignments} @@ -2154,7 +2179,7 @@ default: } Instruction::ResultLift { ty, result, .. } => { self.generator.need_result = true; - self.imports.insert(remote_pkg("wit_types")); + self.imports.insert(remote_pkg("types")); let (err, err_results) = self.blocks.pop().unwrap(); let (ok, ok_results) = self.blocks.pop().unwrap(); assert_eq!(ok_results.is_empty(), result.ok.is_none()); @@ -2163,13 +2188,13 @@ default: &ok_results[0] } else { self.generator.need_unit = true; - "wit_types.Unit{}" + "witTypes.Unit{}" }; let err_result = if result.err.is_some() { &err_results[0] } else { self.generator.need_unit = true; - "wit_types.Unit{}" + "witTypes.Unit{}" }; let ty = self.type_name(resolve, Type::Id(*ty)); let ok_type = result @@ -2177,14 +2202,14 @@ default: .map(|ty| self.type_name(resolve, ty)) .unwrap_or_else(|| { self.generator.need_unit = true; - "wit_types.Unit".into() + "witTypes.Unit".into() }); let err_type = result .err .map(|ty| self.type_name(resolve, ty)) .unwrap_or_else(|| { self.generator.need_unit = true; - "wit_types.Unit".into() + "witTypes.Unit".into() }); let result = self.locals.tmp("result"); let tag = &operands[0]; @@ -2194,10 +2219,10 @@ default: switch {tag} {{ case 0: {ok} - {result} = wit_types.Ok[{ok_type}, {err_type}]({ok_result}) + {result} = witTypes.Ok[{ok_type}, {err_type}]({ok_result}) case 1: {err} - {result} = wit_types.Err[{ok_type}, {err_type}]({err_result}) + {result} = witTypes.Err[{ok_type}, {err_type}]({err_result}) default: panic("unreachable") }}"# @@ -2544,7 +2569,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { .unwrap_or_else(|| "$root".into()); if self.in_import { - self.imports.insert(remote_pkg("wit_runtime")); + self.imports.insert(remote_pkg("runtime")); self.need_runtime = true; let docs = format_docs(docs); uwriteln!( @@ -2554,7 +2579,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { func resourceDrop{camel}(handle int32) {docs}type {camel} struct {{ - handle *wit_runtime.Handle + handle *witRuntime.Handle }} func (self *{camel}) TakeHandle() int32 {{ @@ -2577,7 +2602,7 @@ func (self *{camel}) Drop() {{ }} func {camel}FromOwnHandle(handleValue int32) *{camel} {{ - handle := wit_runtime.MakeHandle(handleValue) + handle := witRuntime.MakeHandle(handleValue) value := &{camel}{{handle}} runtime.AddCleanup(value, func(_ int) {{ handleValue := handle.TakeOrNil() @@ -2589,7 +2614,7 @@ func {camel}FromOwnHandle(handleValue int32) *{camel} {{ }} func {camel}FromBorrowHandle(handleValue int32) *{camel} {{ - handle := wit_runtime.MakeHandle(handleValue) + handle := witRuntime.MakeHandle(handleValue) return &{camel}{{handle}} }} "# @@ -2696,7 +2721,7 @@ const ( } fn type_tuple(&mut self, _: TypeId, name: &str, tuple: &Tuple, docs: &Docs) { - self.imports.insert(remote_pkg("wit_types")); + self.imports.insert(remote_pkg("types")); let count = tuple.types.len(); self.generator.tuples.insert(count); let name = name.to_upper_camel_case(); @@ -2710,7 +2735,7 @@ const ( uwriteln!( self.src, - "{docs}type {name} = wit_types.Tuple{count}[{types}]" + "{docs}type {name} = witTypes.Tuple{count}[{types}]" ); } @@ -2799,35 +2824,35 @@ func (self {name}) Tag() {repr} {{ fn type_option(&mut self, _: TypeId, name: &str, payload: &Type, docs: &Docs) { self.generator.need_option = true; - self.imports.insert(remote_pkg("wit_types")); + self.imports.insert(remote_pkg("types")); let name = name.to_upper_camel_case(); let ty = self.type_name(self.resolve, *payload); let docs = format_docs(docs); - uwriteln!(self.src, "{docs}type {name} = wit_types.Option[{ty}]"); + uwriteln!(self.src, "{docs}type {name} = witTypes.Option[{ty}]"); } fn type_result(&mut self, _: TypeId, name: &str, result: &Result_, docs: &Docs) { self.generator.need_result = true; - self.imports.insert(remote_pkg("wit_types")); + self.imports.insert(remote_pkg("types")); let name = name.to_upper_camel_case(); let ok_type = result .ok .map(|ty| self.type_name(self.resolve, ty)) .unwrap_or_else(|| { self.generator.need_unit = true; - "wit_types.Unit".into() + "witTypes.Unit".into() }); let err_type = result .err .map(|ty| self.type_name(self.resolve, ty)) .unwrap_or_else(|| { self.generator.need_unit = true; - "wit_types.Unit".into() + "witTypes.Unit".into() }); let docs = format_docs(docs); uwriteln!( self.src, - "{docs}type {name} = wit_types.Result[{ok_type}, {err_type}]" + "{docs}type {name} = witTypes.Result[{ok_type}, {err_type}]" ); } diff --git a/crates/go/src/package/go.mod b/crates/go/src/package/go.mod deleted file mode 100644 index 9b4349431..000000000 --- a/crates/go/src/package/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/bytecodealliance/wit-bindgen - -go 1.25.5 diff --git a/crates/go/src/package/wit_async/wit_async.go b/crates/go/src/package/wit_async/wit_async.go deleted file mode 100644 index 83dd6c3ae..000000000 --- a/crates/go/src/package/wit_async/wit_async.go +++ /dev/null @@ -1,229 +0,0 @@ -package wit_async - -import ( - "fmt" - "runtime" - "unsafe" - - "github.com/bytecodealliance/wit-bindgen/wit_runtime" -) - -const EVENT_NONE uint32 = 0 -const EVENT_SUBTASK uint32 = 1 -const EVENT_STREAM_READ uint32 = 2 -const EVENT_STREAM_WRITE uint32 = 3 -const EVENT_FUTURE_READ uint32 = 4 -const EVENT_FUTURE_WRITE uint32 = 5 - -const STATUS_STARTING uint32 = 0 -const STATUS_STARTED uint32 = 1 -const STATUS_RETURNED uint32 = 2 - -const CALLBACK_CODE_EXIT uint32 = 0 -const CALLBACK_CODE_YIELD uint32 = 1 -const CALLBACK_CODE_WAIT uint32 = 2 - -const RETURN_CODE_BLOCKED uint32 = 0xFFFFFFFF -const RETURN_CODE_COMPLETED uint32 = 0 -const RETURN_CODE_DROPPED uint32 = 1 - -type unit struct{} - -type taskState struct { - channel chan unit - waitableSet uint32 - pending map[uint32]chan uint32 - yielding chan unit - pinner runtime.Pinner -} - -var state *taskState = nil - -func Run(closure func()) uint32 { - state = &taskState{ - make(chan unit), - 0, - make(map[uint32]chan uint32), - nil, - runtime.Pinner{}, - } - state.pinner.Pin(state) - - defer func() { - state = nil - }() - - go closure() - - return callback(EVENT_NONE, 0, 0) -} - -func Callback(event0, event1, event2 uint32) uint32 { - state = (*taskState)(contextGet()) - contextSet(nil) - - return callback(event0, event1, event2) -} - -//go:linkname wasiOnIdle runtime.wasiOnIdle -func wasiOnIdle(callback func() bool) - -func callback(event0, event1, event2 uint32) uint32 { - yielding := state.yielding - if state.yielding != nil { - state.yielding = nil - yielding <- unit{} - } - - // Tell the Go scheduler to write to `state.channel` only after all - // goroutines have either blocked or exited. This allows us to reliably - // delay returning control to the host until there's truly nothing more - // we can do in the guest. - // - // Note that this function is _not_ currently part of upstream Go; it - // requires [this - // patch](https://github.com/dicej/go/commit/40fc123d5bce6448fc4e4601fd33bad4250b36a5) - wasiOnIdle(func() bool { - state.channel <- unit{} - return true - }) - defer wasiOnIdle(func() bool { - return false - }) - - for { - switch event0 { - case EVENT_NONE: - - case EVENT_SUBTASK: - switch event2 { - case STATUS_STARTING: - panic(fmt.Sprintf("unexpected subtask status: %v", event2)) - - case STATUS_STARTED: - - case STATUS_RETURNED: - waitableJoin(event1, 0) - subtaskDrop(event1) - channel := state.pending[event1] - delete(state.pending, event1) - channel <- event2 - - default: - panic("todo") - } - - case EVENT_STREAM_READ, EVENT_STREAM_WRITE, EVENT_FUTURE_READ, EVENT_FUTURE_WRITE: - waitableJoin(event1, 0) - channel := state.pending[event1] - delete(state.pending, event1) - channel <- event2 - - default: - panic("todo") - } - - // Block this goroutine until the scheduler wakes us up. - (<-state.channel) - - if state.yielding != nil { - contextSet(unsafe.Pointer(state)) - if len(state.pending) == 0 { - return CALLBACK_CODE_YIELD - } else { - if state.waitableSet == 0 { - panic("unreachable") - } - event0, event1, event2 = func() (uint32, uint32, uint32) { - pinner := runtime.Pinner{} - defer pinner.Unpin() - buffer := wit_runtime.Allocate(&pinner, 8, 4) - event0 := waitableSetPoll(state.waitableSet, buffer) - return event0, - unsafe.Slice((*uint32)(buffer), 2)[0], - unsafe.Slice((*uint32)(buffer), 2)[1] - }() - if event0 == EVENT_NONE { - return CALLBACK_CODE_YIELD - } - } - } else if len(state.pending) == 0 { - state.pinner.Unpin() - if state.waitableSet != 0 { - waitableSetDrop(state.waitableSet) - } - return CALLBACK_CODE_EXIT - } else { - if state.waitableSet == 0 { - panic("unreachable") - } - contextSet(unsafe.Pointer(state)) - return CALLBACK_CODE_WAIT | (state.waitableSet << 4) - } - } -} - -func SubtaskWait(status uint32) { - subtask := status >> 4 - status = status & 0xF - - switch status { - case STATUS_STARTING, STATUS_STARTED: - if state.waitableSet == 0 { - state.waitableSet = waitableSetNew() - } - waitableJoin(subtask, state.waitableSet) - channel := make(chan uint32) - state.pending[subtask] = channel - (<-channel) - - case STATUS_RETURNED: - - default: - panic(fmt.Sprintf("unexpected subtask status: %v", status)) - } -} - -func FutureOrStreamWait(code uint32, handle int32) (uint32, uint32) { - if code == RETURN_CODE_BLOCKED { - if state.waitableSet == 0 { - state.waitableSet = waitableSetNew() - } - waitableJoin(uint32(handle), state.waitableSet) - channel := make(chan uint32) - state.pending[uint32(handle)] = channel - code = (<-channel) - } - - count := code >> 4 - code = code & 0xF - - return code, count -} - -func Yield() { - channel := make(chan unit) - state.yielding = channel - (<-channel) -} - -//go:wasmimport $root [waitable-set-new] -func waitableSetNew() uint32 - -//go:wasmimport $root [waitable-set-poll] -func waitableSetPoll(waitableSet uint32, eventPayload unsafe.Pointer) uint32 - -//go:wasmimport $root [waitable-set-drop] -func waitableSetDrop(waitableSet uint32) - -//go:wasmimport $root [waitable-join] -func waitableJoin(waitable, waitableSet uint32) - -//go:wasmimport $root [context-get-0] -func contextGet() unsafe.Pointer - -//go:wasmimport $root [context-set-0] -func contextSet(value unsafe.Pointer) - -//go:wasmimport $root [subtask-drop] -func subtaskDrop(subtask uint32) diff --git a/crates/go/src/package/wit_runtime/wit_runtime.go b/crates/go/src/package/wit_runtime/wit_runtime.go deleted file mode 100644 index 5313ff1f8..000000000 --- a/crates/go/src/package/wit_runtime/wit_runtime.go +++ /dev/null @@ -1,120 +0,0 @@ -package wit_runtime - -import ( - "fmt" - "runtime" - "unsafe" -) - -type Handle struct { - value int32 -} - -func (self *Handle) Use() int32 { - if self.value == 0 { - panic("nil handle") - } - return self.value -} - -func (self *Handle) Take() int32 { - if self.value == 0 { - panic("nil handle") - } - value := self.value - self.value = 0 - return value -} - -func (self *Handle) Set(value int32) { - if value == 0 { - panic("nil handle") - } - if self.value != 0 { - panic("handle already set") - } - self.value = value -} - -func (self *Handle) TakeOrNil() int32 { - value := self.value - self.value = 0 - return value -} - -func MakeHandle(value int32) *Handle { - if value == 0 { - panic("nil handle") - } - return &Handle{value} -} - -func Allocate(pinner *runtime.Pinner, size, align uintptr) unsafe.Pointer { - pointer := allocateRaw(size, align) - pinner.Pin(pointer) - return pointer -} - -func allocateRaw(size, align uintptr) unsafe.Pointer { - if size == 0 { - return unsafe.Pointer(uintptr(0)) - } - - if size%align != 0 { - panic(fmt.Sprintf("size %v is not compatible with alignment %v", size, align)) - } - - switch align { - case 1: - return unsafe.Pointer(unsafe.SliceData(make([]uint8, size))) - case 2: - return unsafe.Pointer(unsafe.SliceData(make([]uint16, size/align))) - case 4: - return unsafe.Pointer(unsafe.SliceData(make([]uint32, size/align))) - case 8: - return unsafe.Pointer(unsafe.SliceData(make([]uint64, size/align))) - default: - panic(fmt.Sprintf("unsupported alignment: %v", align)) - } -} - -// NB: `cabi_realloc` may be called before the Go runtime has been initialized, -// in which case we need to use `runtime.sbrk` to do allocations. The following -// is an abbreviation of [Till's -// efforts](https://github.com/bytecodealliance/go-modules/pull/367). - -//go:linkname sbrk runtime.sbrk -func sbrk(n uintptr) unsafe.Pointer - -var useGCAllocations = false - -func init() { - useGCAllocations = true -} - -func offset(ptr, align uintptr) uintptr { - newptr := (ptr + align - 1) &^ (align - 1) - return newptr - ptr -} - -var pinner = runtime.Pinner{} - -func Unpin() { - pinner.Unpin() -} - -//go:wasmexport cabi_realloc -func cabiRealloc(oldPointer unsafe.Pointer, oldSize, align, newSize uintptr) unsafe.Pointer { - if oldPointer != nil || oldSize != 0 { - panic("todo") - } - - if useGCAllocations { - return Allocate(&pinner, newSize, align) - } else { - alignedSize := newSize + offset(newSize, align) - unaligned := sbrk(alignedSize) - off := offset(uintptr(unaligned), align) - return unsafe.Add(unaligned, off) - } -} diff --git a/crates/go/src/package/wit_types/wit_future.go b/crates/go/src/package/wit_types/wit_future.go deleted file mode 100644 index d5ed255ac..000000000 --- a/crates/go/src/package/wit_types/wit_future.go +++ /dev/null @@ -1,151 +0,0 @@ -package wit_types - -import ( - "runtime" - "unsafe" - - "github.com/bytecodealliance/wit-bindgen/wit_async" - "github.com/bytecodealliance/wit-bindgen/wit_runtime" -) - -type FutureVtable[T any] struct { - Size uint32 - Align uint32 - Read func(handle int32, item unsafe.Pointer) uint32 - Write func(handle int32, item unsafe.Pointer) uint32 - CancelRead func(handle int32) uint32 - CancelWrite func(handle int32) uint32 - DropReadable func(handle int32) - DropWritable func(handle int32) - Lift func(src unsafe.Pointer) T - Lower func(pinner *runtime.Pinner, value T, dst unsafe.Pointer) func() -} - -type FutureReader[T any] struct { - vtable *FutureVtable[T] - handle *wit_runtime.Handle -} - -// Blocks until the future completes and returns its value. -// -// # Panic -// -// Read will panic if multiple concurrent or sequential reads are attempted on the same future. -func (self *FutureReader[T]) Read() T { - handle := self.handle.Take() - defer self.vtable.DropReadable(handle) - - pinner := runtime.Pinner{} - defer pinner.Unpin() - - buffer := wit_runtime.Allocate(&pinner, uintptr(self.vtable.Size), uintptr(self.vtable.Align)) - - code, _ := wit_async.FutureOrStreamWait(self.vtable.Read(handle, buffer), handle) - - switch code { - case wit_async.RETURN_CODE_COMPLETED: - if self.vtable.Lift == nil { - return unsafe.Slice((*T)(buffer), 1)[0] - } else { - return self.vtable.Lift(buffer) - } - - case wit_async.RETURN_CODE_DROPPED: - panic("unreachable") - - default: - panic("todo: handle cancellation") - } -} - -// Notify the host that the FutureReader is no longer being used. -func (self *FutureReader[T]) Drop() { - handle := self.handle.TakeOrNil() - if handle != 0 { - self.vtable.DropReadable(handle) - } -} - -func (self *FutureReader[T]) TakeHandle() int32 { - return self.handle.Take() -} - -func (self *FutureReader[T]) SetHandle(handle int32) { - self.handle.Set(handle) -} - -func MakeFutureReader[T any](vtable *FutureVtable[T], handleValue int32) *FutureReader[T] { - handle := wit_runtime.MakeHandle(handleValue) - value := &FutureReader[T]{vtable, handle} - runtime.AddCleanup(value, func(_ int) { - handleValue := handle.TakeOrNil() - if handleValue != 0 { - vtable.DropReadable(handleValue) - } - }, 0) - return value -} - -type FutureWriter[T any] struct { - vtable *FutureVtable[T] - handle *wit_runtime.Handle -} - -// Writes data to a future. -// -// # Panic -// -// Write will panic if multiple concurrent or sequential writes are attempted on the same future. -func (self *FutureWriter[T]) Write(item T) bool { - handle := self.handle.Take() - defer self.vtable.DropWritable(handle) - - pinner := runtime.Pinner{} - defer pinner.Unpin() - - var lifter func() - var buffer unsafe.Pointer - if self.vtable.Lower == nil { - buffer = unsafe.Pointer(unsafe.SliceData([]T{item})) - pinner.Pin(buffer) - } else { - buffer = wit_runtime.Allocate(&pinner, uintptr(self.vtable.Size), uintptr(self.vtable.Align)) - lifter = self.vtable.Lower(&pinner, item, buffer) - } - - code, _ := wit_async.FutureOrStreamWait(self.vtable.Write(handle, buffer), handle) - - switch code { - case wit_async.RETURN_CODE_COMPLETED: - return true - - case wit_async.RETURN_CODE_DROPPED: - if lifter != nil { - lifter() - } - return false - - default: - panic("todo: handle cancellation") - } -} - -// Notify the host that the FutureWriter is no longer being used. -func (self *FutureWriter[T]) Drop() { - handle := self.handle.TakeOrNil() - if handle != 0 { - self.vtable.DropWritable(handle) - } -} - -func MakeFutureWriter[T any](vtable *FutureVtable[T], handleValue int32) *FutureWriter[T] { - handle := wit_runtime.MakeHandle(handleValue) - value := &FutureWriter[T]{vtable, handle} - runtime.AddCleanup(value, func(_ int) { - handleValue := handle.TakeOrNil() - if handleValue != 0 { - vtable.DropReadable(handleValue) - } - }, 0) - return value -} diff --git a/crates/go/src/package/wit_types/wit_option.go b/crates/go/src/package/wit_types/wit_option.go deleted file mode 100644 index e54d804c9..000000000 --- a/crates/go/src/package/wit_types/wit_option.go +++ /dev/null @@ -1,46 +0,0 @@ -package wit_types - -const ( - OptionNone = 0 - OptionSome = 1 -) - -type Option[T any] struct { - tag uint8 - value T -} - -func (self Option[T]) Tag() uint8 { - return self.tag -} - -func (self Option[T]) Some() T { - if self.tag != OptionSome { - panic("tag mismatch") - } - return self.value -} - -func (self Option[T]) SomeOr(value T) T { - if self.tag != OptionSome { - return value - } else { - return self.value - } -} - -func (self Option[T]) IsSome() bool { - return self.tag == OptionSome -} - -func (self Option[T]) IsNone() bool { - return self.tag == OptionNone -} - -func None[T any]() Option[T] { - return Option[T]{OptionNone, make([]T, 1)[0]} -} - -func Some[T any](value T) Option[T] { - return Option[T]{OptionSome, value} -} diff --git a/crates/go/src/package/wit_types/wit_result.go b/crates/go/src/package/wit_types/wit_result.go deleted file mode 100644 index 92d7021bf..000000000 --- a/crates/go/src/package/wit_types/wit_result.go +++ /dev/null @@ -1,45 +0,0 @@ -package wit_types - -const ( - ResultOk = 0 - ResultErr = 1 -) - -type Result[T any, U any] struct { - tag uint8 - value any -} - -func (self Result[T, U]) Tag() uint8 { - return self.tag -} - -func (self Result[T, U]) Ok() T { - if self.tag != ResultOk { - panic("tag mismatch") - } - return self.value.(T) -} - -func (self Result[T, U]) Err() U { - if self.tag != ResultErr { - panic("tag mismatch") - } - return self.value.(U) -} - -func (self Result[T, U]) IsErr() bool { - return self.tag == ResultErr -} - -func (self Result[T, U]) IsOk() bool { - return self.tag == ResultOk -} - -func Ok[T any, U any](value T) Result[T, U] { - return Result[T, U]{ResultOk, value} -} - -func Err[T any, U any](value U) Result[T, U] { - return Result[T, U]{ResultErr, value} -} diff --git a/crates/go/src/package/wit_types/wit_stream.go b/crates/go/src/package/wit_types/wit_stream.go deleted file mode 100644 index 1fe248a68..000000000 --- a/crates/go/src/package/wit_types/wit_stream.go +++ /dev/null @@ -1,208 +0,0 @@ -package wit_types - -import ( - "runtime" - "unsafe" - - "github.com/bytecodealliance/wit-bindgen/wit_async" - "github.com/bytecodealliance/wit-bindgen/wit_runtime" -) - -type StreamVtable[T any] struct { - Size uint32 - Align uint32 - Read func(handle int32, items unsafe.Pointer, length uint32) uint32 - Write func(handle int32, items unsafe.Pointer, length uint32) uint32 - CancelRead func(handle int32) uint32 - CancelWrite func(handle int32) uint32 - DropReadable func(handle int32) - DropWritable func(handle int32) - Lift func(src unsafe.Pointer) T - Lower func(pinner *runtime.Pinner, value T, dst unsafe.Pointer) func() -} - -type StreamReader[T any] struct { - vtable *StreamVtable[T] - handle *wit_runtime.Handle - writerDropped bool -} - -func (self *StreamReader[T]) WriterDropped() bool { - return self.writerDropped -} - -// Reads data from a stream into a destination slice. -// -// Blocks until the read completes or the destination slice is full. -// -// # Panic -// -// Read will panic if: -// - dst is empty (length 0) -// - multiple concurrent reads are attempted on the same stream -func (self *StreamReader[T]) Read(dst []T) uint32 { - if len(dst) == 0 { - panic("StreamReader.Read: destination slice cannot be empty") - } - - handle := self.handle.Take() - defer self.handle.Set(handle) - - if self.writerDropped { - return 0 - } - - pinner := runtime.Pinner{} - defer pinner.Unpin() - - var buffer unsafe.Pointer - if self.vtable.Lift == nil { - buffer = unsafe.Pointer(unsafe.SliceData(dst)) - } else { - buffer = wit_runtime.Allocate( - &pinner, - uintptr(self.vtable.Size*uint32(len(dst))), - uintptr(self.vtable.Align), - ) - } - pinner.Pin(buffer) - - code, count := wit_async.FutureOrStreamWait(self.vtable.Read(handle, buffer, uint32(len(dst))), handle) - - if code == wit_async.RETURN_CODE_DROPPED { - self.writerDropped = true - } - - if self.vtable.Lift != nil { - for i := 0; i < int(count); i++ { - dst[i] = self.vtable.Lift(unsafe.Add(buffer, i*int(self.vtable.Size))) - } - } - - return count -} - -// Notify the host that the StreamReader is no longer being used. -func (self *StreamReader[T]) Drop() { - handle := self.handle.TakeOrNil() - if handle != 0 { - self.vtable.DropReadable(handle) - } -} - -func (self *StreamReader[T]) TakeHandle() int32 { - return self.handle.Take() -} - -func (self *StreamReader[T]) SetHandle(handle int32) { - self.handle.Set(handle) -} - -func MakeStreamReader[T any](vtable *StreamVtable[T], handleValue int32) *StreamReader[T] { - handle := wit_runtime.MakeHandle(handleValue) - value := &StreamReader[T]{vtable, handle, false} - runtime.AddCleanup(value, func(_ int) { - handleValue := handle.TakeOrNil() - if handleValue != 0 { - vtable.DropReadable(handleValue) - } - }, 0) - return value -} - -type StreamWriter[T any] struct { - vtable *StreamVtable[T] - handle *wit_runtime.Handle - readerDropped bool -} - -func (self *StreamWriter[T]) ReaderDropped() bool { - return self.readerDropped -} - -// Writes items to a stream, returning the count written (may be partial). -// -// # Panic -// -// Write will panic if multiple concurrent writes are attempted on the same stream. -func (self *StreamWriter[T]) Write(items []T) uint32 { - handle := self.handle.Take() - defer self.handle.Set(handle) - - if self.readerDropped { - return 0 - } - - pinner := runtime.Pinner{} - defer pinner.Unpin() - - writeCount := uint32(len(items)) - - var lifters []func() - var buffer unsafe.Pointer - if self.vtable.Lower == nil { - buffer = unsafe.Pointer(unsafe.SliceData(items)) - pinner.Pin(buffer) - } else { - lifters = make([]func(), 0, writeCount) - buffer = wit_runtime.Allocate( - &pinner, - uintptr(self.vtable.Size*writeCount), - uintptr(self.vtable.Align), - ) - for index, item := range items { - lifters = append( - lifters, - self.vtable.Lower(&pinner, item, unsafe.Add(buffer, index*int(self.vtable.Size))), - ) - } - } - - code, count := wit_async.FutureOrStreamWait(self.vtable.Write(handle, buffer, writeCount), handle) - - if lifters != nil && count < writeCount { - for _, lifter := range lifters[count:] { - lifter() - } - } - - if code == wit_async.RETURN_CODE_DROPPED { - self.readerDropped = true - } - - return count -} - -// Writes all items to the stream, looping until complete or reader drops. -// -// # Panic -// -// WriteAll will panic if multiple concurrent writes are attempted on the same stream. -func (self *StreamWriter[T]) WriteAll(items []T) uint32 { - offset := uint32(0) - count := uint32(len(items)) - for offset < count && !self.readerDropped { - offset += self.Write(items[offset:]) - } - return offset -} - -// Notify the host that the StreamReader is no longer being used. -func (self *StreamWriter[T]) Drop() { - handle := self.handle.TakeOrNil() - if handle != 0 { - self.vtable.DropWritable(handle) - } -} - -func MakeStreamWriter[T any](vtable *StreamVtable[T], handleValue int32) *StreamWriter[T] { - handle := wit_runtime.MakeHandle(handleValue) - value := &StreamWriter[T]{vtable, handle, false} - runtime.AddCleanup(value, func(_ int) { - handleValue := handle.TakeOrNil() - if handleValue != 0 { - vtable.DropReadable(handleValue) - } - }, 0) - return value -} diff --git a/crates/go/src/package/wit_types/wit_tuple.go b/crates/go/src/package/wit_types/wit_tuple.go deleted file mode 100644 index 2c4d11416..000000000 --- a/crates/go/src/package/wit_types/wit_tuple.go +++ /dev/null @@ -1,185 +0,0 @@ -package wit_types - -type Tuple1[T0 any] struct { - F0 T0 -} - -type Tuple2[T0 any, T1 any] struct { - F0 T0 - F1 T1 -} - -type Tuple3[T0 any, T1 any, T2 any] struct { - F0 T0 - F1 T1 - F2 T2 -} - -type Tuple4[T0 any, T1 any, T2 any, T3 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 -} - -type Tuple5[T0 any, T1 any, T2 any, T3 any, T4 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 -} - -type Tuple6[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 -} - -type Tuple7[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 -} - -type Tuple8[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 - F7 T7 -} - -type Tuple9[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 - F7 T7 - F8 T8 -} - -type Tuple10[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 - F7 T7 - F8 T8 - F9 T9 -} - -type Tuple11[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any, T10 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 - F7 T7 - F8 T8 - F9 T9 - F10 T10 -} - -type Tuple12[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any, T10 any, T11 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 - F7 T7 - F8 T8 - F9 T9 - F10 T10 - F11 T11 -} - -type Tuple13[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any, T10 any, T11 any, T12 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 - F7 T7 - F8 T8 - F9 T9 - F10 T10 - F11 T11 - F12 T12 -} - -type Tuple14[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any, T10 any, T11 any, T12 any, T13 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 - F7 T7 - F8 T8 - F9 T9 - F10 T10 - F11 T11 - F12 T12 - F13 T13 -} - -type Tuple15[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any, T10 any, T11 any, T12 any, T13 any, T14 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 - F7 T7 - F8 T8 - F9 T9 - F10 T10 - F11 T11 - F12 T12 - F13 T13 - F14 T14 -} - -type Tuple16[T0 any, T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any, T10 any, T11 any, T12 any, T13 any, T14 any, T15 any] struct { - F0 T0 - F1 T1 - F2 T2 - F3 T3 - F4 T4 - F5 T5 - F6 T6 - F7 T7 - F8 T8 - F9 T9 - F10 T10 - F11 T11 - F12 T12 - F13 T13 - F14 T14 - F15 T15 -} diff --git a/crates/go/src/package/wit_types/wit_unit.go b/crates/go/src/package/wit_types/wit_unit.go deleted file mode 100644 index 26f927b54..000000000 --- a/crates/go/src/package/wit_types/wit_unit.go +++ /dev/null @@ -1,3 +0,0 @@ -package wit_types - -type Unit struct{} diff --git a/crates/go/src/pkg b/crates/go/src/pkg new file mode 160000 index 000000000..f24db4ace --- /dev/null +++ b/crates/go/src/pkg @@ -0,0 +1 @@ +Subproject commit f24db4ace4cedf565fa45b6a18a6d639982119a6 diff --git a/crates/test/src/go.rs b/crates/test/src/go.rs index ef1bf0b58..4ae0bed7e 100644 --- a/crates/test/src/go.rs +++ b/crates/test/src/go.rs @@ -154,14 +154,15 @@ fn all_paths(path: &Path) -> Result> { } fn replace_bindings_go_mod(runner: &Runner, bindings_dir: &Path) -> Result<()> { + // TODO: Update this to be a submodule let test_crate = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let wit_bindgen_root = test_crate.parent().unwrap().parent().unwrap(); - let go_package_path = wit_bindgen_root.join("crates/go/src/package"); + let go_package_path = wit_bindgen_root.join("crates/go/src/pkg"); super::write_if_different( &bindings_dir.join("go.mod"), format!( - "module wit_component\n\ngo 1.25\n\nreplace github.com/bytecodealliance/wit-bindgen => {}", + "module wit_component\n\ngo 1.25\n\nreplace go.bytecodealliance.org => {}", go_package_path.display() ), )?; diff --git a/tests/runtime-async/async/incomplete-writes/test.go b/tests/runtime-async/async/incomplete-writes/test.go index 6fe5ec3cf..46f5a0bab 100644 --- a/tests/runtime-async/async/incomplete-writes/test.go +++ b/tests/runtime-async/async/incomplete-writes/test.go @@ -4,7 +4,7 @@ import ( "runtime" . "wit_component/my_test_test_interface" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) type TestThing struct { diff --git a/tests/runtime-async/async/ping-pong/runner.go b/tests/runtime-async/async/ping-pong/runner.go index 4709858e4..1b7fad253 100644 --- a/tests/runtime-async/async/ping-pong/runner.go +++ b/tests/runtime-async/async/ping-pong/runner.go @@ -6,14 +6,14 @@ import ( "fmt" test "wit_component/my_test_i" - "github.com/bytecodealliance/wit-bindgen/wit_types" + witTypes "go.bytecodealliance.org/pkg/wit/types" ) type Unit struct{} func Run() { { - f1 := make(chan *wit_types.FutureReader[string]) + f1 := make(chan *witTypes.FutureReader[string]) f2 := make(chan Unit) tx, rx := test.MakeFutureString() diff --git a/tests/runtime-async/async/ping-pong/test.go b/tests/runtime-async/async/ping-pong/test.go index ce36602e5..5210dc8fb 100644 --- a/tests/runtime-async/async/ping-pong/test.go +++ b/tests/runtime-async/async/ping-pong/test.go @@ -3,7 +3,7 @@ package export_my_test_i import ( "wit_component/my_test_i" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func Ping(x *FutureReader[string], y string) *FutureReader[string] { diff --git a/tests/runtime-async/async/simple-future/runner.go b/tests/runtime-async/async/simple-future/runner.go index cd0772713..e45b22dc4 100644 --- a/tests/runtime-async/async/simple-future/runner.go +++ b/tests/runtime-async/async/simple-future/runner.go @@ -5,21 +5,21 @@ package export_wit_world import ( test "wit_component/my_test_i" - "github.com/bytecodealliance/wit-bindgen/wit_types" + witTypes "go.bytecodealliance.org/pkg/wit/types" ) func Run() { write := make(chan bool) - read := make(chan wit_types.Unit) + read := make(chan witTypes.Unit) { tx, rx := test.MakeFutureUnit() go func() { - write <- tx.Write(wit_types.Unit{}) + write <- tx.Write(witTypes.Unit{}) }() go func() { test.ReadFuture(rx) - read <- wit_types.Unit{} + read <- witTypes.Unit{} }() (<-read) assert(<-write) @@ -28,11 +28,11 @@ func Run() { { tx, rx := test.MakeFutureUnit() go func() { - write <- tx.Write(wit_types.Unit{}) + write <- tx.Write(witTypes.Unit{}) }() go func() { test.DropFuture(rx) - read <- wit_types.Unit{} + read <- witTypes.Unit{} }() (<-read) assert(!(<-write)) @@ -60,7 +60,7 @@ func Run() { // a "tx.Write" and will result in a "wasm trap: deadlock detected" error. Additionally, // this is placed after "close(syncBarrier)" to ensure that the panics are resulting from // concurrent reads, and not from other scenarios that result in a nil handle. - tx.Write(wit_types.Unit{}) + tx.Write(witTypes.Unit{}) }() p1, p2 := <-panicCh, <-panicCh @@ -80,7 +80,7 @@ func Run() { // point all Goroutines will attempt to simultaneously write to the future. <-syncBarrier panicCh <- checkPanicValue(func() { - tx.Write(wit_types.Unit{}) + tx.Write(witTypes.Unit{}) }) }() } diff --git a/tests/runtime-async/async/simple-future/test.go b/tests/runtime-async/async/simple-future/test.go index f4ae09c57..94f1f5bed 100644 --- a/tests/runtime-async/async/simple-future/test.go +++ b/tests/runtime-async/async/simple-future/test.go @@ -1,6 +1,6 @@ package export_my_test_i -import . "github.com/bytecodealliance/wit-bindgen/wit_types" +import . "go.bytecodealliance.org/pkg/wit/types" func ReadFuture(x *FutureReader[Unit]) { defer x.Drop() diff --git a/tests/runtime-async/async/simple-pending-import/test.go b/tests/runtime-async/async/simple-pending-import/test.go index 403a6aac9..351adba58 100644 --- a/tests/runtime-async/async/simple-pending-import/test.go +++ b/tests/runtime-async/async/simple-pending-import/test.go @@ -1,9 +1,11 @@ package export_a_b_i -import "github.com/bytecodealliance/wit-bindgen/wit_async" +import ( + witAsync "go.bytecodealliance.org/pkg/wit/async" +) func F() { for i := 0; i < 10; i++ { - wit_async.Yield() + witAsync.Yield() } } diff --git a/tests/runtime-async/async/simple-stream-payload/test.go b/tests/runtime-async/async/simple-stream-payload/test.go index 2b681a247..194f5c1a6 100644 --- a/tests/runtime-async/async/simple-stream-payload/test.go +++ b/tests/runtime-async/async/simple-stream-payload/test.go @@ -4,7 +4,7 @@ import ( "fmt" "slices" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func ReadStream(x *StreamReader[uint8]) { diff --git a/tests/runtime-async/async/simple-stream/runner.go b/tests/runtime-async/async/simple-stream/runner.go index ba450c6b8..f61b61c78 100644 --- a/tests/runtime-async/async/simple-stream/runner.go +++ b/tests/runtime-async/async/simple-stream/runner.go @@ -6,30 +6,30 @@ import ( "fmt" test "wit_component/my_test_i" - "github.com/bytecodealliance/wit-bindgen/wit_types" + witTypes "go.bytecodealliance.org/pkg/wit/types" ) func Run() { - write := make(chan wit_types.Unit) - read := make(chan wit_types.Unit) + write := make(chan witTypes.Unit) + read := make(chan witTypes.Unit) { tx, rx := test.MakeStreamUnit() go func() { - assertEqual(tx.Write([]wit_types.Unit{wit_types.Unit{}}), 1) + assertEqual(tx.Write([]witTypes.Unit{witTypes.Unit{}}), 1) assert(!tx.ReaderDropped()) - assertEqual(tx.Write([]wit_types.Unit{wit_types.Unit{}, wit_types.Unit{}}), 2) + assertEqual(tx.Write([]witTypes.Unit{witTypes.Unit{}, witTypes.Unit{}}), 2) - assertEqual(tx.Write([]wit_types.Unit{wit_types.Unit{}, wit_types.Unit{}}), 0) + assertEqual(tx.Write([]witTypes.Unit{witTypes.Unit{}, witTypes.Unit{}}), 0) assert(tx.ReaderDropped()) - write <- wit_types.Unit{} + write <- witTypes.Unit{} }() go func() { test.ReadStream(rx) - read <- wit_types.Unit{} + read <- witTypes.Unit{} }() (<-read) @@ -47,7 +47,7 @@ func Run() { // point all Goroutines will attempt to simultaneously read from the stream. <-syncBarrier panicCh <- checkPanicValue(func() { - result := make([]wit_types.Unit, 1) + result := make([]witTypes.Unit, 1) rx.Read(result) }) }() @@ -59,7 +59,7 @@ func Run() { // a "tx.WriteAll" and will result in a "wasm trap: deadlock detected" error. Additionally, // this is placed after "close(syncBarrier)" to ensure that the panics are resulting from // concurrent reads, and not from other scenarios that result in a nil handle. - tx.WriteAll([]wit_types.Unit{wit_types.Unit{}}) + tx.WriteAll([]witTypes.Unit{witTypes.Unit{}}) }() p1, p2 := <-panicCh, <-panicCh @@ -79,7 +79,7 @@ func Run() { // point all Goroutines will attempt to simultaneously write to the stream. <-syncBarrier panicCh <- checkPanicValue(func() { - tx.WriteAll([]wit_types.Unit{wit_types.Unit{}}) + tx.WriteAll([]witTypes.Unit{witTypes.Unit{}}) }) }() } @@ -90,7 +90,7 @@ func Run() { // an "rx.Read" and will result in a "wasm trap: deadlock detected" error. Additionally, // this is placed after "close(syncBarrier)" to ensure that the panics are resulting from // concurrent writes, and not from other scenarios that result in a nil handle. - result := make([]wit_types.Unit, 1) + result := make([]witTypes.Unit, 1) rx.Read(result) }() diff --git a/tests/runtime-async/async/simple-stream/test.go b/tests/runtime-async/async/simple-stream/test.go index 648025407..e3f4b7d8b 100644 --- a/tests/runtime-async/async/simple-stream/test.go +++ b/tests/runtime-async/async/simple-stream/test.go @@ -3,7 +3,7 @@ package export_my_test_i import ( "fmt" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func ReadStream(x *StreamReader[Unit]) { diff --git a/tests/runtime/flavorful/runner.go b/tests/runtime/flavorful/runner.go index 1d6b279c3..d515c49d3 100644 --- a/tests/runtime/flavorful/runner.go +++ b/tests/runtime/flavorful/runner.go @@ -5,7 +5,7 @@ import ( "slices" test "wit_component/test_flavorful_to_test" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func Run() { diff --git a/tests/runtime/flavorful/test.go b/tests/runtime/flavorful/test.go index 4bd32bcc5..e33748c37 100644 --- a/tests/runtime/flavorful/test.go +++ b/tests/runtime/flavorful/test.go @@ -4,7 +4,7 @@ import ( "slices" . "wit_component/test_flavorful_to_test" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func FListInRecord1(x ListInRecord1) { diff --git a/tests/runtime/lists/runner.go b/tests/runtime/lists/runner.go index 60a988469..5defefca5 100644 --- a/tests/runtime/lists/runner.go +++ b/tests/runtime/lists/runner.go @@ -5,7 +5,7 @@ import ( "slices" test "wit_component/test_lists_to_test" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func Run() { diff --git a/tests/runtime/lists/test.go b/tests/runtime/lists/test.go index 49e67138b..455b9db9a 100644 --- a/tests/runtime/lists/test.go +++ b/tests/runtime/lists/test.go @@ -3,7 +3,7 @@ package export_test_lists_to_test import ( "slices" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func AllocatedBytes() uint32 { diff --git a/tests/runtime/records/runner.go b/tests/runtime/records/runner.go index aab6a81b4..09fb739d6 100644 --- a/tests/runtime/records/runner.go +++ b/tests/runtime/records/runner.go @@ -4,7 +4,7 @@ import ( "fmt" test "wit_component/test_records_to_test" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func Run() { diff --git a/tests/runtime/records/test.go b/tests/runtime/records/test.go index 09742c3c8..09e3030c8 100644 --- a/tests/runtime/records/test.go +++ b/tests/runtime/records/test.go @@ -3,14 +3,14 @@ package export_test_records_to_test import ( . "wit_component/test_records_to_test" - "github.com/bytecodealliance/wit-bindgen/wit_types" + witTypes "go.bytecodealliance.org/pkg/wit/types" ) func MultipleResults() (uint8, uint16) { return 4, 5 } -func SwapTuple(x wit_types.Tuple2[uint8, uint32]) (uint32, uint8) { +func SwapTuple(x witTypes.Tuple2[uint8, uint32]) (uint32, uint8) { return x.F1, x.F0 } @@ -30,6 +30,6 @@ func RoundtripRecord1(x R1) R1 { return x } -func Tuple1(x wit_types.Tuple1[uint8]) uint8 { +func Tuple1(x witTypes.Tuple1[uint8]) uint8 { return x.F0 } diff --git a/tests/runtime/resources/resources.go b/tests/runtime/resources/resources.go index f27bdf849..cf2182efc 100644 --- a/tests/runtime/resources/resources.go +++ b/tests/runtime/resources/resources.go @@ -5,7 +5,7 @@ import ( "runtime" "wit_component/imports" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func Add(a *Z, b *Z) *Z { diff --git a/tests/runtime/results/intermediate.go b/tests/runtime/results/intermediate.go index 50d0af8fb..c73374d26 100644 --- a/tests/runtime/results/intermediate.go +++ b/tests/runtime/results/intermediate.go @@ -3,7 +3,7 @@ package export_test_results_test import ( imports "wit_component/test_results_test" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func StringError(x float32) Result[float32, string] { diff --git a/tests/runtime/results/leaf.go b/tests/runtime/results/leaf.go index f306233d8..5476b0b7a 100644 --- a/tests/runtime/results/leaf.go +++ b/tests/runtime/results/leaf.go @@ -3,7 +3,7 @@ package export_test_results_test import ( . "wit_component/test_results_test" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func StringError(x float32) Result[float32, string] { diff --git a/tests/runtime/variants/runner.go b/tests/runtime/variants/runner.go index fbcdfb20f..051a2c152 100644 --- a/tests/runtime/variants/runner.go +++ b/tests/runtime/variants/runner.go @@ -4,7 +4,7 @@ import ( "fmt" test "wit_component/test_variants_to_test" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func Run() { diff --git a/tests/runtime/variants/test.go b/tests/runtime/variants/test.go index 61daac492..d076a090d 100644 --- a/tests/runtime/variants/test.go +++ b/tests/runtime/variants/test.go @@ -3,7 +3,7 @@ package export_test_variants_to_test import ( . "wit_component/test_variants_to_test" - . "github.com/bytecodealliance/wit-bindgen/wit_types" + . "go.bytecodealliance.org/pkg/wit/types" ) func RoundtripOption(x Option[float32]) Option[uint8] {