Files
wazero/experimental/importresolver_example_test.go
Bjørn Erik Pedersen 2b12e189ee Improves ImportResolver example (#2299)
Signed-off-by: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
2024-08-05 10:03:31 -07:00

103 lines
2.3 KiB
Go

package experimental_test
import (
"bytes"
"context"
_ "embed"
"fmt"
"log"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/experimental"
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
)
var (
// These wasm files were generated by the following:
// cd testdata
// wat2wasm --debug-names inoutdispatcher.wat
// wat2wasm --debug-names inoutdispatcherclient.wat
//go:embed testdata/inoutdispatcher.wasm
inoutdispatcherWasm []byte
//go:embed testdata/inoutdispatcherclient.wasm
inoutdispatcherclientWasm []byte
)
func Example_importResolver() {
ctx := context.Background()
r := wazero.NewRuntime(ctx)
defer r.Close(ctx)
// The client imports the inoutdispatcher module that reads from stdin and writes to stdout.
// This means that we need multiple instances of the inoutdispatcher module to have different stdin/stdout.
// This example demonstrates a way to do that.
type mod struct {
in bytes.Buffer
out bytes.Buffer
client api.Module
}
wasi_snapshot_preview1.MustInstantiate(ctx, r)
idm, err := r.CompileModule(ctx, inoutdispatcherWasm)
if err != nil {
log.Panicln(err)
}
idcm, err := r.CompileModule(ctx, inoutdispatcherclientWasm)
if err != nil {
log.Panicln(err)
}
const numInstances = 3
mods := make([]*mod, numInstances)
for i := range mods {
mods[i] = &mod{}
m := mods[i]
const inoutDispatcherModuleName = "inoutdispatcher"
dispatcherInstance, err := r.InstantiateModule(ctx, idm,
wazero.NewModuleConfig().
WithStdin(&m.in).
WithStdout(&m.out).
WithName("")) // Makes it an anonymous module.
if err != nil {
log.Panicln(err)
}
ctx = experimental.WithImportResolver(ctx, func(name string) api.Module {
if name == inoutDispatcherModuleName {
return dispatcherInstance
}
return nil
})
m.client, err = r.InstantiateModule(ctx, idcm, wazero.NewModuleConfig().WithName(fmt.Sprintf("m%d", i)))
if err != nil {
log.Panicln(err)
}
}
for i, m := range mods {
m.in.WriteString(fmt.Sprintf("Module instance #%d", i))
_, err := m.client.ExportedFunction("dispatch").Call(ctx)
if err != nil {
log.Panicln(err)
}
}
for i, m := range mods {
fmt.Printf("out%d: %s\n", i, m.out.String())
}
// Output:
// out0: Module instance #0
// out1: Module instance #1
// out2: Module instance #2
}