1 package table_test
2
3 import (
4 "context"
5 "testing"
6
7 "github.com/tetratelabs/wazero"
8 "github.com/tetratelabs/wazero/api"
9 "github.com/tetratelabs/wazero/experimental/table"
10 "github.com/tetratelabs/wazero/internal/testing/binaryencoding"
11 "github.com/tetratelabs/wazero/internal/testing/require"
12 "github.com/tetratelabs/wazero/internal/wasm"
13 )
14
15 func TestLookupFunction(t *testing.T) {
16 const i32 = wasm.ValueTypeI32
17 bytes := binaryencoding.EncodeModule(&wasm.Module{
18 TypeSection: []wasm.FunctionType{
19 {Results: []wasm.ValueType{i32}},
20 {Params: []wasm.ValueType{i32, i32}, Results: []wasm.ValueType{i32, i32}},
21 },
22 FunctionSection: []wasm.Index{0, 1},
23 CodeSection: []wasm.Code{
24 {Body: []byte{
25 wasm.OpcodeI32Const, 1,
26 wasm.OpcodeEnd,
27 }},
28 {Body: []byte{
29
30 wasm.OpcodeLocalGet, 1,
31 wasm.OpcodeLocalGet, 0,
32 wasm.OpcodeEnd,
33 }},
34 },
35 ElementSection: []wasm.ElementSegment{
36 {
37 OffsetExpr: wasm.ConstantExpression{Opcode: wasm.OpcodeI32Const, Data: []byte{0}},
38 Init: []wasm.Index{0, 1},
39 Type: wasm.RefTypeFuncref,
40 },
41 },
42 TableSection: []wasm.Table{{Type: wasm.RefTypeFuncref, Min: 100}},
43 })
44
45 r := wazero.NewRuntime(context.Background())
46 m, err := r.Instantiate(context.Background(), bytes)
47 require.NoError(t, err)
48 require.NotNil(t, m)
49
50 t.Run("v_i32", func(t *testing.T) {
51 f := table.LookupFunction(m, 0, 0, nil, []api.ValueType{i32})
52 var result [1]uint64
53 err = f.CallWithStack(context.Background(), result[:])
54 require.NoError(t, err)
55 require.Equal(t, uint64(1), result[0])
56 })
57 t.Run("i32i32_i32i32", func(t *testing.T) {
58 f := table.LookupFunction(m, 0, 1, []api.ValueType{i32, i32}, []api.ValueType{i32, i32})
59 stack := [2]uint64{100, 200}
60 err = f.CallWithStack(context.Background(), stack[:])
61 require.NoError(t, err)
62 require.Equal(t, uint64(200), stack[0])
63 require.Equal(t, uint64(100), stack[1])
64 })
65
66 t.Run("panics", func(t *testing.T) {
67 err := require.CapturePanic(func() {
68 table.LookupFunction(m, 0, 2000, nil, []api.ValueType{i32})
69 })
70 require.Equal(t, "invalid table access", err.Error())
71 err = require.CapturePanic(func() {
72 table.LookupFunction(m, 1000, 0, nil, []api.ValueType{i32})
73 })
74 require.Equal(t, "table index out of range", err.Error())
75 err = require.CapturePanic(func() {
76 table.LookupFunction(m, 0, 0, nil, []api.ValueType{api.ValueTypeF32})
77 })
78 require.Equal(t, "indirect call type mismatch", err.Error())
79 err = require.CapturePanic(func() {
80 table.LookupFunction(m, 0, 0, []api.ValueType{i32}, nil)
81 })
82 require.Equal(t, "indirect call type mismatch", err.Error())
83 err = require.CapturePanic(func() {
84 table.LookupFunction(m, 0, 1, []api.ValueType{i32, i32}, nil)
85 })
86 require.Equal(t, "indirect call type mismatch", err.Error())
87 err = require.CapturePanic(func() {
88 table.LookupFunction(m, 0, 1, []api.ValueType{i32, i32}, []api.ValueType{i32, api.ValueTypeF32})
89 })
90 require.Equal(t, "indirect call type mismatch", err.Error())
91 })
92 }
93
View as plain text