Skip to content

Commit 788b2db

Browse files
committed
compiler: enforce structs.HostLayout usage per wasm types proposal
golang/go#66984 TODO: regenerate WASI syscall packages for GC shape types including structs.HostLayout
1 parent 79f3c95 commit 788b2db

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

compiler/symbol.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -416,14 +416,14 @@ func (c *compilerContext) checkWasmImportExport(f *ssa.Function, pragma string)
416416
c.addError(f.Signature.Results().At(1).Pos(), fmt.Sprintf("%s: too many return values", pragma))
417417
} else if f.Signature.Results().Len() == 1 {
418418
result := f.Signature.Results().At(0)
419-
if !isValidWasmType(result.Type(), siteResult) {
419+
if !c.isValidWasmType(result.Type(), siteResult) {
420420
c.addError(result.Pos(), fmt.Sprintf("%s: unsupported result type %s", pragma, result.Type().String()))
421421
}
422422
}
423423
for _, param := range f.Params {
424424
// Check whether the type is allowed.
425425
// Only a very limited number of types can be mapped to WebAssembly.
426-
if !isValidWasmType(param.Type(), siteParam) {
426+
if !c.isValidWasmType(param.Type(), siteParam) {
427427
c.addError(param.Pos(), fmt.Sprintf("%s: unsupported parameter type %s", pragma, param.Type().String()))
428428
}
429429
}
@@ -436,7 +436,7 @@ func (c *compilerContext) checkWasmImportExport(f *ssa.Function, pragma string)
436436
//
437437
// This previously reflected the additional restrictions documented here:
438438
// https://github.com/golang/go/issues/59149
439-
func isValidWasmType(typ types.Type, site wasmSite) bool {
439+
func (c *compilerContext) isValidWasmType(typ types.Type, site wasmSite) bool {
440440
switch typ := typ.Underlying().(type) {
441441
case *types.Basic:
442442
switch typ.Kind() {
@@ -455,19 +455,32 @@ func isValidWasmType(typ types.Type, site wasmSite) bool {
455455
return site == siteParam || site == siteIndirect
456456
}
457457
case *types.Array:
458-
return site == siteIndirect && isValidWasmType(typ.Elem(), siteIndirect)
458+
return site == siteIndirect && c.isValidWasmType(typ.Elem(), siteIndirect)
459459
case *types.Struct:
460460
if site != siteIndirect {
461461
return false
462462
}
463+
// Structs with no fields do not need structs.HostLayout
464+
if typ.NumFields() == 0 {
465+
return true
466+
}
467+
var hasHostLayout bool
468+
if c.program.ImportedPackage("structs") == nil {
469+
hasHostLayout = true // package structs does not exist before go1.23
470+
}
463471
for i := 0; i < typ.NumFields(); i++ {
464-
if !isValidWasmType(typ.Field(i).Type(), siteIndirect) {
472+
ftyp := typ.Field(i).Type()
473+
if ftyp.String() == "structs.HostLayout" {
474+
hasHostLayout = true
475+
continue
476+
}
477+
if !c.isValidWasmType(ftyp, siteIndirect) {
465478
return false
466479
}
467480
}
468-
return true
481+
return hasHostLayout
469482
case *types.Pointer:
470-
return isValidWasmType(typ.Elem(), siteIndirect)
483+
return c.isValidWasmType(typ.Elem(), siteIndirect)
471484
}
472485
return false
473486
}

0 commit comments

Comments
 (0)