Optimizes GoModuleFunction signature and ensures function result slices are unique (#860)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
Crypt Keeper
2022-11-28 10:00:07 +08:00
committed by GitHub
parent 8990932a12
commit 0e851b71a8
23 changed files with 395 additions and 340 deletions

View File

@@ -307,6 +307,19 @@ type Function interface {
// The Module parameter is the calling module, used to access memory or
// exported functions. See GoModuleFunc for an example.
//
// The stack is includes any parameters encoded according to their ValueType.
// Its length is the max of parameter or result length. When there are results,
// write them in order beginning at index zero. Do not use the stack after the
// function returns.
//
// Here's a typical way to read three parameters and write back one.
//
// // read parameters off the stack in index order
// argv, argvBuf := uint32(stack[0]), uint32(stack[1])
//
// // write results back to the stack in index order
// stack[0] = uint64(ErrnoSuccess)
//
// This function can be non-deterministic or cause side effects. It also
// has special properties not defined in the WebAssembly Core specification.
// Notably, this uses the caller's memory (via Module.Memory). See
@@ -317,25 +330,28 @@ type Function interface {
// idiomatic as they can map go types to ValueType. This type is exposed for
// those willing to trade usability and safety for performance.
type GoModuleFunction interface {
Call(ctx context.Context, mod Module, params []uint64) []uint64
Call(ctx context.Context, mod Module, stack []uint64)
}
// GoModuleFunc is a convenience for defining an inlined function.
//
// For example, the following returns a uint32 value read from parameter zero:
//
// api.GoModuleFunc(func(ctx context.Context, mod api.Module, params []uint64) []uint64 {
// ret, ok := mod.Memory().ReadUint32Le(ctx, uint32(params[0]))
// api.GoModuleFunc(func(ctx context.Context, mod api.Module, stack []uint64) {
// offset := uint32(params[0]) // read the parameter from the stack
//
// ret, ok := mod.Memory().ReadUint32Le(ctx, offset)
// if !ok {
// panic("out of memory")
// }
// return []uint64{uint64(ret)}
// }
type GoModuleFunc func(ctx context.Context, mod Module, params []uint64) []uint64
//
// results[0] = uint64(ret) // add the result back to the stack.
// })
type GoModuleFunc func(ctx context.Context, mod Module, stack []uint64)
// Call implements GoModuleFunction.Call.
func (f GoModuleFunc) Call(ctx context.Context, mod Module, params []uint64) []uint64 {
return f(ctx, mod, params)
func (f GoModuleFunc) Call(ctx context.Context, mod Module, stack []uint64) {
f(ctx, mod, stack)
}
// GoFunction is an optimized form of GoModuleFunction which doesn't require
@@ -344,23 +360,22 @@ func (f GoModuleFunc) Call(ctx context.Context, mod Module, params []uint64) []u
// For example, this function does not need to use the importing module's
// memory or exported functions.
type GoFunction interface {
Call(ctx context.Context, params []uint64) []uint64
Call(ctx context.Context, stack []uint64)
}
// GoFunc is a convenience for defining an inlined function.
//
// For example, the following returns the sum of two uint32 parameters:
//
// api.GoFunc(func(ctx context.Context, params []uint64) []uint64 {
// api.GoFunc(func(ctx context.Context, stack []uint64) {
// x, y := uint32(params[0]), uint32(params[1])
// sum := x + y
// return []uint64{sum}
// }
type GoFunc func(ctx context.Context, params []uint64) []uint64
// results[0] = uint64(x + y)
// })
type GoFunc func(ctx context.Context, stack []uint64)
// Call implements GoFunction.Call.
func (f GoFunc) Call(ctx context.Context, params []uint64) []uint64 {
return f(ctx, params)
func (f GoFunc) Call(ctx context.Context, stack []uint64) {
f(ctx, stack)
}
// Global is a WebAssembly 1.0 (20191205) global exported from an instantiated module (wazero.Runtime InstantiateModule).