93 lines
3.0 KiB
Go
93 lines
3.0 KiB
Go
package table_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/tetratelabs/wazero"
|
|
"github.com/tetratelabs/wazero/api"
|
|
"github.com/tetratelabs/wazero/experimental/table"
|
|
"github.com/tetratelabs/wazero/internal/testing/binaryencoding"
|
|
"github.com/tetratelabs/wazero/internal/testing/require"
|
|
"github.com/tetratelabs/wazero/internal/wasm"
|
|
)
|
|
|
|
func TestLookupFunction(t *testing.T) {
|
|
const i32 = wasm.ValueTypeI32
|
|
bytes := binaryencoding.EncodeModule(&wasm.Module{
|
|
TypeSection: []wasm.FunctionType{
|
|
{Results: []wasm.ValueType{i32}},
|
|
{Params: []wasm.ValueType{i32, i32}, Results: []wasm.ValueType{i32, i32}},
|
|
},
|
|
FunctionSection: []wasm.Index{0, 1},
|
|
CodeSection: []wasm.Code{
|
|
{Body: []byte{
|
|
wasm.OpcodeI32Const, 1,
|
|
wasm.OpcodeEnd,
|
|
}},
|
|
{Body: []byte{
|
|
// Swap the two i32s params.
|
|
wasm.OpcodeLocalGet, 1,
|
|
wasm.OpcodeLocalGet, 0,
|
|
wasm.OpcodeEnd,
|
|
}},
|
|
},
|
|
ElementSection: []wasm.ElementSegment{
|
|
{
|
|
OffsetExpr: wasm.ConstantExpression{Opcode: wasm.OpcodeI32Const, Data: []byte{0}},
|
|
Init: []wasm.Index{0, 1},
|
|
Type: wasm.RefTypeFuncref,
|
|
},
|
|
},
|
|
TableSection: []wasm.Table{{Type: wasm.RefTypeFuncref, Min: 100}},
|
|
})
|
|
|
|
r := wazero.NewRuntime(context.Background())
|
|
m, err := r.Instantiate(context.Background(), bytes)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, m)
|
|
|
|
t.Run("v_i32", func(t *testing.T) {
|
|
f := table.LookupFunction(m, 0, 0, nil, []api.ValueType{i32})
|
|
var result [1]uint64
|
|
err = f.CallWithStack(context.Background(), result[:])
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint64(1), result[0])
|
|
})
|
|
t.Run("i32i32_i32i32", func(t *testing.T) {
|
|
f := table.LookupFunction(m, 0, 1, []api.ValueType{i32, i32}, []api.ValueType{i32, i32})
|
|
stack := [2]uint64{100, 200}
|
|
err = f.CallWithStack(context.Background(), stack[:])
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint64(200), stack[0])
|
|
require.Equal(t, uint64(100), stack[1])
|
|
})
|
|
|
|
t.Run("panics", func(t *testing.T) {
|
|
err := require.CapturePanic(func() {
|
|
table.LookupFunction(m, 0, 2000, nil, []api.ValueType{i32})
|
|
})
|
|
require.Equal(t, "invalid table access", err.Error())
|
|
err = require.CapturePanic(func() {
|
|
table.LookupFunction(m, 1000, 0, nil, []api.ValueType{i32})
|
|
})
|
|
require.Equal(t, "table index out of range", err.Error())
|
|
err = require.CapturePanic(func() {
|
|
table.LookupFunction(m, 0, 0, nil, []api.ValueType{api.ValueTypeF32})
|
|
})
|
|
require.Equal(t, "indirect call type mismatch", err.Error())
|
|
err = require.CapturePanic(func() {
|
|
table.LookupFunction(m, 0, 0, []api.ValueType{i32}, nil)
|
|
})
|
|
require.Equal(t, "indirect call type mismatch", err.Error())
|
|
err = require.CapturePanic(func() {
|
|
table.LookupFunction(m, 0, 1, []api.ValueType{i32, i32}, nil)
|
|
})
|
|
require.Equal(t, "indirect call type mismatch", err.Error())
|
|
err = require.CapturePanic(func() {
|
|
table.LookupFunction(m, 0, 1, []api.ValueType{i32, i32}, []api.ValueType{i32, api.ValueTypeF32})
|
|
})
|
|
require.Equal(t, "indirect call type mismatch", err.Error())
|
|
})
|
|
}
|