wa-lang.org/wazero@v1.0.2/internal/integration_test/vs/bench_allocation.go (about) 1 package vs 2 3 import ( 4 "bytes" 5 _ "embed" 6 "fmt" 7 "testing" 8 9 "wa-lang.org/wazero/internal/testing/require" 10 ) 11 12 var ( 13 // allocationWasm is compiled from ../../../examples/allocation/tinygo/testdata/src/greet.go 14 // We can't use go:embed as it is outside this directory. Copying it isn't ideal due to size and drift. 15 allocationWasmPath = "../../../examples/allocation/tinygo/testdata/greet.wasm" 16 allocationWasm []byte 17 allocationParam = "wazero" 18 allocationResult = []byte("wasm >> Hello, wazero!") 19 allocationConfig *RuntimeConfig 20 ) 21 22 func init() { 23 allocationWasm = readRelativeFile(allocationWasmPath) 24 allocationConfig = &RuntimeConfig{ 25 ModuleName: "greet", 26 ModuleWasm: allocationWasm, 27 FuncNames: []string{"malloc", "free", "greet"}, 28 NeedsWASI: true, // Needed for TinyGo 29 LogFn: func(buf []byte) error { 30 if !bytes.Equal(allocationResult, buf) { 31 return fmt.Errorf("expected %q, but was %q", allocationResult, buf) 32 } 33 return nil 34 }, 35 } 36 } 37 38 func allocationCall(m Module, _ int) error { 39 nameSize := uint32(len(allocationParam)) 40 // Instead of an arbitrary memory offset, use Rust's allocator. Notice 41 // there is nothing string-specific in this allocation function. The same 42 // function could be used to pass binary serialized data to Wasm. 43 namePtr, err := m.CallI32_I32(testCtx, "malloc", nameSize) 44 if err != nil { 45 return err 46 } 47 48 // The pointer is a linear memory offset, which is where we write the name. 49 if err = m.WriteMemory(testCtx, namePtr, []byte(allocationParam)); err != nil { 50 return err 51 } 52 53 // Now, we can call "greet", which reads the string we wrote to memory! 54 if err = m.CallI32I32_V(testCtx, "greet", namePtr, nameSize); err != nil { 55 return err 56 } 57 58 // This pointer was allocated by Rust, but owned by Go, So, we have to 59 // deallocate it when finished 60 return m.CallI32_V(testCtx, "free", namePtr) 61 } 62 63 func RunTestAllocation(t *testing.T, runtime func() Runtime) { 64 testCall(t, runtime, allocationConfig, testAllocationCall) 65 } 66 67 func testAllocationCall(t *testing.T, m Module, instantiation, iteration int) { 68 err := allocationCall(m, iteration) 69 require.NoError(t, err, "instantiation[%d] iteration[%d] failed: %v", instantiation, iteration, err) 70 } 71 72 func RunTestBenchmarkAllocation_Call_CompilerFastest(t *testing.T, vsRuntime Runtime) { 73 runTestBenchmark_Call_CompilerFastest(t, allocationConfig, "Allocation", allocationCall, vsRuntime) 74 } 75 76 func RunBenchmarkAllocation(b *testing.B, runtime func() Runtime) { 77 benchmark(b, runtime, allocationConfig, allocationCall) 78 }