Skip to content

Commit

Permalink
internal/{cm,wasi}: regenerate WASI 0.2 bindings with wasm-tools-go v…
Browse files Browse the repository at this point in the history
…0.3.0
  • Loading branch information
ydnar authored and deadprogram committed Oct 17, 2024
1 parent a0d4ecb commit d5f1953
Show file tree
Hide file tree
Showing 70 changed files with 3,350 additions and 684 deletions.
32 changes: 28 additions & 4 deletions src/internal/cm/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package cm

import "unsafe"

// AnyInteger is a type constraint for any integer type.
type AnyInteger interface {
~int | ~uint | ~uintptr | ~int8 | ~uint8 | ~int16 | ~uint16 | ~int32 | ~uint32 | ~int64 | ~uint64
}

// Reinterpret reinterprets the bits of type From into type T.
// Will panic if the size of From is smaller than the size of To.
func Reinterpret[T, From any](from From) (to T) {
Expand All @@ -19,19 +24,19 @@ func LowerString[S ~string](s S) (*byte, uint32) {
}

// LiftString lifts Core WebAssembly types into a [string].
func LiftString[T ~string, Data unsafe.Pointer | uintptr | *uint8, Len uint | uintptr | uint32 | uint64](data Data, len Len) T {
func LiftString[T ~string, Data unsafe.Pointer | uintptr | *uint8, Len AnyInteger](data Data, len Len) T {
return T(unsafe.String((*uint8)(unsafe.Pointer(data)), int(len)))
}

// LowerList lowers a [List] into a pair of Core WebAssembly types.
func LowerList[L ~struct{ list[T] }, T any](list L) (*T, uint32) {
func LowerList[L AnyList[T], T any](list L) (*T, uint32) {
l := (*List[T])(unsafe.Pointer(&list))
return l.data, uint32(l.len)
}

// LiftList lifts Core WebAssembly types into a [List].
func LiftList[L List[T], T any, Data unsafe.Pointer | uintptr | *T, Len uint | uintptr | uint32 | uint64](data Data, len Len) L {
return L(NewList((*T)(unsafe.Pointer(data)), uint(len)))
func LiftList[L AnyList[T], T any, Data unsafe.Pointer | uintptr | *T, Len AnyInteger](data Data, len Len) L {
return L(NewList((*T)(unsafe.Pointer(data)), len))
}

// BoolToU32 converts a value whose underlying type is [bool] into a [uint32].
Expand Down Expand Up @@ -84,6 +89,25 @@ func F64ToU64(v float64) uint64 { return *(*uint64)(unsafe.Pointer(&v)) }
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
func U64ToF64(v uint64) float64 { return *(*float64)(unsafe.Pointer(&v)) }

// F32ToU64 maps the bits of a [float32] into a [uint64].
// Used to lower a [float32] into a Core WebAssembly i64 when required by the [Canonical ABI].
//
// [float32]: https://pkg.go.dev/builtin#float32
// [uint64]: https://pkg.go.dev/builtin#uint64
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
func F32ToU64(v float32) uint64 { return uint64(*(*uint32)(unsafe.Pointer(&v))) }

// U64ToF32 maps the bits of a [uint64] into a [float32].
// Used to lift a Core WebAssembly i64 into a [float32] when required by the [Canonical ABI].
//
// [uint64]: https://pkg.go.dev/builtin#uint64
// [float32]: https://pkg.go.dev/builtin#float32
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
func U64ToF32(v uint64) float32 {
truncated := uint32(v)
return *(*float32)(unsafe.Pointer(&truncated))
}

// PointerToU32 converts a pointer of type *T into a [uint32].
// Used to lower a pointer into a Core WebAssembly i32 as specified in the [Canonical ABI].
//
Expand Down
11 changes: 11 additions & 0 deletions src/internal/cm/hostlayout_go122.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build !go1.23

package cm

// HostLayout marks a struct as using host memory layout.
// See [structs.HostLayout] in Go 1.23 or later.
type HostLayout struct {
_ hostLayout // prevent accidental conversion with plain struct{}
}

type hostLayout struct{}
9 changes: 9 additions & 0 deletions src/internal/cm/hostlayout_go123.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build go1.23

package cm

import "structs"

// HostLayout marks a struct as using host memory layout.
// See [structs.HostLayout] in Go 1.23 or later.
type HostLayout = structs.HostLayout
28 changes: 20 additions & 8 deletions src/internal/cm/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,25 @@ import "unsafe"

// List represents a Component Model list.
// The binary representation of list<T> is similar to a Go slice minus the cap field.
type List[T any] struct{ list[T] }
type List[T any] struct {
_ HostLayout
list[T]
}

// AnyList is a type constraint for generic functions that accept any [List] type.
type AnyList[T any] interface {
~struct {
_ HostLayout
list[T]
}
}

// NewList returns a List[T] from data and len.
func NewList[T any](data *T, len uint) List[T] {
func NewList[T any, Len AnyInteger](data *T, len Len) List[T] {
return List[T]{
list[T]{
list: list[T]{
data: data,
len: len,
len: uintptr(len),
},
}
}
Expand All @@ -20,15 +31,16 @@ func NewList[T any](data *T, len uint) List[T] {
// The underlying slice data is not copied, and the resulting List points at the
// same array storage as the slice.
func ToList[S ~[]T, T any](s S) List[T] {
return NewList[T](unsafe.SliceData([]T(s)), uint(len(s)))
return NewList[T](unsafe.SliceData([]T(s)), uintptr(len(s)))
}

// list represents the internal representation of a Component Model list.
// It is intended to be embedded in a [List], so embedding types maintain
// the methods defined on this type.
type list[T any] struct {
_ HostLayout
data *T
len uint
len uintptr
}

// Slice returns a Go slice representing the List.
Expand All @@ -42,7 +54,7 @@ func (l list[T]) Data() *T {
}

// Len returns the length of the list.
// TODO: should this return an int instead of a uint?
func (l list[T]) Len() uint {
// TODO: should this return an int instead of a uintptr?
func (l list[T]) Len() uintptr {
return l.len
}
19 changes: 17 additions & 2 deletions src/internal/cm/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package cm
// Option represents a Component Model [option<T>] type.
//
// [option<T>]: https://component-model.bytecodealliance.org/design/wit.html#options
type Option[T any] struct{ option[T] }
type Option[T any] struct {
_ HostLayout
option[T]
}

// None returns an [Option] representing the none case,
// equivalent to the zero value.
Expand All @@ -14,7 +17,7 @@ func None[T any]() Option[T] {
// Some returns an [Option] representing the some case.
func Some[T any](v T) Option[T] {
return Option[T]{
option[T]{
option: option[T]{
isSome: true,
some: v,
},
Expand All @@ -25,6 +28,7 @@ func Some[T any](v T) Option[T] {
// The first byte is a bool representing none or some,
// followed by storage for the associated type T.
type option[T any] struct {
_ HostLayout
isSome bool
some T
}
Expand All @@ -42,3 +46,14 @@ func (o *option[T]) Some() *T {
}
return nil
}

// Value returns T if o represents the some case,
// or the zero value of T if o represents the none case.
// This does not have a pointer receiver, so it can be chained.
func (o option[T]) Value() T {
if !o.isSome {
var zero T
return zero
}
return o.some
}
22 changes: 17 additions & 5 deletions src/internal/cm/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,22 @@ type BoolResult bool
// Result represents a result sized to hold the Shape type.
// The size of the Shape type must be greater than or equal to the size of OK and Err types.
// For results with two zero-length types, use [BoolResult].
type Result[Shape, OK, Err any] struct{ result[Shape, OK, Err] }
type Result[Shape, OK, Err any] struct {
_ HostLayout
result[Shape, OK, Err]
}

// AnyResult is a type constraint for generic functions that accept any [Result] type.
type AnyResult[Shape, OK, Err any] interface {
~struct {
_ HostLayout
result[Shape, OK, Err]
}
}

// result represents the internal representation of a Component Model result type.
type result[Shape, OK, Err any] struct {
_ HostLayout
isErr bool
_ [0]OK
_ [0]Err
Expand Down Expand Up @@ -88,8 +100,8 @@ func (r *result[Shape, OK, Err]) validate() {

// OK returns an OK result with shape Shape and type OK and Err.
// Pass Result[OK, OK, Err] or Result[Err, OK, Err] as the first type argument.
func OK[R ~struct{ result[Shape, OK, Err] }, Shape, OK, Err any](ok OK) R {
var r struct{ result[Shape, OK, Err] }
func OK[R AnyResult[Shape, OK, Err], Shape, OK, Err any](ok OK) R {
var r Result[Shape, OK, Err]
r.validate()
r.isErr = ResultOK
*((*OK)(unsafe.Pointer(&r.data))) = ok
Expand All @@ -98,8 +110,8 @@ func OK[R ~struct{ result[Shape, OK, Err] }, Shape, OK, Err any](ok OK) R {

// Err returns an error result with shape Shape and type OK and Err.
// Pass Result[OK, OK, Err] or Result[Err, OK, Err] as the first type argument.
func Err[R ~struct{ result[Shape, OK, Err] }, Shape, OK, Err any](err Err) R {
var r struct{ result[Shape, OK, Err] }
func Err[R AnyResult[Shape, OK, Err], Shape, OK, Err any](err Err) R {
var r Result[Shape, OK, Err]
r.validate()
r.isErr = ResultErr
*((*Err)(unsafe.Pointer(&r.data))) = err
Expand Down
15 changes: 15 additions & 0 deletions src/internal/cm/tuple.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package cm
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple[T0, T1 any] struct {
_ HostLayout
F0 T0
F1 T1
}
Expand All @@ -12,6 +13,7 @@ type Tuple[T0, T1 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple3[T0, T1, T2 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -21,6 +23,7 @@ type Tuple3[T0, T1, T2 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple4[T0, T1, T2, T3 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -31,6 +34,7 @@ type Tuple4[T0, T1, T2, T3 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple5[T0, T1, T2, T3, T4 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -42,6 +46,7 @@ type Tuple5[T0, T1, T2, T3, T4 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple6[T0, T1, T2, T3, T4, T5 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -54,6 +59,7 @@ type Tuple6[T0, T1, T2, T3, T4, T5 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple7[T0, T1, T2, T3, T4, T5, T6 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -67,6 +73,7 @@ type Tuple7[T0, T1, T2, T3, T4, T5, T6 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple8[T0, T1, T2, T3, T4, T5, T6, T7 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -81,6 +88,7 @@ type Tuple8[T0, T1, T2, T3, T4, T5, T6, T7 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple9[T0, T1, T2, T3, T4, T5, T6, T7, T8 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -96,6 +104,7 @@ type Tuple9[T0, T1, T2, T3, T4, T5, T6, T7, T8 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -112,6 +121,7 @@ type Tuple10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -129,6 +139,7 @@ type Tuple11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -147,6 +158,7 @@ type Tuple12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -166,6 +178,7 @@ type Tuple13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any] struct {
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -186,6 +199,7 @@ type Tuple14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any] str
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand All @@ -207,6 +221,7 @@ type Tuple15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any
//
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
type Tuple16[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any] struct {
_ HostLayout
F0 T0
F1 T1
F2 T2
Expand Down
18 changes: 15 additions & 3 deletions src/internal/cm/variant.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,18 @@ type Discriminant interface {
// Variant represents a loosely-typed Component Model variant.
// Shape and Align must be non-zero sized types. To create a variant with no associated
// types, use an enum.
type Variant[Tag Discriminant, Shape, Align any] struct{ variant[Tag, Shape, Align] }
type Variant[Tag Discriminant, Shape, Align any] struct {
_ HostLayout
variant[Tag, Shape, Align]
}

// AnyVariant is a type constraint for generic functions that accept any [Variant] type.
type AnyVariant[Tag Discriminant, Shape, Align any] interface {
~struct {
_ HostLayout
variant[Tag, Shape, Align]
}
}

// NewVariant returns a [Variant] with tag of type Disc, storage and GC shape of type Shape,
// aligned to type Align, with a value of type T.
Expand All @@ -26,7 +37,7 @@ func NewVariant[Tag Discriminant, Shape, Align any, T any](tag Tag, data T) Vari

// New returns a [Variant] with tag of type Disc, storage and GC shape of type Shape,
// aligned to type Align, with a value of type T.
func New[V ~struct{ variant[Tag, Shape, Align] }, Tag Discriminant, Shape, Align any, T any](tag Tag, data T) V {
func New[V AnyVariant[Tag, Shape, Align], Tag Discriminant, Shape, Align any, T any](tag Tag, data T) V {
validateVariant[Tag, Shape, Align, T]()
var v variant[Tag, Shape, Align]
v.tag = tag
Expand All @@ -35,7 +46,7 @@ func New[V ~struct{ variant[Tag, Shape, Align] }, Tag Discriminant, Shape, Align
}

// Case returns a non-nil *T if the [Variant] case is equal to tag, otherwise it returns nil.
func Case[T any, V ~struct{ variant[Tag, Shape, Align] }, Tag Discriminant, Shape, Align any](v *V, tag Tag) *T {
func Case[T any, V AnyVariant[Tag, Shape, Align], Tag Discriminant, Shape, Align any](v *V, tag Tag) *T {
validateVariant[Tag, Shape, Align, T]()
v2 := (*variant[Tag, Shape, Align])(unsafe.Pointer(v))
if v2.tag == tag {
Expand All @@ -47,6 +58,7 @@ func Case[T any, V ~struct{ variant[Tag, Shape, Align] }, Tag Discriminant, Shap
// variant is the internal representation of a Component Model variant.
// Shape and Align must be non-zero sized types.
type variant[Tag Discriminant, Shape, Align any] struct {
_ HostLayout
tag Tag
_ [0]Align
data Shape // [unsafe.Sizeof(*(*Shape)(unsafe.Pointer(nil)))]byte
Expand Down
Loading

0 comments on commit d5f1953

Please sign in to comment.