Files
wazero/emscripten/emscripten.go
Crypt Keeper 939403c10b Makes it possible to implement FunctionListener and Factory (#716)
This simplifies FunctionListener definition by making it possible to
implement both interfaces without intermediate state. Passing the
function definition to the before/after callbacks is the key.

This also continues efforts towards Go 1.19 doc formatting.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-25 12:53:41 +08:00

82 lines
3.0 KiB
Go

// Package emscripten contains Go-defined special functions imported by
// Emscripten under the module name "env".
//
// Emscripten has many imports which are triggered on build flags. Use
// FunctionExporter, instead of Instantiate, to define more "env" functions.
//
// # Relationship to WASI
//
// Emscripten typically requires wasi_snapshot_preview1 to implement exit.
//
// See wasi_snapshot_preview1.Instantiate and
// https://github.com/emscripten-core/emscripten/wiki/WebAssembly-Standalone
package emscripten
import (
"context"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/internal/wasm"
)
// Instantiate instantiates the "env" module used by Emscripten into the
// runtime default namespace.
//
// # Notes
//
// - Closing the wazero.Runtime has the same effect as closing the result.
// - To add more functions to the "env" module, use FunctionExporter.
// - To instantiate into another wazero.Namespace, use FunctionExporter.
func Instantiate(ctx context.Context, r wazero.Runtime) (api.Closer, error) {
builder := r.NewModuleBuilder("env")
NewFunctionExporter().ExportFunctions(builder)
return builder.Instantiate(ctx, r)
}
// FunctionExporter configures the functions in the "env" module used by
// Emscripten.
type FunctionExporter interface {
// ExportFunctions builds functions to export with a wazero.ModuleBuilder
// named "env".
ExportFunctions(builder wazero.ModuleBuilder)
}
// NewFunctionExporter returns a FunctionExporter object with trace disabled.
func NewFunctionExporter() FunctionExporter {
return &functionExporter{}
}
type functionExporter struct{}
// ExportFunctions implements FunctionExporter.ExportFunctions
func (e *functionExporter) ExportFunctions(builder wazero.ModuleBuilder) {
builder.ExportFunction(notifyMemoryGrowth.Name, notifyMemoryGrowth)
}
// emscriptenNotifyMemoryGrowth is called when wasm is compiled with
// `-s ALLOW_MEMORY_GROWTH` and a "memory.grow" instruction succeeded.
// The memoryIndex parameter will be zero until "multi-memory" is implemented.
//
// Note: This implementation is a no-op and can be overridden by users manually
// by redefining the same function. wazero will likely implement a generic
// memory growth hook obviating this as well.
//
// Here's the import in a user's module that ends up using this, in WebAssembly
// 1.0 (MVP) Text Format:
//
// (import "env" "emscripten_notify_memory_growth"
// (func $emscripten_notify_memory_growth (param $memory_index i32)))
//
// See https://github.com/emscripten-core/emscripten/blob/3.1.16/system/lib/standalone/standalone.c#L118
// and https://emscripten.org/docs/api_reference/emscripten.h.html#abi-functions
const functionNotifyMemoryGrowth = "emscripten_notify_memory_growth"
var notifyMemoryGrowth = &wasm.HostFunc{
ExportNames: []string{functionNotifyMemoryGrowth},
Name: functionNotifyMemoryGrowth,
ParamTypes: []wasm.ValueType{wasm.ValueTypeI32},
ParamNames: []string{"memory_index"},
Code: &wasm.Code{IsHostFunction: true, Body: []byte{wasm.OpcodeEnd}},
}