|
|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
|
// Package gojs allows you to run wasm binaries compiled by Go when `GOOS=js`
|
|
|
|
|
// and `GOARCH=wasm`. See https://wazero.io/languages/go/ for more.
|
|
|
|
|
// Package gojs allows you to run wasm binaries compiled by Go when
|
|
|
|
|
// `GOARCH=wasm GOOS=js`. See https://wazero.io/languages/go/ for more.
|
|
|
|
|
//
|
|
|
|
|
// # Experimental
|
|
|
|
|
//
|
|
|
|
|
@@ -14,10 +14,82 @@ import (
|
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
|
|
"github.com/tetratelabs/wazero"
|
|
|
|
|
"github.com/tetratelabs/wazero/api"
|
|
|
|
|
. "github.com/tetratelabs/wazero/internal/gojs"
|
|
|
|
|
"github.com/tetratelabs/wazero/internal/wasm"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// MustInstantiate calls Instantiate or panics on error.
|
|
|
|
|
//
|
|
|
|
|
// This is a simpler function for those who know the module "go" is not
|
|
|
|
|
// already instantiated, and don't need to unload it.
|
|
|
|
|
func MustInstantiate(ctx context.Context, r wazero.Runtime) {
|
|
|
|
|
if _, err := Instantiate(ctx, r); err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Instantiate instantiates the "go" module, used by `GOARCH=wasm GOOS=js`,
|
|
|
|
|
// into the runtime default namespace.
|
|
|
|
|
//
|
|
|
|
|
// # Notes
|
|
|
|
|
//
|
|
|
|
|
// - Failure cases are documented on wazero.Namespace InstantiateModule.
|
|
|
|
|
// - 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.NewHostModuleBuilder("go")
|
|
|
|
|
NewFunctionExporter().ExportFunctions(builder)
|
|
|
|
|
return builder.Instantiate(ctx, r)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FunctionExporter configures the functions in the "go" module used by
|
|
|
|
|
// `GOARCH=wasm GOOS=js`.
|
|
|
|
|
type FunctionExporter interface {
|
|
|
|
|
// ExportFunctions builds functions to export with a
|
|
|
|
|
// wazero.HostModuleBuilder named "go".
|
|
|
|
|
ExportFunctions(wazero.HostModuleBuilder)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewFunctionExporter returns a FunctionExporter object.
|
|
|
|
|
func NewFunctionExporter() FunctionExporter {
|
|
|
|
|
return &functionExporter{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type functionExporter struct{}
|
|
|
|
|
|
|
|
|
|
// ExportFunctions implements FunctionExporter.ExportFunctions
|
|
|
|
|
func (e *functionExporter) ExportFunctions(builder wazero.HostModuleBuilder) {
|
|
|
|
|
hfExporter := builder.(wasm.HostFuncExporter)
|
|
|
|
|
|
|
|
|
|
hfExporter.ExportHostFunc(GetRandomData)
|
|
|
|
|
hfExporter.ExportHostFunc(Nanotime1)
|
|
|
|
|
hfExporter.ExportHostFunc(WasmExit)
|
|
|
|
|
hfExporter.ExportHostFunc(CopyBytesToJS)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueCall)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueGet)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueIndex)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueLength)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueNew)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueSet)
|
|
|
|
|
hfExporter.ExportHostFunc(WasmWrite)
|
|
|
|
|
hfExporter.ExportHostFunc(ResetMemoryDataView)
|
|
|
|
|
hfExporter.ExportHostFunc(Walltime)
|
|
|
|
|
hfExporter.ExportHostFunc(ScheduleTimeoutEvent)
|
|
|
|
|
hfExporter.ExportHostFunc(ClearTimeoutEvent)
|
|
|
|
|
hfExporter.ExportHostFunc(FinalizeRef)
|
|
|
|
|
hfExporter.ExportHostFunc(StringVal)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueDelete)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueSetIndex)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueInvoke)
|
|
|
|
|
hfExporter.ExportHostFunc(ValuePrepareString)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueInstanceOf)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueLoadString)
|
|
|
|
|
hfExporter.ExportHostFunc(CopyBytesToGo)
|
|
|
|
|
hfExporter.ExportHostFunc(Debug)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WithRoundTripper sets the http.RoundTripper used to Run Wasm.
|
|
|
|
|
//
|
|
|
|
|
// For example, if the code compiled via `GOARCH=wasm GOOS=js` uses
|
|
|
|
|
@@ -46,6 +118,10 @@ func WithRoundTripper(ctx context.Context, rt http.RoundTripper) context.Context
|
|
|
|
|
//
|
|
|
|
|
// // Use compilation cache to reduce performance penalty of multiple runs.
|
|
|
|
|
// ctx = experimental.WithCompilationCacheDirName(ctx, ".build")
|
|
|
|
|
//
|
|
|
|
|
// // Instantiate the host functions used for each call.
|
|
|
|
|
// gojs.MustInstantiate(r)
|
|
|
|
|
//
|
|
|
|
|
// // Execute the "run" function, which corresponds to "main" in stars/main.go.
|
|
|
|
|
// err = gojs.Run(ctx, r, compiled, config)
|
|
|
|
|
// if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
|
|
|
|
|
@@ -60,17 +136,10 @@ func WithRoundTripper(ctx context.Context, rt http.RoundTripper) context.Context
|
|
|
|
|
// features set by `GOWASM` or used internally by Run.
|
|
|
|
|
// - Wasm generated by `GOARCH=wasm GOOS=js` is very slow to compile.
|
|
|
|
|
// Use experimental.WithCompilationCacheDirName to improve performance.
|
|
|
|
|
// - Both the host and guest module are closed after being run.
|
|
|
|
|
func Run(ctx context.Context, r wazero.Runtime, compiled wazero.CompiledModule, config wazero.ModuleConfig) error {
|
|
|
|
|
// Instantiate the imports needed by go-compiled wasm.
|
|
|
|
|
js, err := hostModuleBuilder(r).Instantiate(ctx, r)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer js.Close(ctx)
|
|
|
|
|
|
|
|
|
|
// - The guest module is closed after being run.
|
|
|
|
|
func Run(ctx context.Context, ns wazero.Namespace, compiled wazero.CompiledModule, config wazero.ModuleConfig) error {
|
|
|
|
|
// Instantiate the module compiled by go, noting it has no init function.
|
|
|
|
|
mod, err := r.InstantiateModule(ctx, compiled, config)
|
|
|
|
|
mod, err := ns.InstantiateModule(ctx, compiled, config)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
@@ -86,36 +155,3 @@ func Run(ctx context.Context, r wazero.Runtime, compiled wazero.CompiledModule,
|
|
|
|
|
_, err = mod.ExportedFunction("run").Call(ctx, uint64(argc), uint64(argv))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// hostModuleBuilder returns a new wazero.HostModuleBuilder
|
|
|
|
|
func hostModuleBuilder(r wazero.Runtime) (builder wazero.HostModuleBuilder) {
|
|
|
|
|
builder = r.NewHostModuleBuilder("go")
|
|
|
|
|
hfExporter := builder.(wasm.HostFuncExporter)
|
|
|
|
|
|
|
|
|
|
hfExporter.ExportHostFunc(GetRandomData)
|
|
|
|
|
hfExporter.ExportHostFunc(Nanotime1)
|
|
|
|
|
hfExporter.ExportHostFunc(WasmExit)
|
|
|
|
|
hfExporter.ExportHostFunc(CopyBytesToJS)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueCall)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueGet)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueIndex)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueLength)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueNew)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueSet)
|
|
|
|
|
hfExporter.ExportHostFunc(WasmWrite)
|
|
|
|
|
hfExporter.ExportHostFunc(ResetMemoryDataView)
|
|
|
|
|
hfExporter.ExportHostFunc(Walltime)
|
|
|
|
|
hfExporter.ExportHostFunc(ScheduleTimeoutEvent)
|
|
|
|
|
hfExporter.ExportHostFunc(ClearTimeoutEvent)
|
|
|
|
|
hfExporter.ExportHostFunc(FinalizeRef)
|
|
|
|
|
hfExporter.ExportHostFunc(StringVal)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueDelete)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueSetIndex)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueInvoke)
|
|
|
|
|
hfExporter.ExportHostFunc(ValuePrepareString)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueInstanceOf)
|
|
|
|
|
hfExporter.ExportHostFunc(ValueLoadString)
|
|
|
|
|
hfExporter.ExportHostFunc(CopyBytesToGo)
|
|
|
|
|
hfExporter.ExportHostFunc(Debug)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|