84 lines
2.5 KiB
Go
84 lines
2.5 KiB
Go
package vs
|
|
|
|
import (
|
|
"bytes"
|
|
_ "embed"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/tetratelabs/wazero/internal/testing/require"
|
|
)
|
|
|
|
var (
|
|
// allocationWasm is compiled from ../../../examples/allocation/tinygo/testdata/src/greet.go
|
|
// We can't use go:embed as it is outside this directory. Copying it isn't ideal due to size and drift.
|
|
allocationWasmPath = "../../../examples/allocation/tinygo/testdata/greet.wasm"
|
|
allocationWasm []byte
|
|
allocationParam = "wazero"
|
|
allocationResult = []byte("wasm >> Hello, wazero!")
|
|
allocationConfig *RuntimeConfig
|
|
)
|
|
|
|
func init() {
|
|
allocationWasm = readRelativeFile(allocationWasmPath)
|
|
allocationConfig = &RuntimeConfig{
|
|
ModuleName: "greet",
|
|
ModuleWasm: allocationWasm,
|
|
FuncNames: []string{"malloc", "free", "greet"},
|
|
NeedsWASI: true, // Needed for TinyGo
|
|
LogFn: func(buf []byte) error {
|
|
if !bytes.Equal(allocationResult, buf) {
|
|
return fmt.Errorf("expected %q, but was %q", allocationResult, buf)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func allocationCall(m Module, _ int) error {
|
|
nameSize := uint32(len(allocationParam))
|
|
// Instead of an arbitrary memory offset, use TinyGo's allocator. Notice
|
|
// there is nothing string-specific in this allocation function. The same
|
|
// function could be used to pass binary serialized data to Wasm.
|
|
namePtr, err := m.CallI32_I32(testCtx, "malloc", nameSize)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// The pointer is a linear memory offset, which is where we write the name.
|
|
if err = m.WriteMemory(namePtr, []byte(allocationParam)); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Now, we can call "greeting", which reads the string we wrote to memory!
|
|
fnErr := m.CallI32I32_V(testCtx, "greet", namePtr, nameSize)
|
|
if fnErr != nil {
|
|
return fnErr
|
|
}
|
|
|
|
// This pointer was allocated by TinyGo, but owned by Go, So, we have to
|
|
// deallocate it when finished
|
|
if err := m.CallI32_V(testCtx, "free", namePtr); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func RunTestAllocation(t *testing.T, runtime func() Runtime) {
|
|
testCall(t, runtime, allocationConfig, testAllocationCall)
|
|
}
|
|
|
|
func testAllocationCall(t *testing.T, m Module, instantiation, iteration int) {
|
|
err := allocationCall(m, iteration)
|
|
require.NoError(t, err, "instantiation[%d] iteration[%d] failed: %v", instantiation, iteration, err)
|
|
}
|
|
|
|
func RunTestBenchmarkAllocation_Call_CompilerFastest(t *testing.T, vsRuntime Runtime) {
|
|
runTestBenchmark_Call_CompilerFastest(t, allocationConfig, "Allocation", allocationCall, vsRuntime)
|
|
}
|
|
|
|
func RunBenchmarkAllocation(b *testing.B, runtime func() Runtime) {
|
|
benchmark(b, runtime, allocationConfig, allocationCall)
|
|
}
|