github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/experimental/table/lookup_test.go (about) 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 // Swap the two i32s params. 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 }