From c7a1b97e64362fc0c0df26f4ef01e2c405ae50f8 Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sat, 21 Sep 2024 22:34:15 -0700 Subject: [PATCH 01/10] cm: add HostLayout polyfill for Go 1.22 and below --- cm/hostlayout_go122.go | 11 +++++++++++ cm/hostlayout_go123.go | 9 +++++++++ 2 files changed, 20 insertions(+) create mode 100644 cm/hostlayout_go122.go create mode 100644 cm/hostlayout_go123.go diff --git a/cm/hostlayout_go122.go b/cm/hostlayout_go122.go new file mode 100644 index 00000000..25c14697 --- /dev/null +++ b/cm/hostlayout_go122.go @@ -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{} diff --git a/cm/hostlayout_go123.go b/cm/hostlayout_go123.go new file mode 100644 index 00000000..4fc3a2bd --- /dev/null +++ b/cm/hostlayout_go123.go @@ -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 From f050de3e4b0b0367f9e8d1dd6cb9bd42ff00d985 Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sat, 21 Sep 2024 22:51:38 -0700 Subject: [PATCH 02/10] wit/bindgen: add HostLayout field to wasm structs --- wit/bindgen/generator.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/wit/bindgen/generator.go b/wit/bindgen/generator.go index e892a13d..ff193b64 100644 --- a/wit/bindgen/generator.go +++ b/wit/bindgen/generator.go @@ -704,7 +704,9 @@ func (g *generator) primitiveRep(p wit.Primitive) string { func (g *generator) recordRep(file *gen.File, dir wit.Direction, r *wit.Record, goName string) string { exported := len(goName) == 0 || token.IsExported(goName) var b strings.Builder - b.WriteString("struct {") + cm := file.Import(g.opts.cmPackage) + b.WriteString("struct {\n") + stringio.Write(&b, "_ ", cm, ".HostLayout") for i, f := range r.Fields { if i == 0 || i > 0 && f.Docs.Contents != "" { b.WriteRune('\n') @@ -1723,11 +1725,11 @@ func (g *generator) defineImportedFunction(_ wit.Ident, f *wit.Function, decl fu if pointerParam.typ != nil { stringio.Write(&b, callParams[0].name, " := &", decl.f.params[0].name, "\n") } else if compoundParams.typ != nil { + cm := file.Import(g.opts.cmPackage) stringio.Write(&b, compoundParams.name, " := ", g.typeRep(file, compoundParams.dir, compoundParams.typ), "{ ") - for i, p := range decl.f.params { - if i > 0 { - b.WriteString(", ") - } + stringio.Write(&b, cm, ".HostLayout{}") + for _, p := range decl.f.params { + b.WriteString(", ") b.WriteString(p.name) } b.WriteString(" }\n") From 618dfa2003789f4c6cf50607d3ced23a6e6b632a Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sat, 21 Sep 2024 22:58:19 -0700 Subject: [PATCH 03/10] wit/bindgen: embed HostLayout, not _ field --- wit/bindgen/generator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wit/bindgen/generator.go b/wit/bindgen/generator.go index ff193b64..783e76a6 100644 --- a/wit/bindgen/generator.go +++ b/wit/bindgen/generator.go @@ -706,7 +706,7 @@ func (g *generator) recordRep(file *gen.File, dir wit.Direction, r *wit.Record, var b strings.Builder cm := file.Import(g.opts.cmPackage) b.WriteString("struct {\n") - stringio.Write(&b, "_ ", cm, ".HostLayout") + stringio.Write(&b, cm, ".HostLayout") for i, f := range r.Fields { if i == 0 || i > 0 && f.Docs.Contents != "" { b.WriteRune('\n') From e6f23b68f6a855ced5c8ad70d56a997e1541a6bf Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sun, 22 Sep 2024 07:25:48 -0700 Subject: [PATCH 04/10] cm: embed HostLayout in layout test structs --- cm/{layout_test.go => hostlayout_test.go} | 4 ++++ 1 file changed, 4 insertions(+) rename cm/{layout_test.go => hostlayout_test.go} (98%) diff --git a/cm/layout_test.go b/cm/hostlayout_test.go similarity index 98% rename from cm/layout_test.go rename to cm/hostlayout_test.go index a6069ed9..c1dcf184 100644 --- a/cm/layout_test.go +++ b/cm/hostlayout_test.go @@ -10,6 +10,7 @@ import ( func TestFieldAlignment(t *testing.T) { var v1 struct { + HostLayout _ bool _ [0][7]byte u64 uint64 @@ -22,6 +23,7 @@ func TestFieldAlignment(t *testing.T) { } var v2 struct { + HostLayout _ bool _ [0][7]byte _ [0][51]float64 @@ -40,6 +42,7 @@ func TestFieldAlignment(t *testing.T) { // size 1 var v3 struct { + HostLayout _ struct{} b bool // offset 0 } @@ -52,6 +55,7 @@ func TestFieldAlignment(t *testing.T) { // size 0 var v4 struct { + HostLayout _ [0]uint32 b bool // offset 0! } From ee3c35da91e13e7adf221a13baea1c3e04bc797b Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sun, 22 Sep 2024 07:27:00 -0700 Subject: [PATCH 05/10] cm: embed HostLayout in tuple, list, option, result, and variant types --- cm/list.go | 1 + cm/option.go | 1 + cm/result.go | 1 + cm/result_test.go | 1 + cm/tuple.go | 15 +++++++++++++++ cm/tuple_test.go | 15 ++++++++------- cm/variant.go | 1 + 7 files changed, 28 insertions(+), 7 deletions(-) diff --git a/cm/list.go b/cm/list.go index e170efbe..ec0f9a7f 100644 --- a/cm/list.go +++ b/cm/list.go @@ -27,6 +27,7 @@ func ToList[S ~[]T, T any](s S) List[T] { // 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 } diff --git a/cm/option.go b/cm/option.go index edc288b4..8767b064 100644 --- a/cm/option.go +++ b/cm/option.go @@ -25,6 +25,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 } diff --git a/cm/result.go b/cm/result.go index d2127561..3bfc0e58 100644 --- a/cm/result.go +++ b/cm/result.go @@ -21,6 +21,7 @@ type Result[Shape, OK, Err any] struct{ 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 diff --git a/cm/result_test.go b/cm/result_test.go index 0f3ae6f7..b66f810c 100644 --- a/cm/result_test.go +++ b/cm/result_test.go @@ -183,6 +183,7 @@ func TestIssue95Struct(t *testing.T) { type ( // structResult Result[structVariant, stringStruct, structVariant] stringStruct struct { + HostLayout // i int s string } diff --git a/cm/tuple.go b/cm/tuple.go index 7b0e535c..69518b8c 100644 --- a/cm/tuple.go +++ b/cm/tuple.go @@ -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 } @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/cm/tuple_test.go b/cm/tuple_test.go index 93177f5b..8f9fe1ab 100644 --- a/cm/tuple_test.go +++ b/cm/tuple_test.go @@ -6,11 +6,12 @@ import ( ) func TestTuple(t *testing.T) { - _ = Tuple[string, bool]{"hello", false} - _ = Tuple3[string, bool, uint8]{"hello", false, 1} - _ = Tuple4[string, bool, uint8, uint16]{"hello", false, 1, 32000} - _ = Tuple5[string, bool, uint8, uint16, uint32]{"hello", false, 1, 32000, 1_000_000} - _ = Tuple6[string, bool, uint8, uint16, uint32, uint64]{"hello", false, 1, 32000, 1_000_000, 5_000_000_000} - _ = Tuple7[string, bool, uint8, uint16, uint32, uint64, float32]{"hello", false, math.MaxUint8, math.MaxUint16, math.MaxUint32, math.MaxUint64, math.MaxFloat32} - _ = Tuple8[string, bool, uint8, uint16, uint32, uint64, float32, float64]{"hello", false, math.MaxUint8, math.MaxUint16, math.MaxUint32, math.MaxUint64, math.MaxFloat32, math.MaxFloat64} + var H HostLayout + _ = Tuple[string, bool]{H, "hello", false} + _ = Tuple3[string, bool, uint8]{H, "hello", false, 1} + _ = Tuple4[string, bool, uint8, uint16]{H, "hello", false, 1, 32000} + _ = Tuple5[string, bool, uint8, uint16, uint32]{H, "hello", false, 1, 32000, 1_000_000} + _ = Tuple6[string, bool, uint8, uint16, uint32, uint64]{H, "hello", false, 1, 32000, 1_000_000, 5_000_000_000} + _ = Tuple7[string, bool, uint8, uint16, uint32, uint64, float32]{H, "hello", false, math.MaxUint8, math.MaxUint16, math.MaxUint32, math.MaxUint64, math.MaxFloat32} + _ = Tuple8[string, bool, uint8, uint16, uint32, uint64, float32, float64]{H, "hello", false, math.MaxUint8, math.MaxUint16, math.MaxUint32, math.MaxUint64, math.MaxFloat32, math.MaxFloat64} } diff --git a/cm/variant.go b/cm/variant.go index 5ae5cf38..67025368 100644 --- a/cm/variant.go +++ b/cm/variant.go @@ -47,6 +47,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 From 4883cc85f7083e470dcbd477cf7e7608ebc14752 Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sun, 22 Sep 2024 07:48:40 -0700 Subject: [PATCH 06/10] wit/bindgen: reenable testdata test --- wit/bindgen/testdata_test.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/wit/bindgen/testdata_test.go b/wit/bindgen/testdata_test.go index 7fba06cf..7ce44b01 100644 --- a/wit/bindgen/testdata_test.go +++ b/wit/bindgen/testdata_test.go @@ -15,11 +15,12 @@ import ( "sync" "testing" + "golang.org/x/tools/go/packages" + "github.com/bytecodealliance/wasm-tools-go/internal/codec" "github.com/bytecodealliance/wasm-tools-go/internal/go/gen" "github.com/bytecodealliance/wasm-tools-go/internal/relpath" "github.com/bytecodealliance/wasm-tools-go/wit" - "golang.org/x/tools/go/packages" ) var writeGoFiles = flag.Bool("write", false, "write generated Go files") @@ -192,10 +193,10 @@ func validateGeneratedGo(t *testing.T, res *wit.Resolve, origin string) { if def == nil || def.Parent() != goPkg.Types.Scope() { continue } - // t.Logf("Def: %s", id.String()) - if !pkg.HasName(id.String()) { - // TODO: reenable this test - // t.Errorf("name %s not found in generated package %s", id.String(), pkg.Path) + name := id.String() + // t.Logf("Def: %s %T", name, def.Type()) + if name != "init" && !pkg.HasName(name) { + t.Errorf("name %s not found in generated package %s", name, pkg.Path) } } From 896cff534246e741a0d403ea0bf012d9bc5744dd Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sun, 22 Sep 2024 21:24:07 -0700 Subject: [PATCH 07/10] testdata/example: add reserved keywords to param names to overflow max 16 flat params --- testdata/example/non-flat-params.wit | 2 + testdata/example/non-flat-params.wit.json | 84 +++++++++++++++++++ .../non-flat-params.wit.json.golden.wit | 1 + 3 files changed, 87 insertions(+) diff --git a/testdata/example/non-flat-params.wit b/testdata/example/non-flat-params.wit index a22a8ba6..27c739f4 100644 --- a/testdata/example/non-flat-params.wit +++ b/testdata/example/non-flat-params.wit @@ -57,6 +57,8 @@ interface corner-case { u17-void: func(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8, g: u8, h: u8, i: u8, j: u8, k: u8, l: u8, m: u8, n: u8, o: u8, p: u8, q: u8); u17-u8-u8: func(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8, g: u8, h: u8, i: u8, j: u8, k: u8, l: u8, m: u8, n: u8, o: u8, p: u8, q: u8) -> (r0: u8, r1: u8); } + + reserved-names: func(%bool: u8, int8: u8, uint8: u8, int16: u8, uint16: u8, int32: u8, uint32: u8, %f32: u8, %f64: u8, %string: u8, %record: u8, struct: u8, %world: u8, %interface: u8, %option: u8, %package: u8, %result: u8) -> (r0: u8, r1: u8); } world imports { diff --git a/testdata/example/non-flat-params.wit.json b/testdata/example/non-flat-params.wit.json index 81f89c46..b9c3868c 100644 --- a/testdata/example/non-flat-params.wit.json +++ b/testdata/example/non-flat-params.wit.json @@ -1641,6 +1641,90 @@ "type": "u8" } ] + }, + "reserved-names": { + "name": "reserved-names", + "kind": "freestanding", + "params": [ + { + "name": "bool", + "type": "u8" + }, + { + "name": "int8", + "type": "u8" + }, + { + "name": "uint8", + "type": "u8" + }, + { + "name": "int16", + "type": "u8" + }, + { + "name": "uint16", + "type": "u8" + }, + { + "name": "int32", + "type": "u8" + }, + { + "name": "uint32", + "type": "u8" + }, + { + "name": "f32", + "type": "u8" + }, + { + "name": "f64", + "type": "u8" + }, + { + "name": "string", + "type": "u8" + }, + { + "name": "record", + "type": "u8" + }, + { + "name": "struct", + "type": "u8" + }, + { + "name": "world", + "type": "u8" + }, + { + "name": "interface", + "type": "u8" + }, + { + "name": "option", + "type": "u8" + }, + { + "name": "package", + "type": "u8" + }, + { + "name": "result", + "type": "u8" + } + ], + "results": [ + { + "name": "r0", + "type": "u8" + }, + { + "name": "r1", + "type": "u8" + } + ] } }, "package": 0 diff --git a/testdata/example/non-flat-params.wit.json.golden.wit b/testdata/example/non-flat-params.wit.json.golden.wit index 2ec0071b..8a4d7795 100644 --- a/testdata/example/non-flat-params.wit.json.golden.wit +++ b/testdata/example/non-flat-params.wit.json.golden.wit @@ -44,6 +44,7 @@ interface corner-case { u16-x17-u8: func(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8, g: u8, h: u8, i: u8, j: u8, k: u8, l: u8, m: u8, n: u8, o: u8, p: u8) -> (a: u8, b: u8, c: u8, d: u8, e: u8, f: u8, g: u8, h: u8, i: u8, j: u8, k: u8, l: u8, m: u8, n: u8, o: u8, p: u8, q: u8); u17-void: func(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8, g: u8, h: u8, i: u8, j: u8, k: u8, l: u8, m: u8, n: u8, o: u8, p: u8, q: u8); u17-u8-u8: func(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8, g: u8, h: u8, i: u8, j: u8, k: u8, l: u8, m: u8, n: u8, o: u8, p: u8, q: u8) -> (r0: u8, r1: u8); + reserved-names: func(%bool: u8, int8: u8, uint8: u8, int16: u8, uint16: u8, int32: u8, uint32: u8, %f32: u8, %f64: u8, %string: u8, %record: u8, struct: u8, %world: u8, %interface: u8, %option: u8, %package: u8, %result: u8) -> (r0: u8, r1: u8); } world imports { From abc90992293bba5fb7cfcb1ddb7e96025a968385 Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sun, 22 Sep 2024 21:24:35 -0700 Subject: [PATCH 08/10] cm: rename var H to HL in tuple test --- cm/tuple_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cm/tuple_test.go b/cm/tuple_test.go index 8f9fe1ab..9ff9a3b2 100644 --- a/cm/tuple_test.go +++ b/cm/tuple_test.go @@ -6,12 +6,12 @@ import ( ) func TestTuple(t *testing.T) { - var H HostLayout - _ = Tuple[string, bool]{H, "hello", false} - _ = Tuple3[string, bool, uint8]{H, "hello", false, 1} - _ = Tuple4[string, bool, uint8, uint16]{H, "hello", false, 1, 32000} - _ = Tuple5[string, bool, uint8, uint16, uint32]{H, "hello", false, 1, 32000, 1_000_000} - _ = Tuple6[string, bool, uint8, uint16, uint32, uint64]{H, "hello", false, 1, 32000, 1_000_000, 5_000_000_000} - _ = Tuple7[string, bool, uint8, uint16, uint32, uint64, float32]{H, "hello", false, math.MaxUint8, math.MaxUint16, math.MaxUint32, math.MaxUint64, math.MaxFloat32} - _ = Tuple8[string, bool, uint8, uint16, uint32, uint64, float32, float64]{H, "hello", false, math.MaxUint8, math.MaxUint16, math.MaxUint32, math.MaxUint64, math.MaxFloat32, math.MaxFloat64} + var HL HostLayout + _ = Tuple[string, bool]{HL, "hello", false} + _ = Tuple3[string, bool, uint8]{HL, "hello", false, 1} + _ = Tuple4[string, bool, uint8, uint16]{HL, "hello", false, 1, 32000} + _ = Tuple5[string, bool, uint8, uint16, uint32]{HL, "hello", false, 1, 32000, 1_000_000} + _ = Tuple6[string, bool, uint8, uint16, uint32, uint64]{HL, "hello", false, 1, 32000, 1_000_000, 5_000_000_000} + _ = Tuple7[string, bool, uint8, uint16, uint32, uint64, float32]{HL, "hello", false, math.MaxUint8, math.MaxUint16, math.MaxUint32, math.MaxUint64, math.MaxFloat32} + _ = Tuple8[string, bool, uint8, uint16, uint32, uint64, float32, float64]{HL, "hello", false, math.MaxUint8, math.MaxUint16, math.MaxUint32, math.MaxUint64, math.MaxFloat32, math.MaxFloat64} } From c25391706c4bb834a96b16d3b368368b1dd2ecbc Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sun, 22 Sep 2024 21:26:30 -0700 Subject: [PATCH 09/10] cm, wit/bindgen: use _ field instead of embedding HostLayout in structs --- cm/hostlayout_test.go | 8 ++++---- cm/list.go | 2 +- cm/option.go | 2 +- cm/result.go | 2 +- cm/result_test.go | 2 +- cm/tuple.go | 30 +++++++++++++++--------------- cm/variant.go | 2 +- wit/bindgen/generator.go | 13 +++++++------ 8 files changed, 31 insertions(+), 30 deletions(-) diff --git a/cm/hostlayout_test.go b/cm/hostlayout_test.go index c1dcf184..2c55c67c 100644 --- a/cm/hostlayout_test.go +++ b/cm/hostlayout_test.go @@ -10,7 +10,7 @@ import ( func TestFieldAlignment(t *testing.T) { var v1 struct { - HostLayout + _ HostLayout _ bool _ [0][7]byte u64 uint64 @@ -23,7 +23,7 @@ func TestFieldAlignment(t *testing.T) { } var v2 struct { - HostLayout + _ HostLayout _ bool _ [0][7]byte _ [0][51]float64 @@ -42,7 +42,7 @@ func TestFieldAlignment(t *testing.T) { // size 1 var v3 struct { - HostLayout + _ HostLayout _ struct{} b bool // offset 0 } @@ -55,7 +55,7 @@ func TestFieldAlignment(t *testing.T) { // size 0 var v4 struct { - HostLayout + _ HostLayout _ [0]uint32 b bool // offset 0! } diff --git a/cm/list.go b/cm/list.go index ec0f9a7f..22a32ebb 100644 --- a/cm/list.go +++ b/cm/list.go @@ -27,7 +27,7 @@ func ToList[S ~[]T, T any](s S) List[T] { // 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 + _ HostLayout data *T len uint } diff --git a/cm/option.go b/cm/option.go index 8767b064..9b812a8d 100644 --- a/cm/option.go +++ b/cm/option.go @@ -25,7 +25,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 + _ HostLayout isSome bool some T } diff --git a/cm/result.go b/cm/result.go index 3bfc0e58..dcb2fffe 100644 --- a/cm/result.go +++ b/cm/result.go @@ -21,7 +21,7 @@ type Result[Shape, OK, Err any] struct{ result[Shape, OK, Err] } // result represents the internal representation of a Component Model result type. type result[Shape, OK, Err any] struct { - HostLayout + _ HostLayout isErr bool _ [0]OK _ [0]Err diff --git a/cm/result_test.go b/cm/result_test.go index b66f810c..56bf5b4e 100644 --- a/cm/result_test.go +++ b/cm/result_test.go @@ -183,7 +183,7 @@ func TestIssue95Struct(t *testing.T) { type ( // structResult Result[structVariant, stringStruct, structVariant] stringStruct struct { - HostLayout + _ HostLayout // i int s string } diff --git a/cm/tuple.go b/cm/tuple.go index 69518b8c..610a19be 100644 --- a/cm/tuple.go +++ b/cm/tuple.go @@ -4,7 +4,7 @@ package cm // // [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples type Tuple[T0, T1 any] struct { - HostLayout + _ HostLayout F0 T0 F1 T1 } @@ -13,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -23,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -34,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -46,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -59,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -73,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -88,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -104,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -121,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -139,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -158,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -178,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -199,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 @@ -221,7 +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 + _ HostLayout F0 T0 F1 T1 F2 T2 diff --git a/cm/variant.go b/cm/variant.go index 67025368..61949361 100644 --- a/cm/variant.go +++ b/cm/variant.go @@ -47,7 +47,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 + _ HostLayout tag Tag _ [0]Align data Shape // [unsafe.Sizeof(*(*Shape)(unsafe.Pointer(nil)))]byte diff --git a/wit/bindgen/generator.go b/wit/bindgen/generator.go index 783e76a6..42cff717 100644 --- a/wit/bindgen/generator.go +++ b/wit/bindgen/generator.go @@ -706,7 +706,7 @@ func (g *generator) recordRep(file *gen.File, dir wit.Direction, r *wit.Record, var b strings.Builder cm := file.Import(g.opts.cmPackage) b.WriteString("struct {\n") - stringio.Write(&b, cm, ".HostLayout") + stringio.Write(&b, "_ ", cm, ".HostLayout") for i, f := range r.Fields { if i == 0 || i > 0 && f.Docs.Contents != "" { b.WriteRune('\n') @@ -1725,12 +1725,13 @@ func (g *generator) defineImportedFunction(_ wit.Ident, f *wit.Function, decl fu if pointerParam.typ != nil { stringio.Write(&b, callParams[0].name, " := &", decl.f.params[0].name, "\n") } else if compoundParams.typ != nil { - cm := file.Import(g.opts.cmPackage) stringio.Write(&b, compoundParams.name, " := ", g.typeRep(file, compoundParams.dir, compoundParams.typ), "{ ") - stringio.Write(&b, cm, ".HostLayout{}") - for _, p := range decl.f.params { - b.WriteString(", ") - b.WriteString(p.name) + for i, p := range decl.f.params { + if i > 0 { + b.WriteString(", ") + } + // compound parameter struct field names are identical to parameter names + stringio.Write(&b, p.name, ": ", p.name) } b.WriteString(" }\n") } else if len(callParams) > 0 { From 45615b2048c31001f7b23ff1a8ab2d29ade5c012 Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Sun, 22 Sep 2024 22:12:14 -0700 Subject: [PATCH 10/10] CHANGELOG: added HostLayout --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edd334d2..b38c1eba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### Added +- Generated structs and structs in package `cm` now include a [`HostLayout` field](https://github.com/golang/go/issues/66408) in order to conform with the [relaxed types proposal](https://github.com/golang/go/issues/66984) for `GOARCH=wasm32`. The `cm.HostLayout` type is an alias for `structs.HostLayout` on Go 1.23 or later, and a polyfill for Go 1.22 or earlier. - [#163](https://github.com/bytecodealliance/wasm-tools-go/issues/163): added `cm.F32ToU64()` and `cm.U64ToF32()` for flattening `f32` and `u64` types in the Canonical ABI. -- Test data from [bytecodealliance/wit-bindgen/tests/codegen](https://github.com/bytecodealliance/wit-bindgen/tree/main/tests/codegen) +- Test data from [bytecodealliance/wit-bindgen/tests/codegen](https://github.com/bytecodealliance/wit-bindgen/tree/main/tests/codegen). ### Fixed