wa-lang.org/wazero@v1.0.2/examples/namespace/counter.go (about) 1 package main 2 3 import ( 4 "context" 5 _ "embed" 6 "fmt" 7 "log" 8 9 "wa-lang.org/wazero" 10 "wa-lang.org/wazero/api" 11 ) 12 13 // counterWasm was generated by the following: 14 // 15 // cd testdata; wat2wasm --debug-names counter.wat 16 // 17 //go:embed testdata/counter.wasm 18 var counterWasm []byte 19 20 // main shows how to instantiate the same module name multiple times in the same runtime. 21 // 22 // See README.md for a full description. 23 func main() { 24 // Choose the context to use for function calls. 25 ctx := context.Background() 26 27 // Create a new WebAssembly Runtime. 28 r := wazero.NewRuntime(ctx) 29 defer r.Close(ctx) // This closes everything this Runtime created. 30 31 // Compile WebAssembly that requires its own "env" module. 32 compiled, err := r.CompileModule(ctx, counterWasm) 33 if err != nil { 34 log.Panicln(err) 35 } 36 37 // Instantiate two modules, with identical configuration, but independent state. 38 m1 := instantiateWithEnv(ctx, r, compiled) 39 m2 := instantiateWithEnv(ctx, r, compiled) 40 41 for i := 0; i < 2; i++ { 42 fmt.Printf("m1 counter=%d\n", counterGet(ctx, m1)) 43 fmt.Printf("m2 counter=%d\n", counterGet(ctx, m2)) 44 } 45 } 46 47 // count calls "counter.get" in the given namespace 48 func counterGet(ctx context.Context, mod api.Module) uint64 { 49 results, err := mod.ExportedFunction("get").Call(ctx) 50 if err != nil { 51 log.Panicln(err) 52 } 53 return results[0] 54 } 55 56 // counter is an example showing state that needs to be independent per importing module. 57 type counter struct { 58 counter uint32 59 } 60 61 func (e *counter) getAndIncrement() (ret uint32) { 62 ret = e.counter 63 e.counter++ 64 return 65 } 66 67 // instantiateWithEnv returns a module instantiated with its own "env" module. 68 func instantiateWithEnv(ctx context.Context, r wazero.Runtime, module wazero.CompiledModule) api.Module { 69 // Create a new namespace to instantiate modules into. 70 ns := r.NewNamespace(ctx) // Note: this is closed when the Runtime is 71 72 // Instantiate a new "env" module which exports a stateful function. 73 c := &counter{} 74 _, err := r.NewHostModuleBuilder("env"). 75 NewFunctionBuilder().WithFunc(c.getAndIncrement).Export("next_i32"). 76 Instantiate(ctx, ns) 77 if err != nil { 78 log.Panicln(err) 79 } 80 81 // Instantiate the module that imports "env". 82 mod, err := ns.InstantiateModule(ctx, module, wazero.NewModuleConfig()) 83 if err != nil { 84 log.Panicln(err) 85 } 86 87 return mod 88 }