Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "test/unittests/test-utils.h"
6 :
7 : #include "src/objects-inl.h"
8 : #include "src/objects.h"
9 : #include "src/ostreams.h"
10 : #include "src/v8.h"
11 : #include "src/wasm/function-body-decoder-impl.h"
12 : #include "src/wasm/function-body-decoder.h"
13 : #include "src/wasm/local-decl-encoder.h"
14 : #include "src/wasm/signature-map.h"
15 : #include "src/wasm/wasm-limits.h"
16 : #include "src/wasm/wasm-module.h"
17 : #include "src/wasm/wasm-opcodes.h"
18 :
19 : #include "test/common/wasm/flag-utils.h"
20 : #include "test/common/wasm/test-signatures.h"
21 : #include "test/common/wasm/wasm-macro-gen.h"
22 : #include "testing/gmock-support.h"
23 :
24 : namespace v8 {
25 : namespace internal {
26 : namespace wasm {
27 : namespace function_body_decoder_unittest {
28 :
29 : #define B1(a) WASM_BLOCK(a)
30 : #define B2(a, b) WASM_BLOCK(a, b)
31 : #define B3(a, b, c) WASM_BLOCK(a, b, c)
32 :
33 : #define WASM_IF_OP kExprIf, kLocalVoid
34 : #define WASM_LOOP_OP kExprLoop, kLocalVoid
35 :
36 : static const byte kCodeGetLocal0[] = {kExprGetLocal, 0};
37 : static const byte kCodeGetLocal1[] = {kExprGetLocal, 1};
38 : static const byte kCodeSetLocal0[] = {WASM_SET_LOCAL(0, WASM_ZERO)};
39 : static const byte kCodeTeeLocal0[] = {WASM_TEE_LOCAL(0, WASM_ZERO)};
40 :
41 : static const ValueType kValueTypes[] = {kWasmI32, kWasmI64, kWasmF32, kWasmF64,
42 : kWasmAnyRef};
43 : static const MachineType machineTypes[] = {
44 : MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
45 : MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
46 : MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(),
47 : MachineType::Float64()};
48 :
49 : static const WasmOpcode kInt32BinopOpcodes[] = {
50 : kExprI32Add, kExprI32Sub, kExprI32Mul, kExprI32DivS, kExprI32DivU,
51 : kExprI32RemS, kExprI32RemU, kExprI32And, kExprI32Ior, kExprI32Xor,
52 : kExprI32Shl, kExprI32ShrU, kExprI32ShrS, kExprI32Eq, kExprI32LtS,
53 : kExprI32LeS, kExprI32LtU, kExprI32LeU};
54 :
55 : #define WASM_BRV_IF_ZERO(depth, val) \
56 : val, WASM_ZERO, kExprBrIf, static_cast<byte>(depth)
57 :
58 250 : class FunctionBodyDecoderTest : public TestWithZone {
59 : public:
60 : typedef std::pair<uint32_t, ValueType> LocalsDecl;
61 : // All features are disabled by default and must be activated with
62 : // a WASM_FEATURE_SCOPE in individual tests.
63 : WasmFeatures enabled_features_;
64 :
65 500 : FunctionBodyDecoderTest() : module(nullptr), local_decls(zone()) {}
66 :
67 : TestSignatures sigs;
68 : WasmModule* module;
69 : LocalDeclEncoder local_decls;
70 :
71 : void AddLocals(ValueType type, uint32_t count) {
72 31 : local_decls.AddLocals(count, type);
73 : }
74 :
75 : enum AppendEnd : bool { kAppendEnd, kOmitEnd };
76 :
77 22705 : Vector<const byte> PrepareBytecode(Vector<const byte> code,
78 : AppendEnd append_end) {
79 22705 : size_t locals_size = local_decls.Size();
80 : size_t total_size =
81 22705 : code.size() + locals_size + (append_end == kAppendEnd ? 1 : 0);
82 22705 : byte* buffer = static_cast<byte*>(zone()->New(total_size));
83 : // Prepend the local decls to the code.
84 22705 : local_decls.Emit(buffer);
85 : // Emit the code.
86 22705 : if (code.size() > 0) {
87 22701 : memcpy(buffer + locals_size, code.start(), code.size());
88 : }
89 22705 : if (append_end == kAppendEnd) {
90 : // Append an extra end opcode.
91 22653 : buffer[total_size - 1] = kExprEnd;
92 : }
93 :
94 22705 : return {buffer, total_size};
95 : }
96 :
97 : template <size_t N>
98 : Vector<const byte> CodeToVector(const byte (&code)[N]) {
99 : return ArrayVector(code);
100 : }
101 :
102 : Vector<const byte> CodeToVector(
103 3907 : const std::initializer_list<const byte>& code) {
104 : return VectorOf(&*code.begin(), code.size());
105 : }
106 :
107 : Vector<const byte> CodeToVector(Vector<const byte> vec) { return vec; }
108 :
109 : // Prepends local variable declarations and renders nice error messages for
110 : // verification failures.
111 : template <typename Code = std::initializer_list<const byte>>
112 22705 : void Validate(bool expected_success, FunctionSig* sig, Code&& raw_code,
113 : AppendEnd append_end = kAppendEnd,
114 : const char* message = nullptr) {
115 : Vector<const byte> code =
116 26875 : PrepareBytecode(CodeToVector(std::forward<Code>(raw_code)), append_end);
117 :
118 : // Validate the code.
119 : FunctionBody body(sig, 0, code.start(), code.end());
120 22705 : WasmFeatures unused_detected_features;
121 : DecodeResult result =
122 : VerifyWasmCode(zone()->allocator(), enabled_features_, module,
123 45410 : &unused_detected_features, body);
124 :
125 45410 : std::ostringstream str;
126 22705 : if (result.failed()) {
127 18568 : str << "Verification failed: pc = +" << result.error().offset()
128 18568 : << ", msg = " << result.error().message();
129 : } else {
130 4137 : str << "Verification successed, expected failure";
131 : }
132 45410 : EXPECT_EQ(result.ok(), expected_success) << str.str();
133 22705 : if (result.failed() && message) {
134 4 : EXPECT_THAT(result.error().message(), ::testing::HasSubstr(message));
135 : }
136 22705 : }
137 :
138 : template <typename Code = std::initializer_list<const byte>>
139 : void ExpectValidates(FunctionSig* sig, Code&& raw_code,
140 : AppendEnd append_end = kAppendEnd,
141 : const char* message = nullptr) {
142 3580 : Validate(true, sig, std::forward<Code>(raw_code), append_end, message);
143 : }
144 :
145 : template <typename Code = std::initializer_list<const byte>>
146 : void ExpectFailure(FunctionSig* sig, Code&& raw_code,
147 : AppendEnd append_end = kAppendEnd,
148 : const char* message = nullptr) {
149 17805 : Validate(false, sig, std::forward<Code>(raw_code), append_end, message);
150 : }
151 :
152 18120 : void TestBinop(WasmOpcode opcode, FunctionSig* success) {
153 : // op(local[0], local[1])
154 120 : byte code[] = {WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))};
155 : ExpectValidates(success, code);
156 :
157 : // Try all combinations of return and parameter types.
158 720 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
159 3000 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
160 15000 : for (size_t k = 0; k < arraysize(kValueTypes); k++) {
161 15000 : ValueType types[] = {kValueTypes[i], kValueTypes[j], kValueTypes[k]};
162 18000 : if (types[0] != success->GetReturn(0) ||
163 15600 : types[1] != success->GetParam(0) ||
164 : types[2] != success->GetParam(1)) {
165 : // Test signature mismatch.
166 : FunctionSig sig(1, 2, types);
167 : ExpectFailure(&sig, code);
168 : }
169 : }
170 : }
171 : }
172 120 : }
173 :
174 66 : void TestUnop(WasmOpcode opcode, FunctionSig* success) {
175 132 : TestUnop(opcode, success->GetReturn(), success->GetParam(0));
176 : }
177 :
178 76 : void TestUnop(WasmOpcode opcode, ValueType ret_type, ValueType param_type) {
179 : // Return(op(local[0]))
180 76 : byte code[] = {WASM_UNOP(opcode, WASM_GET_LOCAL(0))};
181 : {
182 76 : ValueType types[] = {ret_type, param_type};
183 : FunctionSig sig(1, 1, types);
184 : ExpectValidates(&sig, code);
185 : }
186 :
187 : // Try all combinations of return and parameter types.
188 456 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
189 1900 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
190 1900 : ValueType types[] = {kValueTypes[i], kValueTypes[j]};
191 1900 : if (types[0] != ret_type || types[1] != param_type) {
192 : // Test signature mismatch.
193 : FunctionSig sig(1, 1, types);
194 : ExpectFailure(&sig, code);
195 : }
196 : }
197 : }
198 76 : }
199 : };
200 :
201 : namespace {
202 :
203 : class EnableBoolScope {
204 : public:
205 : bool prev_;
206 : bool* ptr_;
207 43 : explicit EnableBoolScope(bool* ptr) : prev_(*ptr), ptr_(ptr) { *ptr = true; }
208 42 : ~EnableBoolScope() { *ptr_ = prev_; }
209 : };
210 :
211 : #define WASM_FEATURE_SCOPE(feat) \
212 : EnableBoolScope feat##_scope(&this->enabled_features_.feat);
213 :
214 : constexpr size_t kMaxByteSizedLeb128 = 127;
215 :
216 : // A helper for tests that require a module environment for functions,
217 : // globals, or memories.
218 745 : class TestModuleBuilder {
219 : public:
220 2235 : explicit TestModuleBuilder(ModuleOrigin origin = kWasmOrigin) {
221 745 : mod.origin = origin;
222 745 : }
223 61 : byte AddGlobal(ValueType type, bool mutability = true) {
224 : mod.globals.push_back(
225 183 : {type, mutability, WasmInitExpr(), {0}, false, false});
226 61 : CHECK_LE(mod.globals.size(), kMaxByteSizedLeb128);
227 61 : return static_cast<byte>(mod.globals.size() - 1);
228 : }
229 29 : byte AddSignature(FunctionSig* sig) {
230 29 : mod.signatures.push_back(sig);
231 29 : CHECK_LE(mod.signatures.size(), kMaxByteSizedLeb128);
232 29 : return static_cast<byte>(mod.signatures.size() - 1);
233 : }
234 653 : byte AddFunction(FunctionSig* sig) {
235 : mod.functions.push_back({sig, // sig
236 : 0, // func_index
237 : 0, // sig_index
238 : {0, 0}, // code
239 : false, // import
240 1959 : false}); // export
241 653 : CHECK_LE(mod.functions.size(), kMaxByteSizedLeb128);
242 653 : return static_cast<byte>(mod.functions.size() - 1);
243 : }
244 : byte AddImport(FunctionSig* sig) {
245 5 : byte result = AddFunction(sig);
246 10 : mod.functions[result].imported = true;
247 : return result;
248 : }
249 7 : byte AddException(WasmExceptionSig* sig) {
250 14 : mod.exceptions.emplace_back(sig);
251 14 : CHECK_LE(mod.signatures.size(), kMaxByteSizedLeb128);
252 7 : return static_cast<byte>(mod.exceptions.size() - 1);
253 : }
254 :
255 8 : byte AddTable(ValueType type, uint32_t initial_size, bool has_maximum_size,
256 : uint32_t maximum_size) {
257 8 : CHECK(type == kWasmAnyRef || type == kWasmAnyFunc);
258 16 : mod.tables.emplace_back();
259 : WasmTable& table = mod.tables.back();
260 8 : table.type = type;
261 8 : table.initial_size = initial_size;
262 8 : table.has_maximum_size = has_maximum_size;
263 8 : table.maximum_size = maximum_size;
264 8 : return static_cast<byte>(mod.tables.size() - 1);
265 : }
266 :
267 : void InitializeMemory() {
268 23 : mod.has_memory = true;
269 23 : mod.initial_pages = 1;
270 23 : mod.maximum_pages = 100;
271 : }
272 :
273 15 : void InitializeTable() { mod.tables.emplace_back(); }
274 :
275 : byte AddPassiveElementSegment() {
276 4 : mod.elem_segments.emplace_back();
277 : return static_cast<byte>(mod.elem_segments.size() - 1);
278 : }
279 :
280 : // Set the number of data segments as declared by the DataCount section.
281 : void SetDataSegmentCount(uint32_t data_segment_count) {
282 : // The Data section occurs after the Code section, so we don't need to
283 : // update mod.data_segments, as it is always empty.
284 3 : mod.num_declared_data_segments = data_segment_count;
285 : }
286 :
287 : WasmModule* module() { return &mod; }
288 :
289 : private:
290 : WasmModule mod;
291 : };
292 : } // namespace
293 :
294 15189 : TEST_F(FunctionBodyDecoderTest, Int32Const1) {
295 1 : byte code[] = {kExprI32Const, 0};
296 129 : for (int i = -64; i <= 63; i++) {
297 128 : code[1] = static_cast<byte>(i & 0x7F);
298 128 : ExpectValidates(sigs.i_i(), code);
299 : }
300 1 : }
301 :
302 15189 : TEST_F(FunctionBodyDecoderTest, RefNull) {
303 1 : WASM_FEATURE_SCOPE(anyref);
304 2 : ExpectValidates(sigs.r_v(), {kExprRefNull});
305 1 : }
306 :
307 15189 : TEST_F(FunctionBodyDecoderTest, EmptyFunction) {
308 2 : ExpectValidates(sigs.v_v(), {});
309 2 : ExpectFailure(sigs.i_i(), {});
310 1 : }
311 :
312 15189 : TEST_F(FunctionBodyDecoderTest, IncompleteIf1) {
313 1 : byte code[] = {kExprIf};
314 1 : ExpectFailure(sigs.v_v(), code);
315 1 : ExpectFailure(sigs.i_i(), code);
316 1 : }
317 :
318 15189 : TEST_F(FunctionBodyDecoderTest, Int32Const_fallthru) {
319 2 : ExpectValidates(sigs.i_i(), {WASM_I32V_1(0)});
320 1 : }
321 :
322 15189 : TEST_F(FunctionBodyDecoderTest, Int32Const_fallthru2) {
323 2 : ExpectFailure(sigs.i_i(), {WASM_I32V_1(0), WASM_I32V_1(1)});
324 1 : }
325 :
326 15189 : TEST_F(FunctionBodyDecoderTest, Int32Const) {
327 : const int kInc = 4498211;
328 955 : for (int32_t i = kMinInt; i < kMaxInt - kInc; i = i + kInc) {
329 : // TODO(binji): expand test for other sized int32s; 1 through 5 bytes.
330 1908 : ExpectValidates(sigs.i_i(), {WASM_I32V(i)});
331 : }
332 1 : }
333 :
334 15189 : TEST_F(FunctionBodyDecoderTest, Int64Const) {
335 : const int kInc = 4498211;
336 955 : for (int32_t i = kMinInt; i < kMaxInt - kInc; i = i + kInc) {
337 : ExpectValidates(sigs.l_l(),
338 1908 : {WASM_I64V((static_cast<uint64_t>(i) << 32) | i)});
339 : }
340 1 : }
341 :
342 15189 : TEST_F(FunctionBodyDecoderTest, Float32Const) {
343 1 : byte code[] = {kExprF32Const, 0, 0, 0, 0};
344 : Address ptr = reinterpret_cast<Address>(code + 1);
345 31 : for (int i = 0; i < 30; i++) {
346 30 : WriteLittleEndianValue<float>(ptr, i * -7.75f);
347 30 : ExpectValidates(sigs.f_ff(), code);
348 : }
349 1 : }
350 :
351 15189 : TEST_F(FunctionBodyDecoderTest, Float64Const) {
352 1 : byte code[] = {kExprF64Const, 0, 0, 0, 0, 0, 0, 0, 0};
353 : Address ptr = reinterpret_cast<Address>(code + 1);
354 31 : for (int i = 0; i < 30; i++) {
355 30 : WriteLittleEndianValue<double>(ptr, i * 33.45);
356 30 : ExpectValidates(sigs.d_dd(), code);
357 : }
358 1 : }
359 :
360 15189 : TEST_F(FunctionBodyDecoderTest, Int32Const_off_end) {
361 1 : byte code[] = {kExprI32Const, 0xAA, 0xBB, 0xCC, 0x44};
362 :
363 5 : for (size_t size = 1; size <= 4; ++size) {
364 8 : ExpectFailure(sigs.i_i(), VectorOf(code, size), kAppendEnd);
365 : // Should also fail without the trailing 'end' opcode.
366 8 : ExpectFailure(sigs.i_i(), VectorOf(code, size), kOmitEnd);
367 : }
368 1 : }
369 :
370 15189 : TEST_F(FunctionBodyDecoderTest, GetLocal0_param) {
371 1 : ExpectValidates(sigs.i_i(), kCodeGetLocal0);
372 1 : }
373 :
374 15189 : TEST_F(FunctionBodyDecoderTest, GetLocal0_local) {
375 : AddLocals(kWasmI32, 1);
376 1 : ExpectValidates(sigs.i_v(), kCodeGetLocal0);
377 1 : }
378 :
379 15189 : TEST_F(FunctionBodyDecoderTest, TooManyLocals) {
380 : AddLocals(kWasmI32, 4034986500);
381 1 : ExpectFailure(sigs.i_v(), kCodeGetLocal0);
382 1 : }
383 :
384 15189 : TEST_F(FunctionBodyDecoderTest, GetLocal0_param_n) {
385 1 : FunctionSig* array[] = {sigs.i_i(), sigs.i_ii(), sigs.i_iii()};
386 :
387 4 : for (size_t i = 0; i < arraysize(array); i++) {
388 3 : ExpectValidates(array[i], kCodeGetLocal0);
389 : }
390 1 : }
391 :
392 15189 : TEST_F(FunctionBodyDecoderTest, GetLocalN_local) {
393 8 : for (byte i = 1; i < 8; i++) {
394 : AddLocals(kWasmI32, 1);
395 35 : for (byte j = 0; j < i; j++) {
396 56 : ExpectValidates(sigs.i_v(), {kExprGetLocal, j});
397 : }
398 : }
399 1 : }
400 :
401 15189 : TEST_F(FunctionBodyDecoderTest, GetLocal0_fail_no_params) {
402 1 : ExpectFailure(sigs.i_v(), kCodeGetLocal0);
403 1 : }
404 :
405 15189 : TEST_F(FunctionBodyDecoderTest, GetLocal1_fail_no_locals) {
406 1 : ExpectFailure(sigs.i_i(), kCodeGetLocal1);
407 1 : }
408 :
409 15189 : TEST_F(FunctionBodyDecoderTest, GetLocal_off_end) {
410 2 : ExpectFailure(sigs.i_i(), {kExprGetLocal});
411 1 : }
412 :
413 15189 : TEST_F(FunctionBodyDecoderTest, NumLocalBelowLimit) {
414 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals - 1);
415 2 : ExpectValidates(sigs.v_v(), {WASM_NOP});
416 1 : }
417 :
418 15189 : TEST_F(FunctionBodyDecoderTest, NumLocalAtLimit) {
419 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals);
420 2 : ExpectValidates(sigs.v_v(), {WASM_NOP});
421 1 : }
422 :
423 15189 : TEST_F(FunctionBodyDecoderTest, NumLocalAboveLimit) {
424 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals + 1);
425 2 : ExpectFailure(sigs.v_v(), {WASM_NOP});
426 1 : }
427 :
428 15189 : TEST_F(FunctionBodyDecoderTest, GetLocal_varint) {
429 : const int kMaxLocals = kV8MaxWasmFunctionLocals - 1;
430 : AddLocals(kWasmI32, kMaxLocals);
431 :
432 2 : ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_1(66)});
433 2 : ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_2(7777)});
434 2 : ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_3(8888)});
435 2 : ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_4(9999)});
436 :
437 2 : ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_5(kMaxLocals - 1)});
438 :
439 2 : ExpectFailure(sigs.i_i(), {kExprGetLocal, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF});
440 :
441 2 : ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_4(kMaxLocals - 1)});
442 2 : ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_4(kMaxLocals)});
443 2 : ExpectFailure(sigs.i_i(), {kExprGetLocal, U32V_4(kMaxLocals + 1)});
444 :
445 2 : ExpectFailure(sigs.i_v(), {kExprGetLocal, U32V_4(kMaxLocals)});
446 2 : ExpectFailure(sigs.i_v(), {kExprGetLocal, U32V_4(kMaxLocals + 1)});
447 1 : }
448 :
449 15189 : TEST_F(FunctionBodyDecoderTest, GetLocal_toomany) {
450 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals - 100);
451 : AddLocals(kWasmI32, 100);
452 :
453 2 : ExpectValidates(sigs.i_v(), {kExprGetLocal, U32V_1(66)});
454 2 : ExpectFailure(sigs.i_i(), {kExprGetLocal, U32V_1(66)});
455 1 : }
456 :
457 15189 : TEST_F(FunctionBodyDecoderTest, Binops_off_end) {
458 1 : byte code1[] = {0}; // [opcode]
459 19 : for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) {
460 18 : code1[0] = kInt32BinopOpcodes[i];
461 18 : ExpectFailure(sigs.i_i(), code1);
462 : }
463 :
464 1 : byte code3[] = {kExprGetLocal, 0, 0}; // [expr] [opcode]
465 19 : for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) {
466 18 : code3[2] = kInt32BinopOpcodes[i];
467 18 : ExpectFailure(sigs.i_i(), code3);
468 : }
469 :
470 1 : byte code4[] = {kExprGetLocal, 0, 0, 0}; // [expr] [opcode] [opcode]
471 19 : for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) {
472 18 : code4[2] = kInt32BinopOpcodes[i];
473 18 : code4[3] = kInt32BinopOpcodes[i];
474 18 : ExpectFailure(sigs.i_i(), code4);
475 : }
476 1 : }
477 :
478 15189 : TEST_F(FunctionBodyDecoderTest, BinopsAcrossBlock1) {
479 : ExpectFailure(sigs.i_i(), {WASM_ZERO, kExprBlock, kLocalI32, WASM_ZERO,
480 2 : kExprI32Add, kExprEnd});
481 1 : }
482 :
483 15189 : TEST_F(FunctionBodyDecoderTest, BinopsAcrossBlock2) {
484 : ExpectFailure(sigs.i_i(), {WASM_ZERO, WASM_ZERO, kExprBlock, kLocalI32,
485 2 : kExprI32Add, kExprEnd});
486 1 : }
487 :
488 15189 : TEST_F(FunctionBodyDecoderTest, BinopsAcrossBlock3) {
489 : ExpectFailure(sigs.i_i(), {WASM_ZERO, WASM_ZERO, kExprIf, kLocalI32,
490 2 : kExprI32Add, kExprElse, kExprI32Add, kExprEnd});
491 1 : }
492 :
493 15189 : TEST_F(FunctionBodyDecoderTest, Nop) {
494 2 : ExpectValidates(sigs.v_v(), {kExprNop});
495 1 : }
496 :
497 15189 : TEST_F(FunctionBodyDecoderTest, SetLocal0_void) {
498 2 : ExpectFailure(sigs.i_i(), {WASM_SET_LOCAL(0, WASM_ZERO)});
499 1 : }
500 :
501 15189 : TEST_F(FunctionBodyDecoderTest, SetLocal0_param) {
502 1 : ExpectFailure(sigs.i_i(), kCodeSetLocal0);
503 1 : ExpectFailure(sigs.f_ff(), kCodeSetLocal0);
504 1 : ExpectFailure(sigs.d_dd(), kCodeSetLocal0);
505 1 : }
506 :
507 15189 : TEST_F(FunctionBodyDecoderTest, TeeLocal0_param) {
508 1 : ExpectValidates(sigs.i_i(), kCodeTeeLocal0);
509 1 : ExpectFailure(sigs.f_ff(), kCodeTeeLocal0);
510 1 : ExpectFailure(sigs.d_dd(), kCodeTeeLocal0);
511 1 : }
512 :
513 15189 : TEST_F(FunctionBodyDecoderTest, SetLocal0_local) {
514 1 : ExpectFailure(sigs.i_v(), kCodeSetLocal0);
515 1 : ExpectFailure(sigs.v_v(), kCodeSetLocal0);
516 : AddLocals(kWasmI32, 1);
517 : ExpectFailure(sigs.i_v(), kCodeSetLocal0);
518 : ExpectValidates(sigs.v_v(), kCodeSetLocal0);
519 1 : }
520 :
521 15189 : TEST_F(FunctionBodyDecoderTest, TeeLocal0_local) {
522 1 : ExpectFailure(sigs.i_v(), kCodeTeeLocal0);
523 : AddLocals(kWasmI32, 1);
524 : ExpectValidates(sigs.i_v(), kCodeTeeLocal0);
525 1 : }
526 :
527 15189 : TEST_F(FunctionBodyDecoderTest, TeeLocalN_local) {
528 8 : for (byte i = 1; i < 8; i++) {
529 : AddLocals(kWasmI32, 1);
530 35 : for (byte j = 0; j < i; j++) {
531 56 : ExpectFailure(sigs.v_v(), {WASM_TEE_LOCAL(j, WASM_I32V_1(i))});
532 56 : ExpectValidates(sigs.i_i(), {WASM_TEE_LOCAL(j, WASM_I32V_1(i))});
533 : }
534 : }
535 1 : }
536 :
537 15189 : TEST_F(FunctionBodyDecoderTest, BlockN) {
538 : constexpr size_t kMaxSize = 200;
539 : byte buffer[kMaxSize + 3];
540 :
541 202 : for (size_t i = 0; i <= kMaxSize; i++) {
542 : memset(buffer, kExprNop, sizeof(buffer));
543 201 : buffer[0] = kExprBlock;
544 201 : buffer[1] = kLocalVoid;
545 201 : buffer[i + 2] = kExprEnd;
546 402 : ExpectValidates(sigs.v_i(), VectorOf(buffer, i + 3), kAppendEnd);
547 : }
548 1 : }
549 :
550 : #define WASM_EMPTY_BLOCK kExprBlock, kLocalVoid, kExprEnd
551 :
552 15189 : TEST_F(FunctionBodyDecoderTest, Block0) {
553 2 : ExpectValidates(sigs.v_v(), {WASM_EMPTY_BLOCK});
554 2 : ExpectFailure(sigs.i_i(), {WASM_EMPTY_BLOCK});
555 1 : }
556 :
557 15189 : TEST_F(FunctionBodyDecoderTest, Block0_fallthru1) {
558 2 : ExpectValidates(sigs.v_v(), {WASM_BLOCK(WASM_EMPTY_BLOCK)});
559 2 : ExpectFailure(sigs.i_i(), {WASM_BLOCK(WASM_EMPTY_BLOCK)});
560 1 : }
561 :
562 15189 : TEST_F(FunctionBodyDecoderTest, Block0Block0) {
563 2 : ExpectValidates(sigs.v_v(), {WASM_EMPTY_BLOCK, WASM_EMPTY_BLOCK});
564 2 : ExpectFailure(sigs.i_i(), {WASM_EMPTY_BLOCK, WASM_EMPTY_BLOCK});
565 1 : }
566 :
567 15189 : TEST_F(FunctionBodyDecoderTest, Block0_end) {
568 2 : ExpectFailure(sigs.v_v(), {WASM_EMPTY_BLOCK, kExprEnd});
569 1 : }
570 :
571 : #undef WASM_EMPTY_BLOCK
572 :
573 15189 : TEST_F(FunctionBodyDecoderTest, Block1) {
574 1 : byte code[] = {WASM_BLOCK_I(WASM_GET_LOCAL(0))};
575 1 : ExpectValidates(sigs.i_i(), code);
576 1 : ExpectFailure(sigs.v_i(), code);
577 1 : ExpectFailure(sigs.d_dd(), code);
578 1 : ExpectFailure(sigs.i_f(), code);
579 1 : ExpectFailure(sigs.i_d(), code);
580 1 : }
581 :
582 15189 : TEST_F(FunctionBodyDecoderTest, Block1_i) {
583 1 : byte code[] = {WASM_BLOCK_I(WASM_ZERO)};
584 1 : ExpectValidates(sigs.i_i(), code);
585 1 : ExpectFailure(sigs.f_ff(), code);
586 1 : ExpectFailure(sigs.d_dd(), code);
587 1 : ExpectFailure(sigs.l_ll(), code);
588 1 : }
589 :
590 15189 : TEST_F(FunctionBodyDecoderTest, Block1_f) {
591 1 : byte code[] = {WASM_BLOCK_F(WASM_F32(0))};
592 1 : ExpectFailure(sigs.i_i(), code);
593 1 : ExpectValidates(sigs.f_ff(), code);
594 1 : ExpectFailure(sigs.d_dd(), code);
595 1 : ExpectFailure(sigs.l_ll(), code);
596 1 : }
597 :
598 15189 : TEST_F(FunctionBodyDecoderTest, Block1_continue) {
599 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_BR(0))});
600 1 : }
601 :
602 15189 : TEST_F(FunctionBodyDecoderTest, Block1_br) {
603 2 : ExpectValidates(sigs.v_v(), {B1(WASM_BR(0))});
604 2 : ExpectValidates(sigs.v_v(), {B1(WASM_BR(1))});
605 2 : ExpectFailure(sigs.v_v(), {B1(WASM_BR(2))});
606 1 : }
607 :
608 15189 : TEST_F(FunctionBodyDecoderTest, Block2_br) {
609 2 : ExpectValidates(sigs.v_v(), {B2(WASM_NOP, WASM_BR(0))});
610 2 : ExpectValidates(sigs.v_v(), {B2(WASM_BR(0), WASM_NOP)});
611 2 : ExpectValidates(sigs.v_v(), {B2(WASM_BR(0), WASM_BR(0))});
612 1 : }
613 :
614 15189 : TEST_F(FunctionBodyDecoderTest, Block2) {
615 2 : ExpectFailure(sigs.i_i(), {WASM_BLOCK(WASM_NOP, WASM_NOP)});
616 2 : ExpectFailure(sigs.i_i(), {WASM_BLOCK_I(WASM_NOP, WASM_NOP)});
617 2 : ExpectValidates(sigs.i_i(), {WASM_BLOCK_I(WASM_NOP, WASM_ZERO)});
618 2 : ExpectValidates(sigs.i_i(), {WASM_BLOCK_I(WASM_ZERO, WASM_NOP)});
619 2 : ExpectFailure(sigs.i_i(), {WASM_BLOCK_I(WASM_ZERO, WASM_ZERO)});
620 1 : }
621 :
622 15189 : TEST_F(FunctionBodyDecoderTest, Block2b) {
623 1 : byte code[] = {WASM_BLOCK_I(WASM_SET_LOCAL(0, WASM_ZERO), WASM_ZERO)};
624 1 : ExpectValidates(sigs.i_i(), code);
625 1 : ExpectFailure(sigs.v_v(), code);
626 1 : ExpectFailure(sigs.f_ff(), code);
627 1 : }
628 :
629 15189 : TEST_F(FunctionBodyDecoderTest, Block2_fallthru) {
630 : ExpectValidates(sigs.i_i(), {B2(WASM_SET_LOCAL(0, WASM_ZERO),
631 : WASM_SET_LOCAL(0, WASM_ZERO)),
632 2 : WASM_I32V_1(23)});
633 1 : }
634 :
635 15189 : TEST_F(FunctionBodyDecoderTest, Block3) {
636 : ExpectValidates(sigs.i_i(), {WASM_BLOCK_I(WASM_SET_LOCAL(0, WASM_ZERO),
637 : WASM_SET_LOCAL(0, WASM_ZERO),
638 2 : WASM_I32V_1(11))});
639 1 : }
640 :
641 15189 : TEST_F(FunctionBodyDecoderTest, Block5) {
642 2 : ExpectFailure(sigs.v_i(), {WASM_BLOCK(WASM_ZERO)});
643 :
644 2 : ExpectFailure(sigs.v_i(), {WASM_BLOCK(WASM_ZERO, WASM_ZERO)});
645 :
646 2 : ExpectFailure(sigs.v_i(), {WASM_BLOCK(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
647 :
648 : ExpectFailure(sigs.v_i(),
649 2 : {WASM_BLOCK(WASM_ZERO, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
650 :
651 : ExpectFailure(sigs.v_i(), {WASM_BLOCK(WASM_ZERO, WASM_ZERO, WASM_ZERO,
652 2 : WASM_ZERO, WASM_ZERO)});
653 1 : }
654 :
655 15189 : TEST_F(FunctionBodyDecoderTest, BlockType) {
656 2 : ExpectValidates(sigs.i_i(), {WASM_BLOCK_I(WASM_GET_LOCAL(0))});
657 2 : ExpectValidates(sigs.l_l(), {WASM_BLOCK_L(WASM_GET_LOCAL(0))});
658 2 : ExpectValidates(sigs.f_f(), {WASM_BLOCK_F(WASM_GET_LOCAL(0))});
659 2 : ExpectValidates(sigs.d_d(), {WASM_BLOCK_D(WASM_GET_LOCAL(0))});
660 1 : }
661 :
662 15189 : TEST_F(FunctionBodyDecoderTest, BlockType_fail) {
663 2 : ExpectFailure(sigs.i_i(), {WASM_BLOCK_L(WASM_I64V_1(0))});
664 2 : ExpectFailure(sigs.i_i(), {WASM_BLOCK_F(WASM_F32(0.0))});
665 2 : ExpectFailure(sigs.i_i(), {WASM_BLOCK_D(WASM_F64(1.1))});
666 :
667 2 : ExpectFailure(sigs.l_l(), {WASM_BLOCK_I(WASM_ZERO)});
668 2 : ExpectFailure(sigs.l_l(), {WASM_BLOCK_F(WASM_F32(0.0))});
669 2 : ExpectFailure(sigs.l_l(), {WASM_BLOCK_D(WASM_F64(1.1))});
670 :
671 2 : ExpectFailure(sigs.f_ff(), {WASM_BLOCK_I(WASM_ZERO)});
672 2 : ExpectFailure(sigs.f_ff(), {WASM_BLOCK_L(WASM_I64V_1(0))});
673 2 : ExpectFailure(sigs.f_ff(), {WASM_BLOCK_D(WASM_F64(1.1))});
674 :
675 2 : ExpectFailure(sigs.d_dd(), {WASM_BLOCK_I(WASM_ZERO)});
676 2 : ExpectFailure(sigs.d_dd(), {WASM_BLOCK_L(WASM_I64V_1(0))});
677 2 : ExpectFailure(sigs.d_dd(), {WASM_BLOCK_F(WASM_F32(0.0))});
678 1 : }
679 :
680 15189 : TEST_F(FunctionBodyDecoderTest, BlockF32) {
681 : static const byte code[] = {WASM_BLOCK_F(kExprF32Const, 0, 0, 0, 0)};
682 1 : ExpectValidates(sigs.f_ff(), code);
683 1 : ExpectFailure(sigs.i_i(), code);
684 1 : ExpectFailure(sigs.d_dd(), code);
685 1 : }
686 :
687 15189 : TEST_F(FunctionBodyDecoderTest, BlockN_off_end) {
688 1 : byte code[] = {WASM_BLOCK(kExprNop, kExprNop, kExprNop, kExprNop)};
689 1 : ExpectValidates(sigs.v_v(), code);
690 7 : for (size_t i = 1; i < arraysize(code); i++) {
691 12 : ExpectFailure(sigs.v_v(), VectorOf(code, i), kAppendEnd);
692 12 : ExpectFailure(sigs.v_v(), VectorOf(code, i), kOmitEnd);
693 : }
694 1 : }
695 :
696 15189 : TEST_F(FunctionBodyDecoderTest, Block2_continue) {
697 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_NOP, WASM_BR(0))});
698 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_NOP, WASM_BR(1))});
699 2 : ExpectFailure(sigs.v_v(), {WASM_LOOP(WASM_NOP, WASM_BR(2))});
700 1 : }
701 :
702 15189 : TEST_F(FunctionBodyDecoderTest, Block3_continue) {
703 2 : ExpectValidates(sigs.v_v(), {B1(WASM_LOOP(WASM_NOP, WASM_BR(0)))});
704 2 : ExpectValidates(sigs.v_v(), {B1(WASM_LOOP(WASM_NOP, WASM_BR(1)))});
705 2 : ExpectValidates(sigs.v_v(), {B1(WASM_LOOP(WASM_NOP, WASM_BR(2)))});
706 2 : ExpectFailure(sigs.v_v(), {B1(WASM_LOOP(WASM_NOP, WASM_BR(3)))});
707 1 : }
708 :
709 15189 : TEST_F(FunctionBodyDecoderTest, NestedBlock_return) {
710 2 : ExpectValidates(sigs.i_i(), {B1(B1(WASM_RETURN1(WASM_ZERO))), WASM_ZERO});
711 1 : }
712 :
713 15189 : TEST_F(FunctionBodyDecoderTest, BlockBrBinop) {
714 : ExpectValidates(sigs.i_i(),
715 : {WASM_I32_AND(WASM_BLOCK_I(WASM_BRV(0, WASM_I32V_1(1))),
716 2 : WASM_I32V_1(2))});
717 1 : }
718 :
719 15189 : TEST_F(FunctionBodyDecoderTest, If_empty1) {
720 2 : ExpectValidates(sigs.v_v(), {WASM_ZERO, WASM_IF_OP, kExprEnd});
721 1 : }
722 :
723 15189 : TEST_F(FunctionBodyDecoderTest, If_empty2) {
724 2 : ExpectValidates(sigs.v_v(), {WASM_ZERO, WASM_IF_OP, kExprElse, kExprEnd});
725 1 : }
726 :
727 15189 : TEST_F(FunctionBodyDecoderTest, If_empty3) {
728 : ExpectValidates(sigs.v_v(),
729 2 : {WASM_ZERO, WASM_IF_OP, WASM_NOP, kExprElse, kExprEnd});
730 : ExpectFailure(sigs.v_v(),
731 2 : {WASM_ZERO, WASM_IF_OP, WASM_ZERO, kExprElse, kExprEnd});
732 1 : }
733 :
734 15189 : TEST_F(FunctionBodyDecoderTest, If_empty4) {
735 : ExpectValidates(sigs.v_v(),
736 2 : {WASM_ZERO, WASM_IF_OP, kExprElse, WASM_NOP, kExprEnd});
737 : ExpectFailure(sigs.v_v(),
738 2 : {WASM_ZERO, WASM_IF_OP, kExprElse, WASM_ZERO, kExprEnd});
739 1 : }
740 :
741 15189 : TEST_F(FunctionBodyDecoderTest, If_empty_stack) {
742 1 : byte code[] = {kExprIf};
743 1 : ExpectFailure(sigs.v_v(), code);
744 1 : ExpectFailure(sigs.i_i(), code);
745 1 : }
746 :
747 15189 : TEST_F(FunctionBodyDecoderTest, If_incomplete1) {
748 1 : byte code[] = {kExprI32Const, 0, kExprIf};
749 1 : ExpectFailure(sigs.v_v(), code);
750 1 : ExpectFailure(sigs.i_i(), code);
751 1 : }
752 :
753 15189 : TEST_F(FunctionBodyDecoderTest, If_incomplete2) {
754 1 : byte code[] = {kExprI32Const, 0, kExprIf, kExprNop};
755 1 : ExpectFailure(sigs.v_v(), code);
756 1 : ExpectFailure(sigs.i_i(), code);
757 1 : }
758 :
759 15189 : TEST_F(FunctionBodyDecoderTest, If_else_else) {
760 1 : byte code[] = {kExprI32Const, 0, WASM_IF_OP, kExprElse, kExprElse, kExprEnd};
761 1 : ExpectFailure(sigs.v_v(), code);
762 1 : ExpectFailure(sigs.i_i(), code);
763 1 : }
764 :
765 15189 : TEST_F(FunctionBodyDecoderTest, IfEmpty) {
766 2 : ExpectValidates(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP, kExprEnd});
767 1 : }
768 :
769 15189 : TEST_F(FunctionBodyDecoderTest, IfSet) {
770 : ExpectValidates(sigs.v_i(),
771 2 : {WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO))});
772 : ExpectValidates(sigs.v_i(),
773 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO),
774 2 : WASM_NOP)});
775 1 : }
776 :
777 15189 : TEST_F(FunctionBodyDecoderTest, IfElseEmpty) {
778 : ExpectValidates(sigs.v_i(),
779 2 : {WASM_GET_LOCAL(0), WASM_IF_OP, kExprElse, kExprEnd});
780 : ExpectValidates(sigs.v_i(),
781 2 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP)});
782 1 : }
783 :
784 15189 : TEST_F(FunctionBodyDecoderTest, IfElseUnreachable1) {
785 : ExpectValidates(
786 : sigs.i_i(),
787 2 : {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_UNREACHABLE, WASM_GET_LOCAL(0))});
788 : ExpectValidates(
789 : sigs.i_i(),
790 2 : {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE)});
791 1 : }
792 :
793 15189 : TEST_F(FunctionBodyDecoderTest, IfElseUnreachable2) {
794 : static const byte code[] = {
795 : WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_UNREACHABLE, WASM_GET_LOCAL(0))};
796 :
797 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
798 5 : ValueType types[] = {kWasmI32, kValueTypes[i]};
799 : FunctionSig sig(1, 1, types);
800 :
801 5 : Validate(kValueTypes[i] == kWasmI32, &sig, code);
802 : }
803 1 : }
804 :
805 15189 : TEST_F(FunctionBodyDecoderTest, OneArmedIfWithArity) {
806 : static const byte code[] = {WASM_ZERO, kExprIf, kLocalI32, WASM_ONE,
807 : kExprEnd};
808 : ExpectFailure(sigs.i_v(), code, kAppendEnd,
809 1 : "start-arity and end-arity of one-armed if must match");
810 1 : }
811 :
812 15189 : TEST_F(FunctionBodyDecoderTest, IfBreak) {
813 2 : ExpectValidates(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0), WASM_BR(0))});
814 2 : ExpectValidates(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0), WASM_BR(1))});
815 2 : ExpectFailure(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0), WASM_BR(2))});
816 1 : }
817 :
818 15189 : TEST_F(FunctionBodyDecoderTest, IfElseBreak) {
819 : ExpectValidates(sigs.v_i(),
820 2 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_BR(0))});
821 : ExpectValidates(sigs.v_i(),
822 2 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_BR(1))});
823 : ExpectFailure(sigs.v_i(),
824 2 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_BR(2))});
825 1 : }
826 :
827 15189 : TEST_F(FunctionBodyDecoderTest, Block_else) {
828 1 : byte code[] = {kExprI32Const, 0, kExprBlock, kExprElse, kExprEnd};
829 1 : ExpectFailure(sigs.v_v(), code);
830 1 : ExpectFailure(sigs.i_i(), code);
831 1 : }
832 :
833 15189 : TEST_F(FunctionBodyDecoderTest, IfNop) {
834 2 : ExpectValidates(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0), WASM_NOP)});
835 : ExpectValidates(sigs.v_i(),
836 2 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP)});
837 1 : }
838 :
839 15189 : TEST_F(FunctionBodyDecoderTest, If_end) {
840 2 : ExpectValidates(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP, kExprEnd});
841 2 : ExpectFailure(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP, kExprEnd, kExprEnd});
842 1 : }
843 :
844 15189 : TEST_F(FunctionBodyDecoderTest, If_falloff1) {
845 2 : ExpectFailure(sigs.v_i(), {kExprGetLocal, 0, kExprIf});
846 2 : ExpectFailure(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP});
847 : ExpectFailure(sigs.v_i(),
848 2 : {kExprGetLocal, 0, WASM_IF_OP, kExprNop, kExprElse});
849 1 : }
850 :
851 15189 : TEST_F(FunctionBodyDecoderTest, IfElseNop) {
852 : ExpectValidates(sigs.v_i(),
853 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO),
854 2 : WASM_NOP)});
855 1 : }
856 :
857 15189 : TEST_F(FunctionBodyDecoderTest, IfBlock1) {
858 : ExpectValidates(sigs.v_i(),
859 : {WASM_IF_ELSE(WASM_GET_LOCAL(0),
860 2 : B1(WASM_SET_LOCAL(0, WASM_ZERO)), WASM_NOP)});
861 1 : }
862 :
863 15189 : TEST_F(FunctionBodyDecoderTest, IfBlock1b) {
864 : ExpectValidates(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0),
865 2 : B1(WASM_SET_LOCAL(0, WASM_ZERO)))});
866 1 : }
867 :
868 15189 : TEST_F(FunctionBodyDecoderTest, IfBlock2a) {
869 : ExpectValidates(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0),
870 : B2(WASM_SET_LOCAL(0, WASM_ZERO),
871 2 : WASM_SET_LOCAL(0, WASM_ZERO)))});
872 1 : }
873 :
874 15189 : TEST_F(FunctionBodyDecoderTest, IfBlock2b) {
875 : ExpectValidates(sigs.v_i(), {WASM_IF_ELSE(WASM_GET_LOCAL(0),
876 : B2(WASM_SET_LOCAL(0, WASM_ZERO),
877 : WASM_SET_LOCAL(0, WASM_ZERO)),
878 2 : WASM_NOP)});
879 1 : }
880 :
881 15189 : TEST_F(FunctionBodyDecoderTest, IfElseSet) {
882 : ExpectValidates(sigs.v_i(),
883 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO),
884 2 : WASM_SET_LOCAL(0, WASM_I32V_1(1)))});
885 1 : }
886 :
887 15189 : TEST_F(FunctionBodyDecoderTest, Loop0) {
888 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP_OP, kExprEnd});
889 1 : }
890 :
891 15189 : TEST_F(FunctionBodyDecoderTest, Loop1) {
892 : static const byte code[] = {WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO))};
893 1 : ExpectValidates(sigs.v_i(), code);
894 1 : ExpectFailure(sigs.v_v(), code);
895 1 : ExpectFailure(sigs.f_ff(), code);
896 1 : }
897 :
898 15189 : TEST_F(FunctionBodyDecoderTest, Loop2) {
899 : ExpectValidates(sigs.v_i(), {WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO),
900 2 : WASM_SET_LOCAL(0, WASM_ZERO))});
901 1 : }
902 :
903 15189 : TEST_F(FunctionBodyDecoderTest, Loop1_continue) {
904 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_BR(0))});
905 1 : }
906 :
907 15189 : TEST_F(FunctionBodyDecoderTest, Loop1_break) {
908 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_BR(1))});
909 1 : }
910 :
911 15189 : TEST_F(FunctionBodyDecoderTest, Loop2_continue) {
912 : ExpectValidates(sigs.v_i(),
913 2 : {WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO), WASM_BR(0))});
914 1 : }
915 :
916 15189 : TEST_F(FunctionBodyDecoderTest, Loop2_break) {
917 : ExpectValidates(sigs.v_i(),
918 2 : {WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO), WASM_BR(1))});
919 1 : }
920 :
921 15189 : TEST_F(FunctionBodyDecoderTest, InfiniteLoop1) {
922 2 : ExpectValidates(sigs.i_i(), {WASM_LOOP(WASM_BR(0)), WASM_ZERO});
923 2 : ExpectValidates(sigs.i_i(), {WASM_LOOP(WASM_BR(0)), WASM_ZERO});
924 2 : ExpectValidates(sigs.i_i(), {WASM_LOOP_I(WASM_BRV(1, WASM_ZERO))});
925 1 : }
926 :
927 15189 : TEST_F(FunctionBodyDecoderTest, InfiniteLoop2) {
928 2 : ExpectFailure(sigs.i_i(), {WASM_LOOP(WASM_BR(0), WASM_ZERO), WASM_ZERO});
929 1 : }
930 :
931 15189 : TEST_F(FunctionBodyDecoderTest, Loop2_unreachable) {
932 2 : ExpectValidates(sigs.i_i(), {WASM_LOOP_I(WASM_BR(0), WASM_NOP)});
933 1 : }
934 :
935 15189 : TEST_F(FunctionBodyDecoderTest, LoopType) {
936 2 : ExpectValidates(sigs.i_i(), {WASM_LOOP_I(WASM_GET_LOCAL(0))});
937 2 : ExpectValidates(sigs.l_l(), {WASM_LOOP_L(WASM_GET_LOCAL(0))});
938 2 : ExpectValidates(sigs.f_f(), {WASM_LOOP_F(WASM_GET_LOCAL(0))});
939 2 : ExpectValidates(sigs.d_d(), {WASM_LOOP_D(WASM_GET_LOCAL(0))});
940 1 : }
941 :
942 15189 : TEST_F(FunctionBodyDecoderTest, LoopType_void) {
943 2 : ExpectFailure(sigs.v_v(), {WASM_LOOP_I(WASM_ZERO)});
944 2 : ExpectFailure(sigs.v_v(), {WASM_LOOP_L(WASM_I64V_1(0))});
945 2 : ExpectFailure(sigs.v_v(), {WASM_LOOP_F(WASM_F32(0.0))});
946 2 : ExpectFailure(sigs.v_v(), {WASM_LOOP_D(WASM_F64(1.1))});
947 1 : }
948 :
949 15189 : TEST_F(FunctionBodyDecoderTest, LoopType_fail) {
950 2 : ExpectFailure(sigs.i_i(), {WASM_LOOP_L(WASM_I64V_1(0))});
951 2 : ExpectFailure(sigs.i_i(), {WASM_LOOP_F(WASM_F32(0.0))});
952 2 : ExpectFailure(sigs.i_i(), {WASM_LOOP_D(WASM_F64(1.1))});
953 :
954 2 : ExpectFailure(sigs.l_l(), {WASM_LOOP_I(WASM_ZERO)});
955 2 : ExpectFailure(sigs.l_l(), {WASM_LOOP_F(WASM_F32(0.0))});
956 2 : ExpectFailure(sigs.l_l(), {WASM_LOOP_D(WASM_F64(1.1))});
957 :
958 2 : ExpectFailure(sigs.f_ff(), {WASM_LOOP_I(WASM_ZERO)});
959 2 : ExpectFailure(sigs.f_ff(), {WASM_LOOP_L(WASM_I64V_1(0))});
960 2 : ExpectFailure(sigs.f_ff(), {WASM_LOOP_D(WASM_F64(1.1))});
961 :
962 2 : ExpectFailure(sigs.d_dd(), {WASM_LOOP_I(WASM_ZERO)});
963 2 : ExpectFailure(sigs.d_dd(), {WASM_LOOP_L(WASM_I64V_1(0))});
964 2 : ExpectFailure(sigs.d_dd(), {WASM_LOOP_F(WASM_F32(0.0))});
965 1 : }
966 :
967 15189 : TEST_F(FunctionBodyDecoderTest, ReturnVoid1) {
968 : static const byte code[] = {kExprNop};
969 1 : ExpectValidates(sigs.v_v(), code);
970 1 : ExpectFailure(sigs.i_i(), code);
971 1 : ExpectFailure(sigs.i_f(), code);
972 1 : }
973 :
974 15189 : TEST_F(FunctionBodyDecoderTest, ReturnVoid2) {
975 : static const byte code[] = {WASM_BLOCK(WASM_BR(0))};
976 1 : ExpectValidates(sigs.v_v(), code);
977 1 : ExpectFailure(sigs.i_i(), code);
978 1 : ExpectFailure(sigs.i_f(), code);
979 1 : }
980 :
981 15189 : TEST_F(FunctionBodyDecoderTest, ReturnVoid3) {
982 2 : ExpectFailure(sigs.v_v(), {kExprI32Const, 0});
983 2 : ExpectFailure(sigs.v_v(), {kExprI64Const, 0});
984 2 : ExpectFailure(sigs.v_v(), {kExprF32Const, 0, 0, 0, 0});
985 2 : ExpectFailure(sigs.v_v(), {kExprF64Const, 0, 0, 0, 0, 0, 0, 0, 0});
986 2 : ExpectFailure(sigs.v_v(), {kExprRefNull});
987 :
988 2 : ExpectFailure(sigs.v_i(), {kExprGetLocal, 0});
989 1 : }
990 :
991 15189 : TEST_F(FunctionBodyDecoderTest, Unreachable1) {
992 2 : ExpectValidates(sigs.v_v(), {WASM_UNREACHABLE});
993 2 : ExpectValidates(sigs.v_v(), {WASM_UNREACHABLE, WASM_UNREACHABLE});
994 2 : ExpectValidates(sigs.i_i(), {WASM_UNREACHABLE, WASM_ZERO});
995 1 : }
996 :
997 15189 : TEST_F(FunctionBodyDecoderTest, Unreachable2) {
998 2 : ExpectFailure(sigs.v_v(), {B2(WASM_UNREACHABLE, WASM_ZERO)});
999 2 : ExpectFailure(sigs.v_v(), {B2(WASM_BR(0), WASM_ZERO)});
1000 1 : }
1001 :
1002 15189 : TEST_F(FunctionBodyDecoderTest, UnreachableLoop1) {
1003 2 : ExpectFailure(sigs.v_v(), {WASM_LOOP(WASM_UNREACHABLE, WASM_ZERO)});
1004 2 : ExpectFailure(sigs.v_v(), {WASM_LOOP(WASM_BR(0), WASM_ZERO)});
1005 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_UNREACHABLE, WASM_NOP)});
1006 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_BR(0), WASM_NOP)});
1007 1 : }
1008 :
1009 15189 : TEST_F(FunctionBodyDecoderTest, Unreachable_binop1) {
1010 2 : ExpectValidates(sigs.i_i(), {WASM_I32_AND(WASM_ZERO, WASM_UNREACHABLE)});
1011 2 : ExpectValidates(sigs.i_i(), {WASM_I32_AND(WASM_UNREACHABLE, WASM_ZERO)});
1012 1 : }
1013 :
1014 15189 : TEST_F(FunctionBodyDecoderTest, Unreachable_binop2) {
1015 2 : ExpectValidates(sigs.i_i(), {WASM_I32_AND(WASM_F32(0.0), WASM_UNREACHABLE)});
1016 2 : ExpectFailure(sigs.i_i(), {WASM_I32_AND(WASM_UNREACHABLE, WASM_F32(0.0))});
1017 1 : }
1018 :
1019 15189 : TEST_F(FunctionBodyDecoderTest, Unreachable_select1) {
1020 : ExpectValidates(sigs.i_i(),
1021 2 : {WASM_SELECT(WASM_UNREACHABLE, WASM_ZERO, WASM_ZERO)});
1022 : ExpectValidates(sigs.i_i(),
1023 2 : {WASM_SELECT(WASM_ZERO, WASM_UNREACHABLE, WASM_ZERO)});
1024 : ExpectValidates(sigs.i_i(),
1025 2 : {WASM_SELECT(WASM_ZERO, WASM_ZERO, WASM_UNREACHABLE)});
1026 1 : }
1027 :
1028 15189 : TEST_F(FunctionBodyDecoderTest, Unreachable_select2) {
1029 : ExpectValidates(sigs.i_i(),
1030 2 : {WASM_SELECT(WASM_F32(0.0), WASM_UNREACHABLE, WASM_ZERO)});
1031 : ExpectFailure(sigs.i_i(),
1032 2 : {WASM_SELECT(WASM_UNREACHABLE, WASM_F32(0.0), WASM_ZERO)});
1033 : ExpectFailure(sigs.i_i(),
1034 2 : {WASM_SELECT(WASM_UNREACHABLE, WASM_ZERO, WASM_F32(0.0))});
1035 1 : }
1036 :
1037 15189 : TEST_F(FunctionBodyDecoderTest, If1) {
1038 : ExpectValidates(sigs.i_i(), {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I32V_1(9),
1039 2 : WASM_I32V_1(8))});
1040 : ExpectValidates(sigs.i_i(), {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I32V_1(9),
1041 2 : WASM_GET_LOCAL(0))});
1042 : ExpectValidates(
1043 : sigs.i_i(),
1044 2 : {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_I32V_1(8))});
1045 1 : }
1046 :
1047 15189 : TEST_F(FunctionBodyDecoderTest, If_off_end) {
1048 : static const byte kCode[] = {
1049 : WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_GET_LOCAL(0))};
1050 8 : for (size_t len = 3; len < arraysize(kCode); len++) {
1051 14 : ExpectFailure(sigs.i_i(), VectorOf(kCode, len), kAppendEnd);
1052 14 : ExpectFailure(sigs.i_i(), VectorOf(kCode, len), kOmitEnd);
1053 : }
1054 1 : }
1055 :
1056 15189 : TEST_F(FunctionBodyDecoderTest, If_type1) {
1057 : // float|double ? 1 : 2
1058 : static const byte kCode[] = {
1059 1 : WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I32V_1(0), WASM_I32V_1(2))};
1060 1 : ExpectValidates(sigs.i_i(), kCode);
1061 1 : ExpectFailure(sigs.i_f(), kCode);
1062 1 : ExpectFailure(sigs.i_d(), kCode);
1063 1 : }
1064 :
1065 15189 : TEST_F(FunctionBodyDecoderTest, If_type2) {
1066 : // 1 ? float|double : 2
1067 : static const byte kCode[] = {
1068 1 : WASM_IF_ELSE_I(WASM_I32V_1(1), WASM_GET_LOCAL(0), WASM_I32V_1(1))};
1069 1 : ExpectValidates(sigs.i_i(), kCode);
1070 1 : ExpectFailure(sigs.i_f(), kCode);
1071 1 : ExpectFailure(sigs.i_d(), kCode);
1072 1 : }
1073 :
1074 15189 : TEST_F(FunctionBodyDecoderTest, If_type3) {
1075 : // stmt ? 0 : 1
1076 : static const byte kCode[] = {
1077 1 : WASM_IF_ELSE_I(WASM_NOP, WASM_I32V_1(0), WASM_I32V_1(1))};
1078 1 : ExpectFailure(sigs.i_i(), kCode);
1079 1 : ExpectFailure(sigs.i_f(), kCode);
1080 1 : ExpectFailure(sigs.i_d(), kCode);
1081 1 : }
1082 :
1083 15189 : TEST_F(FunctionBodyDecoderTest, If_type4) {
1084 : // 0 ? stmt : 1
1085 : static const byte kCode[] = {
1086 1 : WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_NOP, WASM_I32V_1(1))};
1087 1 : ExpectFailure(sigs.i_i(), kCode);
1088 1 : ExpectFailure(sigs.i_f(), kCode);
1089 1 : ExpectFailure(sigs.i_d(), kCode);
1090 1 : }
1091 :
1092 15189 : TEST_F(FunctionBodyDecoderTest, If_type5) {
1093 : // 0 ? 1 : stmt
1094 : static const byte kCode[] = {
1095 1 : WASM_IF_ELSE_I(WASM_ZERO, WASM_I32V_1(1), WASM_NOP)};
1096 1 : ExpectFailure(sigs.i_i(), kCode);
1097 1 : ExpectFailure(sigs.i_f(), kCode);
1098 1 : ExpectFailure(sigs.i_d(), kCode);
1099 1 : }
1100 :
1101 15189 : TEST_F(FunctionBodyDecoderTest, Int64Local_param) {
1102 1 : ExpectValidates(sigs.l_l(), kCodeGetLocal0);
1103 1 : }
1104 :
1105 15189 : TEST_F(FunctionBodyDecoderTest, Int64Locals) {
1106 8 : for (byte i = 1; i < 8; i++) {
1107 : AddLocals(kWasmI64, 1);
1108 35 : for (byte j = 0; j < i; j++) {
1109 56 : ExpectValidates(sigs.l_v(), {WASM_GET_LOCAL(j)});
1110 : }
1111 : }
1112 1 : }
1113 :
1114 15189 : TEST_F(FunctionBodyDecoderTest, Int32Binops) {
1115 1 : TestBinop(kExprI32Add, sigs.i_ii());
1116 1 : TestBinop(kExprI32Sub, sigs.i_ii());
1117 1 : TestBinop(kExprI32Mul, sigs.i_ii());
1118 1 : TestBinop(kExprI32DivS, sigs.i_ii());
1119 1 : TestBinop(kExprI32DivU, sigs.i_ii());
1120 1 : TestBinop(kExprI32RemS, sigs.i_ii());
1121 1 : TestBinop(kExprI32RemU, sigs.i_ii());
1122 1 : TestBinop(kExprI32And, sigs.i_ii());
1123 1 : TestBinop(kExprI32Ior, sigs.i_ii());
1124 1 : TestBinop(kExprI32Xor, sigs.i_ii());
1125 1 : TestBinop(kExprI32Shl, sigs.i_ii());
1126 1 : TestBinop(kExprI32ShrU, sigs.i_ii());
1127 1 : TestBinop(kExprI32ShrS, sigs.i_ii());
1128 1 : TestBinop(kExprI32Eq, sigs.i_ii());
1129 1 : TestBinop(kExprI32LtS, sigs.i_ii());
1130 1 : TestBinop(kExprI32LeS, sigs.i_ii());
1131 1 : TestBinop(kExprI32LtU, sigs.i_ii());
1132 1 : TestBinop(kExprI32LeU, sigs.i_ii());
1133 1 : }
1134 :
1135 15189 : TEST_F(FunctionBodyDecoderTest, DoubleBinops) {
1136 1 : TestBinop(kExprF64Add, sigs.d_dd());
1137 1 : TestBinop(kExprF64Sub, sigs.d_dd());
1138 1 : TestBinop(kExprF64Mul, sigs.d_dd());
1139 1 : TestBinop(kExprF64Div, sigs.d_dd());
1140 :
1141 1 : TestBinop(kExprF64Eq, sigs.i_dd());
1142 1 : TestBinop(kExprF64Lt, sigs.i_dd());
1143 1 : TestBinop(kExprF64Le, sigs.i_dd());
1144 1 : }
1145 :
1146 15189 : TEST_F(FunctionBodyDecoderTest, FloatBinops) {
1147 1 : TestBinop(kExprF32Add, sigs.f_ff());
1148 1 : TestBinop(kExprF32Sub, sigs.f_ff());
1149 1 : TestBinop(kExprF32Mul, sigs.f_ff());
1150 1 : TestBinop(kExprF32Div, sigs.f_ff());
1151 :
1152 1 : TestBinop(kExprF32Eq, sigs.i_ff());
1153 1 : TestBinop(kExprF32Lt, sigs.i_ff());
1154 1 : TestBinop(kExprF32Le, sigs.i_ff());
1155 1 : }
1156 :
1157 15189 : TEST_F(FunctionBodyDecoderTest, TypeConversions) {
1158 1 : TestUnop(kExprI32SConvertF32, kWasmI32, kWasmF32);
1159 1 : TestUnop(kExprI32SConvertF64, kWasmI32, kWasmF64);
1160 1 : TestUnop(kExprI32UConvertF32, kWasmI32, kWasmF32);
1161 1 : TestUnop(kExprI32UConvertF64, kWasmI32, kWasmF64);
1162 1 : TestUnop(kExprF64SConvertI32, kWasmF64, kWasmI32);
1163 1 : TestUnop(kExprF64UConvertI32, kWasmF64, kWasmI32);
1164 1 : TestUnop(kExprF64ConvertF32, kWasmF64, kWasmF32);
1165 1 : TestUnop(kExprF32SConvertI32, kWasmF32, kWasmI32);
1166 1 : TestUnop(kExprF32UConvertI32, kWasmF32, kWasmI32);
1167 1 : TestUnop(kExprF32ConvertF64, kWasmF32, kWasmF64);
1168 1 : }
1169 :
1170 15189 : TEST_F(FunctionBodyDecoderTest, MacrosStmt) {
1171 1 : TestModuleBuilder builder;
1172 1 : module = builder.module();
1173 : builder.InitializeMemory();
1174 2 : ExpectValidates(sigs.v_i(), {WASM_SET_LOCAL(0, WASM_I32V_3(87348))});
1175 : ExpectValidates(
1176 : sigs.v_i(),
1177 2 : {WASM_STORE_MEM(MachineType::Int32(), WASM_I32V_1(24), WASM_I32V_1(40))});
1178 2 : ExpectValidates(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0), WASM_NOP)});
1179 : ExpectValidates(sigs.v_i(),
1180 2 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP)});
1181 2 : ExpectValidates(sigs.v_v(), {WASM_NOP});
1182 2 : ExpectValidates(sigs.v_v(), {B1(WASM_NOP)});
1183 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_NOP)});
1184 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_BR(0))});
1185 1 : }
1186 :
1187 15189 : TEST_F(FunctionBodyDecoderTest, MacrosContinue) {
1188 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_CONTINUE(0))});
1189 1 : }
1190 :
1191 15189 : TEST_F(FunctionBodyDecoderTest, MacrosVariadic) {
1192 2 : ExpectValidates(sigs.v_v(), {B2(WASM_NOP, WASM_NOP)});
1193 2 : ExpectValidates(sigs.v_v(), {B3(WASM_NOP, WASM_NOP, WASM_NOP)});
1194 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_NOP, WASM_NOP)});
1195 2 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_NOP, WASM_NOP, WASM_NOP)});
1196 1 : }
1197 :
1198 15189 : TEST_F(FunctionBodyDecoderTest, MacrosNestedBlocks) {
1199 2 : ExpectValidates(sigs.v_v(), {B2(WASM_NOP, B2(WASM_NOP, WASM_NOP))});
1200 : ExpectValidates(sigs.v_v(), {B3(WASM_NOP, // --
1201 : B2(WASM_NOP, WASM_NOP), // --
1202 2 : B2(WASM_NOP, WASM_NOP))}); // --
1203 2 : ExpectValidates(sigs.v_v(), {B1(B1(B2(WASM_NOP, WASM_NOP)))});
1204 1 : }
1205 :
1206 15189 : TEST_F(FunctionBodyDecoderTest, MultipleReturn) {
1207 : static ValueType kIntTypes5[] = {kWasmI32, kWasmI32, kWasmI32, kWasmI32,
1208 : kWasmI32};
1209 1 : FunctionSig sig_ii_v(2, 0, kIntTypes5);
1210 2 : ExpectValidates(&sig_ii_v, {WASM_RETURNN(2, WASM_ZERO, WASM_ONE)});
1211 2 : ExpectFailure(&sig_ii_v, {WASM_RETURNN(1, WASM_ZERO)});
1212 :
1213 1 : FunctionSig sig_iii_v(3, 0, kIntTypes5);
1214 : ExpectValidates(&sig_iii_v,
1215 2 : {WASM_RETURNN(3, WASM_ZERO, WASM_ONE, WASM_I32V_1(44))});
1216 2 : ExpectFailure(&sig_iii_v, {WASM_RETURNN(2, WASM_ZERO, WASM_ONE)});
1217 1 : }
1218 :
1219 15189 : TEST_F(FunctionBodyDecoderTest, MultipleReturn_fallthru) {
1220 : static ValueType kIntTypes5[] = {kWasmI32, kWasmI32, kWasmI32, kWasmI32,
1221 : kWasmI32};
1222 1 : FunctionSig sig_ii_v(2, 0, kIntTypes5);
1223 :
1224 2 : ExpectValidates(&sig_ii_v, {WASM_ZERO, WASM_ONE});
1225 2 : ExpectFailure(&sig_ii_v, {WASM_ZERO});
1226 :
1227 1 : FunctionSig sig_iii_v(3, 0, kIntTypes5);
1228 2 : ExpectValidates(&sig_iii_v, {WASM_ZERO, WASM_ONE, WASM_I32V_1(44)});
1229 2 : ExpectFailure(&sig_iii_v, {WASM_ZERO, WASM_ONE});
1230 1 : }
1231 :
1232 15189 : TEST_F(FunctionBodyDecoderTest, MacrosInt32) {
1233 : ExpectValidates(sigs.i_i(),
1234 2 : {WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I32V_1(12))});
1235 : ExpectValidates(sigs.i_i(),
1236 2 : {WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I32V_1(13))});
1237 : ExpectValidates(sigs.i_i(),
1238 2 : {WASM_I32_MUL(WASM_GET_LOCAL(0), WASM_I32V_1(14))});
1239 : ExpectValidates(sigs.i_i(),
1240 2 : {WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I32V_1(15))});
1241 : ExpectValidates(sigs.i_i(),
1242 2 : {WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32V_1(16))});
1243 : ExpectValidates(sigs.i_i(),
1244 2 : {WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_I32V_1(17))});
1245 : ExpectValidates(sigs.i_i(),
1246 2 : {WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_I32V_1(18))});
1247 : ExpectValidates(sigs.i_i(),
1248 2 : {WASM_I32_AND(WASM_GET_LOCAL(0), WASM_I32V_1(19))});
1249 : ExpectValidates(sigs.i_i(),
1250 2 : {WASM_I32_IOR(WASM_GET_LOCAL(0), WASM_I32V_1(20))});
1251 : ExpectValidates(sigs.i_i(),
1252 2 : {WASM_I32_XOR(WASM_GET_LOCAL(0), WASM_I32V_1(21))});
1253 : ExpectValidates(sigs.i_i(),
1254 2 : {WASM_I32_SHL(WASM_GET_LOCAL(0), WASM_I32V_1(22))});
1255 : ExpectValidates(sigs.i_i(),
1256 2 : {WASM_I32_SHR(WASM_GET_LOCAL(0), WASM_I32V_1(23))});
1257 : ExpectValidates(sigs.i_i(),
1258 2 : {WASM_I32_SAR(WASM_GET_LOCAL(0), WASM_I32V_1(24))});
1259 : ExpectValidates(sigs.i_i(),
1260 2 : {WASM_I32_ROR(WASM_GET_LOCAL(0), WASM_I32V_1(24))});
1261 : ExpectValidates(sigs.i_i(),
1262 2 : {WASM_I32_ROL(WASM_GET_LOCAL(0), WASM_I32V_1(24))});
1263 : ExpectValidates(sigs.i_i(),
1264 2 : {WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(25))});
1265 : ExpectValidates(sigs.i_i(),
1266 2 : {WASM_I32_NE(WASM_GET_LOCAL(0), WASM_I32V_1(25))});
1267 :
1268 : ExpectValidates(sigs.i_i(),
1269 2 : {WASM_I32_LTS(WASM_GET_LOCAL(0), WASM_I32V_1(26))});
1270 : ExpectValidates(sigs.i_i(),
1271 2 : {WASM_I32_LES(WASM_GET_LOCAL(0), WASM_I32V_1(27))});
1272 : ExpectValidates(sigs.i_i(),
1273 2 : {WASM_I32_LTU(WASM_GET_LOCAL(0), WASM_I32V_1(28))});
1274 : ExpectValidates(sigs.i_i(),
1275 2 : {WASM_I32_LEU(WASM_GET_LOCAL(0), WASM_I32V_1(29))});
1276 :
1277 : ExpectValidates(sigs.i_i(),
1278 2 : {WASM_I32_GTS(WASM_GET_LOCAL(0), WASM_I32V_1(26))});
1279 : ExpectValidates(sigs.i_i(),
1280 2 : {WASM_I32_GES(WASM_GET_LOCAL(0), WASM_I32V_1(27))});
1281 : ExpectValidates(sigs.i_i(),
1282 2 : {WASM_I32_GTU(WASM_GET_LOCAL(0), WASM_I32V_1(28))});
1283 : ExpectValidates(sigs.i_i(),
1284 2 : {WASM_I32_GEU(WASM_GET_LOCAL(0), WASM_I32V_1(29))});
1285 1 : }
1286 :
1287 15189 : TEST_F(FunctionBodyDecoderTest, MacrosInt64) {
1288 : ExpectValidates(sigs.l_ll(),
1289 2 : {WASM_I64_ADD(WASM_GET_LOCAL(0), WASM_I64V_1(12))});
1290 : ExpectValidates(sigs.l_ll(),
1291 2 : {WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_I64V_1(13))});
1292 : ExpectValidates(sigs.l_ll(),
1293 2 : {WASM_I64_MUL(WASM_GET_LOCAL(0), WASM_I64V_1(14))});
1294 : ExpectValidates(sigs.l_ll(),
1295 2 : {WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_I64V_1(15))});
1296 : ExpectValidates(sigs.l_ll(),
1297 2 : {WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_I64V_1(16))});
1298 : ExpectValidates(sigs.l_ll(),
1299 2 : {WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_I64V_1(17))});
1300 : ExpectValidates(sigs.l_ll(),
1301 2 : {WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_I64V_1(18))});
1302 : ExpectValidates(sigs.l_ll(),
1303 2 : {WASM_I64_AND(WASM_GET_LOCAL(0), WASM_I64V_1(19))});
1304 : ExpectValidates(sigs.l_ll(),
1305 2 : {WASM_I64_IOR(WASM_GET_LOCAL(0), WASM_I64V_1(20))});
1306 : ExpectValidates(sigs.l_ll(),
1307 2 : {WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_I64V_1(21))});
1308 :
1309 : ExpectValidates(sigs.l_ll(),
1310 2 : {WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(22))});
1311 : ExpectValidates(sigs.l_ll(),
1312 2 : {WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(23))});
1313 : ExpectValidates(sigs.l_ll(),
1314 2 : {WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(24))});
1315 : ExpectValidates(sigs.l_ll(),
1316 2 : {WASM_I64_ROR(WASM_GET_LOCAL(0), WASM_I64V_1(24))});
1317 : ExpectValidates(sigs.l_ll(),
1318 2 : {WASM_I64_ROL(WASM_GET_LOCAL(0), WASM_I64V_1(24))});
1319 :
1320 : ExpectValidates(sigs.i_ll(),
1321 2 : {WASM_I64_LTS(WASM_GET_LOCAL(0), WASM_I64V_1(26))});
1322 : ExpectValidates(sigs.i_ll(),
1323 2 : {WASM_I64_LES(WASM_GET_LOCAL(0), WASM_I64V_1(27))});
1324 : ExpectValidates(sigs.i_ll(),
1325 2 : {WASM_I64_LTU(WASM_GET_LOCAL(0), WASM_I64V_1(28))});
1326 : ExpectValidates(sigs.i_ll(),
1327 2 : {WASM_I64_LEU(WASM_GET_LOCAL(0), WASM_I64V_1(29))});
1328 :
1329 : ExpectValidates(sigs.i_ll(),
1330 2 : {WASM_I64_GTS(WASM_GET_LOCAL(0), WASM_I64V_1(26))});
1331 : ExpectValidates(sigs.i_ll(),
1332 2 : {WASM_I64_GES(WASM_GET_LOCAL(0), WASM_I64V_1(27))});
1333 : ExpectValidates(sigs.i_ll(),
1334 2 : {WASM_I64_GTU(WASM_GET_LOCAL(0), WASM_I64V_1(28))});
1335 : ExpectValidates(sigs.i_ll(),
1336 2 : {WASM_I64_GEU(WASM_GET_LOCAL(0), WASM_I64V_1(29))});
1337 :
1338 : ExpectValidates(sigs.i_ll(),
1339 2 : {WASM_I64_EQ(WASM_GET_LOCAL(0), WASM_I64V_1(25))});
1340 : ExpectValidates(sigs.i_ll(),
1341 2 : {WASM_I64_NE(WASM_GET_LOCAL(0), WASM_I64V_1(25))});
1342 1 : }
1343 :
1344 15189 : TEST_F(FunctionBodyDecoderTest, AllSimpleExpressions) {
1345 1 : WASM_FEATURE_SCOPE(se);
1346 1 : WASM_FEATURE_SCOPE(anyref);
1347 : // Test all simple expressions which are described by a signature.
1348 : #define DECODE_TEST(name, opcode, sig) \
1349 : { \
1350 : FunctionSig* sig = WasmOpcodes::Signature(kExpr##name); \
1351 : if (sig->parameter_count() == 1) { \
1352 : TestUnop(kExpr##name, sig); \
1353 : } else { \
1354 : TestBinop(kExpr##name, sig); \
1355 : } \
1356 : }
1357 :
1358 77 : FOREACH_SIMPLE_OPCODE(DECODE_TEST);
1359 :
1360 : #undef DECODE_TEST
1361 1 : }
1362 :
1363 15189 : TEST_F(FunctionBodyDecoderTest, MemorySize) {
1364 1 : TestModuleBuilder builder;
1365 1 : module = builder.module();
1366 : builder.InitializeMemory();
1367 1 : byte code[] = {kExprMemorySize, 0};
1368 1 : ExpectValidates(sigs.i_i(), code);
1369 1 : ExpectFailure(sigs.f_ff(), code);
1370 1 : }
1371 :
1372 15189 : TEST_F(FunctionBodyDecoderTest, LoadMemOffset) {
1373 1 : TestModuleBuilder builder;
1374 1 : module = builder.module();
1375 : builder.InitializeMemory();
1376 20 : for (int offset = 0; offset < 128; offset += 7) {
1377 : byte code[] = {kExprI32Const, 0, kExprI32LoadMem, ZERO_ALIGNMENT,
1378 19 : static_cast<byte>(offset)};
1379 19 : ExpectValidates(sigs.i_i(), code);
1380 : }
1381 1 : }
1382 :
1383 15189 : TEST_F(FunctionBodyDecoderTest, LoadMemAlignment) {
1384 1 : TestModuleBuilder builder;
1385 1 : module = builder.module();
1386 : builder.InitializeMemory();
1387 : struct {
1388 : WasmOpcode instruction;
1389 : uint32_t maximum_aligment;
1390 : } values[] = {
1391 : {kExprI32LoadMem8U, 0}, // --
1392 : {kExprI32LoadMem8S, 0}, // --
1393 : {kExprI32LoadMem16U, 1}, // --
1394 : {kExprI32LoadMem16S, 1}, // --
1395 : {kExprI64LoadMem8U, 0}, // --
1396 : {kExprI64LoadMem8S, 0}, // --
1397 : {kExprI64LoadMem16U, 1}, // --
1398 : {kExprI64LoadMem16S, 1}, // --
1399 : {kExprI64LoadMem32U, 2}, // --
1400 : {kExprI64LoadMem32S, 2}, // --
1401 : {kExprI32LoadMem, 2}, // --
1402 : {kExprI64LoadMem, 3}, // --
1403 : {kExprF32LoadMem, 2}, // --
1404 : {kExprF64LoadMem, 3}, // --
1405 1 : };
1406 :
1407 15 : for (size_t i = 0; i < arraysize(values); i++) {
1408 70 : for (byte alignment = 0; alignment <= 4; alignment++) {
1409 : byte code[] = {WASM_ZERO, static_cast<byte>(values[i].instruction),
1410 70 : alignment, ZERO_OFFSET, WASM_DROP};
1411 70 : Validate(alignment <= values[i].maximum_aligment, sigs.v_i(), code);
1412 : }
1413 : }
1414 1 : }
1415 :
1416 15189 : TEST_F(FunctionBodyDecoderTest, StoreMemOffset) {
1417 1 : TestModuleBuilder builder;
1418 1 : module = builder.module();
1419 : builder.InitializeMemory();
1420 20 : for (byte offset = 0; offset < 128; offset += 7) {
1421 19 : byte code[] = {WASM_STORE_MEM_OFFSET(MachineType::Int32(), offset,
1422 38 : WASM_ZERO, WASM_ZERO)};
1423 19 : ExpectValidates(sigs.v_i(), code);
1424 : }
1425 1 : }
1426 :
1427 15189 : TEST_F(FunctionBodyDecoderTest, StoreMemOffset_void) {
1428 1 : TestModuleBuilder builder;
1429 1 : module = builder.module();
1430 : builder.InitializeMemory();
1431 1 : ExpectFailure(sigs.i_i(), {WASM_STORE_MEM_OFFSET(MachineType::Int32(), 0,
1432 3 : WASM_ZERO, WASM_ZERO)});
1433 1 : }
1434 :
1435 : #define BYTE0(x) ((x)&0x7F)
1436 : #define BYTE1(x) ((x >> 7) & 0x7F)
1437 : #define BYTE2(x) ((x >> 14) & 0x7F)
1438 : #define BYTE3(x) ((x >> 21) & 0x7F)
1439 :
1440 : #define VARINT1(x) BYTE0(x)
1441 : #define VARINT2(x) BYTE0(x) | 0x80, BYTE1(x)
1442 : #define VARINT3(x) BYTE0(x) | 0x80, BYTE1(x) | 0x80, BYTE2(x)
1443 : #define VARINT4(x) BYTE0(x) | 0x80, BYTE1(x) | 0x80, BYTE2(x) | 0x80, BYTE3(x)
1444 :
1445 15189 : TEST_F(FunctionBodyDecoderTest, LoadMemOffset_varint) {
1446 1 : TestModuleBuilder builder;
1447 1 : module = builder.module();
1448 : builder.InitializeMemory();
1449 : ExpectValidates(sigs.i_i(),
1450 2 : {WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT, VARINT1(0x45)});
1451 : ExpectValidates(sigs.i_i(), {WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT,
1452 2 : VARINT2(0x3999)});
1453 : ExpectValidates(sigs.i_i(), {WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT,
1454 2 : VARINT3(0x344445)});
1455 : ExpectValidates(sigs.i_i(), {WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT,
1456 2 : VARINT4(0x36666667)});
1457 1 : }
1458 :
1459 15189 : TEST_F(FunctionBodyDecoderTest, StoreMemOffset_varint) {
1460 1 : TestModuleBuilder builder;
1461 1 : module = builder.module();
1462 : builder.InitializeMemory();
1463 : ExpectValidates(sigs.v_i(), {WASM_ZERO, WASM_ZERO, kExprI32StoreMem,
1464 2 : ZERO_ALIGNMENT, VARINT1(0x33)});
1465 : ExpectValidates(sigs.v_i(), {WASM_ZERO, WASM_ZERO, kExprI32StoreMem,
1466 2 : ZERO_ALIGNMENT, VARINT2(0x1111)});
1467 : ExpectValidates(sigs.v_i(), {WASM_ZERO, WASM_ZERO, kExprI32StoreMem,
1468 2 : ZERO_ALIGNMENT, VARINT3(0x222222)});
1469 : ExpectValidates(sigs.v_i(), {WASM_ZERO, WASM_ZERO, kExprI32StoreMem,
1470 2 : ZERO_ALIGNMENT, VARINT4(0x44444444)});
1471 1 : }
1472 :
1473 : #undef BYTE0
1474 : #undef BYTE1
1475 : #undef BYTE2
1476 : #undef BYTE3
1477 :
1478 : #undef VARINT1
1479 : #undef VARINT2
1480 : #undef VARINT3
1481 : #undef VARINT4
1482 :
1483 15189 : TEST_F(FunctionBodyDecoderTest, AllLoadMemCombinations) {
1484 1 : TestModuleBuilder builder;
1485 1 : module = builder.module();
1486 : builder.InitializeMemory();
1487 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1488 5 : ValueType local_type = kValueTypes[i];
1489 55 : for (size_t j = 0; j < arraysize(machineTypes); j++) {
1490 50 : MachineType mem_type = machineTypes[j];
1491 50 : byte code[] = {WASM_LOAD_MEM(mem_type, WASM_ZERO)};
1492 : FunctionSig sig(1, 0, &local_type);
1493 50 : Validate(local_type == ValueTypes::ValueTypeFor(mem_type), &sig, code);
1494 : }
1495 : }
1496 1 : }
1497 :
1498 15189 : TEST_F(FunctionBodyDecoderTest, AllStoreMemCombinations) {
1499 1 : TestModuleBuilder builder;
1500 1 : module = builder.module();
1501 : builder.InitializeMemory();
1502 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1503 5 : ValueType local_type = kValueTypes[i];
1504 55 : for (size_t j = 0; j < arraysize(machineTypes); j++) {
1505 50 : MachineType mem_type = machineTypes[j];
1506 50 : byte code[] = {WASM_STORE_MEM(mem_type, WASM_ZERO, WASM_GET_LOCAL(0))};
1507 : FunctionSig sig(0, 1, &local_type);
1508 50 : Validate(local_type == ValueTypes::ValueTypeFor(mem_type), &sig, code);
1509 : }
1510 : }
1511 1 : }
1512 :
1513 15189 : TEST_F(FunctionBodyDecoderTest, SimpleCalls) {
1514 1 : FunctionSig* sig = sigs.i_i();
1515 1 : TestModuleBuilder builder;
1516 1 : module = builder.module();
1517 :
1518 1 : builder.AddFunction(sigs.i_v());
1519 1 : builder.AddFunction(sigs.i_i());
1520 1 : builder.AddFunction(sigs.i_ii());
1521 :
1522 2 : ExpectValidates(sig, {WASM_CALL_FUNCTION0(0)});
1523 2 : ExpectValidates(sig, {WASM_CALL_FUNCTION(1, WASM_I32V_1(27))});
1524 : ExpectValidates(sig,
1525 2 : {WASM_CALL_FUNCTION(2, WASM_I32V_1(37), WASM_I32V_2(77))});
1526 1 : }
1527 :
1528 15189 : TEST_F(FunctionBodyDecoderTest, CallsWithTooFewArguments) {
1529 1 : FunctionSig* sig = sigs.i_i();
1530 1 : TestModuleBuilder builder;
1531 1 : module = builder.module();
1532 :
1533 1 : builder.AddFunction(sigs.i_i());
1534 1 : builder.AddFunction(sigs.i_ii());
1535 1 : builder.AddFunction(sigs.f_ff());
1536 :
1537 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION0(0)});
1538 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(1, WASM_ZERO)});
1539 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(2, WASM_GET_LOCAL(0))});
1540 1 : }
1541 :
1542 15189 : TEST_F(FunctionBodyDecoderTest, CallsWithMismatchedSigs2) {
1543 1 : FunctionSig* sig = sigs.i_i();
1544 1 : TestModuleBuilder builder;
1545 1 : module = builder.module();
1546 :
1547 1 : builder.AddFunction(sigs.i_i());
1548 :
1549 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(0, WASM_I64V_1(17))});
1550 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(0, WASM_F32(17.1))});
1551 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(0, WASM_F64(17.1))});
1552 1 : }
1553 :
1554 15189 : TEST_F(FunctionBodyDecoderTest, CallsWithMismatchedSigs3) {
1555 1 : FunctionSig* sig = sigs.i_i();
1556 1 : TestModuleBuilder builder;
1557 1 : module = builder.module();
1558 :
1559 1 : builder.AddFunction(sigs.i_f());
1560 :
1561 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(0, WASM_I32V_1(17))});
1562 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(0, WASM_I64V_1(27))});
1563 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(0, WASM_F64(37.2))});
1564 :
1565 1 : builder.AddFunction(sigs.i_d());
1566 :
1567 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(1, WASM_I32V_1(16))});
1568 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(1, WASM_I64V_1(16))});
1569 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(1, WASM_F32(17.6))});
1570 1 : }
1571 :
1572 15189 : TEST_F(FunctionBodyDecoderTest, SimpleReturnCalls) {
1573 1 : WASM_FEATURE_SCOPE(return_call);
1574 :
1575 1 : FunctionSig* sig = sigs.i_i();
1576 1 : TestModuleBuilder builder;
1577 1 : module = builder.module();
1578 :
1579 1 : builder.AddFunction(sigs.i_v());
1580 1 : builder.AddFunction(sigs.i_i());
1581 1 : builder.AddFunction(sigs.i_ii());
1582 :
1583 2 : ExpectValidates(sig, {WASM_RETURN_CALL_FUNCTION0(0)});
1584 2 : ExpectValidates(sig, {WASM_RETURN_CALL_FUNCTION(1, WASM_I32V_1(27))});
1585 : ExpectValidates(
1586 2 : sig, {WASM_RETURN_CALL_FUNCTION(2, WASM_I32V_1(37), WASM_I32V_2(77))});
1587 1 : }
1588 :
1589 15189 : TEST_F(FunctionBodyDecoderTest, ReturnCallsWithTooFewArguments) {
1590 1 : WASM_FEATURE_SCOPE(return_call);
1591 :
1592 1 : FunctionSig* sig = sigs.i_i();
1593 1 : TestModuleBuilder builder;
1594 1 : module = builder.module();
1595 :
1596 1 : builder.AddFunction(sigs.i_i());
1597 1 : builder.AddFunction(sigs.i_ii());
1598 1 : builder.AddFunction(sigs.f_ff());
1599 :
1600 2 : ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION0(0)});
1601 2 : ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION(1, WASM_ZERO)});
1602 2 : ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION(2, WASM_GET_LOCAL(0))});
1603 1 : }
1604 :
1605 15189 : TEST_F(FunctionBodyDecoderTest, ReturnCallsWithMismatchedSigs) {
1606 1 : WASM_FEATURE_SCOPE(return_call);
1607 :
1608 1 : FunctionSig* sig = sigs.i_i();
1609 1 : TestModuleBuilder builder;
1610 1 : module = builder.module();
1611 :
1612 1 : builder.AddFunction(sigs.i_f());
1613 1 : builder.AddFunction(sigs.f_f());
1614 :
1615 2 : ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION(0, WASM_I32V_1(17))});
1616 2 : ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION(0, WASM_I64V_1(27))});
1617 2 : ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION(0, WASM_F64(37.2))});
1618 :
1619 2 : ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION(1, WASM_F64(37.2))});
1620 2 : ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION(1, WASM_F32(37.2))});
1621 2 : ExpectFailure(sig, {WASM_RETURN_CALL_FUNCTION(1, WASM_I32V_1(17))});
1622 1 : }
1623 :
1624 15189 : TEST_F(FunctionBodyDecoderTest, SimpleIndirectReturnCalls) {
1625 1 : WASM_FEATURE_SCOPE(return_call);
1626 :
1627 1 : FunctionSig* sig = sigs.i_i();
1628 1 : TestModuleBuilder builder;
1629 : builder.InitializeTable();
1630 1 : module = builder.module();
1631 :
1632 1 : byte f0 = builder.AddSignature(sigs.i_v());
1633 1 : byte f1 = builder.AddSignature(sigs.i_i());
1634 1 : byte f2 = builder.AddSignature(sigs.i_ii());
1635 :
1636 2 : ExpectValidates(sig, {WASM_RETURN_CALL_INDIRECT0(f0, WASM_ZERO)});
1637 : ExpectValidates(sig,
1638 2 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_I32V_1(22))});
1639 : ExpectValidates(sig, {WASM_RETURN_CALL_INDIRECT(
1640 2 : f2, WASM_ZERO, WASM_I32V_1(32), WASM_I32V_2(72))});
1641 1 : }
1642 :
1643 15189 : TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsOutOfBounds) {
1644 1 : WASM_FEATURE_SCOPE(return_call);
1645 :
1646 1 : FunctionSig* sig = sigs.i_i();
1647 1 : TestModuleBuilder builder;
1648 : builder.InitializeTable();
1649 1 : module = builder.module();
1650 :
1651 2 : ExpectFailure(sig, {WASM_RETURN_CALL_INDIRECT0(0, WASM_ZERO)});
1652 1 : builder.AddSignature(sigs.i_v());
1653 2 : ExpectValidates(sig, {WASM_RETURN_CALL_INDIRECT0(0, WASM_ZERO)});
1654 :
1655 : ExpectFailure(sig,
1656 2 : {WASM_RETURN_CALL_INDIRECT(1, WASM_ZERO, WASM_I32V_1(22))});
1657 1 : builder.AddSignature(sigs.i_i());
1658 : ExpectValidates(sig,
1659 2 : {WASM_RETURN_CALL_INDIRECT(1, WASM_ZERO, WASM_I32V_1(27))});
1660 :
1661 : ExpectFailure(sig,
1662 2 : {WASM_RETURN_CALL_INDIRECT(2, WASM_ZERO, WASM_I32V_1(27))});
1663 1 : }
1664 :
1665 15189 : TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsWithMismatchedSigs3) {
1666 1 : WASM_FEATURE_SCOPE(return_call);
1667 :
1668 1 : FunctionSig* sig = sigs.i_i();
1669 1 : TestModuleBuilder builder;
1670 : builder.InitializeTable();
1671 1 : module = builder.module();
1672 :
1673 1 : byte f0 = builder.AddFunction(sigs.i_f());
1674 :
1675 : ExpectFailure(sig,
1676 2 : {WASM_RETURN_CALL_INDIRECT(f0, WASM_ZERO, WASM_I32V_1(17))});
1677 : ExpectFailure(sig,
1678 2 : {WASM_RETURN_CALL_INDIRECT(f0, WASM_ZERO, WASM_I64V_1(27))});
1679 : ExpectFailure(sig,
1680 2 : {WASM_RETURN_CALL_INDIRECT(f0, WASM_ZERO, WASM_F64(37.2))});
1681 :
1682 2 : ExpectFailure(sig, {WASM_RETURN_CALL_INDIRECT0(f0, WASM_I32V_1(17))});
1683 2 : ExpectFailure(sig, {WASM_RETURN_CALL_INDIRECT0(f0, WASM_I64V_1(27))});
1684 2 : ExpectFailure(sig, {WASM_RETURN_CALL_INDIRECT0(f0, WASM_F64(37.2))});
1685 :
1686 1 : byte f1 = builder.AddFunction(sigs.i_d());
1687 :
1688 : ExpectFailure(sig,
1689 2 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_I32V_1(16))});
1690 : ExpectFailure(sig,
1691 2 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_I64V_1(16))});
1692 : ExpectFailure(sig,
1693 2 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_F32(17.6))});
1694 1 : }
1695 :
1696 15189 : TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsWithoutTableCrash) {
1697 1 : WASM_FEATURE_SCOPE(return_call);
1698 :
1699 1 : FunctionSig* sig = sigs.i_i();
1700 1 : TestModuleBuilder builder;
1701 1 : module = builder.module();
1702 :
1703 1 : byte f0 = builder.AddSignature(sigs.i_v());
1704 1 : byte f1 = builder.AddSignature(sigs.i_i());
1705 1 : byte f2 = builder.AddSignature(sigs.i_ii());
1706 :
1707 2 : ExpectFailure(sig, {WASM_RETURN_CALL_INDIRECT0(f0, WASM_ZERO)});
1708 : ExpectFailure(sig,
1709 2 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_I32V_1(22))});
1710 : ExpectFailure(sig, {WASM_RETURN_CALL_INDIRECT(f2, WASM_ZERO, WASM_I32V_1(32),
1711 2 : WASM_I32V_2(72))});
1712 1 : }
1713 :
1714 15189 : TEST_F(FunctionBodyDecoderTest, IncompleteIndirectReturnCall) {
1715 1 : FunctionSig* sig = sigs.i_i();
1716 1 : TestModuleBuilder builder;
1717 : builder.InitializeTable();
1718 1 : module = builder.module();
1719 :
1720 : static byte code[] = {kExprReturnCallIndirect};
1721 2 : ExpectFailure(sig, ArrayVector(code), kOmitEnd);
1722 1 : }
1723 :
1724 15189 : TEST_F(FunctionBodyDecoderTest, MultiReturn) {
1725 1 : WASM_FEATURE_SCOPE(mv);
1726 1 : ValueType storage[] = {kWasmI32, kWasmI32};
1727 : FunctionSig sig_ii_v(2, 0, storage);
1728 : FunctionSig sig_v_ii(0, 2, storage);
1729 1 : TestModuleBuilder builder;
1730 1 : module = builder.module();
1731 :
1732 1 : builder.AddFunction(&sig_v_ii);
1733 1 : builder.AddFunction(&sig_ii_v);
1734 :
1735 2 : ExpectValidates(&sig_ii_v, {WASM_CALL_FUNCTION0(1)});
1736 2 : ExpectValidates(sigs.v_v(), {WASM_CALL_FUNCTION0(1), WASM_DROP, WASM_DROP});
1737 2 : ExpectValidates(sigs.v_v(), {WASM_CALL_FUNCTION0(1), kExprCallFunction, 0});
1738 1 : }
1739 :
1740 15189 : TEST_F(FunctionBodyDecoderTest, MultiReturnType) {
1741 1 : WASM_FEATURE_SCOPE(mv);
1742 6 : for (size_t a = 0; a < arraysize(kValueTypes); a++) {
1743 25 : for (size_t b = 0; b < arraysize(kValueTypes); b++) {
1744 125 : for (size_t c = 0; c < arraysize(kValueTypes); c++) {
1745 625 : for (size_t d = 0; d < arraysize(kValueTypes); d++) {
1746 625 : ValueType storage_ab[] = {kValueTypes[a], kValueTypes[b]};
1747 : FunctionSig sig_ab_v(2, 0, storage_ab);
1748 625 : ValueType storage_cd[] = {kValueTypes[c], kValueTypes[d]};
1749 : FunctionSig sig_cd_v(2, 0, storage_cd);
1750 :
1751 625 : TestModuleBuilder builder;
1752 625 : module = builder.module();
1753 625 : builder.AddFunction(&sig_cd_v);
1754 :
1755 1250 : ExpectValidates(&sig_cd_v, {WASM_CALL_FUNCTION0(0)});
1756 :
1757 625 : if (a == c && b == d) {
1758 50 : ExpectValidates(&sig_ab_v, {WASM_CALL_FUNCTION0(0)});
1759 : } else {
1760 1200 : ExpectFailure(&sig_ab_v, {WASM_CALL_FUNCTION0(0)});
1761 : }
1762 : }
1763 : }
1764 : }
1765 : }
1766 1 : }
1767 :
1768 15189 : TEST_F(FunctionBodyDecoderTest, SimpleIndirectCalls) {
1769 1 : FunctionSig* sig = sigs.i_i();
1770 1 : TestModuleBuilder builder;
1771 : builder.InitializeTable();
1772 1 : module = builder.module();
1773 :
1774 1 : byte f0 = builder.AddSignature(sigs.i_v());
1775 1 : byte f1 = builder.AddSignature(sigs.i_i());
1776 1 : byte f2 = builder.AddSignature(sigs.i_ii());
1777 :
1778 2 : ExpectValidates(sig, {WASM_CALL_INDIRECT0(f0, WASM_ZERO)});
1779 2 : ExpectValidates(sig, {WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_I32V_1(22))});
1780 : ExpectValidates(sig, {WASM_CALL_INDIRECT2(f2, WASM_ZERO, WASM_I32V_1(32),
1781 2 : WASM_I32V_2(72))});
1782 1 : }
1783 :
1784 15189 : TEST_F(FunctionBodyDecoderTest, IndirectCallsOutOfBounds) {
1785 1 : FunctionSig* sig = sigs.i_i();
1786 1 : TestModuleBuilder builder;
1787 : builder.InitializeTable();
1788 1 : module = builder.module();
1789 :
1790 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT0(0, WASM_ZERO)});
1791 1 : builder.AddSignature(sigs.i_v());
1792 2 : ExpectValidates(sig, {WASM_CALL_INDIRECT0(0, WASM_ZERO)});
1793 :
1794 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT1(1, WASM_ZERO, WASM_I32V_1(22))});
1795 1 : builder.AddSignature(sigs.i_i());
1796 2 : ExpectValidates(sig, {WASM_CALL_INDIRECT1(1, WASM_ZERO, WASM_I32V_1(27))});
1797 :
1798 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT1(2, WASM_ZERO, WASM_I32V_1(27))});
1799 1 : }
1800 :
1801 15189 : TEST_F(FunctionBodyDecoderTest, IndirectCallsWithMismatchedSigs3) {
1802 1 : FunctionSig* sig = sigs.i_i();
1803 1 : TestModuleBuilder builder;
1804 : builder.InitializeTable();
1805 1 : module = builder.module();
1806 :
1807 1 : byte f0 = builder.AddFunction(sigs.i_f());
1808 :
1809 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT1(f0, WASM_ZERO, WASM_I32V_1(17))});
1810 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT1(f0, WASM_ZERO, WASM_I64V_1(27))});
1811 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT1(f0, WASM_ZERO, WASM_F64(37.2))});
1812 :
1813 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT0(f0, WASM_I32V_1(17))});
1814 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT0(f0, WASM_I64V_1(27))});
1815 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT0(f0, WASM_F64(37.2))});
1816 :
1817 1 : byte f1 = builder.AddFunction(sigs.i_d());
1818 :
1819 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_I32V_1(16))});
1820 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_I64V_1(16))});
1821 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_F32(17.6))});
1822 1 : }
1823 :
1824 15189 : TEST_F(FunctionBodyDecoderTest, IndirectCallsWithoutTableCrash) {
1825 1 : FunctionSig* sig = sigs.i_i();
1826 1 : TestModuleBuilder builder;
1827 1 : module = builder.module();
1828 :
1829 1 : byte f0 = builder.AddSignature(sigs.i_v());
1830 1 : byte f1 = builder.AddSignature(sigs.i_i());
1831 1 : byte f2 = builder.AddSignature(sigs.i_ii());
1832 :
1833 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT0(f0, WASM_ZERO)});
1834 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT1(f1, WASM_ZERO, WASM_I32V_1(22))});
1835 : ExpectFailure(sig, {WASM_CALL_INDIRECT2(f2, WASM_ZERO, WASM_I32V_1(32),
1836 2 : WASM_I32V_2(72))});
1837 1 : }
1838 :
1839 15189 : TEST_F(FunctionBodyDecoderTest, IncompleteIndirectCall) {
1840 1 : FunctionSig* sig = sigs.i_i();
1841 1 : TestModuleBuilder builder;
1842 : builder.InitializeTable();
1843 1 : module = builder.module();
1844 :
1845 : static byte code[] = {kExprCallIndirect};
1846 2 : ExpectFailure(sig, ArrayVector(code), kOmitEnd);
1847 1 : }
1848 :
1849 15189 : TEST_F(FunctionBodyDecoderTest, IncompleteStore) {
1850 1 : FunctionSig* sig = sigs.i_i();
1851 1 : TestModuleBuilder builder;
1852 : builder.InitializeMemory();
1853 : builder.InitializeTable();
1854 1 : module = builder.module();
1855 :
1856 : static byte code[] = {kExprI32StoreMem};
1857 2 : ExpectFailure(sig, ArrayVector(code), kOmitEnd);
1858 1 : }
1859 :
1860 15189 : TEST_F(FunctionBodyDecoderTest, IncompleteS8x16Shuffle) {
1861 1 : WASM_FEATURE_SCOPE(simd);
1862 1 : FunctionSig* sig = sigs.i_i();
1863 1 : TestModuleBuilder builder;
1864 : builder.InitializeMemory();
1865 : builder.InitializeTable();
1866 1 : module = builder.module();
1867 :
1868 : static byte code[] = {kSimdPrefix,
1869 : static_cast<byte>(kExprS8x16Shuffle & 0xff)};
1870 2 : ExpectFailure(sig, ArrayVector(code), kOmitEnd);
1871 1 : }
1872 :
1873 15189 : TEST_F(FunctionBodyDecoderTest, SimpleImportCalls) {
1874 1 : FunctionSig* sig = sigs.i_i();
1875 1 : TestModuleBuilder builder;
1876 1 : module = builder.module();
1877 :
1878 1 : byte f0 = builder.AddImport(sigs.i_v());
1879 : byte f1 = builder.AddImport(sigs.i_i());
1880 1 : byte f2 = builder.AddImport(sigs.i_ii());
1881 :
1882 2 : ExpectValidates(sig, {WASM_CALL_FUNCTION0(f0)});
1883 2 : ExpectValidates(sig, {WASM_CALL_FUNCTION(f1, WASM_I32V_1(22))});
1884 : ExpectValidates(sig,
1885 2 : {WASM_CALL_FUNCTION(f2, WASM_I32V_1(32), WASM_I32V_2(72))});
1886 1 : }
1887 :
1888 15189 : TEST_F(FunctionBodyDecoderTest, ImportCallsWithMismatchedSigs3) {
1889 1 : FunctionSig* sig = sigs.i_i();
1890 1 : TestModuleBuilder builder;
1891 1 : module = builder.module();
1892 :
1893 1 : byte f0 = builder.AddImport(sigs.i_f());
1894 :
1895 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION0(f0)});
1896 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(f0, WASM_I32V_1(17))});
1897 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(f0, WASM_I64V_1(27))});
1898 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(f0, WASM_F64(37.2))});
1899 :
1900 1 : byte f1 = builder.AddImport(sigs.i_d());
1901 :
1902 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION0(f1)});
1903 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(f1, WASM_I32V_1(16))});
1904 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(f1, WASM_I64V_1(16))});
1905 2 : ExpectFailure(sig, {WASM_CALL_FUNCTION(f1, WASM_F32(17.6))});
1906 1 : }
1907 :
1908 15189 : TEST_F(FunctionBodyDecoderTest, Int32Globals) {
1909 1 : FunctionSig* sig = sigs.i_i();
1910 1 : TestModuleBuilder builder;
1911 1 : module = builder.module();
1912 :
1913 1 : builder.AddGlobal(kWasmI32);
1914 :
1915 2 : ExpectValidates(sig, {WASM_GET_GLOBAL(0)});
1916 2 : ExpectFailure(sig, {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0))});
1917 2 : ExpectValidates(sig, {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_ZERO});
1918 1 : }
1919 :
1920 15189 : TEST_F(FunctionBodyDecoderTest, ImmutableGlobal) {
1921 1 : FunctionSig* sig = sigs.v_v();
1922 1 : TestModuleBuilder builder;
1923 1 : module = builder.module();
1924 :
1925 1 : uint32_t g0 = builder.AddGlobal(kWasmI32, true);
1926 1 : uint32_t g1 = builder.AddGlobal(kWasmI32, false);
1927 :
1928 2 : ExpectValidates(sig, {WASM_SET_GLOBAL(g0, WASM_ZERO)});
1929 2 : ExpectFailure(sig, {WASM_SET_GLOBAL(g1, WASM_ZERO)});
1930 1 : }
1931 :
1932 15189 : TEST_F(FunctionBodyDecoderTest, Int32Globals_fail) {
1933 1 : FunctionSig* sig = sigs.i_i();
1934 1 : TestModuleBuilder builder;
1935 1 : module = builder.module();
1936 :
1937 1 : builder.AddGlobal(kWasmI64);
1938 1 : builder.AddGlobal(kWasmI64);
1939 1 : builder.AddGlobal(kWasmF32);
1940 1 : builder.AddGlobal(kWasmF64);
1941 :
1942 2 : ExpectFailure(sig, {WASM_GET_GLOBAL(0)});
1943 2 : ExpectFailure(sig, {WASM_GET_GLOBAL(1)});
1944 2 : ExpectFailure(sig, {WASM_GET_GLOBAL(2)});
1945 2 : ExpectFailure(sig, {WASM_GET_GLOBAL(3)});
1946 :
1947 2 : ExpectFailure(sig, {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_ZERO});
1948 2 : ExpectFailure(sig, {WASM_SET_GLOBAL(1, WASM_GET_LOCAL(0)), WASM_ZERO});
1949 2 : ExpectFailure(sig, {WASM_SET_GLOBAL(2, WASM_GET_LOCAL(0)), WASM_ZERO});
1950 2 : ExpectFailure(sig, {WASM_SET_GLOBAL(3, WASM_GET_LOCAL(0)), WASM_ZERO});
1951 1 : }
1952 :
1953 15189 : TEST_F(FunctionBodyDecoderTest, Int64Globals) {
1954 1 : FunctionSig* sig = sigs.l_l();
1955 1 : TestModuleBuilder builder;
1956 1 : module = builder.module();
1957 :
1958 1 : builder.AddGlobal(kWasmI64);
1959 1 : builder.AddGlobal(kWasmI64);
1960 :
1961 2 : ExpectValidates(sig, {WASM_GET_GLOBAL(0)});
1962 2 : ExpectValidates(sig, {WASM_GET_GLOBAL(1)});
1963 :
1964 : ExpectValidates(sig,
1965 2 : {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_GET_LOCAL(0)});
1966 : ExpectValidates(sig,
1967 2 : {WASM_SET_GLOBAL(1, WASM_GET_LOCAL(0)), WASM_GET_LOCAL(0)});
1968 1 : }
1969 :
1970 15189 : TEST_F(FunctionBodyDecoderTest, Float32Globals) {
1971 1 : FunctionSig* sig = sigs.f_ff();
1972 1 : TestModuleBuilder builder;
1973 1 : module = builder.module();
1974 :
1975 1 : builder.AddGlobal(kWasmF32);
1976 :
1977 2 : ExpectValidates(sig, {WASM_GET_GLOBAL(0)});
1978 : ExpectValidates(sig,
1979 2 : {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_GET_LOCAL(0)});
1980 1 : }
1981 :
1982 15189 : TEST_F(FunctionBodyDecoderTest, Float64Globals) {
1983 1 : FunctionSig* sig = sigs.d_dd();
1984 1 : TestModuleBuilder builder;
1985 1 : module = builder.module();
1986 :
1987 1 : builder.AddGlobal(kWasmF64);
1988 :
1989 2 : ExpectValidates(sig, {WASM_GET_GLOBAL(0)});
1990 : ExpectValidates(sig,
1991 2 : {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_GET_LOCAL(0)});
1992 1 : }
1993 :
1994 15189 : TEST_F(FunctionBodyDecoderTest, AllGetGlobalCombinations) {
1995 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1996 5 : ValueType local_type = kValueTypes[i];
1997 30 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
1998 25 : ValueType global_type = kValueTypes[j];
1999 : FunctionSig sig(1, 0, &local_type);
2000 25 : TestModuleBuilder builder;
2001 25 : module = builder.module();
2002 25 : builder.AddGlobal(global_type);
2003 25 : Validate(local_type == global_type, &sig, {WASM_GET_GLOBAL(0)});
2004 : }
2005 : }
2006 1 : }
2007 :
2008 15189 : TEST_F(FunctionBodyDecoderTest, AllSetGlobalCombinations) {
2009 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2010 5 : ValueType local_type = kValueTypes[i];
2011 30 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2012 25 : ValueType global_type = kValueTypes[j];
2013 : FunctionSig sig(0, 1, &local_type);
2014 25 : TestModuleBuilder builder;
2015 25 : module = builder.module();
2016 25 : builder.AddGlobal(global_type);
2017 : Validate(local_type == global_type, &sig,
2018 25 : {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0))});
2019 : }
2020 : }
2021 1 : }
2022 :
2023 15189 : TEST_F(FunctionBodyDecoderTest, SetTable) {
2024 1 : WASM_FEATURE_SCOPE(anyref);
2025 1 : TestModuleBuilder builder;
2026 1 : module = builder.module();
2027 1 : byte tab_ref1 = builder.AddTable(kWasmAnyRef, 10, true, 20);
2028 1 : byte tab_func1 = builder.AddTable(kWasmAnyFunc, 20, true, 30);
2029 1 : byte tab_func2 = builder.AddTable(kWasmAnyFunc, 10, false, 20);
2030 1 : byte tab_ref2 = builder.AddTable(kWasmAnyRef, 10, false, 20);
2031 1 : ValueType sig_types[]{kWasmAnyRef, kWasmAnyFunc, kWasmI32};
2032 : FunctionSig sig(0, 3, sig_types);
2033 : byte local_ref = 0;
2034 : byte local_func = 1;
2035 : byte local_int = 2;
2036 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_ref1, WASM_I32V(6),
2037 2 : WASM_GET_LOCAL(local_ref))});
2038 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_func1, WASM_I32V(5),
2039 2 : WASM_GET_LOCAL(local_func))});
2040 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_func2, WASM_I32V(7),
2041 2 : WASM_GET_LOCAL(local_func))});
2042 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_ref2, WASM_I32V(8),
2043 2 : WASM_GET_LOCAL(local_ref))});
2044 :
2045 : // We can store anyfunc values as anyref, but not the other way around.
2046 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_ref1, WASM_I32V(4),
2047 2 : WASM_GET_LOCAL(local_func))});
2048 : ExpectFailure(&sig, {WASM_SET_TABLE(tab_func1, WASM_I32V(9),
2049 2 : WASM_GET_LOCAL(local_ref))});
2050 : ExpectFailure(&sig, {WASM_SET_TABLE(tab_func2, WASM_I32V(3),
2051 2 : WASM_GET_LOCAL(local_ref))});
2052 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_ref2, WASM_I32V(2),
2053 2 : WASM_GET_LOCAL(local_func))});
2054 : ExpectFailure(&sig, {WASM_SET_TABLE(tab_ref1, WASM_I32V(9),
2055 2 : WASM_GET_LOCAL(local_int))});
2056 : ExpectFailure(&sig, {WASM_SET_TABLE(tab_func1, WASM_I32V(3),
2057 2 : WASM_GET_LOCAL(local_int))});
2058 : // Out-of-bounds table index should fail.
2059 : byte oob_tab = 37;
2060 : ExpectFailure(
2061 2 : &sig, {WASM_SET_TABLE(oob_tab, WASM_I32V(9), WASM_GET_LOCAL(local_ref))});
2062 : ExpectFailure(&sig, {WASM_SET_TABLE(oob_tab, WASM_I32V(3),
2063 2 : WASM_GET_LOCAL(local_func))});
2064 1 : }
2065 :
2066 15189 : TEST_F(FunctionBodyDecoderTest, GetTable) {
2067 1 : WASM_FEATURE_SCOPE(anyref);
2068 1 : TestModuleBuilder builder;
2069 1 : module = builder.module();
2070 1 : byte tab_ref1 = builder.AddTable(kWasmAnyRef, 10, true, 20);
2071 1 : byte tab_func1 = builder.AddTable(kWasmAnyFunc, 20, true, 30);
2072 1 : byte tab_func2 = builder.AddTable(kWasmAnyFunc, 10, false, 20);
2073 1 : byte tab_ref2 = builder.AddTable(kWasmAnyRef, 10, false, 20);
2074 1 : ValueType sig_types[]{kWasmAnyRef, kWasmAnyFunc, kWasmI32};
2075 : FunctionSig sig(0, 3, sig_types);
2076 : byte local_ref = 0;
2077 : byte local_func = 1;
2078 : byte local_int = 2;
2079 : ExpectValidates(
2080 : &sig,
2081 2 : {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(tab_ref1, WASM_I32V(6)))});
2082 : ExpectValidates(
2083 : &sig,
2084 2 : {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(tab_ref2, WASM_I32V(8)))});
2085 : ExpectValidates(
2086 : &sig,
2087 2 : {WASM_SET_LOCAL(local_func, WASM_GET_TABLE(tab_func1, WASM_I32V(5)))});
2088 : ExpectValidates(
2089 : &sig,
2090 2 : {WASM_SET_LOCAL(local_func, WASM_GET_TABLE(tab_func2, WASM_I32V(7)))});
2091 :
2092 : // We can store anyfunc values as anyref, but not the other way around.
2093 : ExpectFailure(&sig, {WASM_SET_LOCAL(local_func,
2094 2 : WASM_GET_TABLE(tab_ref1, WASM_I32V(4)))});
2095 : ExpectValidates(
2096 : &sig,
2097 2 : {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(tab_func1, WASM_I32V(9)))});
2098 : ExpectValidates(
2099 : &sig,
2100 2 : {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(tab_func2, WASM_I32V(3)))});
2101 : ExpectFailure(&sig, {WASM_SET_LOCAL(local_func,
2102 2 : WASM_GET_TABLE(tab_ref2, WASM_I32V(2)))});
2103 :
2104 : ExpectFailure(&sig, {WASM_SET_LOCAL(local_int,
2105 2 : WASM_GET_TABLE(tab_ref1, WASM_I32V(9)))});
2106 : ExpectFailure(&sig, {WASM_SET_LOCAL(
2107 2 : local_int, WASM_GET_TABLE(tab_func1, WASM_I32V(3)))});
2108 : // Out-of-bounds table index should fail.
2109 : byte oob_tab = 37;
2110 : ExpectFailure(
2111 2 : &sig, {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(oob_tab, WASM_I32V(9)))});
2112 : ExpectFailure(&sig, {WASM_SET_LOCAL(local_func,
2113 2 : WASM_GET_TABLE(oob_tab, WASM_I32V(3)))});
2114 1 : }
2115 :
2116 15189 : TEST_F(FunctionBodyDecoderTest, WasmMemoryGrow) {
2117 1 : TestModuleBuilder builder;
2118 1 : module = builder.module();
2119 : builder.InitializeMemory();
2120 :
2121 1 : byte code[] = {WASM_GET_LOCAL(0), kExprMemoryGrow, 0};
2122 1 : ExpectValidates(sigs.i_i(), code);
2123 1 : ExpectFailure(sigs.i_d(), code);
2124 1 : }
2125 :
2126 15189 : TEST_F(FunctionBodyDecoderTest, AsmJsMemoryGrow) {
2127 1 : TestModuleBuilder builder(kAsmJsOrigin);
2128 1 : module = builder.module();
2129 : builder.InitializeMemory();
2130 :
2131 1 : byte code[] = {WASM_GET_LOCAL(0), kExprMemoryGrow, 0};
2132 1 : ExpectFailure(sigs.i_i(), code);
2133 1 : }
2134 :
2135 15189 : TEST_F(FunctionBodyDecoderTest, AsmJsBinOpsCheckOrigin) {
2136 1 : ValueType float32int32float32[] = {kWasmF32, kWasmI32, kWasmF32};
2137 : FunctionSig sig_f_if(1, 2, float32int32float32);
2138 1 : ValueType float64int32float64[] = {kWasmF64, kWasmI32, kWasmF64};
2139 : FunctionSig sig_d_id(1, 2, float64int32float64);
2140 : struct {
2141 : WasmOpcode op;
2142 : FunctionSig* sig;
2143 : } AsmJsBinOps[] = {
2144 1 : {kExprF64Atan2, sigs.d_dd()},
2145 : {kExprF64Pow, sigs.d_dd()},
2146 : {kExprF64Mod, sigs.d_dd()},
2147 1 : {kExprI32AsmjsDivS, sigs.i_ii()},
2148 : {kExprI32AsmjsDivU, sigs.i_ii()},
2149 : {kExprI32AsmjsRemS, sigs.i_ii()},
2150 : {kExprI32AsmjsRemU, sigs.i_ii()},
2151 : {kExprI32AsmjsStoreMem8, sigs.i_ii()},
2152 : {kExprI32AsmjsStoreMem16, sigs.i_ii()},
2153 : {kExprI32AsmjsStoreMem, sigs.i_ii()},
2154 : {kExprF32AsmjsStoreMem, &sig_f_if},
2155 : {kExprF64AsmjsStoreMem, &sig_d_id},
2156 3 : };
2157 :
2158 : {
2159 1 : TestModuleBuilder builder(kAsmJsOrigin);
2160 1 : module = builder.module();
2161 : builder.InitializeMemory();
2162 13 : for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) {
2163 12 : TestBinop(AsmJsBinOps[i].op, AsmJsBinOps[i].sig);
2164 : }
2165 : }
2166 :
2167 : {
2168 1 : TestModuleBuilder builder;
2169 1 : module = builder.module();
2170 : builder.InitializeMemory();
2171 13 : for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) {
2172 : ExpectFailure(AsmJsBinOps[i].sig,
2173 : {WASM_BINOP(AsmJsBinOps[i].op, WASM_GET_LOCAL(0),
2174 24 : WASM_GET_LOCAL(1))});
2175 : }
2176 : }
2177 1 : }
2178 :
2179 15189 : TEST_F(FunctionBodyDecoderTest, AsmJsUnOpsCheckOrigin) {
2180 1 : ValueType float32int32[] = {kWasmF32, kWasmI32};
2181 : FunctionSig sig_f_i(1, 1, float32int32);
2182 1 : ValueType float64int32[] = {kWasmF64, kWasmI32};
2183 : FunctionSig sig_d_i(1, 1, float64int32);
2184 : struct {
2185 : WasmOpcode op;
2186 : FunctionSig* sig;
2187 1 : } AsmJsUnOps[] = {{kExprF64Acos, sigs.d_d()},
2188 : {kExprF64Asin, sigs.d_d()},
2189 : {kExprF64Atan, sigs.d_d()},
2190 : {kExprF64Cos, sigs.d_d()},
2191 : {kExprF64Sin, sigs.d_d()},
2192 : {kExprF64Tan, sigs.d_d()},
2193 : {kExprF64Exp, sigs.d_d()},
2194 : {kExprF64Log, sigs.d_d()},
2195 1 : {kExprI32AsmjsLoadMem8S, sigs.i_i()},
2196 : {kExprI32AsmjsLoadMem8U, sigs.i_i()},
2197 : {kExprI32AsmjsLoadMem16S, sigs.i_i()},
2198 : {kExprI32AsmjsLoadMem16U, sigs.i_i()},
2199 : {kExprI32AsmjsLoadMem, sigs.i_i()},
2200 : {kExprF32AsmjsLoadMem, &sig_f_i},
2201 : {kExprF64AsmjsLoadMem, &sig_d_i},
2202 1 : {kExprI32AsmjsSConvertF32, sigs.i_f()},
2203 : {kExprI32AsmjsUConvertF32, sigs.i_f()},
2204 1 : {kExprI32AsmjsSConvertF64, sigs.i_d()},
2205 5 : {kExprI32AsmjsUConvertF64, sigs.i_d()}};
2206 : {
2207 1 : TestModuleBuilder builder(kAsmJsOrigin);
2208 1 : module = builder.module();
2209 : builder.InitializeMemory();
2210 20 : for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) {
2211 19 : TestUnop(AsmJsUnOps[i].op, AsmJsUnOps[i].sig);
2212 : }
2213 : }
2214 :
2215 : {
2216 1 : TestModuleBuilder builder;
2217 1 : module = builder.module();
2218 : builder.InitializeMemory();
2219 20 : for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) {
2220 : ExpectFailure(AsmJsUnOps[i].sig,
2221 38 : {WASM_UNOP(AsmJsUnOps[i].op, WASM_GET_LOCAL(0))});
2222 : }
2223 : }
2224 1 : }
2225 :
2226 15189 : TEST_F(FunctionBodyDecoderTest, BreakEnd) {
2227 : ExpectValidates(
2228 : sigs.i_i(),
2229 2 : {WASM_BLOCK_I(WASM_I32_ADD(WASM_BRV(0, WASM_ZERO), WASM_ZERO))});
2230 : ExpectValidates(
2231 : sigs.i_i(),
2232 2 : {WASM_BLOCK_I(WASM_I32_ADD(WASM_ZERO, WASM_BRV(0, WASM_ZERO)))});
2233 1 : }
2234 :
2235 15189 : TEST_F(FunctionBodyDecoderTest, BreakIfBinop) {
2236 : ExpectValidates(sigs.i_i(),
2237 : {WASM_BLOCK_I(WASM_I32_ADD(
2238 2 : WASM_BRV_IF(0, WASM_ZERO, WASM_ZERO), WASM_ZERO))});
2239 : ExpectValidates(sigs.i_i(),
2240 : {WASM_BLOCK_I(WASM_I32_ADD(
2241 2 : WASM_ZERO, WASM_BRV_IF(0, WASM_ZERO, WASM_ZERO)))});
2242 : ExpectValidates(
2243 : sigs.f_ff(),
2244 2 : {WASM_BLOCK_F(WASM_F32_ABS(WASM_BRV_IF(0, WASM_F32(0.0f), WASM_ZERO)))});
2245 1 : }
2246 :
2247 15189 : TEST_F(FunctionBodyDecoderTest, BreakIfBinop_fail) {
2248 : ExpectFailure(
2249 : sigs.f_ff(),
2250 2 : {WASM_BLOCK_F(WASM_F32_ABS(WASM_BRV_IF(0, WASM_ZERO, WASM_ZERO)))});
2251 : ExpectFailure(
2252 : sigs.i_i(),
2253 2 : {WASM_BLOCK_I(WASM_F32_ABS(WASM_BRV_IF(0, WASM_F32(0.0f), WASM_ZERO)))});
2254 1 : }
2255 :
2256 15189 : TEST_F(FunctionBodyDecoderTest, BreakIfUnrNarrow) {
2257 : ExpectFailure(
2258 : sigs.f_ff(),
2259 : {WASM_BLOCK_I(WASM_BRV_IF(0, WASM_UNREACHABLE, WASM_UNREACHABLE),
2260 : WASM_RETURN0),
2261 2 : WASM_F32(0.0)});
2262 1 : }
2263 :
2264 15189 : TEST_F(FunctionBodyDecoderTest, BreakNesting1) {
2265 6 : for (int i = 0; i < 5; i++) {
2266 : // (block[2] (loop[2] (if (get p) break[N]) (set p 1)) p)
2267 : byte code[] = {WASM_BLOCK_I(
2268 : WASM_LOOP(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(i + 1, WASM_ZERO)),
2269 : WASM_SET_LOCAL(0, WASM_I32V_1(1))),
2270 5 : WASM_ZERO)};
2271 5 : Validate(i < 3, sigs.i_i(), code);
2272 : }
2273 1 : }
2274 :
2275 15189 : TEST_F(FunctionBodyDecoderTest, BreakNesting2) {
2276 8 : for (int i = 0; i < 7; i++) {
2277 7 : byte code[] = {B1(WASM_LOOP(WASM_IF(WASM_ZERO, WASM_BR(i)), WASM_NOP))};
2278 7 : Validate(i <= 3, sigs.v_v(), code);
2279 : }
2280 1 : }
2281 :
2282 15189 : TEST_F(FunctionBodyDecoderTest, BreakNesting3) {
2283 8 : for (int i = 0; i < 7; i++) {
2284 : // (block[1] (loop[1] (block[1] (if 0 break[N])
2285 : byte code[] = {
2286 7 : WASM_BLOCK(WASM_LOOP(B1(WASM_IF(WASM_ZERO, WASM_BR(i + 1)))))};
2287 7 : Validate(i < 4, sigs.v_v(), code);
2288 : }
2289 1 : }
2290 :
2291 15189 : TEST_F(FunctionBodyDecoderTest, BreaksWithMultipleTypes) {
2292 : ExpectFailure(sigs.i_i(),
2293 2 : {B2(WASM_BRV_IF_ZERO(0, WASM_I32V_1(7)), WASM_F32(7.7))});
2294 :
2295 : ExpectFailure(sigs.i_i(), {B2(WASM_BRV_IF_ZERO(0, WASM_I32V_1(7)),
2296 2 : WASM_BRV_IF_ZERO(0, WASM_F32(7.7)))});
2297 : ExpectFailure(sigs.i_i(), {B3(WASM_BRV_IF_ZERO(0, WASM_I32V_1(8)),
2298 : WASM_BRV_IF_ZERO(0, WASM_I32V_1(0)),
2299 2 : WASM_BRV_IF_ZERO(0, WASM_F32(7.7)))});
2300 : ExpectFailure(sigs.i_i(), {B3(WASM_BRV_IF_ZERO(0, WASM_I32V_1(9)),
2301 : WASM_BRV_IF_ZERO(0, WASM_F32(7.7)),
2302 2 : WASM_BRV_IF_ZERO(0, WASM_I32V_1(11)))});
2303 1 : }
2304 :
2305 15189 : TEST_F(FunctionBodyDecoderTest, BreakNesting_6_levels) {
2306 65 : for (int mask = 0; mask < 64; mask++) {
2307 896 : for (int i = 0; i < 14; i++) {
2308 : byte code[] = {WASM_BLOCK(WASM_BLOCK(
2309 896 : WASM_BLOCK(WASM_BLOCK(WASM_BLOCK(WASM_BLOCK(WASM_BR(i)))))))};
2310 :
2311 : int depth = 6;
2312 : int m = mask;
2313 17920 : for (size_t pos = 0; pos < sizeof(code) - 1; pos++) {
2314 17024 : if (code[pos] != kExprBlock) continue;
2315 5440 : if (m & 1) {
2316 2688 : code[pos] = kExprLoop;
2317 2688 : code[pos + 1] = kLocalVoid;
2318 : }
2319 5440 : m >>= 1;
2320 : }
2321 :
2322 896 : Validate(i <= depth, sigs.v_v(), code);
2323 : }
2324 : }
2325 1 : }
2326 :
2327 15189 : TEST_F(FunctionBodyDecoderTest, Break_TypeCheck) {
2328 1 : FunctionSig* sigarray[] = {sigs.i_i(), sigs.l_l(), sigs.f_ff(), sigs.d_dd()};
2329 5 : for (size_t i = 0; i < arraysize(sigarray); i++) {
2330 8 : FunctionSig* sig = sigarray[i];
2331 : // unify X and X => OK
2332 4 : byte code[] = {WASM_BLOCK_T(
2333 : sig->GetReturn(), WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))),
2334 8 : WASM_GET_LOCAL(0))};
2335 4 : ExpectValidates(sig, code);
2336 : }
2337 :
2338 : // unify i32 and f32 => fail
2339 : ExpectFailure(sigs.i_i(),
2340 : {WASM_BLOCK_I(WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_ZERO)),
2341 2 : WASM_F32(1.2))});
2342 :
2343 : // unify f64 and f64 => OK
2344 : ExpectValidates(
2345 : sigs.d_dd(),
2346 : {WASM_BLOCK_D(WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))),
2347 2 : WASM_F64(1.2))});
2348 1 : }
2349 :
2350 15189 : TEST_F(FunctionBodyDecoderTest, Break_TypeCheckAll1) {
2351 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2352 25 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2353 25 : ValueType storage[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j]};
2354 : FunctionSig sig(1, 2, storage);
2355 25 : byte code[] = {WASM_BLOCK_T(
2356 : sig.GetReturn(), WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))),
2357 50 : WASM_GET_LOCAL(1))};
2358 :
2359 25 : Validate(i == j, &sig, code);
2360 : }
2361 : }
2362 1 : }
2363 :
2364 15189 : TEST_F(FunctionBodyDecoderTest, Break_TypeCheckAll2) {
2365 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2366 25 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2367 25 : ValueType storage[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j]};
2368 : FunctionSig sig(1, 2, storage);
2369 25 : byte code[] = {WASM_IF_ELSE_T(sig.GetReturn(0), WASM_ZERO,
2370 : WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)),
2371 50 : WASM_GET_LOCAL(1))};
2372 :
2373 25 : Validate(i == j, &sig, code);
2374 : }
2375 : }
2376 1 : }
2377 :
2378 15189 : TEST_F(FunctionBodyDecoderTest, Break_TypeCheckAll3) {
2379 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2380 25 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2381 25 : ValueType storage[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j]};
2382 : FunctionSig sig(1, 2, storage);
2383 25 : byte code[] = {WASM_IF_ELSE_T(sig.GetReturn(), WASM_ZERO,
2384 : WASM_GET_LOCAL(1),
2385 50 : WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))};
2386 :
2387 25 : Validate(i == j, &sig, code);
2388 : }
2389 : }
2390 1 : }
2391 :
2392 15189 : TEST_F(FunctionBodyDecoderTest, Break_Unify) {
2393 3 : for (int which = 0; which < 2; which++) {
2394 10 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2395 10 : ValueType type = kValueTypes[i];
2396 10 : ValueType storage[] = {kWasmI32, kWasmI32, type};
2397 : FunctionSig sig(1, 2, storage);
2398 :
2399 10 : byte code1[] = {WASM_BLOCK_T(
2400 : type, WASM_IF(WASM_ZERO, WASM_BRV(1, WASM_GET_LOCAL(which))),
2401 20 : WASM_GET_LOCAL(which ^ 1))};
2402 :
2403 10 : Validate(type == kWasmI32, &sig, code1);
2404 : }
2405 : }
2406 1 : }
2407 :
2408 15189 : TEST_F(FunctionBodyDecoderTest, BreakIf_cond_type) {
2409 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2410 25 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2411 25 : ValueType types[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j]};
2412 : FunctionSig sig(1, 2, types);
2413 25 : byte code[] = {WASM_BLOCK_T(
2414 50 : types[0], WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)))};
2415 :
2416 25 : Validate(types[2] == kWasmI32, &sig, code);
2417 : }
2418 : }
2419 1 : }
2420 :
2421 15189 : TEST_F(FunctionBodyDecoderTest, BreakIf_val_type) {
2422 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2423 25 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2424 50 : ValueType types[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j],
2425 75 : kWasmI32};
2426 : FunctionSig sig(1, 3, types);
2427 25 : byte code[] = {WASM_BLOCK_T(
2428 : types[1], WASM_BRV_IF(0, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)),
2429 50 : WASM_DROP, WASM_GET_LOCAL(0))};
2430 :
2431 25 : Validate(i == j, &sig, code);
2432 : }
2433 : }
2434 1 : }
2435 :
2436 15189 : TEST_F(FunctionBodyDecoderTest, BreakIf_Unify) {
2437 3 : for (int which = 0; which < 2; which++) {
2438 10 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2439 10 : ValueType type = kValueTypes[i];
2440 10 : ValueType storage[] = {kWasmI32, kWasmI32, type};
2441 : FunctionSig sig(1, 2, storage);
2442 : byte code[] = {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(which)),
2443 10 : WASM_DROP, WASM_GET_LOCAL(which ^ 1))};
2444 :
2445 10 : Validate(type == kWasmI32, &sig, code);
2446 : }
2447 : }
2448 1 : }
2449 :
2450 15189 : TEST_F(FunctionBodyDecoderTest, BrTable0) {
2451 2 : ExpectFailure(sigs.v_v(), {kExprBrTable, 0, BR_TARGET(0)});
2452 1 : }
2453 :
2454 15189 : TEST_F(FunctionBodyDecoderTest, BrTable0b) {
2455 : static byte code[] = {kExprI32Const, 11, kExprBrTable, 0, BR_TARGET(0)};
2456 1 : ExpectValidates(sigs.v_v(), code);
2457 1 : ExpectFailure(sigs.i_i(), code);
2458 1 : }
2459 :
2460 15189 : TEST_F(FunctionBodyDecoderTest, BrTable0c) {
2461 : static byte code[] = {kExprI32Const, 11, kExprBrTable, 0, BR_TARGET(1)};
2462 1 : ExpectFailure(sigs.v_v(), code);
2463 1 : ExpectFailure(sigs.i_i(), code);
2464 1 : }
2465 :
2466 15189 : TEST_F(FunctionBodyDecoderTest, BrTable1a) {
2467 : ExpectValidates(sigs.v_v(),
2468 2 : {B1(WASM_BR_TABLE(WASM_I32V_2(67), 0, BR_TARGET(0)))});
2469 1 : }
2470 :
2471 15189 : TEST_F(FunctionBodyDecoderTest, BrTable1b) {
2472 : static byte code[] = {B1(WASM_BR_TABLE(WASM_ZERO, 0, BR_TARGET(0)))};
2473 1 : ExpectValidates(sigs.v_v(), code);
2474 1 : ExpectFailure(sigs.i_i(), code);
2475 1 : ExpectFailure(sigs.f_ff(), code);
2476 1 : ExpectFailure(sigs.d_dd(), code);
2477 1 : }
2478 :
2479 15189 : TEST_F(FunctionBodyDecoderTest, BrTable2a) {
2480 : ExpectValidates(
2481 : sigs.v_v(),
2482 2 : {B1(WASM_BR_TABLE(WASM_I32V_2(67), 1, BR_TARGET(0), BR_TARGET(0)))});
2483 1 : }
2484 :
2485 15189 : TEST_F(FunctionBodyDecoderTest, BrTable2b) {
2486 : ExpectValidates(sigs.v_v(),
2487 : {WASM_BLOCK(WASM_BLOCK(WASM_BR_TABLE(
2488 2 : WASM_I32V_2(67), 1, BR_TARGET(0), BR_TARGET(1))))});
2489 1 : }
2490 :
2491 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_off_end) {
2492 : static byte code[] = {B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(0)))};
2493 8 : for (size_t len = 1; len < sizeof(code); len++) {
2494 14 : ExpectFailure(sigs.i_i(), VectorOf(code, len), kAppendEnd);
2495 14 : ExpectFailure(sigs.i_i(), VectorOf(code, len), kOmitEnd);
2496 : }
2497 1 : }
2498 :
2499 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_invalid_br1) {
2500 5 : for (int depth = 0; depth < 4; depth++) {
2501 4 : byte code[] = {B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(depth)))};
2502 4 : Validate(depth <= 1, sigs.v_i(), code);
2503 : }
2504 1 : }
2505 :
2506 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_invalid_br2) {
2507 8 : for (int depth = 0; depth < 7; depth++) {
2508 : byte code[] = {
2509 7 : WASM_LOOP(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(depth)))};
2510 7 : Validate(depth < 2, sigs.v_i(), code);
2511 : }
2512 1 : }
2513 :
2514 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_arity_mismatch1) {
2515 : ExpectFailure(
2516 : sigs.v_v(),
2517 : {WASM_BLOCK(WASM_BLOCK_I(
2518 2 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2519 1 : }
2520 :
2521 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_arity_mismatch2) {
2522 : ExpectFailure(
2523 : sigs.v_v(),
2524 : {WASM_BLOCK_I(WASM_BLOCK(
2525 2 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2526 1 : }
2527 :
2528 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_arity_mismatch_loop1) {
2529 : ExpectFailure(
2530 : sigs.v_v(),
2531 : {WASM_LOOP(WASM_BLOCK_I(
2532 2 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2533 1 : }
2534 :
2535 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_arity_mismatch_loop2) {
2536 : ExpectFailure(
2537 : sigs.v_v(),
2538 : {WASM_BLOCK_I(WASM_LOOP(
2539 2 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2540 1 : }
2541 :
2542 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_loop_block) {
2543 : ExpectValidates(
2544 : sigs.v_v(),
2545 : {WASM_LOOP(WASM_BLOCK(
2546 2 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2547 1 : }
2548 :
2549 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_block_loop) {
2550 : ExpectValidates(
2551 : sigs.v_v(),
2552 : {WASM_LOOP(WASM_BLOCK(
2553 2 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2554 1 : }
2555 :
2556 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_type_mismatch1) {
2557 : ExpectFailure(
2558 : sigs.v_v(),
2559 : {WASM_BLOCK_I(WASM_BLOCK_F(
2560 2 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2561 1 : }
2562 :
2563 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_type_mismatch2) {
2564 : ExpectFailure(
2565 : sigs.v_v(),
2566 : {WASM_BLOCK_F(WASM_BLOCK_I(
2567 2 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2568 1 : }
2569 :
2570 15189 : TEST_F(FunctionBodyDecoderTest, BrTable_type_mismatch_unreachable) {
2571 : ExpectFailure(sigs.v_v(),
2572 : {WASM_BLOCK_F(WASM_BLOCK_I(
2573 : WASM_UNREACHABLE,
2574 2 : WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2575 1 : }
2576 :
2577 15189 : TEST_F(FunctionBodyDecoderTest, BrUnreachable1) {
2578 : ExpectValidates(sigs.v_i(),
2579 2 : {WASM_GET_LOCAL(0), kExprBrTable, 0, BR_TARGET(0)});
2580 1 : }
2581 :
2582 15189 : TEST_F(FunctionBodyDecoderTest, BrUnreachable2) {
2583 : ExpectValidates(sigs.v_i(),
2584 2 : {WASM_GET_LOCAL(0), kExprBrTable, 0, BR_TARGET(0), WASM_NOP});
2585 : ExpectFailure(sigs.v_i(),
2586 2 : {WASM_GET_LOCAL(0), kExprBrTable, 0, BR_TARGET(0), WASM_ZERO});
2587 1 : }
2588 :
2589 15189 : TEST_F(FunctionBodyDecoderTest, Brv1) {
2590 2 : ExpectValidates(sigs.i_i(), {WASM_BLOCK_I(WASM_BRV(0, WASM_ZERO))});
2591 : ExpectValidates(sigs.i_i(),
2592 2 : {WASM_BLOCK_I(WASM_LOOP_I(WASM_BRV(2, WASM_ZERO)))});
2593 1 : }
2594 :
2595 15189 : TEST_F(FunctionBodyDecoderTest, Brv1_type) {
2596 2 : ExpectValidates(sigs.i_ii(), {WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2597 2 : ExpectValidates(sigs.l_ll(), {WASM_BLOCK_L(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2598 2 : ExpectValidates(sigs.f_ff(), {WASM_BLOCK_F(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2599 2 : ExpectValidates(sigs.d_dd(), {WASM_BLOCK_D(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2600 1 : }
2601 :
2602 15189 : TEST_F(FunctionBodyDecoderTest, Brv1_type_n) {
2603 2 : ExpectFailure(sigs.i_f(), {WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2604 2 : ExpectFailure(sigs.i_d(), {WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2605 1 : }
2606 :
2607 15189 : TEST_F(FunctionBodyDecoderTest, BrvIf1) {
2608 2 : ExpectValidates(sigs.i_v(), {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_ZERO))});
2609 1 : }
2610 :
2611 15189 : TEST_F(FunctionBodyDecoderTest, BrvIf1_type) {
2612 : ExpectValidates(sigs.i_i(),
2613 2 : {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2614 : ExpectValidates(sigs.l_l(),
2615 2 : {WASM_BLOCK_L(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2616 : ExpectValidates(sigs.f_ff(),
2617 2 : {WASM_BLOCK_F(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2618 : ExpectValidates(sigs.d_dd(),
2619 2 : {WASM_BLOCK_D(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2620 1 : }
2621 :
2622 15189 : TEST_F(FunctionBodyDecoderTest, BrvIf1_type_n) {
2623 : ExpectFailure(sigs.i_f(),
2624 2 : {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2625 : ExpectFailure(sigs.i_d(),
2626 2 : {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2627 1 : }
2628 :
2629 15189 : TEST_F(FunctionBodyDecoderTest, Select) {
2630 : ExpectValidates(sigs.i_i(), {WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2631 2 : WASM_ZERO)});
2632 : ExpectValidates(sigs.f_ff(),
2633 2 : {WASM_SELECT(WASM_F32(0.0), WASM_F32(0.0), WASM_ZERO)});
2634 : ExpectValidates(sigs.d_dd(),
2635 2 : {WASM_SELECT(WASM_F64(0.0), WASM_F64(0.0), WASM_ZERO)});
2636 : ExpectValidates(sigs.l_l(),
2637 2 : {WASM_SELECT(WASM_I64V_1(0), WASM_I64V_1(0), WASM_ZERO)});
2638 1 : }
2639 :
2640 15189 : TEST_F(FunctionBodyDecoderTest, Select_fail1) {
2641 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_F32(0.0), WASM_GET_LOCAL(0),
2642 2 : WASM_GET_LOCAL(0))});
2643 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_GET_LOCAL(0), WASM_F32(0.0),
2644 2 : WASM_GET_LOCAL(0))});
2645 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2646 2 : WASM_F32(0.0))});
2647 1 : }
2648 :
2649 15189 : TEST_F(FunctionBodyDecoderTest, Select_fail2) {
2650 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2651 5 : ValueType type = kValueTypes[i];
2652 6 : if (type == kWasmI32) continue;
2653 :
2654 4 : ValueType types[] = {type, kWasmI32, type};
2655 : FunctionSig sig(1, 2, types);
2656 :
2657 : ExpectValidates(&sig, {WASM_SELECT(WASM_GET_LOCAL(1), WASM_GET_LOCAL(1),
2658 8 : WASM_GET_LOCAL(0))});
2659 :
2660 : ExpectFailure(&sig, {WASM_SELECT(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0),
2661 8 : WASM_GET_LOCAL(0))});
2662 :
2663 : ExpectFailure(&sig, {WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2664 8 : WASM_GET_LOCAL(0))});
2665 :
2666 : ExpectFailure(&sig, {WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2667 8 : WASM_GET_LOCAL(1))});
2668 : }
2669 1 : }
2670 :
2671 15189 : TEST_F(FunctionBodyDecoderTest, Select_TypeCheck) {
2672 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_F32(9.9), WASM_GET_LOCAL(0),
2673 2 : WASM_GET_LOCAL(0))});
2674 :
2675 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_GET_LOCAL(0), WASM_F64(0.25),
2676 2 : WASM_GET_LOCAL(0))});
2677 :
2678 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_F32(9.9), WASM_GET_LOCAL(0),
2679 2 : WASM_I64V_1(0))});
2680 1 : }
2681 :
2682 15189 : TEST_F(FunctionBodyDecoderTest, Throw) {
2683 1 : WASM_FEATURE_SCOPE(eh);
2684 1 : TestModuleBuilder builder;
2685 1 : module = builder.module();
2686 1 : byte ex1 = builder.AddException(sigs.v_v());
2687 1 : byte ex2 = builder.AddException(sigs.v_i());
2688 1 : byte ex3 = builder.AddException(sigs.v_ii());
2689 2 : ExpectValidates(sigs.v_v(), {kExprThrow, ex1});
2690 2 : ExpectValidates(sigs.v_v(), {WASM_I32V(0), kExprThrow, ex2});
2691 2 : ExpectFailure(sigs.v_v(), {WASM_F32(0.0), kExprThrow, ex2});
2692 2 : ExpectValidates(sigs.v_v(), {WASM_I32V(0), WASM_I32V(0), kExprThrow, ex3});
2693 2 : ExpectFailure(sigs.v_v(), {WASM_F32(0.0), WASM_I32V(0), kExprThrow, ex3});
2694 2 : ExpectFailure(sigs.v_v(), {kExprThrow, 99});
2695 1 : }
2696 :
2697 15189 : TEST_F(FunctionBodyDecoderTest, ThrowUnreachable) {
2698 1 : WASM_FEATURE_SCOPE(eh);
2699 1 : TestModuleBuilder builder;
2700 1 : module = builder.module();
2701 1 : byte ex1 = builder.AddException(sigs.v_v());
2702 1 : byte ex2 = builder.AddException(sigs.v_i());
2703 2 : ExpectValidates(sigs.i_i(), {WASM_GET_LOCAL(0), kExprThrow, ex1, WASM_NOP});
2704 2 : ExpectValidates(sigs.v_i(), {WASM_GET_LOCAL(0), kExprThrow, ex2, WASM_NOP});
2705 2 : ExpectValidates(sigs.i_i(), {WASM_GET_LOCAL(0), kExprThrow, ex1, WASM_ZERO});
2706 2 : ExpectFailure(sigs.v_i(), {WASM_GET_LOCAL(0), kExprThrow, ex2, WASM_ZERO});
2707 : ExpectFailure(sigs.i_i(),
2708 2 : {WASM_GET_LOCAL(0), kExprThrow, ex1, WASM_F32(0.0)});
2709 : ExpectFailure(sigs.v_i(),
2710 2 : {WASM_GET_LOCAL(0), kExprThrow, ex2, WASM_F32(0.0)});
2711 1 : }
2712 :
2713 : #define WASM_TRY_OP kExprTry, kLocalVoid
2714 : #define WASM_BR_ON_EXN(depth, index) \
2715 : kExprBrOnExn, static_cast<byte>(depth), static_cast<byte>(index)
2716 :
2717 15189 : TEST_F(FunctionBodyDecoderTest, TryCatch) {
2718 1 : WASM_FEATURE_SCOPE(eh);
2719 1 : TestModuleBuilder builder;
2720 1 : module = builder.module();
2721 2 : ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprCatch, kExprDrop, kExprEnd});
2722 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprCatch, kExprCatch, kExprEnd});
2723 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprEnd}); // Missing catch.
2724 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprCatch}); // Missing end.
2725 2 : ExpectFailure(sigs.v_v(), {kExprCatch, kExprEnd}); // Missing try.
2726 1 : }
2727 :
2728 15189 : TEST_F(FunctionBodyDecoderTest, Rethrow) {
2729 1 : WASM_FEATURE_SCOPE(eh);
2730 1 : TestModuleBuilder builder;
2731 1 : module = builder.module();
2732 : ExpectValidates(sigs.v_v(),
2733 2 : {WASM_TRY_OP, kExprCatch, kExprRethrow, kExprEnd});
2734 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprRethrow, kExprCatch, kExprEnd});
2735 2 : ExpectFailure(sigs.v_v(), {WASM_BLOCK(kExprRethrow)});
2736 2 : ExpectFailure(sigs.v_v(), {kExprRethrow});
2737 1 : }
2738 :
2739 15189 : TEST_F(FunctionBodyDecoderTest, BrOnExn) {
2740 1 : WASM_FEATURE_SCOPE(eh);
2741 1 : TestModuleBuilder builder;
2742 1 : module = builder.module();
2743 1 : byte ex1 = builder.AddException(sigs.v_v());
2744 1 : byte ex2 = builder.AddException(sigs.v_i());
2745 : ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(0, ex1),
2746 2 : kExprDrop, kExprEnd});
2747 : ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(1, ex1),
2748 2 : kExprDrop, kExprEnd});
2749 : ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(0, ex1),
2750 2 : WASM_BR_ON_EXN(0, ex1), kExprDrop, kExprEnd});
2751 : ExpectValidates(sigs.v_v(),
2752 : {WASM_BLOCK(WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(1, ex1),
2753 2 : kExprDrop, kExprEnd)});
2754 : ExpectValidates(sigs.i_v(),
2755 : {WASM_BLOCK_I(WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(1, ex2),
2756 2 : kExprDrop, kExprEnd, kExprI32Const, 0)});
2757 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(2, ex1),
2758 2 : kExprDrop, kExprEnd});
2759 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprCatch, kExprDrop,
2760 2 : WASM_BR_ON_EXN(0, ex1), kExprEnd});
2761 : ExpectFailure(sigs.v_v(),
2762 2 : {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(0, ex1), kExprEnd});
2763 1 : }
2764 :
2765 : #undef WASM_BR_ON_EXN
2766 : #undef WASM_TRY_OP
2767 :
2768 15189 : TEST_F(FunctionBodyDecoderTest, MultiValBlock1) {
2769 1 : WASM_FEATURE_SCOPE(mv);
2770 1 : TestModuleBuilder builder;
2771 1 : module = builder.module();
2772 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2773 : ExpectValidates(
2774 : sigs.i_ii(),
2775 2 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprI32Add});
2776 2 : ExpectFailure(sigs.i_ii(), {WASM_BLOCK_X(f0, WASM_NOP), kExprI32Add});
2777 : ExpectFailure(sigs.i_ii(),
2778 2 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0)), kExprI32Add});
2779 : ExpectFailure(sigs.i_ii(),
2780 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2781 : WASM_GET_LOCAL(0)),
2782 2 : kExprI32Add});
2783 : ExpectFailure(
2784 : sigs.i_ii(),
2785 2 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprF32Add});
2786 1 : }
2787 :
2788 15189 : TEST_F(FunctionBodyDecoderTest, MultiValBlock2) {
2789 1 : WASM_FEATURE_SCOPE(mv);
2790 1 : TestModuleBuilder builder;
2791 1 : module = builder.module();
2792 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2793 : ExpectValidates(sigs.i_ii(),
2794 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2795 2 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2796 : ExpectFailure(sigs.i_ii(),
2797 2 : {WASM_BLOCK_X(f0, WASM_NOP), WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2798 : ExpectFailure(sigs.i_ii(), {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0)),
2799 2 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2800 : ExpectFailure(sigs.i_ii(),
2801 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2802 : WASM_GET_LOCAL(0)),
2803 2 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2804 : ExpectFailure(sigs.i_ii(),
2805 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2806 2 : WASM_F32_ADD(WASM_NOP, WASM_NOP)});
2807 1 : }
2808 :
2809 15189 : TEST_F(FunctionBodyDecoderTest, MultiValBlockBr) {
2810 1 : WASM_FEATURE_SCOPE(mv);
2811 1 : TestModuleBuilder builder;
2812 1 : module = builder.module();
2813 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2814 : ExpectFailure(sigs.i_ii(),
2815 2 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_BR(0)), kExprI32Add});
2816 : ExpectValidates(sigs.i_ii(), {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0),
2817 : WASM_GET_LOCAL(1), WASM_BR(0)),
2818 2 : kExprI32Add});
2819 1 : }
2820 :
2821 15189 : TEST_F(FunctionBodyDecoderTest, MultiValLoop1) {
2822 1 : WASM_FEATURE_SCOPE(mv);
2823 1 : TestModuleBuilder builder;
2824 1 : module = builder.module();
2825 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2826 : ExpectValidates(
2827 : sigs.i_ii(),
2828 2 : {WASM_LOOP_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprI32Add});
2829 2 : ExpectFailure(sigs.i_ii(), {WASM_LOOP_X(f0, WASM_NOP), kExprI32Add});
2830 2 : ExpectFailure(sigs.i_ii(), {WASM_LOOP_X(f0, WASM_GET_LOCAL(0)), kExprI32Add});
2831 : ExpectFailure(sigs.i_ii(), {WASM_LOOP_X(f0, WASM_GET_LOCAL(0),
2832 : WASM_GET_LOCAL(1), WASM_GET_LOCAL(0)),
2833 2 : kExprI32Add});
2834 : ExpectFailure(
2835 : sigs.i_ii(),
2836 2 : {WASM_LOOP_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprF32Add});
2837 1 : }
2838 :
2839 15189 : TEST_F(FunctionBodyDecoderTest, MultiValIf) {
2840 1 : WASM_FEATURE_SCOPE(mv);
2841 1 : TestModuleBuilder builder;
2842 1 : module = builder.module();
2843 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2844 : ExpectValidates(
2845 : sigs.i_ii(),
2846 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2847 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2848 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
2849 2 : kExprI32Add});
2850 : ExpectFailure(
2851 : sigs.i_ii(),
2852 2 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP), kExprI32Add});
2853 : ExpectFailure(sigs.i_ii(),
2854 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), WASM_NOP,
2855 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
2856 2 : kExprI32Add});
2857 : ExpectFailure(
2858 : sigs.i_ii(),
2859 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2860 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_NOP),
2861 2 : kExprI32Add});
2862 : ExpectFailure(sigs.i_ii(),
2863 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2864 : WASM_GET_LOCAL(1)),
2865 2 : kExprI32Add});
2866 : ExpectFailure(sigs.i_ii(),
2867 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2868 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
2869 2 : kExprI32Add});
2870 : ExpectFailure(sigs.i_ii(),
2871 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2872 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2873 : WASM_GET_LOCAL(1)),
2874 2 : kExprI32Add});
2875 : ExpectFailure(
2876 : sigs.i_ii(),
2877 : {WASM_IF_ELSE_X(
2878 : f0, WASM_GET_LOCAL(0),
2879 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)),
2880 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0), WASM_GET_LOCAL(0))),
2881 2 : kExprI32Add});
2882 : ExpectFailure(sigs.i_ii(),
2883 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2884 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2885 : WASM_GET_LOCAL(0)),
2886 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))),
2887 2 : kExprI32Add});
2888 : ExpectFailure(sigs.i_ii(),
2889 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2890 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2891 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(1),
2892 : WASM_GET_LOCAL(1))),
2893 2 : kExprI32Add});
2894 : ExpectFailure(sigs.i_ii(),
2895 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2896 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2897 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
2898 2 : kExprF32Add});
2899 1 : }
2900 :
2901 15189 : TEST_F(FunctionBodyDecoderTest, BlockParam) {
2902 1 : WASM_FEATURE_SCOPE(mv);
2903 1 : TestModuleBuilder builder;
2904 1 : module = builder.module();
2905 1 : byte f1 = builder.AddSignature(sigs.i_i());
2906 1 : byte f2 = builder.AddSignature(sigs.i_ii());
2907 : ExpectValidates(
2908 : sigs.i_ii(),
2909 : {WASM_GET_LOCAL(0),
2910 2 : WASM_BLOCK_X(f1, WASM_GET_LOCAL(1), WASM_I32_ADD(WASM_NOP, WASM_NOP))});
2911 : ExpectValidates(sigs.i_ii(),
2912 : {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2913 2 : WASM_BLOCK_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP))});
2914 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2915 : WASM_BLOCK_X(f1, WASM_NOP),
2916 2 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2917 : ExpectFailure(sigs.i_ii(),
2918 2 : {WASM_BLOCK_X(f1, WASM_NOP), WASM_RETURN1(WASM_GET_LOCAL(0))});
2919 : ExpectFailure(sigs.i_ii(), {WASM_BLOCK_X(f1, WASM_GET_LOCAL(0)),
2920 2 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2921 : ExpectFailure(
2922 : sigs.i_ii(),
2923 : {WASM_GET_LOCAL(0), WASM_BLOCK_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP)),
2924 2 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2925 : ExpectFailure(sigs.i_ii(),
2926 : {WASM_GET_LOCAL(0), WASM_BLOCK_X(f1, WASM_F32_NEG(WASM_NOP)),
2927 2 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2928 1 : }
2929 :
2930 15189 : TEST_F(FunctionBodyDecoderTest, LoopParam) {
2931 1 : WASM_FEATURE_SCOPE(mv);
2932 1 : TestModuleBuilder builder;
2933 1 : module = builder.module();
2934 1 : byte f1 = builder.AddSignature(sigs.i_i());
2935 1 : byte f2 = builder.AddSignature(sigs.i_ii());
2936 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0),
2937 : WASM_LOOP_X(f1, WASM_GET_LOCAL(1),
2938 2 : WASM_I32_ADD(WASM_NOP, WASM_NOP))});
2939 : ExpectValidates(sigs.i_ii(),
2940 : {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2941 2 : WASM_LOOP_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP))});
2942 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2943 : WASM_LOOP_X(f1, WASM_NOP),
2944 2 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2945 : ExpectFailure(sigs.i_ii(),
2946 2 : {WASM_LOOP_X(f1, WASM_NOP), WASM_RETURN1(WASM_GET_LOCAL(0))});
2947 : ExpectFailure(sigs.i_ii(), {WASM_LOOP_X(f1, WASM_GET_LOCAL(0)),
2948 2 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2949 : ExpectFailure(sigs.i_ii(), {WASM_GET_LOCAL(0),
2950 : WASM_LOOP_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP)),
2951 2 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2952 : ExpectFailure(sigs.i_ii(),
2953 : {WASM_GET_LOCAL(0), WASM_LOOP_X(f1, WASM_F32_NEG(WASM_NOP)),
2954 2 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2955 1 : }
2956 :
2957 15189 : TEST_F(FunctionBodyDecoderTest, LoopParamBr) {
2958 1 : WASM_FEATURE_SCOPE(mv);
2959 1 : TestModuleBuilder builder;
2960 1 : module = builder.module();
2961 1 : byte f1 = builder.AddSignature(sigs.i_i());
2962 1 : byte f2 = builder.AddSignature(sigs.i_ii());
2963 : ExpectValidates(sigs.i_ii(),
2964 2 : {WASM_GET_LOCAL(0), WASM_LOOP_X(f1, WASM_BR(0))});
2965 : ExpectValidates(
2966 : sigs.i_ii(),
2967 2 : {WASM_GET_LOCAL(0), WASM_LOOP_X(f1, WASM_BRV(0, WASM_GET_LOCAL(1)))});
2968 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2969 2 : WASM_LOOP_X(f2, WASM_BR(0))});
2970 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0),
2971 2 : WASM_LOOP_X(f1, WASM_BLOCK_X(f1, WASM_BR(1)))});
2972 : ExpectFailure(sigs.i_ii(),
2973 : {WASM_GET_LOCAL(0), WASM_LOOP_X(f1, WASM_BLOCK(WASM_BR(1))),
2974 2 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2975 : ExpectFailure(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2976 : WASM_LOOP_X(f2, WASM_BLOCK_X(f1, WASM_BR(1))),
2977 2 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2978 1 : }
2979 :
2980 15189 : TEST_F(FunctionBodyDecoderTest, IfParam) {
2981 1 : WASM_FEATURE_SCOPE(mv);
2982 1 : TestModuleBuilder builder;
2983 1 : module = builder.module();
2984 1 : byte f1 = builder.AddSignature(sigs.i_i());
2985 1 : byte f2 = builder.AddSignature(sigs.i_ii());
2986 : ExpectValidates(sigs.i_ii(),
2987 : {WASM_GET_LOCAL(0),
2988 : WASM_IF_X(f1, WASM_GET_LOCAL(0),
2989 2 : WASM_I32_ADD(WASM_NOP, WASM_GET_LOCAL(1)))});
2990 : ExpectValidates(sigs.i_ii(),
2991 : {WASM_GET_LOCAL(0),
2992 : WASM_IF_ELSE_X(f1, WASM_GET_LOCAL(0),
2993 : WASM_I32_ADD(WASM_NOP, WASM_GET_LOCAL(1)),
2994 2 : WASM_I32_EQZ(WASM_NOP))});
2995 : ExpectValidates(
2996 : sigs.i_ii(),
2997 : {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2998 : WASM_IF_ELSE_X(f2, WASM_GET_LOCAL(0), WASM_I32_ADD(WASM_NOP, WASM_NOP),
2999 2 : WASM_I32_MUL(WASM_NOP, WASM_NOP))});
3000 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
3001 : WASM_IF_X(f1, WASM_GET_LOCAL(0), WASM_NOP),
3002 2 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
3003 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
3004 : WASM_IF_ELSE_X(f1, WASM_GET_LOCAL(0), WASM_NOP,
3005 : WASM_I32_EQZ(WASM_NOP)),
3006 2 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
3007 1 : }
3008 :
3009 15189 : TEST_F(FunctionBodyDecoderTest, Regression709741) {
3010 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals - 1);
3011 2 : ExpectValidates(sigs.v_v(), {WASM_NOP});
3012 1 : byte code[] = {WASM_NOP, WASM_END};
3013 :
3014 3 : for (size_t i = 0; i < arraysize(code); ++i) {
3015 2 : FunctionBody body(sigs.v_v(), 0, code, code + i);
3016 2 : WasmFeatures unused_detected_features;
3017 : DecodeResult result =
3018 : VerifyWasmCode(zone()->allocator(), kAllWasmFeatures, nullptr,
3019 4 : &unused_detected_features, body);
3020 2 : if (result.ok()) {
3021 0 : std::ostringstream str;
3022 0 : str << "Expected verification to fail";
3023 : }
3024 : }
3025 1 : }
3026 :
3027 15189 : TEST_F(FunctionBodyDecoderTest, MemoryInit) {
3028 1 : TestModuleBuilder builder;
3029 : builder.InitializeMemory();
3030 : builder.SetDataSegmentCount(1);
3031 1 : module = builder.module();
3032 :
3033 : ExpectFailure(sigs.v_v(),
3034 2 : {WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3035 1 : WASM_FEATURE_SCOPE(bulk_memory);
3036 : ExpectValidates(sigs.v_v(),
3037 2 : {WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3038 : ExpectFailure(sigs.v_v(),
3039 2 : {WASM_TABLE_INIT(1, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3040 1 : }
3041 :
3042 15189 : TEST_F(FunctionBodyDecoderTest, MemoryInitInvalid) {
3043 1 : TestModuleBuilder builder;
3044 : builder.InitializeMemory();
3045 : builder.SetDataSegmentCount(1);
3046 1 : module = builder.module();
3047 :
3048 1 : WASM_FEATURE_SCOPE(bulk_memory);
3049 : byte code[] = {WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO),
3050 1 : WASM_END};
3051 13 : for (size_t i = 0; i <= arraysize(code); ++i) {
3052 12 : Validate(i == arraysize(code), sigs.v_v(), VectorOf(code, i), kOmitEnd);
3053 : }
3054 1 : }
3055 :
3056 15189 : TEST_F(FunctionBodyDecoderTest, DataDrop) {
3057 1 : TestModuleBuilder builder;
3058 : builder.InitializeMemory();
3059 : builder.SetDataSegmentCount(1);
3060 1 : module = builder.module();
3061 :
3062 2 : ExpectFailure(sigs.v_v(), {WASM_DATA_DROP(0)});
3063 1 : WASM_FEATURE_SCOPE(bulk_memory);
3064 2 : ExpectValidates(sigs.v_v(), {WASM_DATA_DROP(0)});
3065 2 : ExpectFailure(sigs.v_v(), {WASM_DATA_DROP(1)});
3066 1 : }
3067 :
3068 15189 : TEST_F(FunctionBodyDecoderTest, MemoryCopy) {
3069 1 : TestModuleBuilder builder;
3070 : builder.InitializeMemory();
3071 1 : module = builder.module();
3072 :
3073 : ExpectFailure(sigs.v_v(),
3074 2 : {WASM_MEMORY_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3075 1 : WASM_FEATURE_SCOPE(bulk_memory);
3076 : ExpectValidates(sigs.v_v(),
3077 2 : {WASM_MEMORY_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3078 1 : }
3079 :
3080 15189 : TEST_F(FunctionBodyDecoderTest, MemoryFill) {
3081 1 : TestModuleBuilder builder;
3082 : builder.InitializeMemory();
3083 1 : module = builder.module();
3084 :
3085 : ExpectFailure(sigs.v_v(),
3086 2 : {WASM_MEMORY_FILL(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3087 1 : WASM_FEATURE_SCOPE(bulk_memory);
3088 : ExpectValidates(sigs.v_v(),
3089 2 : {WASM_MEMORY_FILL(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3090 1 : }
3091 :
3092 15189 : TEST_F(FunctionBodyDecoderTest, BulkMemoryOpsWithoutMemory) {
3093 1 : WASM_FEATURE_SCOPE(bulk_memory);
3094 : ExpectFailure(sigs.v_v(),
3095 2 : {WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3096 : ExpectFailure(sigs.v_v(),
3097 2 : {WASM_MEMORY_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3098 : ExpectFailure(sigs.v_v(),
3099 2 : {WASM_MEMORY_FILL(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3100 1 : }
3101 :
3102 15189 : TEST_F(FunctionBodyDecoderTest, TableInit) {
3103 1 : TestModuleBuilder builder;
3104 : builder.InitializeTable();
3105 : builder.AddPassiveElementSegment();
3106 1 : module = builder.module();
3107 :
3108 : ExpectFailure(sigs.v_v(),
3109 2 : {WASM_TABLE_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3110 1 : WASM_FEATURE_SCOPE(bulk_memory);
3111 : ExpectValidates(sigs.v_v(),
3112 2 : {WASM_TABLE_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3113 : ExpectFailure(sigs.v_v(),
3114 2 : {WASM_TABLE_INIT(1, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3115 1 : }
3116 :
3117 15189 : TEST_F(FunctionBodyDecoderTest, TableInitInvalid) {
3118 1 : TestModuleBuilder builder;
3119 : builder.InitializeTable();
3120 : builder.AddPassiveElementSegment();
3121 1 : module = builder.module();
3122 :
3123 1 : WASM_FEATURE_SCOPE(bulk_memory);
3124 1 : byte code[] = {WASM_TABLE_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO), WASM_END};
3125 13 : for (size_t i = 0; i <= arraysize(code); ++i) {
3126 12 : Validate(i == arraysize(code), sigs.v_v(), VectorOf(code, i), kOmitEnd);
3127 : }
3128 1 : }
3129 :
3130 15189 : TEST_F(FunctionBodyDecoderTest, ElemDrop) {
3131 1 : TestModuleBuilder builder;
3132 : builder.InitializeTable();
3133 : builder.AddPassiveElementSegment();
3134 1 : module = builder.module();
3135 :
3136 2 : ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(0)});
3137 1 : WASM_FEATURE_SCOPE(bulk_memory);
3138 2 : ExpectValidates(sigs.v_v(), {WASM_ELEM_DROP(0)});
3139 2 : ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(1)});
3140 1 : }
3141 :
3142 15189 : TEST_F(FunctionBodyDecoderTest, TableCopy) {
3143 1 : TestModuleBuilder builder;
3144 : builder.InitializeTable();
3145 1 : module = builder.module();
3146 :
3147 2 : ExpectFailure(sigs.v_v(), {WASM_TABLE_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3148 1 : WASM_FEATURE_SCOPE(bulk_memory);
3149 : ExpectValidates(sigs.v_v(),
3150 2 : {WASM_TABLE_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3151 1 : }
3152 :
3153 15189 : TEST_F(FunctionBodyDecoderTest, BulkTableOpsWithoutTable) {
3154 1 : TestModuleBuilder builder;
3155 : builder.InitializeTable();
3156 : builder.AddPassiveElementSegment();
3157 :
3158 1 : WASM_FEATURE_SCOPE(bulk_memory);
3159 : ExpectFailure(sigs.v_v(),
3160 2 : {WASM_TABLE_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3161 2 : ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(0)});
3162 2 : ExpectFailure(sigs.v_v(), {WASM_TABLE_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3163 1 : }
3164 :
3165 3 : class BranchTableIteratorTest : public TestWithZone {
3166 : public:
3167 3 : BranchTableIteratorTest() : TestWithZone() {}
3168 16 : void CheckBrTableSize(const byte* start, const byte* end) {
3169 : Decoder decoder(start, end);
3170 16 : BranchTableImmediate<Decoder::kValidate> operand(&decoder, start);
3171 : BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand);
3172 32 : EXPECT_EQ(end - start - 1u, iterator.length());
3173 16 : EXPECT_TRUE(decoder.ok());
3174 16 : }
3175 2 : void CheckBrTableError(const byte* start, const byte* end) {
3176 : Decoder decoder(start, end);
3177 2 : BranchTableImmediate<Decoder::kValidate> operand(&decoder, start);
3178 : BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand);
3179 2 : iterator.length();
3180 4 : EXPECT_FALSE(decoder.ok());
3181 2 : }
3182 : };
3183 :
3184 : #define CHECK_BR_TABLE_LENGTH(...) \
3185 : { \
3186 : static byte code[] = {kExprBrTable, __VA_ARGS__}; \
3187 : CheckBrTableSize(code, code + sizeof(code)); \
3188 : }
3189 :
3190 : #define CHECK_BR_TABLE_ERROR(...) \
3191 : { \
3192 : static byte code[] = {kExprBrTable, __VA_ARGS__}; \
3193 : CheckBrTableError(code, code + sizeof(code)); \
3194 : }
3195 :
3196 15189 : TEST_F(BranchTableIteratorTest, count0) {
3197 1 : CHECK_BR_TABLE_LENGTH(0, U32V_1(1));
3198 1 : CHECK_BR_TABLE_LENGTH(0, U32V_2(200));
3199 1 : CHECK_BR_TABLE_LENGTH(0, U32V_3(30000));
3200 1 : CHECK_BR_TABLE_LENGTH(0, U32V_4(400000));
3201 :
3202 1 : CHECK_BR_TABLE_LENGTH(0, U32V_1(2));
3203 1 : CHECK_BR_TABLE_LENGTH(0, U32V_2(300));
3204 1 : CHECK_BR_TABLE_LENGTH(0, U32V_3(40000));
3205 1 : CHECK_BR_TABLE_LENGTH(0, U32V_4(500000));
3206 1 : }
3207 :
3208 15189 : TEST_F(BranchTableIteratorTest, count1) {
3209 1 : CHECK_BR_TABLE_LENGTH(1, U32V_1(1), U32V_1(6));
3210 1 : CHECK_BR_TABLE_LENGTH(1, U32V_2(200), U32V_1(8));
3211 1 : CHECK_BR_TABLE_LENGTH(1, U32V_3(30000), U32V_1(9));
3212 1 : CHECK_BR_TABLE_LENGTH(1, U32V_4(400000), U32V_1(11));
3213 :
3214 1 : CHECK_BR_TABLE_LENGTH(1, U32V_1(2), U32V_2(6));
3215 1 : CHECK_BR_TABLE_LENGTH(1, U32V_2(300), U32V_2(7));
3216 1 : CHECK_BR_TABLE_LENGTH(1, U32V_3(40000), U32V_2(8));
3217 1 : CHECK_BR_TABLE_LENGTH(1, U32V_4(500000), U32V_2(9));
3218 1 : }
3219 :
3220 15189 : TEST_F(BranchTableIteratorTest, error0) {
3221 1 : CHECK_BR_TABLE_ERROR(0);
3222 1 : CHECK_BR_TABLE_ERROR(1, U32V_1(33));
3223 1 : }
3224 :
3225 : #undef CHECK_BR_TABLE_LENGTH
3226 : #undef CHECK_BR_TABLE_ERROR
3227 :
3228 : struct PrintOpcodes {
3229 : const byte* start;
3230 : const byte* end;
3231 : };
3232 0 : std::ostream& operator<<(std::ostream& out, const PrintOpcodes& range) {
3233 0 : out << "First opcode: \""
3234 0 : << WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(*range.start))
3235 0 : << "\"\nall bytes: [";
3236 0 : for (const byte* b = range.start; b < range.end; ++b) {
3237 0 : out << (b == range.start ? "" : ", ") << uint32_t{*b} << "/"
3238 0 : << AsHex(*b, 2, true);
3239 : }
3240 0 : return out << "]";
3241 : }
3242 :
3243 9 : class WasmOpcodeLengthTest : public TestWithZone {
3244 : public:
3245 9 : WasmOpcodeLengthTest() : TestWithZone() {}
3246 :
3247 : template <typename... Bytes>
3248 320 : void ExpectLength(unsigned expected, Bytes... bytes) {
3249 320 : const byte code[] = {bytes..., 0, 0, 0, 0, 0, 0, 0, 0};
3250 640 : EXPECT_EQ(expected, OpcodeLength(code, code + sizeof(code)))
3251 0 : << PrintOpcodes{code, code + sizeof...(bytes)};
3252 320 : }
3253 : };
3254 :
3255 15189 : TEST_F(WasmOpcodeLengthTest, Statements) {
3256 1 : ExpectLength(1, kExprNop);
3257 1 : ExpectLength(1, kExprElse);
3258 1 : ExpectLength(1, kExprEnd);
3259 1 : ExpectLength(1, kExprSelect);
3260 1 : ExpectLength(1, kExprCatch);
3261 1 : ExpectLength(1, kExprRethrow);
3262 1 : ExpectLength(2, kExprBr);
3263 1 : ExpectLength(2, kExprBrIf);
3264 1 : ExpectLength(2, kExprThrow);
3265 1 : ExpectLength(3, kExprBrOnExn);
3266 1 : ExpectLength(2, kExprBlock, kLocalI32);
3267 1 : ExpectLength(2, kExprLoop, kLocalI32);
3268 1 : ExpectLength(2, kExprIf, kLocalI32);
3269 1 : ExpectLength(2, kExprTry, kLocalI32);
3270 1 : }
3271 :
3272 15189 : TEST_F(WasmOpcodeLengthTest, MiscExpressions) {
3273 1 : ExpectLength(5, kExprF32Const);
3274 1 : ExpectLength(9, kExprF64Const);
3275 1 : ExpectLength(1, kExprRefNull);
3276 1 : ExpectLength(2, kExprGetLocal);
3277 1 : ExpectLength(2, kExprSetLocal);
3278 1 : ExpectLength(2, kExprGetGlobal);
3279 1 : ExpectLength(2, kExprSetGlobal);
3280 1 : ExpectLength(2, kExprCallFunction);
3281 1 : ExpectLength(3, kExprCallIndirect);
3282 1 : }
3283 :
3284 15189 : TEST_F(WasmOpcodeLengthTest, I32Const) {
3285 1 : ExpectLength(2, kExprI32Const, U32V_1(1));
3286 1 : ExpectLength(3, kExprI32Const, U32V_2(999));
3287 1 : ExpectLength(4, kExprI32Const, U32V_3(9999));
3288 1 : ExpectLength(5, kExprI32Const, U32V_4(999999));
3289 1 : ExpectLength(6, kExprI32Const, U32V_5(99999999));
3290 1 : }
3291 :
3292 15189 : TEST_F(WasmOpcodeLengthTest, I64Const) {
3293 1 : ExpectLength(2, kExprI64Const, U32V_1(1));
3294 1 : ExpectLength(3, kExprI64Const, U32V_2(99));
3295 1 : ExpectLength(4, kExprI64Const, U32V_3(9999));
3296 1 : ExpectLength(5, kExprI64Const, U32V_4(99999));
3297 1 : ExpectLength(6, kExprI64Const, U32V_5(9999999));
3298 1 : ExpectLength(7, WASM_I64V_6(777777));
3299 1 : ExpectLength(8, WASM_I64V_7(7777777));
3300 1 : ExpectLength(9, WASM_I64V_8(77777777));
3301 1 : ExpectLength(10, WASM_I64V_9(777777777));
3302 1 : }
3303 :
3304 15189 : TEST_F(WasmOpcodeLengthTest, VariableLength) {
3305 1 : ExpectLength(2, kExprGetGlobal, U32V_1(1));
3306 1 : ExpectLength(3, kExprGetGlobal, U32V_2(33));
3307 1 : ExpectLength(4, kExprGetGlobal, U32V_3(44));
3308 1 : ExpectLength(5, kExprGetGlobal, U32V_4(66));
3309 1 : ExpectLength(6, kExprGetGlobal, U32V_5(77));
3310 1 : }
3311 :
3312 15189 : TEST_F(WasmOpcodeLengthTest, LoadsAndStores) {
3313 1 : ExpectLength(3, kExprI32LoadMem8S);
3314 1 : ExpectLength(3, kExprI32LoadMem8U);
3315 1 : ExpectLength(3, kExprI32LoadMem16S);
3316 1 : ExpectLength(3, kExprI32LoadMem16U);
3317 1 : ExpectLength(3, kExprI32LoadMem);
3318 1 : ExpectLength(3, kExprI64LoadMem8S);
3319 1 : ExpectLength(3, kExprI64LoadMem8U);
3320 1 : ExpectLength(3, kExprI64LoadMem16S);
3321 1 : ExpectLength(3, kExprI64LoadMem16U);
3322 1 : ExpectLength(3, kExprI64LoadMem32S);
3323 1 : ExpectLength(3, kExprI64LoadMem32U);
3324 1 : ExpectLength(3, kExprI64LoadMem);
3325 1 : ExpectLength(3, kExprF32LoadMem);
3326 1 : ExpectLength(3, kExprF64LoadMem);
3327 :
3328 1 : ExpectLength(3, kExprI32StoreMem8);
3329 1 : ExpectLength(3, kExprI32StoreMem16);
3330 1 : ExpectLength(3, kExprI32StoreMem);
3331 1 : ExpectLength(3, kExprI64StoreMem8);
3332 1 : ExpectLength(3, kExprI64StoreMem16);
3333 1 : ExpectLength(3, kExprI64StoreMem32);
3334 1 : ExpectLength(3, kExprI64StoreMem);
3335 1 : ExpectLength(3, kExprF32StoreMem);
3336 1 : ExpectLength(3, kExprF64StoreMem);
3337 1 : }
3338 :
3339 15189 : TEST_F(WasmOpcodeLengthTest, MiscMemExpressions) {
3340 1 : ExpectLength(2, kExprMemorySize);
3341 1 : ExpectLength(2, kExprMemoryGrow);
3342 1 : }
3343 :
3344 15189 : TEST_F(WasmOpcodeLengthTest, SimpleExpressions) {
3345 : #define SIMPLE_OPCODE(name, byte, sig) byte,
3346 : static constexpr uint8_t kSimpleOpcodes[] = {
3347 : FOREACH_SIMPLE_OPCODE(SIMPLE_OPCODE)};
3348 : #undef SIMPLE_OPCODE
3349 124 : for (uint8_t simple_opcode : kSimpleOpcodes) {
3350 123 : ExpectLength(1, simple_opcode);
3351 : }
3352 1 : }
3353 :
3354 15189 : TEST_F(WasmOpcodeLengthTest, SimdExpressions) {
3355 : #define TEST_SIMD(name, opcode, sig) \
3356 : ExpectLength(2, kSimdPrefix, static_cast<byte>(kExpr##name & 0xFF));
3357 1 : FOREACH_SIMD_0_OPERAND_OPCODE(TEST_SIMD)
3358 : #undef TEST_SIMD
3359 : #define TEST_SIMD(name, opcode, sig) \
3360 : ExpectLength(3, kSimdPrefix, static_cast<byte>(kExpr##name & 0xFF));
3361 1 : FOREACH_SIMD_1_OPERAND_OPCODE(TEST_SIMD)
3362 : #undef TEST_SIMD
3363 1 : ExpectLength(18, kSimdPrefix, static_cast<byte>(kExprS8x16Shuffle & 0xFF));
3364 : // test for bad simd opcode
3365 1 : ExpectLength(2, kSimdPrefix, 0xFF);
3366 1 : }
3367 :
3368 : typedef ZoneVector<ValueType> TypesOfLocals;
3369 :
3370 14 : class LocalDeclDecoderTest : public TestWithZone {
3371 : public:
3372 : v8::internal::AccountingAllocator allocator;
3373 : WasmFeatures enabled_features_;
3374 :
3375 332 : size_t ExpectRun(TypesOfLocals map, size_t pos, ValueType expected,
3376 : size_t count) {
3377 2235 : for (size_t i = 0; i < count; i++) {
3378 3806 : EXPECT_EQ(expected, map[pos++]);
3379 : }
3380 332 : return pos;
3381 : }
3382 :
3383 : bool DecodeLocalDecls(BodyLocalDecls* decls, const byte* start,
3384 : const byte* end) {
3385 95 : return i::wasm::DecodeLocalDecls(enabled_features_, decls, start, end);
3386 : }
3387 : };
3388 :
3389 15189 : TEST_F(LocalDeclDecoderTest, EmptyLocals) {
3390 1 : BodyLocalDecls decls(zone());
3391 : bool result = DecodeLocalDecls(&decls, nullptr, nullptr);
3392 2 : EXPECT_FALSE(result);
3393 1 : }
3394 :
3395 15189 : TEST_F(LocalDeclDecoderTest, NoLocals) {
3396 : static const byte data[] = {0};
3397 1 : BodyLocalDecls decls(zone());
3398 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3399 1 : EXPECT_TRUE(result);
3400 1 : EXPECT_TRUE(decls.type_list.empty());
3401 1 : }
3402 :
3403 15189 : TEST_F(LocalDeclDecoderTest, OneLocal) {
3404 1 : WASM_FEATURE_SCOPE(anyref);
3405 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
3406 5 : ValueType type = kValueTypes[i];
3407 : const byte data[] = {1, 1,
3408 5 : static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
3409 5 : BodyLocalDecls decls(zone());
3410 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3411 5 : EXPECT_TRUE(result);
3412 15 : EXPECT_EQ(1u, decls.type_list.size());
3413 :
3414 : TypesOfLocals map = decls.type_list;
3415 10 : EXPECT_EQ(type, map[0]);
3416 : }
3417 1 : }
3418 :
3419 15189 : TEST_F(LocalDeclDecoderTest, FiveLocals) {
3420 1 : WASM_FEATURE_SCOPE(anyref);
3421 6 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
3422 5 : ValueType type = kValueTypes[i];
3423 : const byte data[] = {1, 5,
3424 5 : static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
3425 5 : BodyLocalDecls decls(zone());
3426 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3427 5 : EXPECT_TRUE(result);
3428 10 : EXPECT_EQ(sizeof(data), decls.encoded_size);
3429 15 : EXPECT_EQ(5u, decls.type_list.size());
3430 :
3431 : TypesOfLocals map = decls.type_list;
3432 15 : EXPECT_EQ(5u, map.size());
3433 5 : ExpectRun(map, 0, type, 5);
3434 : }
3435 1 : }
3436 :
3437 15189 : TEST_F(LocalDeclDecoderTest, MixedLocals) {
3438 4 : for (byte a = 0; a < 3; a++) {
3439 9 : for (byte b = 0; b < 3; b++) {
3440 27 : for (byte c = 0; c < 3; c++) {
3441 81 : for (byte d = 0; d < 3; d++) {
3442 : const byte data[] = {4, a, kLocalI32, b, kLocalI64,
3443 81 : c, kLocalF32, d, kLocalF64};
3444 81 : BodyLocalDecls decls(zone());
3445 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3446 81 : EXPECT_TRUE(result);
3447 162 : EXPECT_EQ(sizeof(data), decls.encoded_size);
3448 243 : EXPECT_EQ(static_cast<uint32_t>(a + b + c + d),
3449 0 : decls.type_list.size());
3450 :
3451 : TypesOfLocals map = decls.type_list;
3452 :
3453 : size_t pos = 0;
3454 162 : pos = ExpectRun(map, pos, kWasmI32, a);
3455 162 : pos = ExpectRun(map, pos, kWasmI64, b);
3456 162 : pos = ExpectRun(map, pos, kWasmF32, c);
3457 162 : pos = ExpectRun(map, pos, kWasmF64, d);
3458 : }
3459 : }
3460 : }
3461 : }
3462 1 : }
3463 :
3464 15189 : TEST_F(LocalDeclDecoderTest, UseEncoder) {
3465 1 : const byte* data = nullptr;
3466 1 : const byte* end = nullptr;
3467 1 : LocalDeclEncoder local_decls(zone());
3468 :
3469 1 : local_decls.AddLocals(5, kWasmF32);
3470 1 : local_decls.AddLocals(1337, kWasmI32);
3471 1 : local_decls.AddLocals(212, kWasmI64);
3472 1 : local_decls.Prepend(zone(), &data, &end);
3473 :
3474 : BodyLocalDecls decls(zone());
3475 1 : bool result = DecodeLocalDecls(&decls, data, end);
3476 1 : EXPECT_TRUE(result);
3477 3 : EXPECT_EQ(5u + 1337u + 212u, decls.type_list.size());
3478 :
3479 : TypesOfLocals map = decls.type_list;
3480 : size_t pos = 0;
3481 1 : pos = ExpectRun(map, pos, kWasmF32, 5);
3482 1 : pos = ExpectRun(map, pos, kWasmI32, 1337);
3483 1 : pos = ExpectRun(map, pos, kWasmI64, 212);
3484 1 : }
3485 :
3486 15189 : TEST_F(LocalDeclDecoderTest, ExceptRef) {
3487 1 : WASM_FEATURE_SCOPE(eh);
3488 1 : ValueType type = kWasmExceptRef;
3489 : const byte data[] = {1, 1,
3490 1 : static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
3491 1 : BodyLocalDecls decls(zone());
3492 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3493 1 : EXPECT_TRUE(result);
3494 3 : EXPECT_EQ(1u, decls.type_list.size());
3495 :
3496 : TypesOfLocals map = decls.type_list;
3497 2 : EXPECT_EQ(type, map[0]);
3498 1 : }
3499 :
3500 8 : class BytecodeIteratorTest : public TestWithZone {};
3501 :
3502 15189 : TEST_F(BytecodeIteratorTest, SimpleForeach) {
3503 1 : byte code[] = {WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO)};
3504 1 : BytecodeIterator iter(code, code + sizeof(code));
3505 : WasmOpcode expected[] = {kExprI32Const, kExprIf, kExprI32Const,
3506 1 : kExprElse, kExprI32Const, kExprEnd};
3507 1 : size_t pos = 0;
3508 14 : for (WasmOpcode opcode : iter.opcodes()) {
3509 6 : if (pos >= arraysize(expected)) {
3510 0 : EXPECT_TRUE(false);
3511 0 : break;
3512 : }
3513 12 : EXPECT_EQ(expected[pos++], opcode);
3514 : }
3515 2 : EXPECT_EQ(arraysize(expected), pos);
3516 1 : }
3517 :
3518 15189 : TEST_F(BytecodeIteratorTest, ForeachTwice) {
3519 1 : byte code[] = {WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO)};
3520 1 : BytecodeIterator iter(code, code + sizeof(code));
3521 1 : int count = 0;
3522 :
3523 : count = 0;
3524 8 : for (WasmOpcode opcode : iter.opcodes()) {
3525 : USE(opcode);
3526 6 : count++;
3527 : }
3528 2 : EXPECT_EQ(6, count);
3529 :
3530 1 : count = 0;
3531 8 : for (WasmOpcode opcode : iter.opcodes()) {
3532 : USE(opcode);
3533 6 : count++;
3534 : }
3535 2 : EXPECT_EQ(6, count);
3536 1 : }
3537 :
3538 15189 : TEST_F(BytecodeIteratorTest, ForeachOffset) {
3539 1 : byte code[] = {WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO)};
3540 1 : BytecodeIterator iter(code, code + sizeof(code));
3541 1 : int count = 0;
3542 :
3543 : count = 0;
3544 7 : for (auto offset : iter.offsets()) {
3545 : USE(offset);
3546 6 : count++;
3547 : }
3548 2 : EXPECT_EQ(6, count);
3549 :
3550 1 : count = 0;
3551 7 : for (auto offset : iter.offsets()) {
3552 : USE(offset);
3553 6 : count++;
3554 : }
3555 2 : EXPECT_EQ(6, count);
3556 1 : }
3557 :
3558 15189 : TEST_F(BytecodeIteratorTest, WithLocalDecls) {
3559 1 : byte code[] = {1, 1, kLocalI32, WASM_I32V_1(9), WASM_I32V_1(11)};
3560 1 : BodyLocalDecls decls(zone());
3561 1 : BytecodeIterator iter(code, code + sizeof(code), &decls);
3562 :
3563 2 : EXPECT_EQ(3u, decls.encoded_size);
3564 2 : EXPECT_EQ(3u, iter.pc_offset());
3565 2 : EXPECT_TRUE(iter.has_next());
3566 3 : EXPECT_EQ(kExprI32Const, iter.current());
3567 1 : iter.next();
3568 2 : EXPECT_TRUE(iter.has_next());
3569 3 : EXPECT_EQ(kExprI32Const, iter.current());
3570 1 : iter.next();
3571 2 : EXPECT_FALSE(iter.has_next());
3572 1 : }
3573 :
3574 : #undef WASM_FEATURE_SCOPE
3575 : #undef B1
3576 : #undef B2
3577 : #undef B3
3578 : #undef WASM_IF_OP
3579 : #undef WASM_LOOP_OP
3580 : #undef WASM_BRV_IF_ZERO
3581 :
3582 : } // namespace function_body_decoder_unittest
3583 : } // namespace wasm
3584 : } // namespace internal
3585 9111 : } // namespace v8
|