github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/integration_test/vs/bench_allocation.go (about) 1 package vs 2 3 import ( 4 "bytes" 5 _ "embed" 6 "fmt" 7 "testing" 8 9 "github.com/wasilibs/wazerox/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 TinyGo'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(namePtr, []byte(allocationParam)); err != nil { 50 return err 51 } 52 53 // Now, we can call "greeting", which reads the string we wrote to memory! 54 fnErr := m.CallI32I32_V(testCtx, "greet", namePtr, nameSize) 55 if fnErr != nil { 56 return fnErr 57 } 58 59 // This pointer was allocated by TinyGo, but owned by Go, So, we have to 60 // deallocate it when finished 61 if err := m.CallI32_V(testCtx, "free", namePtr); err != nil { 62 return err 63 } 64 65 return nil 66 } 67 68 func RunTestAllocation(t *testing.T, runtime func() Runtime) { 69 testCall(t, runtime, allocationConfig, testAllocationCall) 70 } 71 72 func testAllocationCall(t *testing.T, m Module, instantiation, iteration int) { 73 err := allocationCall(m, iteration) 74 require.NoError(t, err, "instantiation[%d] iteration[%d] failed: %v", instantiation, iteration, err) 75 } 76 77 func RunTestBenchmarkAllocation_Call_CompilerFastest(t *testing.T, vsRuntime Runtime) { 78 runTestBenchmark_Call_CompilerFastest(t, allocationConfig, "Allocation", allocationCall, vsRuntime) 79 } 80 81 func RunBenchmarkAllocation(b *testing.B, runtime func() Runtime) { 82 benchmark(b, runtime, allocationConfig, allocationCall) 83 }