Skip to content

Commit

Permalink
Merge pull request #277 from bytecodealliance/ydnar/async
Browse files Browse the repository at this point in the history
all: initial support for async types
  • Loading branch information
ydnar authored Dec 26, 2024
2 parents 41ab7de + 6d17128 commit 0403dba
Show file tree
Hide file tree
Showing 31 changed files with 427 additions and 87 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ on:

env:
go-modules: ./... ./cm/...
wasm-tools-version: "1.219.1"
wasm-tools-version: "1.222.0"
wasmtime-version: "26.0.0"

jobs:
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

### Changed

- Incremental support for Component Model async types `stream<T>` and `future<T>`.
- Initial support for Component Model [async](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md) types `stream`, `future`, and `error-context`.
- Breaking: generated `*.wasm.go` files will now have correct WIT kebab-case base name. Interfaces or worlds with `-` in their name will require removal of the previous `*.wasm.go` files.
- Dropped support for TinyGo v0.32.0.

## [v0.5.0] — 2024-12-14
Expand Down
6 changes: 6 additions & 0 deletions cm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Initial support for Component Model [async](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md) types `stream`, `future`, and `error-context`.

## [v0.1.0] — 2024-12-14

Initial version, extracted into module [`go.bytecodealliance.org/cm`](https://pkg.go.dev/go.bytecodealliance.org/cm).
Expand Down
3 changes: 3 additions & 0 deletions cm/empty.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file exists for testing this package without WebAssembly,
// allowing empty function bodies with a //go:wasmimport directive.
// See https://pkg.go.dev/cmd/compile for more information.
48 changes: 48 additions & 0 deletions cm/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package cm

import "unsafe"

// ErrorContext represents the Component Model [error-context] type,
// an immutable, non-deterministic, host-defined value meant to aid in debugging.
//
// [error-context]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#error-context-type
type ErrorContext struct {
_ HostLayout
errorContext
}

type errorContext uint32

// Error implements the [error] interface. It returns the debug message associated with err.
func (err errorContext) Error() string {
return err.DebugMessage()
}

// String implements [fmt.Stringer].
func (err errorContext) String() string {
return err.DebugMessage()
}

// DebugMessage represents the Canonical ABI [error-context.debug-message] function.
//
// [error-context.debug-message]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#error-contextdebug-message
func (err errorContext) DebugMessage() string {
var s string
errorContextDebugMessage(err, unsafe.Pointer(&s))
return s
}

//go:wasmimport canon error-context.debug-message
//go:noescape
func errorContextDebugMessage(err errorContext, msg unsafe.Pointer)

// Drop represents the Canonical ABI [error-context.drop] function.
//
// [error-context.drop]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#error-contextdrop
func (err errorContext) Drop() {
errorContextDrop(err)
}

//go:wasmimport canon error-context.drop
//go:noescape
func errorContextDrop(err errorContext)
15 changes: 15 additions & 0 deletions cm/future.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cm

// Future represents the Component Model [future] type.
// A future is a special case of stream. In non-error cases,
// a future delivers exactly one value before being automatically closed.
//
// [future]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#asynchronous-value-types
type Future[T any] struct {
_ HostLayout
future[T]
}

type future[T any] uint32

// TODO: implement methods on type future
15 changes: 15 additions & 0 deletions cm/stream.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cm

// Stream represents the Component Model [stream] type.
// A stream is a special case of stream. In non-error cases,
// a stream delivers exactly one value before being automatically closed.
//
// [stream]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#asynchronous-value-types
type Stream[T any] struct {
_ HostLayout
stream[T]
}

type stream[T any] uint32

// TODO: implement methods on type stream
13 changes: 13 additions & 0 deletions testdata/codegen/error-context.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package foo:foo;

interface error-contexts {
type foo = error-context;

bar: func(x: foo, y: error-context, z: future<error-context>) -> result<stream<error-context>, error-context>;
}

world foo {
import error-contexts;
export error-contexts;
}

105 changes: 105 additions & 0 deletions testdata/codegen/error-context.wit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{
"worlds": [
{
"name": "foo",
"imports": {
"interface-0": {
"interface": {
"id": 0
}
}
},
"exports": {
"interface-0": {
"interface": {
"id": 0
}
}
},
"package": 0
}
],
"interfaces": [
{
"name": "error-contexts",
"types": {
"foo": 0
},
"functions": {
"bar": {
"name": "bar",
"kind": "freestanding",
"params": [
{
"name": "x",
"type": 0
},
{
"name": "y",
"type": 1
},
{
"name": "z",
"type": 2
}
],
"results": [
{
"type": 4
}
]
}
},
"package": 0
}
],
"types": [
{
"name": "foo",
"kind": "errorcontext",
"owner": {
"interface": 0
}
},
{
"name": null,
"kind": "errorcontext",
"owner": null
},
{
"name": null,
"kind": {
"future": 1
},
"owner": null
},
{
"name": null,
"kind": {
"stream": 1
},
"owner": null
},
{
"name": null,
"kind": {
"result": {
"ok": 3,
"err": 1
}
},
"owner": null
}
],
"packages": [
{
"name": "foo:foo",
"interfaces": {
"error-contexts": 0
},
"worlds": {
"foo": 0
}
}
]
}
11 changes: 11 additions & 0 deletions testdata/codegen/error-context.wit.json.golden.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package foo:foo;

interface error-contexts {
type foo = error-context;
bar: func(x: foo, y: error-context, z: future<error-context>) -> result<stream<error-context>, error-context>;
}

world foo {
import error-contexts;
export error-contexts;
}
66 changes: 66 additions & 0 deletions testdata/wit-parser/error-context.wit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"worlds": [],
"interfaces": [
{
"name": "error-contexts",
"types": {
"t1": 0
},
"functions": {
"foo": {
"name": "foo",
"kind": "freestanding",
"params": [
{
"name": "x",
"type": 1
},
{
"name": "y",
"type": 0
}
],
"results": [
{
"type": 2
}
]
}
},
"package": 0
}
],
"types": [
{
"name": "t1",
"kind": "errorcontext",
"owner": {
"interface": 0
}
},
{
"name": null,
"kind": "errorcontext",
"owner": null
},
{
"name": null,
"kind": {
"result": {
"ok": null,
"err": 1
}
},
"owner": null
}
],
"packages": [
{
"name": "foo:error-contexts",
"interfaces": {
"error-contexts": 0
},
"worlds": {}
}
]
}
6 changes: 6 additions & 0 deletions testdata/wit-parser/error-context.wit.json.golden.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package foo:error-contexts;

interface error-contexts {
type t1 = error-context;
foo: func(x: error-context, y: t1) -> result<_, error-context>;
}
Loading

0 comments on commit 0403dba

Please sign in to comment.