From cec7863e537511d9164da311b65883a20598063e Mon Sep 17 00:00:00 2001
From: Andrew Steurer <94206073+asteurer@users.noreply.github.com>
Date: Mon, 16 Feb 2026 13:14:49 -0600
Subject: [PATCH] feat: migrating vanity imports to bytecodealliance/go-pkg
Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com>
---
README.md | 32 ++----
docs/404.html | 11 --
docs/CNAME | 1 -
docs/cm.html | 11 --
docs/cmd.html | 11 --
docs/index.html | 11 --
docs/wit.html | 11 --
docs/wit_async.html | 10 --
docs/wit_runtime.html | 10 --
docs/wit_types.html | 10 --
docs/x.html | 11 --
wit_async/wit_async.go | 229 -------------------------------------
wit_runtime/wit_runtime.go | 120 -------------------
wit_types/wit_future.go | 151 ------------------------
wit_types/wit_option.go | 46 --------
wit_types/wit_result.go | 45 --------
wit_types/wit_stream.go | 208 ---------------------------------
wit_types/wit_tuple.go | 185 ------------------------------
wit_types/wit_unit.go | 3 -
19 files changed, 10 insertions(+), 1106 deletions(-)
delete mode 100644 docs/404.html
delete mode 100644 docs/CNAME
delete mode 100644 docs/cm.html
delete mode 100644 docs/cmd.html
delete mode 100644 docs/index.html
delete mode 100644 docs/wit.html
delete mode 100644 docs/wit_async.html
delete mode 100644 docs/wit_runtime.html
delete mode 100644 docs/wit_types.html
delete mode 100644 docs/x.html
delete mode 100644 wit_async/wit_async.go
delete mode 100644 wit_runtime/wit_runtime.go
delete mode 100644 wit_types/wit_future.go
delete mode 100644 wit_types/wit_option.go
delete mode 100644 wit_types/wit_result.go
delete mode 100644 wit_types/wit_stream.go
delete mode 100644 wit_types/wit_tuple.go
delete mode 100644 wit_types/wit_unit.go
diff --git a/README.md b/README.md
index 4a8ae48..853f367 100644
--- a/README.md
+++ b/README.md
@@ -12,8 +12,6 @@
-# Overview
-## componentize-go
This is a tool to convert a Go application to a [WebAssembly component](https://github.com/WebAssembly/component-model). It takes the following as input:
- a [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) file or directory
@@ -22,30 +20,20 @@ This is a tool to convert a Go application to a [WebAssembly component](https://
The output is a component which may be run using e.g. [`wasmtime`](https://github.com/bytecodealliance/wasmtime).
-### Installation
+## Installation
+
+### Download a release
+
+You can download a specific release from the [release page](https://github.com/bytecodealliance/componentize-go/releases).
+
+### Build from source
+
#### Prerequisites
+
- [**Rust toolchain**](https://rust-lang.org/) - Latest version
#### Run
+
```sh
cargo install --git https://github.com/bytecodealliance/componentize-go
```
-
-## go.bytecodealliance.org
-This repository hosts the vanity import path redirects for `go.bytecodealliance.org`. The HTML files in the [docs/](docs/) directory are served via GitHub Pages.
-
-### Actively Maintained Packages
-| Import Path | Description |
-|-------------|-------------|
-| `go.bytecodealliance.org/wit_types` | WIT type definitions (Option, Result, Tuple, Future, Stream, etc.) |
-| `go.bytecodealliance.org/wit_async` | Async primitives for WIT. |
-| `go.bytecodealliance.org/wit_runtime` | Runtime support for WIT. |
-
-### Legacy Packages:
-These packages are located at [bytecodealliance/go-modules](https://github.com/bytecodealliance/go-modules)
-| Import Path | Description |
-|-------------|-------------|
-| `go.bytecodealliance.org/cm` | Component Model types and utilities for use with TinyGo. |
-| `go.bytecodealliance.org/wit` | TinyGo representation of the WIT (WebAssembly Interface Type) specification. |
-| `go.bytecodealliance.org/cmd/wit-bindgen-go` | Legacy wit-bindgen-go for use with TinyGo. |
-| `go.bytecodealliance.org/x` | Experimental packages. |
diff --git a/docs/404.html b/docs/404.html
deleted file mode 100644
index 3da2bcd..0000000
--- a/docs/404.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- go.bytecodealliance.org
-
-
-
-
- Not Found
- Looking for Go packages? Try pkg.go.dev
-
-
diff --git a/docs/CNAME b/docs/CNAME
deleted file mode 100644
index a060d84..0000000
--- a/docs/CNAME
+++ /dev/null
@@ -1 +0,0 @@
-go.bytecodealliance.org
diff --git a/docs/cm.html b/docs/cm.html
deleted file mode 100644
index 5140d6a..0000000
--- a/docs/cm.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- go.bytecodealliance.org/cm
-
-
-
-
-
- Redirecting to documentation…
-
-
diff --git a/docs/cmd.html b/docs/cmd.html
deleted file mode 100644
index 74a73a4..0000000
--- a/docs/cmd.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- go.bytecodealliance.org/cmd
-
-
-
-
-
- Redirecting to documentation…
-
-
diff --git a/docs/index.html b/docs/index.html
deleted file mode 100644
index 44984ab..0000000
--- a/docs/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- go.bytecodealliance.org
-
-
-
-
-
- Redirecting to documentation…
-
-
diff --git a/docs/wit.html b/docs/wit.html
deleted file mode 100644
index 716b104..0000000
--- a/docs/wit.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- go.bytecodealliance.org/wit
-
-
-
-
-
- Redirecting to documentation…
-
-
diff --git a/docs/wit_async.html b/docs/wit_async.html
deleted file mode 100644
index b559aca..0000000
--- a/docs/wit_async.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- go.bytecodealliance.org/wit_async
-
-
-
-
- Redirecting to documentation…
-
-
diff --git a/docs/wit_runtime.html b/docs/wit_runtime.html
deleted file mode 100644
index fa4286b..0000000
--- a/docs/wit_runtime.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- go.bytecodealliance.org/wit_runtime
-
-
-
-
- Redirecting to documentation…
-
-
diff --git a/docs/wit_types.html b/docs/wit_types.html
deleted file mode 100644
index f2dcdbe..0000000
--- a/docs/wit_types.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- go.bytecodealliance.org/wit_types
-
-
-
-
- Redirecting to documentation…
-
-
diff --git a/docs/x.html b/docs/x.html
deleted file mode 100644
index 9615de9..0000000
--- a/docs/x.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- go.bytecodealliance.org/x
-
-
-
-
-
- Redirecting to documentation…
-
-
diff --git a/wit_async/wit_async.go b/wit_async/wit_async.go
deleted file mode 100644
index de5751e..0000000
--- a/wit_async/wit_async.go
+++ /dev/null
@@ -1,229 +0,0 @@
-package wit_async
-
-import (
- "fmt"
- "runtime"
- "unsafe"
-
- "go.bytecodealliance.org/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/wit_runtime/wit_runtime.go b/wit_runtime/wit_runtime.go
deleted file mode 100644
index 5313ff1..0000000
--- a/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/wit_types/wit_future.go b/wit_types/wit_future.go
deleted file mode 100644
index f66e5ba..0000000
--- a/wit_types/wit_future.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package wit_types
-
-import (
- "runtime"
- "unsafe"
-
- "go.bytecodealliance.org/wit_async"
- "go.bytecodealliance.org/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/wit_types/wit_option.go b/wit_types/wit_option.go
deleted file mode 100644
index e54d804..0000000
--- a/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/wit_types/wit_result.go b/wit_types/wit_result.go
deleted file mode 100644
index 92d7021..0000000
--- a/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/wit_types/wit_stream.go b/wit_types/wit_stream.go
deleted file mode 100644
index c1d71ee..0000000
--- a/wit_types/wit_stream.go
+++ /dev/null
@@ -1,208 +0,0 @@
-package wit_types
-
-import (
- "runtime"
- "unsafe"
-
- "go.bytecodealliance.org/wit_async"
- "go.bytecodealliance.org/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/wit_types/wit_tuple.go b/wit_types/wit_tuple.go
deleted file mode 100644
index 2c4d114..0000000
--- a/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/wit_types/wit_unit.go b/wit_types/wit_unit.go
deleted file mode 100644
index 26f927b..0000000
--- a/wit_types/wit_unit.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package wit_types
-
-type Unit struct{}