cmd/compile: add basic wasmexport support

This CL adds a compiler directive go:wasmexport, which applies to
a Go function and makes it an exported function of the Wasm module
being built, so it can be called directly from the host. As
proposed in #65199, parameter and result types are limited to
32-bit and 64-bit integers and floats, and there can be at most
one result.

As the Go and Wasm calling conventions are different, for a
wasmexport function we generate a wrapper function does the ABI
conversion at compile time.

Currently this CL only adds basic support. In particular,
- it only supports executable mode, i.e. the Go wasm module calls
  into the host via wasmimport, which then calls back to Go via
  wasmexport. Library (c-shared) mode is not implemented yet.
- only supports wasip1, not js.
- if the exported function unwinds stacks (goroutine switch, stack
growth, etc.), it probably doesn't work.

TODO: support stack unwinding, c-shared mode, js.

For #65199.

Change-Id: Id1777c2d44f7d51942c1caed3173c0a82f120cc4
Reviewed-on: https://go-review.googlesource.com/c/go/+/603055
Reviewed-by: Than McIntosh <thanm@golang.org>
Reviewed-by: Randy Reddig <randy.reddig@fastly.com>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Cherry Mui 2024-08-03 14:20:58 -04:00
parent ff2a57ba92
commit 1cf6e31f0d
17 changed files with 331 additions and 21 deletions

View file

@ -500,6 +500,7 @@ type FuncInfo struct {
FuncInfoSym *LSym
WasmImport *WasmImport
WasmExport *WasmExport
sehUnwindInfoSym *LSym
}
@ -665,9 +666,9 @@ func (wi *WasmImport) Read(b []byte) {
// parameters and results translated into WASM types based on the Go function
// declaration.
type WasmFuncType struct {
// Params holds the imported function parameter fields.
// Params holds the function parameter fields.
Params []WasmField
// Results holds the imported function result fields.
// Results holds the function result fields.
Results []WasmField
}
@ -724,6 +725,27 @@ func (ft *WasmFuncType) Read(b []byte) {
}
}
// WasmExport represents a WebAssembly (WASM) exported function with
// parameters and results translated into WASM types based on the Go function
// declaration.
type WasmExport struct {
WasmFuncType
WrappedSym *LSym // the wrapped Go function
AuxSym *LSym // aux symbol to pass metadata to the linker
}
func (we *WasmExport) CreateAuxSym() {
var b bytes.Buffer
we.WasmFuncType.Write(&b)
p := b.Bytes()
we.AuxSym = &LSym{
Type: objabi.SDATA, // doesn't really matter
P: append([]byte(nil), p...),
Size: int64(len(p)),
}
}
type WasmField struct {
Type WasmFieldType
// Offset holds the frame-pointer-relative locations for Go's stack-based