github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/wasm/binary/const_expr_test.go (about) 1 package binary 2 3 import ( 4 "bytes" 5 "strconv" 6 "testing" 7 8 "github.com/tetratelabs/wazero/api" 9 "github.com/tetratelabs/wazero/internal/testing/require" 10 "github.com/tetratelabs/wazero/internal/wasm" 11 ) 12 13 func TestDecodeConstantExpression(t *testing.T) { 14 tests := []struct { 15 in []byte 16 exp wasm.ConstantExpression 17 }{ 18 { 19 in: []byte{ 20 wasm.OpcodeRefFunc, 21 0x80, 0, // Multi byte zero. 22 wasm.OpcodeEnd, 23 }, 24 exp: wasm.ConstantExpression{ 25 Opcode: wasm.OpcodeRefFunc, 26 Data: []byte{0x80, 0}, 27 }, 28 }, 29 { 30 in: []byte{ 31 wasm.OpcodeRefFunc, 32 0x80, 0x80, 0x80, 0x4f, // 165675008 in varint encoding. 33 wasm.OpcodeEnd, 34 }, 35 exp: wasm.ConstantExpression{ 36 Opcode: wasm.OpcodeRefFunc, 37 Data: []byte{0x80, 0x80, 0x80, 0x4f}, 38 }, 39 }, 40 { 41 in: []byte{ 42 wasm.OpcodeRefNull, 43 wasm.RefTypeFuncref, 44 wasm.OpcodeEnd, 45 }, 46 exp: wasm.ConstantExpression{ 47 Opcode: wasm.OpcodeRefNull, 48 Data: []byte{ 49 wasm.RefTypeFuncref, 50 }, 51 }, 52 }, 53 { 54 in: []byte{ 55 wasm.OpcodeRefNull, 56 wasm.RefTypeExternref, 57 wasm.OpcodeEnd, 58 }, 59 exp: wasm.ConstantExpression{ 60 Opcode: wasm.OpcodeRefNull, 61 Data: []byte{ 62 wasm.RefTypeExternref, 63 }, 64 }, 65 }, 66 { 67 in: []byte{ 68 wasm.OpcodeVecPrefix, 69 wasm.OpcodeVecV128Const, 70 1, 1, 1, 1, 1, 1, 1, 1, 71 1, 1, 1, 1, 1, 1, 1, 1, 72 wasm.OpcodeEnd, 73 }, 74 exp: wasm.ConstantExpression{ 75 Opcode: wasm.OpcodeVecV128Const, 76 Data: []byte{ 77 1, 1, 1, 1, 1, 1, 1, 1, 78 1, 1, 1, 1, 1, 1, 1, 1, 79 }, 80 }, 81 }, 82 } 83 84 for i, tt := range tests { 85 tc := tt 86 t.Run(strconv.Itoa(i), func(t *testing.T) { 87 var actual wasm.ConstantExpression 88 err := decodeConstantExpression(bytes.NewReader(tc.in), 89 api.CoreFeatureBulkMemoryOperations|api.CoreFeatureSIMD, &actual) 90 require.NoError(t, err) 91 require.Equal(t, tc.exp, actual) 92 }) 93 } 94 } 95 96 func TestDecodeConstantExpression_errors(t *testing.T) { 97 tests := []struct { 98 in []byte 99 expectedErr string 100 features api.CoreFeatures 101 }{ 102 { 103 in: []byte{ 104 wasm.OpcodeRefFunc, 105 0, 106 }, 107 expectedErr: "look for end opcode: EOF", 108 features: api.CoreFeatureBulkMemoryOperations, 109 }, 110 { 111 in: []byte{ 112 wasm.OpcodeRefNull, 113 }, 114 expectedErr: "read reference type for ref.null: EOF", 115 features: api.CoreFeatureBulkMemoryOperations, 116 }, 117 { 118 in: []byte{ 119 wasm.OpcodeRefNull, 120 0xff, 121 wasm.OpcodeEnd, 122 }, 123 expectedErr: "invalid type for ref.null: 0xff", 124 features: api.CoreFeatureBulkMemoryOperations, 125 }, 126 { 127 in: []byte{ 128 wasm.OpcodeRefNull, 129 wasm.RefTypeExternref, 130 wasm.OpcodeEnd, 131 }, 132 expectedErr: "ref.null is not supported as feature \"bulk-memory-operations\" is disabled", 133 features: api.CoreFeaturesV1, 134 }, 135 { 136 in: []byte{ 137 wasm.OpcodeRefFunc, 138 0x80, 0, 139 wasm.OpcodeEnd, 140 }, 141 expectedErr: "ref.func is not supported as feature \"bulk-memory-operations\" is disabled", 142 features: api.CoreFeaturesV1, 143 }, 144 { 145 in: []byte{ 146 wasm.OpcodeVecPrefix, 147 wasm.OpcodeVecV128Const, 148 1, 1, 1, 1, 1, 1, 1, 1, 149 1, 1, 1, 1, 1, 1, 1, 1, 150 wasm.OpcodeEnd, 151 }, 152 expectedErr: "vector instructions are not supported as feature \"simd\" is disabled", 153 features: api.CoreFeaturesV1, 154 }, 155 { 156 in: []byte{ 157 wasm.OpcodeVecPrefix, 158 }, 159 expectedErr: "read vector instruction opcode suffix: EOF", 160 features: api.CoreFeatureSIMD, 161 }, 162 { 163 in: []byte{ 164 wasm.OpcodeVecPrefix, 165 1, 1, 1, 1, 1, 1, 1, 1, 166 1, 1, 1, 1, 1, 1, 1, 1, 167 wasm.OpcodeEnd, 168 }, 169 expectedErr: "invalid vector opcode for const expression: 0x1", 170 features: api.CoreFeatureSIMD, 171 }, 172 { 173 in: []byte{ 174 wasm.OpcodeVecPrefix, 175 wasm.OpcodeVecV128Const, 176 1, 1, 1, 1, 1, 1, 1, 1, 177 }, 178 expectedErr: "read vector const instruction immediates: needs 16 bytes but was 8 bytes", 179 features: api.CoreFeatureSIMD, 180 }, 181 } 182 183 for _, tt := range tests { 184 tc := tt 185 t.Run(tc.expectedErr, func(t *testing.T) { 186 var actual wasm.ConstantExpression 187 err := decodeConstantExpression(bytes.NewReader(tc.in), tc.features, &actual) 188 require.EqualError(t, err, tc.expectedErr) 189 }) 190 } 191 }