github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/experimental/table/lookup_test.go (about)

     1  package table_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	wazero "github.com/wasilibs/wazerox"
     8  	"github.com/wasilibs/wazerox/api"
     9  	"github.com/wasilibs/wazerox/experimental/table"
    10  	"github.com/wasilibs/wazerox/internal/testing/binaryencoding"
    11  	"github.com/wasilibs/wazerox/internal/testing/require"
    12  	"github.com/wasilibs/wazerox/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  }