Skip to content

Commit 1c3c363

Browse files
committed
update examples
Signed-off-by: Lucas Fontes <[email protected]>
1 parent 6818704 commit 1c3c363

File tree

152 files changed

+2669
-1298
lines changed

Some content is hidden

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

152 files changed

+2669
-1298
lines changed

component/cm/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Vendored version of `go.bytecodealliance.org/cm` and published under `go.wasmcloud.dev/component/cm`.
2+
3+
This package is included in bindings generated by `go.wasmcloud.dev/component/wit-bindgen`.
4+
5+
Do not use it if you generate bindings with the upstream `go.bytecodealliance.org/cmd/wit-bindgen-go`.
6+
7+
## Differences
8+
9+
- codegen & cm packages locked to wasmcloud component-sdk version
10+
- JSON marshaling for Option types

component/cm/abi.go

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package cm
2+
3+
import "unsafe"
4+
5+
// AnyInteger is a type constraint for any integer type.
6+
type AnyInteger interface {
7+
~int | ~uint | ~uintptr | ~int8 | ~uint8 | ~int16 | ~uint16 | ~int32 | ~uint32 | ~int64 | ~uint64
8+
}
9+
10+
// Reinterpret reinterprets the bits of type From into type T.
11+
// Will panic if the size of From is smaller than the size of To.
12+
func Reinterpret[T, From any](from From) (to T) {
13+
if unsafe.Sizeof(to) > unsafe.Sizeof(from) {
14+
panic("reinterpret: size of to > from")
15+
}
16+
return *(*T)(unsafe.Pointer(&from))
17+
}
18+
19+
// LowerString lowers a [string] into a pair of Core WebAssembly types.
20+
//
21+
// [string]: https://pkg.go.dev/builtin#string
22+
func LowerString[S ~string](s S) (*byte, uint32) {
23+
return unsafe.StringData(string(s)), uint32(len(s))
24+
}
25+
26+
// LiftString lifts Core WebAssembly types into a [string].
27+
func LiftString[T ~string, Data unsafe.Pointer | uintptr | *uint8, Len AnyInteger](data Data, len Len) T {
28+
return T(unsafe.String((*uint8)(unsafe.Pointer(data)), int(len)))
29+
}
30+
31+
// LowerList lowers a [List] into a pair of Core WebAssembly types.
32+
func LowerList[L AnyList[T], T any](list L) (*T, uint32) {
33+
l := (*List[T])(unsafe.Pointer(&list))
34+
return l.data, uint32(l.len)
35+
}
36+
37+
// LiftList lifts Core WebAssembly types into a [List].
38+
func LiftList[L AnyList[T], T any, Data unsafe.Pointer | uintptr | *T, Len AnyInteger](data Data, len Len) L {
39+
return L(NewList((*T)(unsafe.Pointer(data)), len))
40+
}
41+
42+
// BoolToU32 converts a value whose underlying type is [bool] into a [uint32].
43+
// Used to lower a [bool] into a Core WebAssembly i32 as specified in the [Canonical ABI].
44+
//
45+
// [bool]: https://pkg.go.dev/builtin#bool
46+
// [uint32]: https://pkg.go.dev/builtin#uint32
47+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
48+
func BoolToU32[B ~bool](v B) uint32 { return uint32(*(*uint8)(unsafe.Pointer(&v))) }
49+
50+
// U32ToBool converts a [uint32] into a [bool].
51+
// Used to lift a Core WebAssembly i32 into a [bool] as specified in the [Canonical ABI].
52+
//
53+
// [uint32]: https://pkg.go.dev/builtin#uint32
54+
// [bool]: https://pkg.go.dev/builtin#bool
55+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
56+
func U32ToBool(v uint32) bool { tmp := uint8(v); return *(*bool)(unsafe.Pointer(&tmp)) }
57+
58+
// F32ToU32 maps the bits of a [float32] into a [uint32].
59+
// Used to lower a [float32] into a Core WebAssembly i32 as specified in the [Canonical ABI].
60+
//
61+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
62+
// [float32]: https://pkg.go.dev/builtin#float32
63+
// [uint32]: https://pkg.go.dev/builtin#uint32
64+
func F32ToU32(v float32) uint32 { return *(*uint32)(unsafe.Pointer(&v)) }
65+
66+
// U32ToF32 maps the bits of a [uint32] into a [float32].
67+
// Used to lift a Core WebAssembly i32 into a [float32] as specified in the [Canonical ABI].
68+
//
69+
// [uint32]: https://pkg.go.dev/builtin#uint32
70+
// [float32]: https://pkg.go.dev/builtin#float32
71+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
72+
func U32ToF32(v uint32) float32 { return *(*float32)(unsafe.Pointer(&v)) }
73+
74+
// F64ToU64 maps the bits of a [float64] into a [uint64].
75+
// Used to lower a [float64] into a Core WebAssembly i64 as specified in the [Canonical ABI].
76+
//
77+
// [float64]: https://pkg.go.dev/builtin#float64
78+
// [uint64]: https://pkg.go.dev/builtin#uint64
79+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
80+
//
81+
// [uint32]: https://pkg.go.dev/builtin#uint32
82+
func F64ToU64(v float64) uint64 { return *(*uint64)(unsafe.Pointer(&v)) }
83+
84+
// U64ToF64 maps the bits of a [uint64] into a [float64].
85+
// Used to lift a Core WebAssembly i64 into a [float64] as specified in the [Canonical ABI].
86+
//
87+
// [uint64]: https://pkg.go.dev/builtin#uint64
88+
// [float64]: https://pkg.go.dev/builtin#float64
89+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
90+
func U64ToF64(v uint64) float64 { return *(*float64)(unsafe.Pointer(&v)) }
91+
92+
// F32ToU64 maps the bits of a [float32] into a [uint64].
93+
// Used to lower a [float32] into a Core WebAssembly i64 when required by the [Canonical ABI].
94+
//
95+
// [float32]: https://pkg.go.dev/builtin#float32
96+
// [uint64]: https://pkg.go.dev/builtin#uint64
97+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
98+
func F32ToU64(v float32) uint64 { return uint64(*(*uint32)(unsafe.Pointer(&v))) }
99+
100+
// U64ToF32 maps the bits of a [uint64] into a [float32].
101+
// Used to lift a Core WebAssembly i64 into a [float32] when required by the [Canonical ABI].
102+
//
103+
// [uint64]: https://pkg.go.dev/builtin#uint64
104+
// [float32]: https://pkg.go.dev/builtin#float32
105+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
106+
func U64ToF32(v uint64) float32 {
107+
truncated := uint32(v)
108+
return *(*float32)(unsafe.Pointer(&truncated))
109+
}
110+
111+
// PointerToU32 converts a pointer of type *T into a [uint32].
112+
// Used to lower a pointer into a Core WebAssembly i32 as specified in the [Canonical ABI].
113+
//
114+
// [uint32]: https://pkg.go.dev/builtin#uint32
115+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
116+
func PointerToU32[T any](v *T) uint32 { return uint32(uintptr(unsafe.Pointer(v))) }
117+
118+
// U32ToPointer converts a [uint32] into a pointer of type *T.
119+
// Used to lift a Core WebAssembly i32 into a pointer as specified in the [Canonical ABI].
120+
//
121+
// [uint32]: https://pkg.go.dev/builtin#uint32
122+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
123+
func U32ToPointer[T any](v uint32) *T { return (*T)(unsafePointer(uintptr(v))) }
124+
125+
// PointerToU64 converts a pointer of type *T into a [uint64].
126+
// Used to lower a pointer into a Core WebAssembly i64 as specified in the [Canonical ABI].
127+
//
128+
// [uint64]: https://pkg.go.dev/builtin#uint64
129+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
130+
func PointerToU64[T any](v *T) uint64 { return uint64(uintptr(unsafe.Pointer(v))) }
131+
132+
// U64ToPointer converts a [uint64] into a pointer of type *T.
133+
// Used to lift a Core WebAssembly i64 into a pointer as specified in the [Canonical ABI].
134+
//
135+
// [uint64]: https://pkg.go.dev/builtin#uint64
136+
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
137+
func U64ToPointer[T any](v uint64) *T { return (*T)(unsafePointer(uintptr(v))) }
138+
139+
// Appease vet, see https://github.com/golang/go/issues/58625
140+
func unsafePointer(p uintptr) unsafe.Pointer {
141+
return *(*unsafe.Pointer)(unsafe.Pointer(&p))
142+
}

component/cm/abi_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package cm
2+
3+
import (
4+
"math"
5+
"testing"
6+
)
7+
8+
func TestIntConversions(t *testing.T) {
9+
for i := int8(math.MinInt8); i < math.MaxInt8; i++ {
10+
testIntRoundTrip[uint32](t, i)
11+
testIntRoundTrip[uint64](t, i)
12+
}
13+
14+
for i := uint8(0); i < math.MaxUint8; i++ {
15+
testIntRoundTrip[uint32](t, i)
16+
testIntRoundTrip[uint64](t, i)
17+
}
18+
19+
for i := int16(math.MinInt16); i < math.MaxInt16; i++ {
20+
testIntRoundTrip[uint32](t, i)
21+
testIntRoundTrip[uint64](t, i)
22+
}
23+
24+
for i := uint16(0); i < math.MaxUint16; i++ {
25+
testIntRoundTrip[uint32](t, i)
26+
testIntRoundTrip[uint64](t, i)
27+
}
28+
29+
// int32/uint32 into uint32
30+
testIntRoundTrip[uint32](t, int32(0))
31+
testIntRoundTrip[uint32](t, int32(math.MinInt8))
32+
testIntRoundTrip[uint32](t, int32(math.MinInt16))
33+
testIntRoundTrip[uint32](t, int32(math.MinInt32))
34+
testIntRoundTrip[uint32](t, int32(math.MaxInt8))
35+
testIntRoundTrip[uint32](t, int32(math.MaxInt16))
36+
testIntRoundTrip[uint32](t, int32(math.MaxInt32))
37+
testIntRoundTrip[uint32](t, uint32(0))
38+
testIntRoundTrip[uint32](t, uint32(math.MaxUint8))
39+
testIntRoundTrip[uint32](t, uint32(math.MaxUint16))
40+
testIntRoundTrip[uint32](t, uint32(math.MaxUint32))
41+
42+
// int32/uint32 into uint64
43+
testIntRoundTrip[uint64](t, int32(0))
44+
testIntRoundTrip[uint64](t, int32(math.MinInt8))
45+
testIntRoundTrip[uint64](t, int32(math.MinInt16))
46+
testIntRoundTrip[uint64](t, int32(math.MinInt32))
47+
testIntRoundTrip[uint64](t, int32(math.MaxInt8))
48+
testIntRoundTrip[uint64](t, int32(math.MaxInt16))
49+
testIntRoundTrip[uint64](t, int32(math.MaxInt32))
50+
testIntRoundTrip[uint64](t, uint32(0))
51+
testIntRoundTrip[uint64](t, uint32(math.MaxUint8))
52+
testIntRoundTrip[uint64](t, uint32(math.MaxUint16))
53+
testIntRoundTrip[uint64](t, uint32(math.MaxUint32))
54+
55+
// int64/uint64 into uint64
56+
testIntRoundTrip[uint64](t, int64(0))
57+
testIntRoundTrip[uint64](t, int64(math.MinInt8))
58+
testIntRoundTrip[uint64](t, int64(math.MinInt16))
59+
testIntRoundTrip[uint64](t, int64(math.MinInt32))
60+
testIntRoundTrip[uint64](t, int64(math.MaxInt8))
61+
testIntRoundTrip[uint64](t, int64(math.MaxInt16))
62+
testIntRoundTrip[uint64](t, int64(math.MaxInt32))
63+
testIntRoundTrip[uint64](t, uint64(0))
64+
testIntRoundTrip[uint64](t, uint64(math.MaxUint8))
65+
testIntRoundTrip[uint64](t, uint64(math.MaxUint16))
66+
testIntRoundTrip[uint64](t, uint64(math.MaxUint32))
67+
}
68+
69+
func testIntRoundTrip[Core CoreIntegers, From Integers](t *testing.T, want From) {
70+
core := Core(want) // Convert to a core integer type
71+
got := From(core) // Convert back to original type
72+
if got != want {
73+
t.Errorf("testLowerLift[%T, %T](t, %v): got %v, expected %v", want, core, want, got, want)
74+
}
75+
}
76+
77+
type Integers interface {
78+
int8 | uint8 | int16 | uint16 | int32 | uint32 | int64 | uint64 | uintptr
79+
}
80+
81+
type CoreIntegers interface {
82+
uint32 | uint64
83+
}

component/cm/case.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package cm
2+
3+
// CaseUnmarshaler returns an function that can unmarshal text into
4+
// [variant] or [enum] case T.
5+
//
6+
// [enum]: https://component-model.bytecodealliance.org/design/wit.html#enums
7+
// [variant]: https://component-model.bytecodealliance.org/design/wit.html#variants
8+
func CaseUnmarshaler[T ~uint8 | ~uint16 | ~uint32](cases []string) func(v *T, text []byte) error {
9+
if len(cases) <= linearScanThreshold {
10+
return func(v *T, text []byte) error {
11+
if len(text) == 0 {
12+
return &emptyTextError{}
13+
}
14+
s := string(text)
15+
for i := 0; i < len(cases); i++ {
16+
if cases[i] == s {
17+
*v = T(i)
18+
return nil
19+
}
20+
}
21+
return &noMatchingCaseError{}
22+
}
23+
}
24+
25+
m := make(map[string]T, len(cases))
26+
for i, v := range cases {
27+
m[v] = T(i)
28+
}
29+
30+
return func(v *T, text []byte) error {
31+
if len(text) == 0 {
32+
return &emptyTextError{}
33+
}
34+
c, ok := m[string(text)]
35+
if !ok {
36+
return &noMatchingCaseError{}
37+
}
38+
*v = c
39+
return nil
40+
}
41+
}
42+
43+
const linearScanThreshold = 16
44+
45+
type emptyTextError struct{}
46+
47+
func (*emptyTextError) Error() string { return "empty text" }
48+
49+
type noMatchingCaseError struct{}
50+
51+
func (*noMatchingCaseError) Error() string { return "no matching case" }

component/cm/case_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package cm
2+
3+
import (
4+
"strings"
5+
"testing"
6+
)
7+
8+
func TestCaseUnmarshaler(t *testing.T) {
9+
tests := []struct {
10+
name string
11+
cases []string
12+
}{
13+
{"nil", nil},
14+
{"empty slice", []string{}},
15+
{"a b c", strings.SplitAfter("abc", "")},
16+
{"a b c d e f g", strings.SplitAfter("abcdefg", "")},
17+
}
18+
for _, tt := range tests {
19+
t.Run(tt.name, func(t *testing.T) {
20+
f := CaseUnmarshaler[uint8](tt.cases)
21+
for want, c := range tt.cases {
22+
var got uint8
23+
err := f(&got, []byte(c))
24+
if err != nil {
25+
t.Error(err)
26+
return
27+
}
28+
if got != uint8(want) {
29+
t.Errorf("f(%q): got %d, expected %d", c, got, want)
30+
}
31+
}
32+
})
33+
}
34+
}

component/cm/debug_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package cm
2+
3+
import (
4+
"reflect"
5+
"strings"
6+
"unsafe"
7+
)
8+
9+
func typeName(v any) string {
10+
var name string
11+
if t := reflect.TypeOf(v); t.Kind() == reflect.Ptr {
12+
name = "*" + t.Elem().String()
13+
} else {
14+
name = t.String()
15+
}
16+
return strings.ReplaceAll(name, " ", "")
17+
}
18+
19+
func sizePlusAlignOf[T any]() uintptr {
20+
var v T
21+
return unsafe.Sizeof(v) + unsafe.Alignof(v)
22+
}
23+
24+
func alignOf[T any]() uintptr {
25+
var v T
26+
return unsafe.Alignof(v)
27+
}
28+
29+
func zeroPtr[T any]() *T {
30+
var zero T
31+
return &zero
32+
}
33+
34+
// TODO: remove this when TinyGo supports unsafe.Offsetof
35+
func offsetOf[Struct any, Field any](s *Struct, f *Field) uintptr {
36+
return uintptr(unsafe.Pointer(f)) - uintptr(unsafe.Pointer(s))
37+
}
38+
39+
// VariantDebug is an interface used in tests to validate layout of variant types.
40+
type VariantDebug interface {
41+
Size() uintptr
42+
DataAlign() uintptr
43+
DataOffset() uintptr
44+
}
45+
46+
func (v variant[Disc, Shape, Align]) Size() uintptr { return unsafe.Sizeof(v) }
47+
func (v variant[Disc, Shape, Align]) DataAlign() uintptr { return unsafe.Alignof(v.data) }
48+
func (v variant[Disc, Shape, Align]) DataOffset() uintptr { return offsetOf(&v, &v.data) }
49+
50+
// ResultDebug is an interface used in tests to validate layout of result types.
51+
type ResultDebug interface {
52+
VariantDebug
53+
}
54+
55+
func (r BoolResult) Size() uintptr { return unsafe.Sizeof(r) }
56+
func (r BoolResult) DataAlign() uintptr { return 0 }
57+
func (r BoolResult) DataOffset() uintptr { return 0 }
58+
59+
func (r result[Shape, OK, Err]) Size() uintptr { return unsafe.Sizeof(r) }
60+
func (r result[Shape, OK, Err]) DataAlign() uintptr { return unsafe.Alignof(r.data) }
61+
func (r result[Shape, OK, Err]) DataOffset() uintptr { return offsetOf(&r, &r.data) }

0 commit comments

Comments
 (0)