github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/wasm/binary/function_test.go (about) 1 package binary 2 3 import ( 4 "bytes" 5 "fmt" 6 "testing" 7 8 "github.com/tetratelabs/wazero/api" 9 "github.com/tetratelabs/wazero/internal/testing/binaryencoding" 10 "github.com/tetratelabs/wazero/internal/testing/require" 11 "github.com/tetratelabs/wazero/internal/wasm" 12 ) 13 14 func TestFunctionType(t *testing.T) { 15 i32, i64, funcRef, externRef := wasm.ValueTypeI32, wasm.ValueTypeI64, wasm.ValueTypeFuncref, wasm.ValueTypeExternref 16 tests := []struct { 17 name string 18 input wasm.FunctionType 19 expected []byte 20 }{ 21 { 22 name: "empty", 23 input: wasm.FunctionType{}, 24 expected: []byte{0x60, 0, 0}, 25 }, 26 { 27 name: "one param no result", 28 input: wasm.FunctionType{Params: []wasm.ValueType{i32}}, 29 expected: []byte{0x60, 1, i32, 0}, 30 }, 31 { 32 name: "no param one result", 33 input: wasm.FunctionType{Results: []wasm.ValueType{i32}}, 34 expected: []byte{0x60, 0, 1, i32}, 35 }, 36 { 37 name: "one param one result", 38 input: wasm.FunctionType{Params: []wasm.ValueType{i64}, Results: []wasm.ValueType{i32}}, 39 expected: []byte{0x60, 1, i64, 1, i32}, 40 }, 41 { 42 name: "two params no result", 43 input: wasm.FunctionType{Params: []wasm.ValueType{i32, i64}}, 44 expected: []byte{0x60, 2, i32, i64, 0}, 45 }, 46 { 47 name: "two param one result", 48 input: wasm.FunctionType{Params: []wasm.ValueType{i32, i64}, Results: []wasm.ValueType{i32}}, 49 expected: []byte{0x60, 2, i32, i64, 1, i32}, 50 }, 51 { 52 name: "no param two results", 53 input: wasm.FunctionType{Results: []wasm.ValueType{i32, i64}}, 54 expected: []byte{0x60, 0, 2, i32, i64}, 55 }, 56 { 57 name: "one param two results", 58 input: wasm.FunctionType{Params: []wasm.ValueType{i64}, Results: []wasm.ValueType{i32, i64}}, 59 expected: []byte{0x60, 1, i64, 2, i32, i64}, 60 }, 61 { 62 name: "two param two results", 63 input: wasm.FunctionType{Params: []wasm.ValueType{i32, i64}, Results: []wasm.ValueType{i32, i64}}, 64 expected: []byte{0x60, 2, i32, i64, 2, i32, i64}, 65 }, 66 { 67 name: "two param two results with funcrefs", 68 input: wasm.FunctionType{Params: []wasm.ValueType{i32, funcRef}, Results: []wasm.ValueType{funcRef, i64}}, 69 expected: []byte{0x60, 2, i32, funcRef, 2, funcRef, i64}, 70 }, 71 { 72 name: "two param two results with externrefs", 73 input: wasm.FunctionType{Params: []wasm.ValueType{i32, externRef}, Results: []wasm.ValueType{externRef, i64}}, 74 expected: []byte{0x60, 2, i32, externRef, 2, externRef, i64}, 75 }, 76 } 77 78 for _, tt := range tests { 79 tc := tt 80 81 b := binaryencoding.EncodeFunctionType(&tc.input) 82 t.Run(fmt.Sprintf("encode - %s", tc.name), func(t *testing.T) { 83 require.Equal(t, tc.expected, b) 84 }) 85 86 t.Run(fmt.Sprintf("decode - %s", tc.name), func(t *testing.T) { 87 var actual wasm.FunctionType 88 err := decodeFunctionType(api.CoreFeaturesV2, bytes.NewReader(b), &actual) 89 require.NoError(t, err) 90 // Set the FunctionType key on the input. 91 _ = tc.input.String() 92 require.Equal(t, actual, tc.input) 93 }) 94 } 95 } 96 97 func TestDecodeFunctionType_Errors(t *testing.T) { 98 i32, i64 := wasm.ValueTypeI32, wasm.ValueTypeI64 99 tests := []struct { 100 name string 101 input []byte 102 enabledFeatures api.CoreFeatures 103 expectedErr string 104 }{ 105 { 106 name: "undefined param no result", 107 input: []byte{0x60, 1, 0x6e, 0}, 108 expectedErr: "could not read parameter types: invalid value type: 110", 109 }, 110 { 111 name: "no param undefined result", 112 input: []byte{0x60, 0, 1, 0x6e}, 113 expectedErr: "could not read result types: invalid value type: 110", 114 }, 115 { 116 name: "undefined param undefined result", 117 input: []byte{0x60, 1, 0x6e, 1, 0x6e}, 118 expectedErr: "could not read parameter types: invalid value type: 110", 119 }, 120 { 121 name: "no param two results - multi-value not enabled", 122 input: []byte{0x60, 0, 2, i32, i64}, 123 expectedErr: "multiple result types invalid as feature \"multi-value\" is disabled", 124 }, 125 { 126 name: "one param two results - multi-value not enabled", 127 input: []byte{0x60, 1, i64, 2, i32, i64}, 128 expectedErr: "multiple result types invalid as feature \"multi-value\" is disabled", 129 }, 130 { 131 name: "two param two results - multi-value not enabled", 132 input: []byte{0x60, 2, i32, i64, 2, i32, i64}, 133 expectedErr: "multiple result types invalid as feature \"multi-value\" is disabled", 134 }, 135 } 136 137 for _, tt := range tests { 138 tc := tt 139 140 t.Run(tc.name, func(t *testing.T) { 141 var actual wasm.FunctionType 142 err := decodeFunctionType(api.CoreFeaturesV1, bytes.NewReader(tc.input), &actual) 143 require.EqualError(t, err, tc.expectedErr) 144 }) 145 } 146 }