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 502 : class FunctionBodyDecoderTest : public TestWithZone {
59 : public:
60 : using LocalsDecl = std::pair<uint32_t, ValueType>;
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 753 : 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 22707 : Vector<const byte> PrepareBytecode(Vector<const byte> code,
78 : AppendEnd append_end) {
79 22707 : size_t locals_size = local_decls.Size();
80 : size_t total_size =
81 22707 : code.size() + locals_size + (append_end == kAppendEnd ? 1 : 0);
82 22707 : byte* buffer = static_cast<byte*>(zone()->New(total_size));
83 : // Prepend the local decls to the code.
84 22707 : local_decls.Emit(buffer);
85 : // Emit the code.
86 22707 : if (code.size() > 0) {
87 22703 : memcpy(buffer + locals_size, code.start(), code.size());
88 : }
89 22707 : if (append_end == kAppendEnd) {
90 : // Append an extra end opcode.
91 22655 : buffer[total_size - 1] = kExprEnd;
92 : }
93 :
94 22707 : 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 : 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 22707 : 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 22970 : PrepareBytecode(CodeToVector(std::forward<Code>(raw_code)), append_end);
117 :
118 : // Validate the code.
119 : FunctionBody body(sig, 0, code.start(), code.end());
120 22707 : WasmFeatures unused_detected_features;
121 : DecodeResult result =
122 22707 : VerifyWasmCode(zone()->allocator(), enabled_features_, module,
123 45414 : &unused_detected_features, body);
124 :
125 45414 : std::ostringstream str;
126 22707 : if (result.failed()) {
127 : str << "Verification failed: pc = +" << result.error().offset()
128 : << ", msg = " << result.error().message();
129 : } else {
130 4138 : str << "Verification successed, expected failure";
131 : }
132 45414 : EXPECT_EQ(result.ok(), expected_success) << str.str();
133 22707 : if (result.failed() && message) {
134 4 : EXPECT_THAT(result.error().message(), ::testing::HasSubstr(message));
135 : }
136 22707 : }
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 3581 : 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 17806 : Validate(false, sig, std::forward<Code>(raw_code), append_end, message);
150 : }
151 :
152 120 : 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 1320 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
159 6600 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
160 33000 : 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 : 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 836 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
189 4180 : 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 44 : explicit EnableBoolScope(bool* ptr) : prev_(*ptr), ptr_(ptr) { *ptr = true; }
208 43 : ~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 746 : class TestModuleBuilder {
219 : public:
220 746 : explicit TestModuleBuilder(ModuleOrigin origin = kWasmOrigin) {
221 746 : mod.origin = origin;
222 : }
223 61 : byte AddGlobal(ValueType type, bool mutability = true) {
224 183 : mod.globals.push_back(
225 : {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 30 : byte AddSignature(FunctionSig* sig) {
230 30 : mod.signatures.push_back(sig);
231 30 : CHECK_LE(mod.signatures.size(), kMaxByteSizedLeb128);
232 30 : return static_cast<byte>(mod.signatures.size() - 1);
233 : }
234 653 : byte AddFunction(FunctionSig* sig) {
235 1959 : mod.functions.push_back({sig, // sig
236 : 0, // func_index
237 : 0, // sig_index
238 : {0, 0}, // code
239 : false, // import
240 : 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 7 : mod.exceptions.emplace_back(sig);
251 7 : CHECK_LE(mod.signatures.size(), kMaxByteSizedLeb128);
252 7 : return static_cast<byte>(mod.exceptions.size() - 1);
253 : }
254 :
255 14 : byte AddTable(ValueType type, uint32_t initial_size, bool has_maximum_size,
256 : uint32_t maximum_size) {
257 14 : CHECK(type == kWasmAnyRef || type == kWasmAnyFunc);
258 14 : mod.tables.emplace_back();
259 : WasmTable& table = mod.tables.back();
260 14 : table.type = type;
261 14 : table.initial_size = initial_size;
262 14 : table.has_maximum_size = has_maximum_size;
263 14 : table.maximum_size = maximum_size;
264 14 : 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 11 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Int32Const1) {
295 1 : byte code[] = {kExprI32Const, 0};
296 257 : 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 15444 : TEST_F(FunctionBodyDecoderTest, RefNull) {
303 1 : WASM_FEATURE_SCOPE(anyref);
304 3 : ExpectValidates(sigs.r_v(), {kExprRefNull});
305 1 : }
306 :
307 15444 : TEST_F(FunctionBodyDecoderTest, EmptyFunction) {
308 3 : ExpectValidates(sigs.v_v(), {});
309 2 : ExpectFailure(sigs.i_i(), {});
310 1 : }
311 :
312 15444 : TEST_F(FunctionBodyDecoderTest, IncompleteIf1) {
313 1 : byte code[] = {kExprIf};
314 1 : ExpectFailure(sigs.v_v(), code);
315 : ExpectFailure(sigs.i_i(), code);
316 1 : }
317 :
318 15444 : TEST_F(FunctionBodyDecoderTest, Int32Const_fallthru) {
319 3 : ExpectValidates(sigs.i_i(), {WASM_I32V_1(0)});
320 1 : }
321 :
322 15444 : TEST_F(FunctionBodyDecoderTest, Int32Const_fallthru2) {
323 3 : ExpectFailure(sigs.i_i(), {WASM_I32V_1(0), WASM_I32V_1(1)});
324 1 : }
325 :
326 15444 : TEST_F(FunctionBodyDecoderTest, Int32Const) {
327 : const int kInc = 4498211;
328 1909 : 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 2862 : ExpectValidates(sigs.i_i(), {WASM_I32V(i)});
331 : }
332 1 : }
333 :
334 15444 : TEST_F(FunctionBodyDecoderTest, Int64Const) {
335 : const int kInc = 4498211;
336 1909 : for (int32_t i = kMinInt; i < kMaxInt - kInc; i = i + kInc) {
337 10494 : ExpectValidates(sigs.l_l(),
338 7632 : {WASM_I64V((static_cast<uint64_t>(i) << 32) | i)});
339 : }
340 1 : }
341 :
342 15444 : TEST_F(FunctionBodyDecoderTest, Float32Const) {
343 1 : byte code[] = {kExprF32Const, 0, 0, 0, 0};
344 : Address ptr = reinterpret_cast<Address>(code + 1);
345 61 : 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 15444 : 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 61 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Int32Const_off_end) {
361 1 : byte code[] = {kExprI32Const, 0xAA, 0xBB, 0xCC, 0x44};
362 :
363 9 : for (size_t size = 1; size <= 4; ++size) {
364 12 : 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 15444 : TEST_F(FunctionBodyDecoderTest, GetLocal0_param) {
371 1 : ExpectValidates(sigs.i_i(), kCodeGetLocal0);
372 1 : }
373 :
374 15444 : TEST_F(FunctionBodyDecoderTest, GetLocal0_local) {
375 : AddLocals(kWasmI32, 1);
376 1 : ExpectValidates(sigs.i_v(), kCodeGetLocal0);
377 1 : }
378 :
379 15444 : TEST_F(FunctionBodyDecoderTest, TooManyLocals) {
380 : AddLocals(kWasmI32, 4034986500);
381 1 : ExpectFailure(sigs.i_v(), kCodeGetLocal0);
382 1 : }
383 :
384 15444 : TEST_F(FunctionBodyDecoderTest, GetLocal0_param_n) {
385 3 : FunctionSig* array[] = {sigs.i_i(), sigs.i_ii(), sigs.i_iii()};
386 :
387 7 : for (size_t i = 0; i < arraysize(array); i++) {
388 3 : ExpectValidates(array[i], kCodeGetLocal0);
389 : }
390 1 : }
391 :
392 15444 : TEST_F(FunctionBodyDecoderTest, GetLocalN_local) {
393 15 : for (byte i = 1; i < 8; i++) {
394 : AddLocals(kWasmI32, 1);
395 63 : for (byte j = 0; j < i; j++) {
396 84 : ExpectValidates(sigs.i_v(), {kExprGetLocal, j});
397 : }
398 : }
399 1 : }
400 :
401 15444 : TEST_F(FunctionBodyDecoderTest, GetLocal0_fail_no_params) {
402 1 : ExpectFailure(sigs.i_v(), kCodeGetLocal0);
403 1 : }
404 :
405 15444 : TEST_F(FunctionBodyDecoderTest, GetLocal1_fail_no_locals) {
406 1 : ExpectFailure(sigs.i_i(), kCodeGetLocal1);
407 1 : }
408 :
409 15444 : TEST_F(FunctionBodyDecoderTest, GetLocal_off_end) {
410 3 : ExpectFailure(sigs.i_i(), {kExprGetLocal});
411 1 : }
412 :
413 15444 : TEST_F(FunctionBodyDecoderTest, NumLocalBelowLimit) {
414 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals - 1);
415 3 : ExpectValidates(sigs.v_v(), {WASM_NOP});
416 1 : }
417 :
418 15444 : TEST_F(FunctionBodyDecoderTest, NumLocalAtLimit) {
419 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals);
420 3 : ExpectValidates(sigs.v_v(), {WASM_NOP});
421 1 : }
422 :
423 15444 : TEST_F(FunctionBodyDecoderTest, NumLocalAboveLimit) {
424 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals + 1);
425 3 : ExpectFailure(sigs.v_v(), {WASM_NOP});
426 1 : }
427 :
428 15444 : TEST_F(FunctionBodyDecoderTest, GetLocal_varint) {
429 : const int kMaxLocals = kV8MaxWasmFunctionLocals - 1;
430 : AddLocals(kWasmI32, kMaxLocals);
431 :
432 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, GetLocal_toomany) {
450 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals - 100);
451 : AddLocals(kWasmI32, 100);
452 :
453 3 : ExpectValidates(sigs.i_v(), {kExprGetLocal, U32V_1(66)});
454 2 : ExpectFailure(sigs.i_i(), {kExprGetLocal, U32V_1(66)});
455 1 : }
456 :
457 15444 : TEST_F(FunctionBodyDecoderTest, Binops_off_end) {
458 1 : byte code1[] = {0}; // [opcode]
459 37 : 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 37 : 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 37 : 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 15444 : TEST_F(FunctionBodyDecoderTest, BinopsAcrossBlock1) {
479 3 : ExpectFailure(sigs.i_i(), {WASM_ZERO, kExprBlock, kLocalI32, WASM_ZERO,
480 : kExprI32Add, kExprEnd});
481 1 : }
482 :
483 15444 : TEST_F(FunctionBodyDecoderTest, BinopsAcrossBlock2) {
484 3 : ExpectFailure(sigs.i_i(), {WASM_ZERO, WASM_ZERO, kExprBlock, kLocalI32,
485 : kExprI32Add, kExprEnd});
486 1 : }
487 :
488 15444 : TEST_F(FunctionBodyDecoderTest, BinopsAcrossBlock3) {
489 3 : ExpectFailure(sigs.i_i(), {WASM_ZERO, WASM_ZERO, kExprIf, kLocalI32,
490 : kExprI32Add, kExprElse, kExprI32Add, kExprEnd});
491 1 : }
492 :
493 15444 : TEST_F(FunctionBodyDecoderTest, Nop) {
494 3 : ExpectValidates(sigs.v_v(), {kExprNop});
495 1 : }
496 :
497 15444 : TEST_F(FunctionBodyDecoderTest, SetLocal0_void) {
498 3 : ExpectFailure(sigs.i_i(), {WASM_SET_LOCAL(0, WASM_ZERO)});
499 1 : }
500 :
501 15444 : TEST_F(FunctionBodyDecoderTest, SetLocal0_param) {
502 1 : ExpectFailure(sigs.i_i(), kCodeSetLocal0);
503 : ExpectFailure(sigs.f_ff(), kCodeSetLocal0);
504 : ExpectFailure(sigs.d_dd(), kCodeSetLocal0);
505 1 : }
506 :
507 15444 : TEST_F(FunctionBodyDecoderTest, TeeLocal0_param) {
508 1 : ExpectValidates(sigs.i_i(), kCodeTeeLocal0);
509 : ExpectFailure(sigs.f_ff(), kCodeTeeLocal0);
510 : ExpectFailure(sigs.d_dd(), kCodeTeeLocal0);
511 1 : }
512 :
513 15444 : TEST_F(FunctionBodyDecoderTest, SetLocal0_local) {
514 1 : ExpectFailure(sigs.i_v(), kCodeSetLocal0);
515 : 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 15444 : 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 15444 : TEST_F(FunctionBodyDecoderTest, TeeLocalN_local) {
528 15 : for (byte i = 1; i < 8; i++) {
529 : AddLocals(kWasmI32, 1);
530 63 : for (byte j = 0; j < i; j++) {
531 84 : 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 15444 : TEST_F(FunctionBodyDecoderTest, BlockN) {
538 : constexpr size_t kMaxSize = 200;
539 : byte buffer[kMaxSize + 3];
540 :
541 403 : 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 603 : ExpectValidates(sigs.v_i(), VectorOf(buffer, i + 3), kAppendEnd);
547 : }
548 1 : }
549 :
550 : #define WASM_EMPTY_BLOCK kExprBlock, kLocalVoid, kExprEnd
551 :
552 15444 : TEST_F(FunctionBodyDecoderTest, Block0) {
553 3 : ExpectValidates(sigs.v_v(), {WASM_EMPTY_BLOCK});
554 2 : ExpectFailure(sigs.i_i(), {WASM_EMPTY_BLOCK});
555 1 : }
556 :
557 15444 : TEST_F(FunctionBodyDecoderTest, Block0_fallthru1) {
558 3 : ExpectValidates(sigs.v_v(), {WASM_BLOCK(WASM_EMPTY_BLOCK)});
559 2 : ExpectFailure(sigs.i_i(), {WASM_BLOCK(WASM_EMPTY_BLOCK)});
560 1 : }
561 :
562 15444 : TEST_F(FunctionBodyDecoderTest, Block0Block0) {
563 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Block0_end) {
568 3 : ExpectFailure(sigs.v_v(), {WASM_EMPTY_BLOCK, kExprEnd});
569 1 : }
570 :
571 : #undef WASM_EMPTY_BLOCK
572 :
573 15444 : TEST_F(FunctionBodyDecoderTest, Block1) {
574 1 : byte code[] = {WASM_BLOCK_I(WASM_GET_LOCAL(0))};
575 1 : ExpectValidates(sigs.i_i(), code);
576 : ExpectFailure(sigs.v_i(), code);
577 : ExpectFailure(sigs.d_dd(), code);
578 : ExpectFailure(sigs.i_f(), code);
579 : ExpectFailure(sigs.i_d(), code);
580 1 : }
581 :
582 15444 : TEST_F(FunctionBodyDecoderTest, Block1_i) {
583 1 : byte code[] = {WASM_BLOCK_I(WASM_ZERO)};
584 1 : ExpectValidates(sigs.i_i(), code);
585 : ExpectFailure(sigs.f_ff(), code);
586 : ExpectFailure(sigs.d_dd(), code);
587 : ExpectFailure(sigs.l_ll(), code);
588 1 : }
589 :
590 15444 : TEST_F(FunctionBodyDecoderTest, Block1_f) {
591 1 : byte code[] = {WASM_BLOCK_F(WASM_F32(0))};
592 1 : ExpectFailure(sigs.i_i(), code);
593 : ExpectValidates(sigs.f_ff(), code);
594 : ExpectFailure(sigs.d_dd(), code);
595 : ExpectFailure(sigs.l_ll(), code);
596 1 : }
597 :
598 15444 : TEST_F(FunctionBodyDecoderTest, Block1_continue) {
599 3 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_BR(0))});
600 1 : }
601 :
602 15444 : TEST_F(FunctionBodyDecoderTest, Block1_br) {
603 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Block2_br) {
609 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Block2) {
615 3 : 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 15444 : 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 : ExpectFailure(sigs.v_v(), code);
626 : ExpectFailure(sigs.f_ff(), code);
627 1 : }
628 :
629 15444 : TEST_F(FunctionBodyDecoderTest, Block2_fallthru) {
630 3 : ExpectValidates(sigs.i_i(), {B2(WASM_SET_LOCAL(0, WASM_ZERO),
631 : WASM_SET_LOCAL(0, WASM_ZERO)),
632 : WASM_I32V_1(23)});
633 1 : }
634 :
635 15444 : TEST_F(FunctionBodyDecoderTest, Block3) {
636 3 : ExpectValidates(sigs.i_i(), {WASM_BLOCK_I(WASM_SET_LOCAL(0, WASM_ZERO),
637 : WASM_SET_LOCAL(0, WASM_ZERO),
638 : WASM_I32V_1(11))});
639 1 : }
640 :
641 15444 : TEST_F(FunctionBodyDecoderTest, Block5) {
642 3 : 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 2 : ExpectFailure(sigs.v_i(),
649 : {WASM_BLOCK(WASM_ZERO, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
650 :
651 2 : ExpectFailure(sigs.v_i(), {WASM_BLOCK(WASM_ZERO, WASM_ZERO, WASM_ZERO,
652 : WASM_ZERO, WASM_ZERO)});
653 1 : }
654 :
655 15444 : TEST_F(FunctionBodyDecoderTest, BlockType) {
656 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, BlockType_fail) {
663 3 : 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 15444 : 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 : ExpectFailure(sigs.i_i(), code);
684 : ExpectFailure(sigs.d_dd(), code);
685 1 : }
686 :
687 15444 : TEST_F(FunctionBodyDecoderTest, BlockN_off_end) {
688 1 : byte code[] = {WASM_BLOCK(kExprNop, kExprNop, kExprNop, kExprNop)};
689 1 : ExpectValidates(sigs.v_v(), code);
690 13 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Block2_continue) {
697 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Block3_continue) {
703 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, NestedBlock_return) {
710 3 : ExpectValidates(sigs.i_i(), {B1(B1(WASM_RETURN1(WASM_ZERO))), WASM_ZERO});
711 1 : }
712 :
713 15444 : TEST_F(FunctionBodyDecoderTest, BlockBrBinop) {
714 3 : ExpectValidates(sigs.i_i(),
715 : {WASM_I32_AND(WASM_BLOCK_I(WASM_BRV(0, WASM_I32V_1(1))),
716 : WASM_I32V_1(2))});
717 1 : }
718 :
719 15444 : TEST_F(FunctionBodyDecoderTest, If_empty1) {
720 3 : ExpectValidates(sigs.v_v(), {WASM_ZERO, WASM_IF_OP, kExprEnd});
721 1 : }
722 :
723 15444 : TEST_F(FunctionBodyDecoderTest, If_empty2) {
724 3 : ExpectValidates(sigs.v_v(), {WASM_ZERO, WASM_IF_OP, kExprElse, kExprEnd});
725 1 : }
726 :
727 15444 : TEST_F(FunctionBodyDecoderTest, If_empty3) {
728 3 : ExpectValidates(sigs.v_v(),
729 : {WASM_ZERO, WASM_IF_OP, WASM_NOP, kExprElse, kExprEnd});
730 2 : ExpectFailure(sigs.v_v(),
731 : {WASM_ZERO, WASM_IF_OP, WASM_ZERO, kExprElse, kExprEnd});
732 1 : }
733 :
734 15444 : TEST_F(FunctionBodyDecoderTest, If_empty4) {
735 3 : ExpectValidates(sigs.v_v(),
736 : {WASM_ZERO, WASM_IF_OP, kExprElse, WASM_NOP, kExprEnd});
737 2 : ExpectFailure(sigs.v_v(),
738 : {WASM_ZERO, WASM_IF_OP, kExprElse, WASM_ZERO, kExprEnd});
739 1 : }
740 :
741 15444 : TEST_F(FunctionBodyDecoderTest, If_empty_stack) {
742 1 : byte code[] = {kExprIf};
743 1 : ExpectFailure(sigs.v_v(), code);
744 : ExpectFailure(sigs.i_i(), code);
745 1 : }
746 :
747 15444 : TEST_F(FunctionBodyDecoderTest, If_incomplete1) {
748 1 : byte code[] = {kExprI32Const, 0, kExprIf};
749 1 : ExpectFailure(sigs.v_v(), code);
750 : ExpectFailure(sigs.i_i(), code);
751 1 : }
752 :
753 15444 : TEST_F(FunctionBodyDecoderTest, If_incomplete2) {
754 1 : byte code[] = {kExprI32Const, 0, kExprIf, kExprNop};
755 1 : ExpectFailure(sigs.v_v(), code);
756 : ExpectFailure(sigs.i_i(), code);
757 1 : }
758 :
759 15444 : 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 : ExpectFailure(sigs.i_i(), code);
763 1 : }
764 :
765 15444 : TEST_F(FunctionBodyDecoderTest, IfEmpty) {
766 3 : ExpectValidates(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP, kExprEnd});
767 1 : }
768 :
769 15444 : TEST_F(FunctionBodyDecoderTest, IfSet) {
770 3 : ExpectValidates(sigs.v_i(),
771 : {WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO))});
772 2 : ExpectValidates(sigs.v_i(),
773 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO),
774 : WASM_NOP)});
775 1 : }
776 :
777 15444 : TEST_F(FunctionBodyDecoderTest, IfElseEmpty) {
778 3 : ExpectValidates(sigs.v_i(),
779 : {WASM_GET_LOCAL(0), WASM_IF_OP, kExprElse, kExprEnd});
780 2 : ExpectValidates(sigs.v_i(),
781 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP)});
782 1 : }
783 :
784 15444 : TEST_F(FunctionBodyDecoderTest, IfElseUnreachable1) {
785 3 : ExpectValidates(
786 : sigs.i_i(),
787 : {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_UNREACHABLE, WASM_GET_LOCAL(0))});
788 2 : ExpectValidates(
789 : sigs.i_i(),
790 : {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE)});
791 1 : }
792 :
793 15444 : 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 11 : 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 15444 : TEST_F(FunctionBodyDecoderTest, OneArmedIfWithArity) {
806 : static const byte code[] = {WASM_ZERO, kExprIf, kLocalI32, WASM_ONE,
807 : kExprEnd};
808 1 : ExpectFailure(sigs.i_v(), code, kAppendEnd,
809 : "start-arity and end-arity of one-armed if must match");
810 1 : }
811 :
812 15444 : TEST_F(FunctionBodyDecoderTest, IfBreak) {
813 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, IfElseBreak) {
819 3 : ExpectValidates(sigs.v_i(),
820 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_BR(0))});
821 2 : ExpectValidates(sigs.v_i(),
822 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_BR(1))});
823 2 : ExpectFailure(sigs.v_i(),
824 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_BR(2))});
825 1 : }
826 :
827 15444 : TEST_F(FunctionBodyDecoderTest, Block_else) {
828 1 : byte code[] = {kExprI32Const, 0, kExprBlock, kExprElse, kExprEnd};
829 1 : ExpectFailure(sigs.v_v(), code);
830 : ExpectFailure(sigs.i_i(), code);
831 1 : }
832 :
833 15444 : TEST_F(FunctionBodyDecoderTest, IfNop) {
834 3 : ExpectValidates(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0), WASM_NOP)});
835 2 : ExpectValidates(sigs.v_i(),
836 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP)});
837 1 : }
838 :
839 15444 : TEST_F(FunctionBodyDecoderTest, If_end) {
840 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, If_falloff1) {
845 3 : ExpectFailure(sigs.v_i(), {kExprGetLocal, 0, kExprIf});
846 2 : ExpectFailure(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP});
847 2 : ExpectFailure(sigs.v_i(),
848 : {kExprGetLocal, 0, WASM_IF_OP, kExprNop, kExprElse});
849 1 : }
850 :
851 15444 : TEST_F(FunctionBodyDecoderTest, IfElseNop) {
852 3 : ExpectValidates(sigs.v_i(),
853 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO),
854 : WASM_NOP)});
855 1 : }
856 :
857 15444 : TEST_F(FunctionBodyDecoderTest, IfBlock1) {
858 3 : ExpectValidates(sigs.v_i(),
859 : {WASM_IF_ELSE(WASM_GET_LOCAL(0),
860 : B1(WASM_SET_LOCAL(0, WASM_ZERO)), WASM_NOP)});
861 1 : }
862 :
863 15444 : TEST_F(FunctionBodyDecoderTest, IfBlock1b) {
864 3 : ExpectValidates(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0),
865 : B1(WASM_SET_LOCAL(0, WASM_ZERO)))});
866 1 : }
867 :
868 15444 : TEST_F(FunctionBodyDecoderTest, IfBlock2a) {
869 3 : ExpectValidates(sigs.v_i(), {WASM_IF(WASM_GET_LOCAL(0),
870 : B2(WASM_SET_LOCAL(0, WASM_ZERO),
871 : WASM_SET_LOCAL(0, WASM_ZERO)))});
872 1 : }
873 :
874 15444 : TEST_F(FunctionBodyDecoderTest, IfBlock2b) {
875 3 : 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 : WASM_NOP)});
879 1 : }
880 :
881 15444 : TEST_F(FunctionBodyDecoderTest, IfElseSet) {
882 3 : ExpectValidates(sigs.v_i(),
883 : {WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_ZERO),
884 : WASM_SET_LOCAL(0, WASM_I32V_1(1)))});
885 1 : }
886 :
887 15444 : TEST_F(FunctionBodyDecoderTest, Loop0) {
888 3 : ExpectValidates(sigs.v_v(), {WASM_LOOP_OP, kExprEnd});
889 1 : }
890 :
891 15444 : 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 : ExpectFailure(sigs.v_v(), code);
895 : ExpectFailure(sigs.f_ff(), code);
896 1 : }
897 :
898 15444 : TEST_F(FunctionBodyDecoderTest, Loop2) {
899 3 : ExpectValidates(sigs.v_i(), {WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO),
900 : WASM_SET_LOCAL(0, WASM_ZERO))});
901 1 : }
902 :
903 15444 : TEST_F(FunctionBodyDecoderTest, Loop1_continue) {
904 3 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_BR(0))});
905 1 : }
906 :
907 15444 : TEST_F(FunctionBodyDecoderTest, Loop1_break) {
908 3 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_BR(1))});
909 1 : }
910 :
911 15444 : TEST_F(FunctionBodyDecoderTest, Loop2_continue) {
912 3 : ExpectValidates(sigs.v_i(),
913 : {WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO), WASM_BR(0))});
914 1 : }
915 :
916 15444 : TEST_F(FunctionBodyDecoderTest, Loop2_break) {
917 3 : ExpectValidates(sigs.v_i(),
918 : {WASM_LOOP(WASM_SET_LOCAL(0, WASM_ZERO), WASM_BR(1))});
919 1 : }
920 :
921 15444 : TEST_F(FunctionBodyDecoderTest, InfiniteLoop1) {
922 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, InfiniteLoop2) {
928 3 : ExpectFailure(sigs.i_i(), {WASM_LOOP(WASM_BR(0), WASM_ZERO), WASM_ZERO});
929 1 : }
930 :
931 15444 : TEST_F(FunctionBodyDecoderTest, Loop2_unreachable) {
932 3 : ExpectValidates(sigs.i_i(), {WASM_LOOP_I(WASM_BR(0), WASM_NOP)});
933 1 : }
934 :
935 15444 : TEST_F(FunctionBodyDecoderTest, LoopType) {
936 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, LoopType_void) {
943 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, LoopType_fail) {
950 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, ReturnVoid1) {
968 : static const byte code[] = {kExprNop};
969 1 : ExpectValidates(sigs.v_v(), code);
970 : ExpectFailure(sigs.i_i(), code);
971 : ExpectFailure(sigs.i_f(), code);
972 1 : }
973 :
974 15444 : TEST_F(FunctionBodyDecoderTest, ReturnVoid2) {
975 : static const byte code[] = {WASM_BLOCK(WASM_BR(0))};
976 1 : ExpectValidates(sigs.v_v(), code);
977 : ExpectFailure(sigs.i_i(), code);
978 : ExpectFailure(sigs.i_f(), code);
979 1 : }
980 :
981 15444 : TEST_F(FunctionBodyDecoderTest, ReturnVoid3) {
982 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Unreachable1) {
992 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Unreachable2) {
998 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, UnreachableLoop1) {
1003 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Unreachable_binop1) {
1010 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Unreachable_binop2) {
1015 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Unreachable_select1) {
1020 3 : ExpectValidates(sigs.i_i(),
1021 : {WASM_SELECT(WASM_UNREACHABLE, WASM_ZERO, WASM_ZERO)});
1022 2 : ExpectValidates(sigs.i_i(),
1023 : {WASM_SELECT(WASM_ZERO, WASM_UNREACHABLE, WASM_ZERO)});
1024 2 : ExpectValidates(sigs.i_i(),
1025 : {WASM_SELECT(WASM_ZERO, WASM_ZERO, WASM_UNREACHABLE)});
1026 1 : }
1027 :
1028 15444 : TEST_F(FunctionBodyDecoderTest, Unreachable_select2) {
1029 3 : ExpectValidates(sigs.i_i(),
1030 : {WASM_SELECT(WASM_F32(0.0), WASM_UNREACHABLE, WASM_ZERO)});
1031 2 : ExpectFailure(sigs.i_i(),
1032 : {WASM_SELECT(WASM_UNREACHABLE, WASM_F32(0.0), WASM_ZERO)});
1033 2 : ExpectFailure(sigs.i_i(),
1034 : {WASM_SELECT(WASM_UNREACHABLE, WASM_ZERO, WASM_F32(0.0))});
1035 1 : }
1036 :
1037 15444 : TEST_F(FunctionBodyDecoderTest, If1) {
1038 3 : ExpectValidates(sigs.i_i(), {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I32V_1(9),
1039 : WASM_I32V_1(8))});
1040 2 : ExpectValidates(sigs.i_i(), {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I32V_1(9),
1041 : WASM_GET_LOCAL(0))});
1042 2 : ExpectValidates(
1043 : sigs.i_i(),
1044 : {WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_I32V_1(8))});
1045 1 : }
1046 :
1047 15444 : 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 15 : for (size_t len = 3; len < arraysize(kCode); len++) {
1051 21 : ExpectFailure(sigs.i_i(), VectorOf(kCode, len), kAppendEnd);
1052 14 : ExpectFailure(sigs.i_i(), VectorOf(kCode, len), kOmitEnd);
1053 : }
1054 1 : }
1055 :
1056 15444 : 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 : ExpectFailure(sigs.i_f(), kCode);
1062 : ExpectFailure(sigs.i_d(), kCode);
1063 1 : }
1064 :
1065 15444 : 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 : ExpectFailure(sigs.i_f(), kCode);
1071 : ExpectFailure(sigs.i_d(), kCode);
1072 1 : }
1073 :
1074 15444 : 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 : ExpectFailure(sigs.i_f(), kCode);
1080 : ExpectFailure(sigs.i_d(), kCode);
1081 1 : }
1082 :
1083 15444 : 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 : ExpectFailure(sigs.i_f(), kCode);
1089 : ExpectFailure(sigs.i_d(), kCode);
1090 1 : }
1091 :
1092 15444 : 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 : ExpectFailure(sigs.i_f(), kCode);
1098 : ExpectFailure(sigs.i_d(), kCode);
1099 1 : }
1100 :
1101 15444 : TEST_F(FunctionBodyDecoderTest, Int64Local_param) {
1102 1 : ExpectValidates(sigs.l_l(), kCodeGetLocal0);
1103 1 : }
1104 :
1105 15444 : TEST_F(FunctionBodyDecoderTest, Int64Locals) {
1106 15 : for (byte i = 1; i < 8; i++) {
1107 : AddLocals(kWasmI64, 1);
1108 63 : for (byte j = 0; j < i; j++) {
1109 84 : ExpectValidates(sigs.l_v(), {WASM_GET_LOCAL(j)});
1110 : }
1111 : }
1112 1 : }
1113 :
1114 15444 : 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 15444 : 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 15444 : 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 15444 : 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 15444 : TEST_F(FunctionBodyDecoderTest, MacrosStmt) {
1171 : TestModuleBuilder builder;
1172 1 : module = builder.module();
1173 : builder.InitializeMemory();
1174 3 : ExpectValidates(sigs.v_i(), {WASM_SET_LOCAL(0, WASM_I32V_3(87348))});
1175 3 : ExpectValidates(
1176 : sigs.v_i(),
1177 1 : {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 2 : ExpectValidates(sigs.v_i(),
1180 : {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 15444 : TEST_F(FunctionBodyDecoderTest, MacrosContinue) {
1188 3 : ExpectValidates(sigs.v_v(), {WASM_LOOP(WASM_CONTINUE(0))});
1189 1 : }
1190 :
1191 15444 : TEST_F(FunctionBodyDecoderTest, MacrosVariadic) {
1192 3 : 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 15444 : TEST_F(FunctionBodyDecoderTest, MacrosNestedBlocks) {
1199 3 : ExpectValidates(sigs.v_v(), {B2(WASM_NOP, B2(WASM_NOP, WASM_NOP))});
1200 2 : ExpectValidates(sigs.v_v(), {B3(WASM_NOP, // --
1201 : B2(WASM_NOP, WASM_NOP), // --
1202 : B2(WASM_NOP, WASM_NOP))}); // --
1203 2 : ExpectValidates(sigs.v_v(), {B1(B1(B2(WASM_NOP, WASM_NOP)))});
1204 1 : }
1205 :
1206 15444 : 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 2 : ExpectValidates(&sig_iii_v,
1215 : {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 15444 : 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 15444 : TEST_F(FunctionBodyDecoderTest, MacrosInt32) {
1233 3 : ExpectValidates(sigs.i_i(),
1234 : {WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I32V_1(12))});
1235 2 : ExpectValidates(sigs.i_i(),
1236 : {WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I32V_1(13))});
1237 2 : ExpectValidates(sigs.i_i(),
1238 : {WASM_I32_MUL(WASM_GET_LOCAL(0), WASM_I32V_1(14))});
1239 2 : ExpectValidates(sigs.i_i(),
1240 : {WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I32V_1(15))});
1241 2 : ExpectValidates(sigs.i_i(),
1242 : {WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32V_1(16))});
1243 2 : ExpectValidates(sigs.i_i(),
1244 : {WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_I32V_1(17))});
1245 2 : ExpectValidates(sigs.i_i(),
1246 : {WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_I32V_1(18))});
1247 2 : ExpectValidates(sigs.i_i(),
1248 : {WASM_I32_AND(WASM_GET_LOCAL(0), WASM_I32V_1(19))});
1249 2 : ExpectValidates(sigs.i_i(),
1250 : {WASM_I32_IOR(WASM_GET_LOCAL(0), WASM_I32V_1(20))});
1251 2 : ExpectValidates(sigs.i_i(),
1252 : {WASM_I32_XOR(WASM_GET_LOCAL(0), WASM_I32V_1(21))});
1253 2 : ExpectValidates(sigs.i_i(),
1254 : {WASM_I32_SHL(WASM_GET_LOCAL(0), WASM_I32V_1(22))});
1255 2 : ExpectValidates(sigs.i_i(),
1256 : {WASM_I32_SHR(WASM_GET_LOCAL(0), WASM_I32V_1(23))});
1257 2 : ExpectValidates(sigs.i_i(),
1258 : {WASM_I32_SAR(WASM_GET_LOCAL(0), WASM_I32V_1(24))});
1259 2 : ExpectValidates(sigs.i_i(),
1260 : {WASM_I32_ROR(WASM_GET_LOCAL(0), WASM_I32V_1(24))});
1261 2 : ExpectValidates(sigs.i_i(),
1262 : {WASM_I32_ROL(WASM_GET_LOCAL(0), WASM_I32V_1(24))});
1263 2 : ExpectValidates(sigs.i_i(),
1264 : {WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(25))});
1265 2 : ExpectValidates(sigs.i_i(),
1266 : {WASM_I32_NE(WASM_GET_LOCAL(0), WASM_I32V_1(25))});
1267 :
1268 2 : ExpectValidates(sigs.i_i(),
1269 : {WASM_I32_LTS(WASM_GET_LOCAL(0), WASM_I32V_1(26))});
1270 2 : ExpectValidates(sigs.i_i(),
1271 : {WASM_I32_LES(WASM_GET_LOCAL(0), WASM_I32V_1(27))});
1272 2 : ExpectValidates(sigs.i_i(),
1273 : {WASM_I32_LTU(WASM_GET_LOCAL(0), WASM_I32V_1(28))});
1274 2 : ExpectValidates(sigs.i_i(),
1275 : {WASM_I32_LEU(WASM_GET_LOCAL(0), WASM_I32V_1(29))});
1276 :
1277 2 : ExpectValidates(sigs.i_i(),
1278 : {WASM_I32_GTS(WASM_GET_LOCAL(0), WASM_I32V_1(26))});
1279 2 : ExpectValidates(sigs.i_i(),
1280 : {WASM_I32_GES(WASM_GET_LOCAL(0), WASM_I32V_1(27))});
1281 2 : ExpectValidates(sigs.i_i(),
1282 : {WASM_I32_GTU(WASM_GET_LOCAL(0), WASM_I32V_1(28))});
1283 2 : ExpectValidates(sigs.i_i(),
1284 : {WASM_I32_GEU(WASM_GET_LOCAL(0), WASM_I32V_1(29))});
1285 1 : }
1286 :
1287 15444 : TEST_F(FunctionBodyDecoderTest, MacrosInt64) {
1288 3 : ExpectValidates(sigs.l_ll(),
1289 : {WASM_I64_ADD(WASM_GET_LOCAL(0), WASM_I64V_1(12))});
1290 2 : ExpectValidates(sigs.l_ll(),
1291 : {WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_I64V_1(13))});
1292 2 : ExpectValidates(sigs.l_ll(),
1293 : {WASM_I64_MUL(WASM_GET_LOCAL(0), WASM_I64V_1(14))});
1294 2 : ExpectValidates(sigs.l_ll(),
1295 : {WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_I64V_1(15))});
1296 2 : ExpectValidates(sigs.l_ll(),
1297 : {WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_I64V_1(16))});
1298 2 : ExpectValidates(sigs.l_ll(),
1299 : {WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_I64V_1(17))});
1300 2 : ExpectValidates(sigs.l_ll(),
1301 : {WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_I64V_1(18))});
1302 2 : ExpectValidates(sigs.l_ll(),
1303 : {WASM_I64_AND(WASM_GET_LOCAL(0), WASM_I64V_1(19))});
1304 2 : ExpectValidates(sigs.l_ll(),
1305 : {WASM_I64_IOR(WASM_GET_LOCAL(0), WASM_I64V_1(20))});
1306 2 : ExpectValidates(sigs.l_ll(),
1307 : {WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_I64V_1(21))});
1308 :
1309 2 : ExpectValidates(sigs.l_ll(),
1310 : {WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(22))});
1311 2 : ExpectValidates(sigs.l_ll(),
1312 : {WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(23))});
1313 2 : ExpectValidates(sigs.l_ll(),
1314 : {WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(24))});
1315 2 : ExpectValidates(sigs.l_ll(),
1316 : {WASM_I64_ROR(WASM_GET_LOCAL(0), WASM_I64V_1(24))});
1317 2 : ExpectValidates(sigs.l_ll(),
1318 : {WASM_I64_ROL(WASM_GET_LOCAL(0), WASM_I64V_1(24))});
1319 :
1320 2 : ExpectValidates(sigs.i_ll(),
1321 : {WASM_I64_LTS(WASM_GET_LOCAL(0), WASM_I64V_1(26))});
1322 2 : ExpectValidates(sigs.i_ll(),
1323 : {WASM_I64_LES(WASM_GET_LOCAL(0), WASM_I64V_1(27))});
1324 2 : ExpectValidates(sigs.i_ll(),
1325 : {WASM_I64_LTU(WASM_GET_LOCAL(0), WASM_I64V_1(28))});
1326 2 : ExpectValidates(sigs.i_ll(),
1327 : {WASM_I64_LEU(WASM_GET_LOCAL(0), WASM_I64V_1(29))});
1328 :
1329 2 : ExpectValidates(sigs.i_ll(),
1330 : {WASM_I64_GTS(WASM_GET_LOCAL(0), WASM_I64V_1(26))});
1331 2 : ExpectValidates(sigs.i_ll(),
1332 : {WASM_I64_GES(WASM_GET_LOCAL(0), WASM_I64V_1(27))});
1333 2 : ExpectValidates(sigs.i_ll(),
1334 : {WASM_I64_GTU(WASM_GET_LOCAL(0), WASM_I64V_1(28))});
1335 2 : ExpectValidates(sigs.i_ll(),
1336 : {WASM_I64_GEU(WASM_GET_LOCAL(0), WASM_I64V_1(29))});
1337 :
1338 2 : ExpectValidates(sigs.i_ll(),
1339 : {WASM_I64_EQ(WASM_GET_LOCAL(0), WASM_I64V_1(25))});
1340 2 : ExpectValidates(sigs.i_ll(),
1341 : {WASM_I64_NE(WASM_GET_LOCAL(0), WASM_I64V_1(25))});
1342 1 : }
1343 :
1344 15444 : 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 15444 : TEST_F(FunctionBodyDecoderTest, MemorySize) {
1364 : TestModuleBuilder builder;
1365 1 : module = builder.module();
1366 : builder.InitializeMemory();
1367 1 : byte code[] = {kExprMemorySize, 0};
1368 1 : ExpectValidates(sigs.i_i(), code);
1369 : ExpectFailure(sigs.f_ff(), code);
1370 1 : }
1371 :
1372 15444 : TEST_F(FunctionBodyDecoderTest, LoadMemOffset) {
1373 : TestModuleBuilder builder;
1374 1 : module = builder.module();
1375 : builder.InitializeMemory();
1376 39 : 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 15444 : TEST_F(FunctionBodyDecoderTest, LoadMemAlignment) {
1384 : 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 29 : for (size_t i = 0; i < arraysize(values); i++) {
1408 154 : for (byte alignment = 0; alignment <= 4; alignment++) {
1409 70 : byte code[] = {WASM_ZERO, static_cast<byte>(values[i].instruction),
1410 140 : alignment, ZERO_OFFSET, WASM_DROP};
1411 70 : Validate(alignment <= values[i].maximum_aligment, sigs.v_i(), code);
1412 : }
1413 : }
1414 1 : }
1415 :
1416 15444 : TEST_F(FunctionBodyDecoderTest, StoreMemOffset) {
1417 : TestModuleBuilder builder;
1418 1 : module = builder.module();
1419 : builder.InitializeMemory();
1420 39 : 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 15444 : TEST_F(FunctionBodyDecoderTest, StoreMemOffset_void) {
1428 : TestModuleBuilder builder;
1429 1 : module = builder.module();
1430 : builder.InitializeMemory();
1431 3 : ExpectFailure(sigs.i_i(), {WASM_STORE_MEM_OFFSET(MachineType::Int32(), 0,
1432 : 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 15444 : TEST_F(FunctionBodyDecoderTest, LoadMemOffset_varint) {
1446 : TestModuleBuilder builder;
1447 1 : module = builder.module();
1448 : builder.InitializeMemory();
1449 3 : ExpectValidates(sigs.i_i(),
1450 : {WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT, VARINT1(0x45)});
1451 2 : ExpectValidates(sigs.i_i(), {WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT,
1452 : VARINT2(0x3999)});
1453 2 : ExpectValidates(sigs.i_i(), {WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT,
1454 : VARINT3(0x344445)});
1455 2 : ExpectValidates(sigs.i_i(), {WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT,
1456 : VARINT4(0x36666667)});
1457 1 : }
1458 :
1459 15444 : TEST_F(FunctionBodyDecoderTest, StoreMemOffset_varint) {
1460 : TestModuleBuilder builder;
1461 1 : module = builder.module();
1462 : builder.InitializeMemory();
1463 3 : ExpectValidates(sigs.v_i(), {WASM_ZERO, WASM_ZERO, kExprI32StoreMem,
1464 : ZERO_ALIGNMENT, VARINT1(0x33)});
1465 2 : ExpectValidates(sigs.v_i(), {WASM_ZERO, WASM_ZERO, kExprI32StoreMem,
1466 : ZERO_ALIGNMENT, VARINT2(0x1111)});
1467 2 : ExpectValidates(sigs.v_i(), {WASM_ZERO, WASM_ZERO, kExprI32StoreMem,
1468 : ZERO_ALIGNMENT, VARINT3(0x222222)});
1469 2 : ExpectValidates(sigs.v_i(), {WASM_ZERO, WASM_ZERO, kExprI32StoreMem,
1470 : 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 15444 : TEST_F(FunctionBodyDecoderTest, AllLoadMemCombinations) {
1484 : TestModuleBuilder builder;
1485 1 : module = builder.module();
1486 : builder.InitializeMemory();
1487 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1488 5 : ValueType local_type = kValueTypes[i];
1489 105 : 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 15444 : TEST_F(FunctionBodyDecoderTest, AllStoreMemCombinations) {
1499 : TestModuleBuilder builder;
1500 1 : module = builder.module();
1501 : builder.InitializeMemory();
1502 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1503 5 : ValueType local_type = kValueTypes[i];
1504 105 : 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 15444 : TEST_F(FunctionBodyDecoderTest, SimpleCalls) {
1514 : FunctionSig* sig = sigs.i_i();
1515 : 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 2 : ExpectValidates(sig,
1525 : {WASM_CALL_FUNCTION(2, WASM_I32V_1(37), WASM_I32V_2(77))});
1526 1 : }
1527 :
1528 15444 : TEST_F(FunctionBodyDecoderTest, CallsWithTooFewArguments) {
1529 : FunctionSig* sig = sigs.i_i();
1530 : 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 15444 : TEST_F(FunctionBodyDecoderTest, CallsWithMismatchedSigs2) {
1543 : FunctionSig* sig = sigs.i_i();
1544 : 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 15444 : TEST_F(FunctionBodyDecoderTest, CallsWithMismatchedSigs3) {
1555 : FunctionSig* sig = sigs.i_i();
1556 : 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 15444 : TEST_F(FunctionBodyDecoderTest, SimpleReturnCalls) {
1573 1 : WASM_FEATURE_SCOPE(return_call);
1574 :
1575 : FunctionSig* sig = sigs.i_i();
1576 : 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 2 : ExpectValidates(
1586 : sig, {WASM_RETURN_CALL_FUNCTION(2, WASM_I32V_1(37), WASM_I32V_2(77))});
1587 1 : }
1588 :
1589 15444 : TEST_F(FunctionBodyDecoderTest, ReturnCallsWithTooFewArguments) {
1590 1 : WASM_FEATURE_SCOPE(return_call);
1591 :
1592 : FunctionSig* sig = sigs.i_i();
1593 : 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 15444 : TEST_F(FunctionBodyDecoderTest, ReturnCallsWithMismatchedSigs) {
1606 1 : WASM_FEATURE_SCOPE(return_call);
1607 :
1608 : FunctionSig* sig = sigs.i_i();
1609 : 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 15444 : TEST_F(FunctionBodyDecoderTest, SimpleIndirectReturnCalls) {
1625 1 : WASM_FEATURE_SCOPE(return_call);
1626 :
1627 : FunctionSig* sig = sigs.i_i();
1628 : TestModuleBuilder builder;
1629 1 : builder.AddTable(kWasmAnyFunc, 20, true, 30);
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 2 : ExpectValidates(sig,
1638 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_I32V_1(22))});
1639 2 : ExpectValidates(sig, {WASM_RETURN_CALL_INDIRECT(
1640 : f2, WASM_ZERO, WASM_I32V_1(32), WASM_I32V_2(72))});
1641 1 : }
1642 :
1643 15444 : TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsOutOfBounds) {
1644 1 : WASM_FEATURE_SCOPE(return_call);
1645 :
1646 : FunctionSig* sig = sigs.i_i();
1647 : TestModuleBuilder builder;
1648 1 : builder.AddTable(kWasmAnyFunc, 20, false, 20);
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 2 : ExpectFailure(sig,
1656 : {WASM_RETURN_CALL_INDIRECT(1, WASM_ZERO, WASM_I32V_1(22))});
1657 1 : builder.AddSignature(sigs.i_i());
1658 2 : ExpectValidates(sig,
1659 : {WASM_RETURN_CALL_INDIRECT(1, WASM_ZERO, WASM_I32V_1(27))});
1660 :
1661 2 : ExpectFailure(sig,
1662 : {WASM_RETURN_CALL_INDIRECT(2, WASM_ZERO, WASM_I32V_1(27))});
1663 1 : }
1664 :
1665 15444 : TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsWithMismatchedSigs3) {
1666 1 : WASM_FEATURE_SCOPE(return_call);
1667 :
1668 : FunctionSig* sig = sigs.i_i();
1669 : TestModuleBuilder builder;
1670 : builder.InitializeTable();
1671 1 : module = builder.module();
1672 :
1673 1 : byte f0 = builder.AddFunction(sigs.i_f());
1674 :
1675 2 : ExpectFailure(sig,
1676 : {WASM_RETURN_CALL_INDIRECT(f0, WASM_ZERO, WASM_I32V_1(17))});
1677 2 : ExpectFailure(sig,
1678 : {WASM_RETURN_CALL_INDIRECT(f0, WASM_ZERO, WASM_I64V_1(27))});
1679 2 : ExpectFailure(sig,
1680 : {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 2 : ExpectFailure(sig,
1689 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_I32V_1(16))});
1690 2 : ExpectFailure(sig,
1691 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_I64V_1(16))});
1692 2 : ExpectFailure(sig,
1693 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_F32(17.6))});
1694 1 : }
1695 :
1696 15444 : TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsWithoutTableCrash) {
1697 1 : WASM_FEATURE_SCOPE(return_call);
1698 :
1699 : FunctionSig* sig = sigs.i_i();
1700 : 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 2 : ExpectFailure(sig,
1709 : {WASM_RETURN_CALL_INDIRECT(f1, WASM_ZERO, WASM_I32V_1(22))});
1710 2 : ExpectFailure(sig, {WASM_RETURN_CALL_INDIRECT(f2, WASM_ZERO, WASM_I32V_1(32),
1711 : WASM_I32V_2(72))});
1712 1 : }
1713 :
1714 15444 : TEST_F(FunctionBodyDecoderTest, IncompleteIndirectReturnCall) {
1715 : FunctionSig* sig = sigs.i_i();
1716 : 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 15444 : 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 : 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 15444 : TEST_F(FunctionBodyDecoderTest, MultiReturnType) {
1741 1 : WASM_FEATURE_SCOPE(mv);
1742 11 : for (size_t a = 0; a < arraysize(kValueTypes); a++) {
1743 55 : for (size_t b = 0; b < arraysize(kValueTypes); b++) {
1744 275 : for (size_t c = 0; c < arraysize(kValueTypes); c++) {
1745 1375 : 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 : 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 15444 : TEST_F(FunctionBodyDecoderTest, SimpleIndirectCalls) {
1769 : FunctionSig* sig = sigs.i_i();
1770 : TestModuleBuilder builder;
1771 1 : builder.AddTable(kWasmAnyFunc, 20, false, 20);
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 2 : ExpectValidates(sig, {WASM_CALL_INDIRECT2(f2, WASM_ZERO, WASM_I32V_1(32),
1781 : WASM_I32V_2(72))});
1782 1 : }
1783 :
1784 15444 : TEST_F(FunctionBodyDecoderTest, IndirectCallsOutOfBounds) {
1785 : FunctionSig* sig = sigs.i_i();
1786 : TestModuleBuilder builder;
1787 1 : builder.AddTable(kWasmAnyFunc, 20, false, 20);
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 15444 : TEST_F(FunctionBodyDecoderTest, IndirectCallsWithMismatchedSigs3) {
1802 : FunctionSig* sig = sigs.i_i();
1803 : 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 15444 : TEST_F(FunctionBodyDecoderTest, IndirectCallsWithoutTableCrash) {
1825 : FunctionSig* sig = sigs.i_i();
1826 : 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 2 : ExpectFailure(sig, {WASM_CALL_INDIRECT2(f2, WASM_ZERO, WASM_I32V_1(32),
1836 : WASM_I32V_2(72))});
1837 1 : }
1838 :
1839 15444 : TEST_F(FunctionBodyDecoderTest, IncompleteIndirectCall) {
1840 : FunctionSig* sig = sigs.i_i();
1841 : 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 15444 : TEST_F(FunctionBodyDecoderTest, IncompleteStore) {
1850 : FunctionSig* sig = sigs.i_i();
1851 : 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 15444 : TEST_F(FunctionBodyDecoderTest, IncompleteS8x16Shuffle) {
1861 1 : WASM_FEATURE_SCOPE(simd);
1862 : FunctionSig* sig = sigs.i_i();
1863 : 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 15444 : TEST_F(FunctionBodyDecoderTest, SimpleImportCalls) {
1874 : FunctionSig* sig = sigs.i_i();
1875 : TestModuleBuilder builder;
1876 1 : module = builder.module();
1877 :
1878 : byte f0 = builder.AddImport(sigs.i_v());
1879 : byte f1 = builder.AddImport(sigs.i_i());
1880 : 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 2 : ExpectValidates(sig,
1885 : {WASM_CALL_FUNCTION(f2, WASM_I32V_1(32), WASM_I32V_2(72))});
1886 1 : }
1887 :
1888 15444 : TEST_F(FunctionBodyDecoderTest, ImportCallsWithMismatchedSigs3) {
1889 : FunctionSig* sig = sigs.i_i();
1890 : TestModuleBuilder builder;
1891 1 : module = builder.module();
1892 :
1893 : 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 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Int32Globals) {
1909 : FunctionSig* sig = sigs.i_i();
1910 : 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 15444 : TEST_F(FunctionBodyDecoderTest, ImmutableGlobal) {
1921 : FunctionSig* sig = sigs.v_v();
1922 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Int32Globals_fail) {
1933 : FunctionSig* sig = sigs.i_i();
1934 : 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 15444 : TEST_F(FunctionBodyDecoderTest, Int64Globals) {
1954 : FunctionSig* sig = sigs.l_l();
1955 : 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 2 : ExpectValidates(sig,
1965 : {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_GET_LOCAL(0)});
1966 2 : ExpectValidates(sig,
1967 : {WASM_SET_GLOBAL(1, WASM_GET_LOCAL(0)), WASM_GET_LOCAL(0)});
1968 1 : }
1969 :
1970 15444 : TEST_F(FunctionBodyDecoderTest, Float32Globals) {
1971 : FunctionSig* sig = sigs.f_ff();
1972 : TestModuleBuilder builder;
1973 1 : module = builder.module();
1974 :
1975 1 : builder.AddGlobal(kWasmF32);
1976 :
1977 2 : ExpectValidates(sig, {WASM_GET_GLOBAL(0)});
1978 2 : ExpectValidates(sig,
1979 : {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_GET_LOCAL(0)});
1980 1 : }
1981 :
1982 15444 : TEST_F(FunctionBodyDecoderTest, Float64Globals) {
1983 : FunctionSig* sig = sigs.d_dd();
1984 : TestModuleBuilder builder;
1985 1 : module = builder.module();
1986 :
1987 1 : builder.AddGlobal(kWasmF64);
1988 :
1989 2 : ExpectValidates(sig, {WASM_GET_GLOBAL(0)});
1990 2 : ExpectValidates(sig,
1991 : {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0)), WASM_GET_LOCAL(0)});
1992 1 : }
1993 :
1994 15444 : TEST_F(FunctionBodyDecoderTest, AllGetGlobalCombinations) {
1995 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
1996 5 : ValueType local_type = kValueTypes[i];
1997 55 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
1998 25 : ValueType global_type = kValueTypes[j];
1999 : FunctionSig sig(1, 0, &local_type);
2000 : 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 15444 : TEST_F(FunctionBodyDecoderTest, AllSetGlobalCombinations) {
2009 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2010 5 : ValueType local_type = kValueTypes[i];
2011 55 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2012 25 : ValueType global_type = kValueTypes[j];
2013 : FunctionSig sig(0, 1, &local_type);
2014 : TestModuleBuilder builder;
2015 25 : module = builder.module();
2016 25 : builder.AddGlobal(global_type);
2017 50 : Validate(local_type == global_type, &sig,
2018 25 : {WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0))});
2019 : }
2020 : }
2021 1 : }
2022 :
2023 15444 : TEST_F(FunctionBodyDecoderTest, SetTable) {
2024 1 : WASM_FEATURE_SCOPE(anyref);
2025 : 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 2 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_ref1, WASM_I32V(6),
2037 : WASM_GET_LOCAL(local_ref))});
2038 2 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_func1, WASM_I32V(5),
2039 : WASM_GET_LOCAL(local_func))});
2040 2 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_func2, WASM_I32V(7),
2041 : WASM_GET_LOCAL(local_func))});
2042 2 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_ref2, WASM_I32V(8),
2043 : WASM_GET_LOCAL(local_ref))});
2044 :
2045 : // We can store anyfunc values as anyref, but not the other way around.
2046 2 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_ref1, WASM_I32V(4),
2047 : WASM_GET_LOCAL(local_func))});
2048 2 : ExpectFailure(&sig, {WASM_SET_TABLE(tab_func1, WASM_I32V(9),
2049 : WASM_GET_LOCAL(local_ref))});
2050 2 : ExpectFailure(&sig, {WASM_SET_TABLE(tab_func2, WASM_I32V(3),
2051 : WASM_GET_LOCAL(local_ref))});
2052 2 : ExpectValidates(&sig, {WASM_SET_TABLE(tab_ref2, WASM_I32V(2),
2053 : WASM_GET_LOCAL(local_func))});
2054 2 : ExpectFailure(&sig, {WASM_SET_TABLE(tab_ref1, WASM_I32V(9),
2055 : WASM_GET_LOCAL(local_int))});
2056 2 : ExpectFailure(&sig, {WASM_SET_TABLE(tab_func1, WASM_I32V(3),
2057 : WASM_GET_LOCAL(local_int))});
2058 : // Out-of-bounds table index should fail.
2059 : byte oob_tab = 37;
2060 2 : ExpectFailure(
2061 : &sig, {WASM_SET_TABLE(oob_tab, WASM_I32V(9), WASM_GET_LOCAL(local_ref))});
2062 2 : ExpectFailure(&sig, {WASM_SET_TABLE(oob_tab, WASM_I32V(3),
2063 : WASM_GET_LOCAL(local_func))});
2064 1 : }
2065 :
2066 15444 : TEST_F(FunctionBodyDecoderTest, GetTable) {
2067 1 : WASM_FEATURE_SCOPE(anyref);
2068 : 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 2 : ExpectValidates(
2080 : &sig,
2081 : {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(tab_ref1, WASM_I32V(6)))});
2082 2 : ExpectValidates(
2083 : &sig,
2084 : {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(tab_ref2, WASM_I32V(8)))});
2085 2 : ExpectValidates(
2086 : &sig,
2087 : {WASM_SET_LOCAL(local_func, WASM_GET_TABLE(tab_func1, WASM_I32V(5)))});
2088 2 : ExpectValidates(
2089 : &sig,
2090 : {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 2 : ExpectFailure(&sig, {WASM_SET_LOCAL(local_func,
2094 : WASM_GET_TABLE(tab_ref1, WASM_I32V(4)))});
2095 2 : ExpectValidates(
2096 : &sig,
2097 : {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(tab_func1, WASM_I32V(9)))});
2098 2 : ExpectValidates(
2099 : &sig,
2100 : {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(tab_func2, WASM_I32V(3)))});
2101 2 : ExpectFailure(&sig, {WASM_SET_LOCAL(local_func,
2102 : WASM_GET_TABLE(tab_ref2, WASM_I32V(2)))});
2103 :
2104 2 : ExpectFailure(&sig, {WASM_SET_LOCAL(local_int,
2105 : WASM_GET_TABLE(tab_ref1, WASM_I32V(9)))});
2106 2 : ExpectFailure(&sig, {WASM_SET_LOCAL(
2107 : local_int, WASM_GET_TABLE(tab_func1, WASM_I32V(3)))});
2108 : // Out-of-bounds table index should fail.
2109 : byte oob_tab = 37;
2110 2 : ExpectFailure(
2111 : &sig, {WASM_SET_LOCAL(local_ref, WASM_GET_TABLE(oob_tab, WASM_I32V(9)))});
2112 2 : ExpectFailure(&sig, {WASM_SET_LOCAL(local_func,
2113 : WASM_GET_TABLE(oob_tab, WASM_I32V(3)))});
2114 1 : }
2115 :
2116 15444 : TEST_F(FunctionBodyDecoderTest, MultiTableCallIndirect) {
2117 1 : WASM_FEATURE_SCOPE(anyref);
2118 : TestModuleBuilder builder;
2119 1 : module = builder.module();
2120 1 : byte tab_ref = builder.AddTable(kWasmAnyRef, 10, true, 20);
2121 1 : byte tab_func = builder.AddTable(kWasmAnyFunc, 20, true, 30);
2122 :
2123 1 : ValueType sig_types[]{kWasmAnyRef, kWasmAnyFunc, kWasmI32};
2124 : FunctionSig sig(0, 3, sig_types);
2125 1 : byte sig_index = builder.AddSignature(sigs.i_v());
2126 :
2127 : // We can store anyfunc values as anyref, but not the other way around.
2128 2 : ExpectValidates(sigs.i_v(),
2129 : {kExprI32Const, 0, kExprCallIndirect, sig_index, tab_func});
2130 :
2131 2 : ExpectFailure(sigs.i_v(),
2132 : {kExprI32Const, 0, kExprCallIndirect, sig_index, tab_ref});
2133 1 : }
2134 :
2135 15444 : TEST_F(FunctionBodyDecoderTest, WasmMemoryGrow) {
2136 : TestModuleBuilder builder;
2137 1 : module = builder.module();
2138 : builder.InitializeMemory();
2139 :
2140 1 : byte code[] = {WASM_GET_LOCAL(0), kExprMemoryGrow, 0};
2141 1 : ExpectValidates(sigs.i_i(), code);
2142 : ExpectFailure(sigs.i_d(), code);
2143 1 : }
2144 :
2145 15444 : TEST_F(FunctionBodyDecoderTest, AsmJsMemoryGrow) {
2146 : TestModuleBuilder builder(kAsmJsOrigin);
2147 1 : module = builder.module();
2148 : builder.InitializeMemory();
2149 :
2150 1 : byte code[] = {WASM_GET_LOCAL(0), kExprMemoryGrow, 0};
2151 1 : ExpectFailure(sigs.i_i(), code);
2152 1 : }
2153 :
2154 15444 : TEST_F(FunctionBodyDecoderTest, AsmJsBinOpsCheckOrigin) {
2155 1 : ValueType float32int32float32[] = {kWasmF32, kWasmI32, kWasmF32};
2156 : FunctionSig sig_f_if(1, 2, float32int32float32);
2157 1 : ValueType float64int32float64[] = {kWasmF64, kWasmI32, kWasmF64};
2158 : FunctionSig sig_d_id(1, 2, float64int32float64);
2159 : struct {
2160 : WasmOpcode op;
2161 : FunctionSig* sig;
2162 : } AsmJsBinOps[] = {
2163 : {kExprF64Atan2, sigs.d_dd()},
2164 : {kExprF64Pow, sigs.d_dd()},
2165 : {kExprF64Mod, sigs.d_dd()},
2166 : {kExprI32AsmjsDivS, sigs.i_ii()},
2167 : {kExprI32AsmjsDivU, sigs.i_ii()},
2168 : {kExprI32AsmjsRemS, sigs.i_ii()},
2169 : {kExprI32AsmjsRemU, sigs.i_ii()},
2170 : {kExprI32AsmjsStoreMem8, sigs.i_ii()},
2171 : {kExprI32AsmjsStoreMem16, sigs.i_ii()},
2172 : {kExprI32AsmjsStoreMem, sigs.i_ii()},
2173 : {kExprF32AsmjsStoreMem, &sig_f_if},
2174 : {kExprF64AsmjsStoreMem, &sig_d_id},
2175 3 : };
2176 :
2177 : {
2178 : TestModuleBuilder builder(kAsmJsOrigin);
2179 1 : module = builder.module();
2180 : builder.InitializeMemory();
2181 25 : for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) {
2182 12 : TestBinop(AsmJsBinOps[i].op, AsmJsBinOps[i].sig);
2183 : }
2184 : }
2185 :
2186 : {
2187 : TestModuleBuilder builder;
2188 1 : module = builder.module();
2189 : builder.InitializeMemory();
2190 25 : for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) {
2191 36 : ExpectFailure(AsmJsBinOps[i].sig,
2192 12 : {WASM_BINOP(AsmJsBinOps[i].op, WASM_GET_LOCAL(0),
2193 : WASM_GET_LOCAL(1))});
2194 : }
2195 : }
2196 1 : }
2197 :
2198 15444 : TEST_F(FunctionBodyDecoderTest, AsmJsUnOpsCheckOrigin) {
2199 1 : ValueType float32int32[] = {kWasmF32, kWasmI32};
2200 : FunctionSig sig_f_i(1, 1, float32int32);
2201 1 : ValueType float64int32[] = {kWasmF64, kWasmI32};
2202 : FunctionSig sig_d_i(1, 1, float64int32);
2203 : struct {
2204 : WasmOpcode op;
2205 : FunctionSig* sig;
2206 : } AsmJsUnOps[] = {{kExprF64Acos, sigs.d_d()},
2207 : {kExprF64Asin, sigs.d_d()},
2208 : {kExprF64Atan, sigs.d_d()},
2209 : {kExprF64Cos, sigs.d_d()},
2210 : {kExprF64Sin, sigs.d_d()},
2211 : {kExprF64Tan, sigs.d_d()},
2212 : {kExprF64Exp, sigs.d_d()},
2213 : {kExprF64Log, sigs.d_d()},
2214 : {kExprI32AsmjsLoadMem8S, sigs.i_i()},
2215 : {kExprI32AsmjsLoadMem8U, sigs.i_i()},
2216 : {kExprI32AsmjsLoadMem16S, sigs.i_i()},
2217 : {kExprI32AsmjsLoadMem16U, sigs.i_i()},
2218 : {kExprI32AsmjsLoadMem, sigs.i_i()},
2219 : {kExprF32AsmjsLoadMem, &sig_f_i},
2220 : {kExprF64AsmjsLoadMem, &sig_d_i},
2221 : {kExprI32AsmjsSConvertF32, sigs.i_f()},
2222 : {kExprI32AsmjsUConvertF32, sigs.i_f()},
2223 : {kExprI32AsmjsSConvertF64, sigs.i_d()},
2224 5 : {kExprI32AsmjsUConvertF64, sigs.i_d()}};
2225 : {
2226 : TestModuleBuilder builder(kAsmJsOrigin);
2227 1 : module = builder.module();
2228 : builder.InitializeMemory();
2229 39 : for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) {
2230 19 : TestUnop(AsmJsUnOps[i].op, AsmJsUnOps[i].sig);
2231 : }
2232 : }
2233 :
2234 : {
2235 : TestModuleBuilder builder;
2236 1 : module = builder.module();
2237 : builder.InitializeMemory();
2238 39 : for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) {
2239 57 : ExpectFailure(AsmJsUnOps[i].sig,
2240 19 : {WASM_UNOP(AsmJsUnOps[i].op, WASM_GET_LOCAL(0))});
2241 : }
2242 : }
2243 1 : }
2244 :
2245 15444 : TEST_F(FunctionBodyDecoderTest, BreakEnd) {
2246 3 : ExpectValidates(
2247 : sigs.i_i(),
2248 : {WASM_BLOCK_I(WASM_I32_ADD(WASM_BRV(0, WASM_ZERO), WASM_ZERO))});
2249 2 : ExpectValidates(
2250 : sigs.i_i(),
2251 : {WASM_BLOCK_I(WASM_I32_ADD(WASM_ZERO, WASM_BRV(0, WASM_ZERO)))});
2252 1 : }
2253 :
2254 15444 : TEST_F(FunctionBodyDecoderTest, BreakIfBinop) {
2255 3 : ExpectValidates(sigs.i_i(),
2256 : {WASM_BLOCK_I(WASM_I32_ADD(
2257 : WASM_BRV_IF(0, WASM_ZERO, WASM_ZERO), WASM_ZERO))});
2258 2 : ExpectValidates(sigs.i_i(),
2259 : {WASM_BLOCK_I(WASM_I32_ADD(
2260 : WASM_ZERO, WASM_BRV_IF(0, WASM_ZERO, WASM_ZERO)))});
2261 2 : ExpectValidates(
2262 : sigs.f_ff(),
2263 : {WASM_BLOCK_F(WASM_F32_ABS(WASM_BRV_IF(0, WASM_F32(0.0f), WASM_ZERO)))});
2264 1 : }
2265 :
2266 15444 : TEST_F(FunctionBodyDecoderTest, BreakIfBinop_fail) {
2267 3 : ExpectFailure(
2268 : sigs.f_ff(),
2269 : {WASM_BLOCK_F(WASM_F32_ABS(WASM_BRV_IF(0, WASM_ZERO, WASM_ZERO)))});
2270 2 : ExpectFailure(
2271 : sigs.i_i(),
2272 : {WASM_BLOCK_I(WASM_F32_ABS(WASM_BRV_IF(0, WASM_F32(0.0f), WASM_ZERO)))});
2273 1 : }
2274 :
2275 15444 : TEST_F(FunctionBodyDecoderTest, BreakIfUnrNarrow) {
2276 3 : ExpectFailure(
2277 : sigs.f_ff(),
2278 : {WASM_BLOCK_I(WASM_BRV_IF(0, WASM_UNREACHABLE, WASM_UNREACHABLE),
2279 : WASM_RETURN0),
2280 : WASM_F32(0.0)});
2281 1 : }
2282 :
2283 15444 : TEST_F(FunctionBodyDecoderTest, BreakNesting1) {
2284 11 : for (int i = 0; i < 5; i++) {
2285 : // (block[2] (loop[2] (if (get p) break[N]) (set p 1)) p)
2286 : byte code[] = {WASM_BLOCK_I(
2287 : WASM_LOOP(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(i + 1, WASM_ZERO)),
2288 : WASM_SET_LOCAL(0, WASM_I32V_1(1))),
2289 5 : WASM_ZERO)};
2290 5 : Validate(i < 3, sigs.i_i(), code);
2291 : }
2292 1 : }
2293 :
2294 15444 : TEST_F(FunctionBodyDecoderTest, BreakNesting2) {
2295 15 : for (int i = 0; i < 7; i++) {
2296 7 : byte code[] = {B1(WASM_LOOP(WASM_IF(WASM_ZERO, WASM_BR(i)), WASM_NOP))};
2297 7 : Validate(i <= 3, sigs.v_v(), code);
2298 : }
2299 1 : }
2300 :
2301 15444 : TEST_F(FunctionBodyDecoderTest, BreakNesting3) {
2302 15 : for (int i = 0; i < 7; i++) {
2303 : // (block[1] (loop[1] (block[1] (if 0 break[N])
2304 : byte code[] = {
2305 7 : WASM_BLOCK(WASM_LOOP(B1(WASM_IF(WASM_ZERO, WASM_BR(i + 1)))))};
2306 7 : Validate(i < 4, sigs.v_v(), code);
2307 : }
2308 1 : }
2309 :
2310 15444 : TEST_F(FunctionBodyDecoderTest, BreaksWithMultipleTypes) {
2311 3 : ExpectFailure(sigs.i_i(),
2312 : {B2(WASM_BRV_IF_ZERO(0, WASM_I32V_1(7)), WASM_F32(7.7))});
2313 :
2314 2 : ExpectFailure(sigs.i_i(), {B2(WASM_BRV_IF_ZERO(0, WASM_I32V_1(7)),
2315 : WASM_BRV_IF_ZERO(0, WASM_F32(7.7)))});
2316 2 : ExpectFailure(sigs.i_i(), {B3(WASM_BRV_IF_ZERO(0, WASM_I32V_1(8)),
2317 : WASM_BRV_IF_ZERO(0, WASM_I32V_1(0)),
2318 : WASM_BRV_IF_ZERO(0, WASM_F32(7.7)))});
2319 2 : ExpectFailure(sigs.i_i(), {B3(WASM_BRV_IF_ZERO(0, WASM_I32V_1(9)),
2320 : WASM_BRV_IF_ZERO(0, WASM_F32(7.7)),
2321 : WASM_BRV_IF_ZERO(0, WASM_I32V_1(11)))});
2322 1 : }
2323 :
2324 15444 : TEST_F(FunctionBodyDecoderTest, BreakNesting_6_levels) {
2325 129 : for (int mask = 0; mask < 64; mask++) {
2326 1856 : for (int i = 0; i < 14; i++) {
2327 : byte code[] = {WASM_BLOCK(WASM_BLOCK(
2328 896 : WASM_BLOCK(WASM_BLOCK(WASM_BLOCK(WASM_BLOCK(WASM_BR(i)))))))};
2329 :
2330 : int depth = 6;
2331 : int m = mask;
2332 34944 : for (size_t pos = 0; pos < sizeof(code) - 1; pos++) {
2333 17024 : if (code[pos] != kExprBlock) continue;
2334 5440 : if (m & 1) {
2335 2688 : code[pos] = kExprLoop;
2336 2688 : code[pos + 1] = kLocalVoid;
2337 : }
2338 5440 : m >>= 1;
2339 : }
2340 :
2341 896 : Validate(i <= depth, sigs.v_v(), code);
2342 : }
2343 : }
2344 1 : }
2345 :
2346 15444 : TEST_F(FunctionBodyDecoderTest, Break_TypeCheck) {
2347 4 : FunctionSig* sigarray[] = {sigs.i_i(), sigs.l_l(), sigs.f_ff(), sigs.d_dd()};
2348 9 : for (size_t i = 0; i < arraysize(sigarray); i++) {
2349 4 : FunctionSig* sig = sigarray[i];
2350 : // unify X and X => OK
2351 4 : byte code[] = {WASM_BLOCK_T(
2352 : sig->GetReturn(), WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))),
2353 8 : WASM_GET_LOCAL(0))};
2354 4 : ExpectValidates(sig, code);
2355 : }
2356 :
2357 : // unify i32 and f32 => fail
2358 2 : ExpectFailure(sigs.i_i(),
2359 : {WASM_BLOCK_I(WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_ZERO)),
2360 : WASM_F32(1.2))});
2361 :
2362 : // unify f64 and f64 => OK
2363 2 : ExpectValidates(
2364 : sigs.d_dd(),
2365 : {WASM_BLOCK_D(WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))),
2366 : WASM_F64(1.2))});
2367 1 : }
2368 :
2369 15444 : TEST_F(FunctionBodyDecoderTest, Break_TypeCheckAll1) {
2370 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2371 55 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2372 25 : ValueType storage[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j]};
2373 : FunctionSig sig(1, 2, storage);
2374 25 : byte code[] = {WASM_BLOCK_T(
2375 : sig.GetReturn(), WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))),
2376 50 : WASM_GET_LOCAL(1))};
2377 :
2378 25 : Validate(i == j, &sig, code);
2379 : }
2380 : }
2381 1 : }
2382 :
2383 15444 : TEST_F(FunctionBodyDecoderTest, Break_TypeCheckAll2) {
2384 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2385 55 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2386 25 : ValueType storage[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j]};
2387 : FunctionSig sig(1, 2, storage);
2388 25 : byte code[] = {WASM_IF_ELSE_T(sig.GetReturn(0), WASM_ZERO,
2389 : WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)),
2390 50 : WASM_GET_LOCAL(1))};
2391 :
2392 25 : Validate(i == j, &sig, code);
2393 : }
2394 : }
2395 1 : }
2396 :
2397 15444 : TEST_F(FunctionBodyDecoderTest, Break_TypeCheckAll3) {
2398 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2399 55 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2400 25 : ValueType storage[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j]};
2401 : FunctionSig sig(1, 2, storage);
2402 25 : byte code[] = {WASM_IF_ELSE_T(sig.GetReturn(), WASM_ZERO,
2403 : WASM_GET_LOCAL(1),
2404 50 : WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))};
2405 :
2406 25 : Validate(i == j, &sig, code);
2407 : }
2408 : }
2409 1 : }
2410 :
2411 15444 : TEST_F(FunctionBodyDecoderTest, Break_Unify) {
2412 5 : for (int which = 0; which < 2; which++) {
2413 22 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2414 10 : ValueType type = kValueTypes[i];
2415 10 : ValueType storage[] = {kWasmI32, kWasmI32, type};
2416 : FunctionSig sig(1, 2, storage);
2417 :
2418 10 : byte code1[] = {WASM_BLOCK_T(
2419 : type, WASM_IF(WASM_ZERO, WASM_BRV(1, WASM_GET_LOCAL(which))),
2420 20 : WASM_GET_LOCAL(which ^ 1))};
2421 :
2422 10 : Validate(type == kWasmI32, &sig, code1);
2423 : }
2424 : }
2425 1 : }
2426 :
2427 15444 : TEST_F(FunctionBodyDecoderTest, BreakIf_cond_type) {
2428 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2429 55 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2430 25 : ValueType types[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j]};
2431 : FunctionSig sig(1, 2, types);
2432 25 : byte code[] = {WASM_BLOCK_T(
2433 50 : types[0], WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)))};
2434 :
2435 25 : Validate(types[2] == kWasmI32, &sig, code);
2436 : }
2437 : }
2438 1 : }
2439 :
2440 15444 : TEST_F(FunctionBodyDecoderTest, BreakIf_val_type) {
2441 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2442 55 : for (size_t j = 0; j < arraysize(kValueTypes); j++) {
2443 50 : ValueType types[] = {kValueTypes[i], kValueTypes[i], kValueTypes[j],
2444 75 : kWasmI32};
2445 : FunctionSig sig(1, 3, types);
2446 25 : byte code[] = {WASM_BLOCK_T(
2447 : types[1], WASM_BRV_IF(0, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)),
2448 50 : WASM_DROP, WASM_GET_LOCAL(0))};
2449 :
2450 25 : Validate(i == j, &sig, code);
2451 : }
2452 : }
2453 1 : }
2454 :
2455 15444 : TEST_F(FunctionBodyDecoderTest, BreakIf_Unify) {
2456 5 : for (int which = 0; which < 2; which++) {
2457 22 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2458 10 : ValueType type = kValueTypes[i];
2459 10 : ValueType storage[] = {kWasmI32, kWasmI32, type};
2460 : FunctionSig sig(1, 2, storage);
2461 : byte code[] = {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(which)),
2462 10 : WASM_DROP, WASM_GET_LOCAL(which ^ 1))};
2463 :
2464 10 : Validate(type == kWasmI32, &sig, code);
2465 : }
2466 : }
2467 1 : }
2468 :
2469 15444 : TEST_F(FunctionBodyDecoderTest, BrTable0) {
2470 3 : ExpectFailure(sigs.v_v(), {kExprBrTable, 0, BR_TARGET(0)});
2471 1 : }
2472 :
2473 15444 : TEST_F(FunctionBodyDecoderTest, BrTable0b) {
2474 : static byte code[] = {kExprI32Const, 11, kExprBrTable, 0, BR_TARGET(0)};
2475 1 : ExpectValidates(sigs.v_v(), code);
2476 : ExpectFailure(sigs.i_i(), code);
2477 1 : }
2478 :
2479 15444 : TEST_F(FunctionBodyDecoderTest, BrTable0c) {
2480 : static byte code[] = {kExprI32Const, 11, kExprBrTable, 0, BR_TARGET(1)};
2481 1 : ExpectFailure(sigs.v_v(), code);
2482 : ExpectFailure(sigs.i_i(), code);
2483 1 : }
2484 :
2485 15444 : TEST_F(FunctionBodyDecoderTest, BrTable1a) {
2486 3 : ExpectValidates(sigs.v_v(),
2487 : {B1(WASM_BR_TABLE(WASM_I32V_2(67), 0, BR_TARGET(0)))});
2488 1 : }
2489 :
2490 15444 : TEST_F(FunctionBodyDecoderTest, BrTable1b) {
2491 : static byte code[] = {B1(WASM_BR_TABLE(WASM_ZERO, 0, BR_TARGET(0)))};
2492 1 : ExpectValidates(sigs.v_v(), code);
2493 : ExpectFailure(sigs.i_i(), code);
2494 : ExpectFailure(sigs.f_ff(), code);
2495 : ExpectFailure(sigs.d_dd(), code);
2496 1 : }
2497 :
2498 15444 : TEST_F(FunctionBodyDecoderTest, BrTable2a) {
2499 3 : ExpectValidates(
2500 : sigs.v_v(),
2501 : {B1(WASM_BR_TABLE(WASM_I32V_2(67), 1, BR_TARGET(0), BR_TARGET(0)))});
2502 1 : }
2503 :
2504 15444 : TEST_F(FunctionBodyDecoderTest, BrTable2b) {
2505 3 : ExpectValidates(sigs.v_v(),
2506 : {WASM_BLOCK(WASM_BLOCK(WASM_BR_TABLE(
2507 : WASM_I32V_2(67), 1, BR_TARGET(0), BR_TARGET(1))))});
2508 1 : }
2509 :
2510 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_off_end) {
2511 : static byte code[] = {B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(0)))};
2512 15 : for (size_t len = 1; len < sizeof(code); len++) {
2513 21 : ExpectFailure(sigs.i_i(), VectorOf(code, len), kAppendEnd);
2514 14 : ExpectFailure(sigs.i_i(), VectorOf(code, len), kOmitEnd);
2515 : }
2516 1 : }
2517 :
2518 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_invalid_br1) {
2519 9 : for (int depth = 0; depth < 4; depth++) {
2520 4 : byte code[] = {B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(depth)))};
2521 4 : Validate(depth <= 1, sigs.v_i(), code);
2522 : }
2523 1 : }
2524 :
2525 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_invalid_br2) {
2526 15 : for (int depth = 0; depth < 7; depth++) {
2527 : byte code[] = {
2528 7 : WASM_LOOP(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(depth)))};
2529 7 : Validate(depth < 2, sigs.v_i(), code);
2530 : }
2531 1 : }
2532 :
2533 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_arity_mismatch1) {
2534 3 : ExpectFailure(
2535 : sigs.v_v(),
2536 : {WASM_BLOCK(WASM_BLOCK_I(
2537 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2538 1 : }
2539 :
2540 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_arity_mismatch2) {
2541 3 : ExpectFailure(
2542 : sigs.v_v(),
2543 : {WASM_BLOCK_I(WASM_BLOCK(
2544 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2545 1 : }
2546 :
2547 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_arity_mismatch_loop1) {
2548 3 : ExpectFailure(
2549 : sigs.v_v(),
2550 : {WASM_LOOP(WASM_BLOCK_I(
2551 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2552 1 : }
2553 :
2554 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_arity_mismatch_loop2) {
2555 3 : ExpectFailure(
2556 : sigs.v_v(),
2557 : {WASM_BLOCK_I(WASM_LOOP(
2558 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2559 1 : }
2560 :
2561 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_loop_block) {
2562 3 : ExpectValidates(
2563 : sigs.v_v(),
2564 : {WASM_LOOP(WASM_BLOCK(
2565 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2566 1 : }
2567 :
2568 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_block_loop) {
2569 3 : ExpectValidates(
2570 : sigs.v_v(),
2571 : {WASM_LOOP(WASM_BLOCK(
2572 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2573 1 : }
2574 :
2575 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_type_mismatch1) {
2576 3 : ExpectFailure(
2577 : sigs.v_v(),
2578 : {WASM_BLOCK_I(WASM_BLOCK_F(
2579 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2580 1 : }
2581 :
2582 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_type_mismatch2) {
2583 3 : ExpectFailure(
2584 : sigs.v_v(),
2585 : {WASM_BLOCK_F(WASM_BLOCK_I(
2586 : WASM_ONE, WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2587 1 : }
2588 :
2589 15444 : TEST_F(FunctionBodyDecoderTest, BrTable_type_mismatch_unreachable) {
2590 3 : ExpectFailure(sigs.v_v(),
2591 : {WASM_BLOCK_F(WASM_BLOCK_I(
2592 : WASM_UNREACHABLE,
2593 : WASM_BR_TABLE(WASM_ONE, 1, BR_TARGET(0), BR_TARGET(1))))});
2594 1 : }
2595 :
2596 15444 : TEST_F(FunctionBodyDecoderTest, BrUnreachable1) {
2597 3 : ExpectValidates(sigs.v_i(),
2598 : {WASM_GET_LOCAL(0), kExprBrTable, 0, BR_TARGET(0)});
2599 1 : }
2600 :
2601 15444 : TEST_F(FunctionBodyDecoderTest, BrUnreachable2) {
2602 3 : ExpectValidates(sigs.v_i(),
2603 : {WASM_GET_LOCAL(0), kExprBrTable, 0, BR_TARGET(0), WASM_NOP});
2604 2 : ExpectFailure(sigs.v_i(),
2605 : {WASM_GET_LOCAL(0), kExprBrTable, 0, BR_TARGET(0), WASM_ZERO});
2606 1 : }
2607 :
2608 15444 : TEST_F(FunctionBodyDecoderTest, Brv1) {
2609 3 : ExpectValidates(sigs.i_i(), {WASM_BLOCK_I(WASM_BRV(0, WASM_ZERO))});
2610 2 : ExpectValidates(sigs.i_i(),
2611 : {WASM_BLOCK_I(WASM_LOOP_I(WASM_BRV(2, WASM_ZERO)))});
2612 1 : }
2613 :
2614 15444 : TEST_F(FunctionBodyDecoderTest, Brv1_type) {
2615 3 : ExpectValidates(sigs.i_ii(), {WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2616 2 : ExpectValidates(sigs.l_ll(), {WASM_BLOCK_L(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2617 2 : ExpectValidates(sigs.f_ff(), {WASM_BLOCK_F(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2618 2 : ExpectValidates(sigs.d_dd(), {WASM_BLOCK_D(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2619 1 : }
2620 :
2621 15444 : TEST_F(FunctionBodyDecoderTest, Brv1_type_n) {
2622 3 : ExpectFailure(sigs.i_f(), {WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2623 2 : ExpectFailure(sigs.i_d(), {WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)))});
2624 1 : }
2625 :
2626 15444 : TEST_F(FunctionBodyDecoderTest, BrvIf1) {
2627 3 : ExpectValidates(sigs.i_v(), {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_ZERO))});
2628 1 : }
2629 :
2630 15444 : TEST_F(FunctionBodyDecoderTest, BrvIf1_type) {
2631 3 : ExpectValidates(sigs.i_i(),
2632 : {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2633 2 : ExpectValidates(sigs.l_l(),
2634 : {WASM_BLOCK_L(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2635 2 : ExpectValidates(sigs.f_ff(),
2636 : {WASM_BLOCK_F(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2637 2 : ExpectValidates(sigs.d_dd(),
2638 : {WASM_BLOCK_D(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2639 1 : }
2640 :
2641 15444 : TEST_F(FunctionBodyDecoderTest, BrvIf1_type_n) {
2642 3 : ExpectFailure(sigs.i_f(),
2643 : {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2644 2 : ExpectFailure(sigs.i_d(),
2645 : {WASM_BLOCK_I(WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))});
2646 1 : }
2647 :
2648 15444 : TEST_F(FunctionBodyDecoderTest, Select) {
2649 3 : ExpectValidates(sigs.i_i(), {WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2650 : WASM_ZERO)});
2651 2 : ExpectValidates(sigs.f_ff(),
2652 : {WASM_SELECT(WASM_F32(0.0), WASM_F32(0.0), WASM_ZERO)});
2653 2 : ExpectValidates(sigs.d_dd(),
2654 : {WASM_SELECT(WASM_F64(0.0), WASM_F64(0.0), WASM_ZERO)});
2655 2 : ExpectValidates(sigs.l_l(),
2656 : {WASM_SELECT(WASM_I64V_1(0), WASM_I64V_1(0), WASM_ZERO)});
2657 1 : }
2658 :
2659 15444 : TEST_F(FunctionBodyDecoderTest, Select_fail1) {
2660 3 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_F32(0.0), WASM_GET_LOCAL(0),
2661 : WASM_GET_LOCAL(0))});
2662 2 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_GET_LOCAL(0), WASM_F32(0.0),
2663 : WASM_GET_LOCAL(0))});
2664 2 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2665 : WASM_F32(0.0))});
2666 1 : }
2667 :
2668 15444 : TEST_F(FunctionBodyDecoderTest, Select_fail2) {
2669 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
2670 5 : ValueType type = kValueTypes[i];
2671 6 : if (type == kWasmI32) continue;
2672 :
2673 4 : ValueType types[] = {type, kWasmI32, type};
2674 : FunctionSig sig(1, 2, types);
2675 :
2676 8 : ExpectValidates(&sig, {WASM_SELECT(WASM_GET_LOCAL(1), WASM_GET_LOCAL(1),
2677 : WASM_GET_LOCAL(0))});
2678 :
2679 8 : ExpectFailure(&sig, {WASM_SELECT(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0),
2680 : WASM_GET_LOCAL(0))});
2681 :
2682 8 : ExpectFailure(&sig, {WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2683 : WASM_GET_LOCAL(0))});
2684 :
2685 8 : ExpectFailure(&sig, {WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2686 : WASM_GET_LOCAL(1))});
2687 : }
2688 1 : }
2689 :
2690 15444 : TEST_F(FunctionBodyDecoderTest, Select_TypeCheck) {
2691 3 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_F32(9.9), WASM_GET_LOCAL(0),
2692 : WASM_GET_LOCAL(0))});
2693 :
2694 2 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_GET_LOCAL(0), WASM_F64(0.25),
2695 : WASM_GET_LOCAL(0))});
2696 :
2697 2 : ExpectFailure(sigs.i_i(), {WASM_SELECT(WASM_F32(9.9), WASM_GET_LOCAL(0),
2698 : WASM_I64V_1(0))});
2699 1 : }
2700 :
2701 15444 : TEST_F(FunctionBodyDecoderTest, Throw) {
2702 1 : WASM_FEATURE_SCOPE(eh);
2703 : TestModuleBuilder builder;
2704 1 : module = builder.module();
2705 1 : byte ex1 = builder.AddException(sigs.v_v());
2706 1 : byte ex2 = builder.AddException(sigs.v_i());
2707 1 : byte ex3 = builder.AddException(sigs.v_ii());
2708 2 : ExpectValidates(sigs.v_v(), {kExprThrow, ex1});
2709 2 : ExpectValidates(sigs.v_v(), {WASM_I32V(0), kExprThrow, ex2});
2710 2 : ExpectFailure(sigs.v_v(), {WASM_F32(0.0), kExprThrow, ex2});
2711 2 : ExpectValidates(sigs.v_v(), {WASM_I32V(0), WASM_I32V(0), kExprThrow, ex3});
2712 2 : ExpectFailure(sigs.v_v(), {WASM_F32(0.0), WASM_I32V(0), kExprThrow, ex3});
2713 2 : ExpectFailure(sigs.v_v(), {kExprThrow, 99});
2714 1 : }
2715 :
2716 15444 : TEST_F(FunctionBodyDecoderTest, ThrowUnreachable) {
2717 1 : WASM_FEATURE_SCOPE(eh);
2718 : TestModuleBuilder builder;
2719 1 : module = builder.module();
2720 1 : byte ex1 = builder.AddException(sigs.v_v());
2721 1 : byte ex2 = builder.AddException(sigs.v_i());
2722 3 : ExpectValidates(sigs.i_i(), {WASM_GET_LOCAL(0), kExprThrow, ex1, WASM_NOP});
2723 2 : ExpectValidates(sigs.v_i(), {WASM_GET_LOCAL(0), kExprThrow, ex2, WASM_NOP});
2724 2 : ExpectValidates(sigs.i_i(), {WASM_GET_LOCAL(0), kExprThrow, ex1, WASM_ZERO});
2725 2 : ExpectFailure(sigs.v_i(), {WASM_GET_LOCAL(0), kExprThrow, ex2, WASM_ZERO});
2726 2 : ExpectFailure(sigs.i_i(),
2727 : {WASM_GET_LOCAL(0), kExprThrow, ex1, WASM_F32(0.0)});
2728 2 : ExpectFailure(sigs.v_i(),
2729 : {WASM_GET_LOCAL(0), kExprThrow, ex2, WASM_F32(0.0)});
2730 1 : }
2731 :
2732 : #define WASM_TRY_OP kExprTry, kLocalVoid
2733 : #define WASM_BR_ON_EXN(depth, index) \
2734 : kExprBrOnExn, static_cast<byte>(depth), static_cast<byte>(index)
2735 :
2736 15444 : TEST_F(FunctionBodyDecoderTest, TryCatch) {
2737 1 : WASM_FEATURE_SCOPE(eh);
2738 : TestModuleBuilder builder;
2739 1 : module = builder.module();
2740 3 : ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprCatch, kExprDrop, kExprEnd});
2741 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprCatch, kExprCatch, kExprEnd});
2742 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprEnd}); // Missing catch.
2743 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprCatch}); // Missing end.
2744 2 : ExpectFailure(sigs.v_v(), {kExprCatch, kExprEnd}); // Missing try.
2745 1 : }
2746 :
2747 15444 : TEST_F(FunctionBodyDecoderTest, Rethrow) {
2748 1 : WASM_FEATURE_SCOPE(eh);
2749 : TestModuleBuilder builder;
2750 1 : module = builder.module();
2751 3 : ExpectValidates(sigs.v_v(),
2752 : {WASM_TRY_OP, kExprCatch, kExprRethrow, kExprEnd});
2753 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprRethrow, kExprCatch, kExprEnd});
2754 2 : ExpectFailure(sigs.v_v(), {WASM_BLOCK(kExprRethrow)});
2755 2 : ExpectFailure(sigs.v_v(), {kExprRethrow});
2756 1 : }
2757 :
2758 15444 : TEST_F(FunctionBodyDecoderTest, BrOnExn) {
2759 1 : WASM_FEATURE_SCOPE(eh);
2760 : TestModuleBuilder builder;
2761 1 : module = builder.module();
2762 1 : byte ex1 = builder.AddException(sigs.v_v());
2763 1 : byte ex2 = builder.AddException(sigs.v_i());
2764 2 : ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(0, ex1),
2765 : kExprDrop, kExprEnd});
2766 2 : ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(1, ex1),
2767 : kExprDrop, kExprEnd});
2768 2 : ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(0, ex1),
2769 : WASM_BR_ON_EXN(0, ex1), kExprDrop, kExprEnd});
2770 2 : ExpectValidates(sigs.v_v(),
2771 : {WASM_BLOCK(WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(1, ex1),
2772 : kExprDrop, kExprEnd)});
2773 2 : ExpectValidates(sigs.i_v(),
2774 : {WASM_BLOCK_I(WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(1, ex2),
2775 : kExprDrop, kExprEnd, kExprI32Const, 0)});
2776 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(2, ex1),
2777 : kExprDrop, kExprEnd});
2778 2 : ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprCatch, kExprDrop,
2779 : WASM_BR_ON_EXN(0, ex1), kExprEnd});
2780 2 : ExpectFailure(sigs.v_v(),
2781 : {WASM_TRY_OP, kExprCatch, WASM_BR_ON_EXN(0, ex1), kExprEnd});
2782 1 : }
2783 :
2784 : #undef WASM_BR_ON_EXN
2785 : #undef WASM_TRY_OP
2786 :
2787 15444 : TEST_F(FunctionBodyDecoderTest, MultiValBlock1) {
2788 1 : WASM_FEATURE_SCOPE(mv);
2789 : TestModuleBuilder builder;
2790 1 : module = builder.module();
2791 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2792 3 : ExpectValidates(
2793 : sigs.i_ii(),
2794 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprI32Add});
2795 2 : ExpectFailure(sigs.i_ii(), {WASM_BLOCK_X(f0, WASM_NOP), kExprI32Add});
2796 2 : ExpectFailure(sigs.i_ii(),
2797 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0)), kExprI32Add});
2798 2 : ExpectFailure(sigs.i_ii(),
2799 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2800 : WASM_GET_LOCAL(0)),
2801 : kExprI32Add});
2802 2 : ExpectFailure(
2803 : sigs.i_ii(),
2804 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprF32Add});
2805 1 : }
2806 :
2807 15444 : TEST_F(FunctionBodyDecoderTest, MultiValBlock2) {
2808 1 : WASM_FEATURE_SCOPE(mv);
2809 : TestModuleBuilder builder;
2810 1 : module = builder.module();
2811 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2812 3 : ExpectValidates(sigs.i_ii(),
2813 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2814 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2815 2 : ExpectFailure(sigs.i_ii(),
2816 : {WASM_BLOCK_X(f0, WASM_NOP), WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2817 2 : ExpectFailure(sigs.i_ii(), {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0)),
2818 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2819 2 : ExpectFailure(sigs.i_ii(),
2820 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2821 : WASM_GET_LOCAL(0)),
2822 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2823 2 : ExpectFailure(sigs.i_ii(),
2824 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2825 : WASM_F32_ADD(WASM_NOP, WASM_NOP)});
2826 1 : }
2827 :
2828 15444 : TEST_F(FunctionBodyDecoderTest, MultiValBlockBr) {
2829 1 : WASM_FEATURE_SCOPE(mv);
2830 : TestModuleBuilder builder;
2831 1 : module = builder.module();
2832 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2833 3 : ExpectFailure(sigs.i_ii(),
2834 : {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0), WASM_BR(0)), kExprI32Add});
2835 2 : ExpectValidates(sigs.i_ii(), {WASM_BLOCK_X(f0, WASM_GET_LOCAL(0),
2836 : WASM_GET_LOCAL(1), WASM_BR(0)),
2837 : kExprI32Add});
2838 1 : }
2839 :
2840 15444 : TEST_F(FunctionBodyDecoderTest, MultiValLoop1) {
2841 1 : WASM_FEATURE_SCOPE(mv);
2842 : TestModuleBuilder builder;
2843 1 : module = builder.module();
2844 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2845 3 : ExpectValidates(
2846 : sigs.i_ii(),
2847 : {WASM_LOOP_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprI32Add});
2848 2 : ExpectFailure(sigs.i_ii(), {WASM_LOOP_X(f0, WASM_NOP), kExprI32Add});
2849 2 : ExpectFailure(sigs.i_ii(), {WASM_LOOP_X(f0, WASM_GET_LOCAL(0)), kExprI32Add});
2850 2 : ExpectFailure(sigs.i_ii(), {WASM_LOOP_X(f0, WASM_GET_LOCAL(0),
2851 : WASM_GET_LOCAL(1), WASM_GET_LOCAL(0)),
2852 : kExprI32Add});
2853 2 : ExpectFailure(
2854 : sigs.i_ii(),
2855 : {WASM_LOOP_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), kExprF32Add});
2856 1 : }
2857 :
2858 15444 : TEST_F(FunctionBodyDecoderTest, MultiValIf) {
2859 1 : WASM_FEATURE_SCOPE(mv);
2860 : TestModuleBuilder builder;
2861 1 : module = builder.module();
2862 1 : byte f0 = builder.AddSignature(sigs.ii_v());
2863 3 : ExpectValidates(
2864 : sigs.i_ii(),
2865 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2866 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2867 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
2868 : kExprI32Add});
2869 2 : ExpectFailure(
2870 : sigs.i_ii(),
2871 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), WASM_NOP, WASM_NOP), kExprI32Add});
2872 2 : ExpectFailure(sigs.i_ii(),
2873 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), WASM_NOP,
2874 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
2875 : kExprI32Add});
2876 2 : ExpectFailure(
2877 : sigs.i_ii(),
2878 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2879 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_NOP),
2880 : kExprI32Add});
2881 2 : ExpectFailure(sigs.i_ii(),
2882 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2883 : WASM_GET_LOCAL(1)),
2884 : kExprI32Add});
2885 2 : ExpectFailure(sigs.i_ii(),
2886 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2887 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
2888 : kExprI32Add});
2889 2 : ExpectFailure(sigs.i_ii(),
2890 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2891 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2892 : WASM_GET_LOCAL(1)),
2893 : kExprI32Add});
2894 2 : ExpectFailure(
2895 : sigs.i_ii(),
2896 : {WASM_IF_ELSE_X(
2897 : f0, WASM_GET_LOCAL(0),
2898 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)),
2899 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0), WASM_GET_LOCAL(0))),
2900 : kExprI32Add});
2901 2 : ExpectFailure(sigs.i_ii(),
2902 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2903 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0),
2904 : WASM_GET_LOCAL(0)),
2905 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))),
2906 : kExprI32Add});
2907 2 : ExpectFailure(sigs.i_ii(),
2908 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2909 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2910 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(1),
2911 : WASM_GET_LOCAL(1))),
2912 : kExprI32Add});
2913 2 : ExpectFailure(sigs.i_ii(),
2914 : {WASM_IF_ELSE_X(f0, WASM_GET_LOCAL(0),
2915 : WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
2916 : WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
2917 : kExprF32Add});
2918 1 : }
2919 :
2920 15444 : TEST_F(FunctionBodyDecoderTest, BlockParam) {
2921 1 : WASM_FEATURE_SCOPE(mv);
2922 : TestModuleBuilder builder;
2923 1 : module = builder.module();
2924 1 : byte f1 = builder.AddSignature(sigs.i_i());
2925 1 : byte f2 = builder.AddSignature(sigs.i_ii());
2926 2 : ExpectValidates(
2927 : sigs.i_ii(),
2928 : {WASM_GET_LOCAL(0),
2929 : WASM_BLOCK_X(f1, WASM_GET_LOCAL(1), WASM_I32_ADD(WASM_NOP, WASM_NOP))});
2930 2 : ExpectValidates(sigs.i_ii(),
2931 : {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2932 : WASM_BLOCK_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP))});
2933 2 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2934 : WASM_BLOCK_X(f1, WASM_NOP),
2935 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2936 2 : ExpectFailure(sigs.i_ii(),
2937 : {WASM_BLOCK_X(f1, WASM_NOP), WASM_RETURN1(WASM_GET_LOCAL(0))});
2938 2 : ExpectFailure(sigs.i_ii(), {WASM_BLOCK_X(f1, WASM_GET_LOCAL(0)),
2939 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2940 2 : ExpectFailure(
2941 : sigs.i_ii(),
2942 : {WASM_GET_LOCAL(0), WASM_BLOCK_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP)),
2943 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2944 2 : ExpectFailure(sigs.i_ii(),
2945 : {WASM_GET_LOCAL(0), WASM_BLOCK_X(f1, WASM_F32_NEG(WASM_NOP)),
2946 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2947 1 : }
2948 :
2949 15444 : TEST_F(FunctionBodyDecoderTest, LoopParam) {
2950 1 : WASM_FEATURE_SCOPE(mv);
2951 : TestModuleBuilder builder;
2952 1 : module = builder.module();
2953 1 : byte f1 = builder.AddSignature(sigs.i_i());
2954 1 : byte f2 = builder.AddSignature(sigs.i_ii());
2955 2 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0),
2956 : WASM_LOOP_X(f1, WASM_GET_LOCAL(1),
2957 : WASM_I32_ADD(WASM_NOP, WASM_NOP))});
2958 2 : ExpectValidates(sigs.i_ii(),
2959 : {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2960 : WASM_LOOP_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP))});
2961 2 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2962 : WASM_LOOP_X(f1, WASM_NOP),
2963 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
2964 2 : ExpectFailure(sigs.i_ii(),
2965 : {WASM_LOOP_X(f1, WASM_NOP), WASM_RETURN1(WASM_GET_LOCAL(0))});
2966 2 : ExpectFailure(sigs.i_ii(), {WASM_LOOP_X(f1, WASM_GET_LOCAL(0)),
2967 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2968 2 : ExpectFailure(sigs.i_ii(), {WASM_GET_LOCAL(0),
2969 : WASM_LOOP_X(f2, WASM_I32_ADD(WASM_NOP, WASM_NOP)),
2970 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2971 2 : ExpectFailure(sigs.i_ii(),
2972 : {WASM_GET_LOCAL(0), WASM_LOOP_X(f1, WASM_F32_NEG(WASM_NOP)),
2973 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2974 1 : }
2975 :
2976 15444 : TEST_F(FunctionBodyDecoderTest, LoopParamBr) {
2977 1 : WASM_FEATURE_SCOPE(mv);
2978 : TestModuleBuilder builder;
2979 1 : module = builder.module();
2980 1 : byte f1 = builder.AddSignature(sigs.i_i());
2981 1 : byte f2 = builder.AddSignature(sigs.i_ii());
2982 2 : ExpectValidates(sigs.i_ii(),
2983 : {WASM_GET_LOCAL(0), WASM_LOOP_X(f1, WASM_BR(0))});
2984 2 : ExpectValidates(
2985 : sigs.i_ii(),
2986 : {WASM_GET_LOCAL(0), WASM_LOOP_X(f1, WASM_BRV(0, WASM_GET_LOCAL(1)))});
2987 2 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2988 : WASM_LOOP_X(f2, WASM_BR(0))});
2989 2 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0),
2990 : WASM_LOOP_X(f1, WASM_BLOCK_X(f1, WASM_BR(1)))});
2991 2 : ExpectFailure(sigs.i_ii(),
2992 : {WASM_GET_LOCAL(0), WASM_LOOP_X(f1, WASM_BLOCK(WASM_BR(1))),
2993 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2994 2 : ExpectFailure(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
2995 : WASM_LOOP_X(f2, WASM_BLOCK_X(f1, WASM_BR(1))),
2996 : WASM_RETURN1(WASM_GET_LOCAL(0))});
2997 1 : }
2998 :
2999 15444 : TEST_F(FunctionBodyDecoderTest, IfParam) {
3000 1 : WASM_FEATURE_SCOPE(mv);
3001 : TestModuleBuilder builder;
3002 1 : module = builder.module();
3003 1 : byte f1 = builder.AddSignature(sigs.i_i());
3004 1 : byte f2 = builder.AddSignature(sigs.i_ii());
3005 2 : ExpectValidates(sigs.i_ii(),
3006 : {WASM_GET_LOCAL(0),
3007 : WASM_IF_X(f1, WASM_GET_LOCAL(0),
3008 : WASM_I32_ADD(WASM_NOP, WASM_GET_LOCAL(1)))});
3009 2 : ExpectValidates(sigs.i_ii(),
3010 : {WASM_GET_LOCAL(0),
3011 : WASM_IF_ELSE_X(f1, WASM_GET_LOCAL(0),
3012 : WASM_I32_ADD(WASM_NOP, WASM_GET_LOCAL(1)),
3013 : WASM_I32_EQZ(WASM_NOP))});
3014 2 : ExpectValidates(
3015 : sigs.i_ii(),
3016 : {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
3017 : WASM_IF_ELSE_X(f2, WASM_GET_LOCAL(0), WASM_I32_ADD(WASM_NOP, WASM_NOP),
3018 : WASM_I32_MUL(WASM_NOP, WASM_NOP))});
3019 2 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
3020 : WASM_IF_X(f1, WASM_GET_LOCAL(0), WASM_NOP),
3021 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
3022 2 : ExpectValidates(sigs.i_ii(), {WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
3023 : WASM_IF_ELSE_X(f1, WASM_GET_LOCAL(0), WASM_NOP,
3024 : WASM_I32_EQZ(WASM_NOP)),
3025 : WASM_I32_ADD(WASM_NOP, WASM_NOP)});
3026 1 : }
3027 :
3028 15444 : TEST_F(FunctionBodyDecoderTest, Regression709741) {
3029 : AddLocals(kWasmI32, kV8MaxWasmFunctionLocals - 1);
3030 3 : ExpectValidates(sigs.v_v(), {WASM_NOP});
3031 1 : byte code[] = {WASM_NOP, WASM_END};
3032 :
3033 5 : for (size_t i = 0; i < arraysize(code); ++i) {
3034 2 : FunctionBody body(sigs.v_v(), 0, code, code + i);
3035 2 : WasmFeatures unused_detected_features;
3036 : DecodeResult result =
3037 4 : VerifyWasmCode(zone()->allocator(), kAllWasmFeatures, nullptr,
3038 : &unused_detected_features, body);
3039 2 : if (result.ok()) {
3040 0 : std::ostringstream str;
3041 0 : str << "Expected verification to fail";
3042 : }
3043 : }
3044 1 : }
3045 :
3046 15444 : TEST_F(FunctionBodyDecoderTest, MemoryInit) {
3047 : TestModuleBuilder builder;
3048 : builder.InitializeMemory();
3049 : builder.SetDataSegmentCount(1);
3050 1 : module = builder.module();
3051 :
3052 3 : ExpectFailure(sigs.v_v(),
3053 : {WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3054 1 : WASM_FEATURE_SCOPE(bulk_memory);
3055 2 : ExpectValidates(sigs.v_v(),
3056 : {WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3057 2 : ExpectFailure(sigs.v_v(),
3058 : {WASM_TABLE_INIT(1, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3059 1 : }
3060 :
3061 15444 : TEST_F(FunctionBodyDecoderTest, MemoryInitInvalid) {
3062 : TestModuleBuilder builder;
3063 : builder.InitializeMemory();
3064 : builder.SetDataSegmentCount(1);
3065 1 : module = builder.module();
3066 :
3067 1 : WASM_FEATURE_SCOPE(bulk_memory);
3068 : byte code[] = {WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO),
3069 1 : WASM_END};
3070 25 : for (size_t i = 0; i <= arraysize(code); ++i) {
3071 24 : Validate(i == arraysize(code), sigs.v_v(), VectorOf(code, i), kOmitEnd);
3072 : }
3073 1 : }
3074 :
3075 15444 : TEST_F(FunctionBodyDecoderTest, DataDrop) {
3076 : TestModuleBuilder builder;
3077 : builder.InitializeMemory();
3078 : builder.SetDataSegmentCount(1);
3079 1 : module = builder.module();
3080 :
3081 3 : ExpectFailure(sigs.v_v(), {WASM_DATA_DROP(0)});
3082 1 : WASM_FEATURE_SCOPE(bulk_memory);
3083 2 : ExpectValidates(sigs.v_v(), {WASM_DATA_DROP(0)});
3084 2 : ExpectFailure(sigs.v_v(), {WASM_DATA_DROP(1)});
3085 1 : }
3086 :
3087 15444 : TEST_F(FunctionBodyDecoderTest, MemoryCopy) {
3088 : TestModuleBuilder builder;
3089 : builder.InitializeMemory();
3090 1 : module = builder.module();
3091 :
3092 3 : ExpectFailure(sigs.v_v(),
3093 : {WASM_MEMORY_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3094 1 : WASM_FEATURE_SCOPE(bulk_memory);
3095 2 : ExpectValidates(sigs.v_v(),
3096 : {WASM_MEMORY_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3097 1 : }
3098 :
3099 15444 : TEST_F(FunctionBodyDecoderTest, MemoryFill) {
3100 : TestModuleBuilder builder;
3101 : builder.InitializeMemory();
3102 1 : module = builder.module();
3103 :
3104 3 : ExpectFailure(sigs.v_v(),
3105 : {WASM_MEMORY_FILL(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3106 1 : WASM_FEATURE_SCOPE(bulk_memory);
3107 2 : ExpectValidates(sigs.v_v(),
3108 : {WASM_MEMORY_FILL(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3109 1 : }
3110 :
3111 15444 : TEST_F(FunctionBodyDecoderTest, BulkMemoryOpsWithoutMemory) {
3112 1 : WASM_FEATURE_SCOPE(bulk_memory);
3113 3 : ExpectFailure(sigs.v_v(),
3114 : {WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3115 2 : ExpectFailure(sigs.v_v(),
3116 : {WASM_MEMORY_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3117 2 : ExpectFailure(sigs.v_v(),
3118 : {WASM_MEMORY_FILL(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3119 1 : }
3120 :
3121 15444 : TEST_F(FunctionBodyDecoderTest, TableInit) {
3122 : TestModuleBuilder builder;
3123 : builder.InitializeTable();
3124 : builder.AddPassiveElementSegment();
3125 1 : module = builder.module();
3126 :
3127 3 : ExpectFailure(sigs.v_v(),
3128 : {WASM_TABLE_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3129 1 : WASM_FEATURE_SCOPE(bulk_memory);
3130 2 : ExpectValidates(sigs.v_v(),
3131 : {WASM_TABLE_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3132 2 : ExpectFailure(sigs.v_v(),
3133 : {WASM_TABLE_INIT(1, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3134 1 : }
3135 :
3136 15444 : TEST_F(FunctionBodyDecoderTest, TableInitInvalid) {
3137 : TestModuleBuilder builder;
3138 : builder.InitializeTable();
3139 : builder.AddPassiveElementSegment();
3140 1 : module = builder.module();
3141 :
3142 1 : WASM_FEATURE_SCOPE(bulk_memory);
3143 1 : byte code[] = {WASM_TABLE_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO), WASM_END};
3144 25 : for (size_t i = 0; i <= arraysize(code); ++i) {
3145 24 : Validate(i == arraysize(code), sigs.v_v(), VectorOf(code, i), kOmitEnd);
3146 : }
3147 1 : }
3148 :
3149 15444 : TEST_F(FunctionBodyDecoderTest, ElemDrop) {
3150 : TestModuleBuilder builder;
3151 : builder.InitializeTable();
3152 : builder.AddPassiveElementSegment();
3153 1 : module = builder.module();
3154 :
3155 3 : ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(0)});
3156 1 : WASM_FEATURE_SCOPE(bulk_memory);
3157 2 : ExpectValidates(sigs.v_v(), {WASM_ELEM_DROP(0)});
3158 2 : ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(1)});
3159 1 : }
3160 :
3161 15444 : TEST_F(FunctionBodyDecoderTest, TableCopy) {
3162 : TestModuleBuilder builder;
3163 : builder.InitializeTable();
3164 1 : module = builder.module();
3165 :
3166 3 : ExpectFailure(sigs.v_v(), {WASM_TABLE_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3167 1 : WASM_FEATURE_SCOPE(bulk_memory);
3168 2 : ExpectValidates(sigs.v_v(),
3169 : {WASM_TABLE_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3170 1 : }
3171 :
3172 15444 : TEST_F(FunctionBodyDecoderTest, BulkTableOpsWithoutTable) {
3173 : TestModuleBuilder builder;
3174 : builder.InitializeTable();
3175 : builder.AddPassiveElementSegment();
3176 :
3177 1 : WASM_FEATURE_SCOPE(bulk_memory);
3178 3 : ExpectFailure(sigs.v_v(),
3179 : {WASM_TABLE_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3180 2 : ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(0)});
3181 2 : ExpectFailure(sigs.v_v(), {WASM_TABLE_COPY(WASM_ZERO, WASM_ZERO, WASM_ZERO)});
3182 1 : }
3183 :
3184 3 : class BranchTableIteratorTest : public TestWithZone {
3185 : public:
3186 3 : BranchTableIteratorTest() : TestWithZone() {}
3187 16 : void CheckBrTableSize(const byte* start, const byte* end) {
3188 : Decoder decoder(start, end);
3189 16 : BranchTableImmediate<Decoder::kValidate> operand(&decoder, start);
3190 : BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand);
3191 32 : EXPECT_EQ(end - start - 1u, iterator.length());
3192 16 : EXPECT_TRUE(decoder.ok());
3193 16 : }
3194 2 : void CheckBrTableError(const byte* start, const byte* end) {
3195 : Decoder decoder(start, end);
3196 2 : BranchTableImmediate<Decoder::kValidate> operand(&decoder, start);
3197 : BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand);
3198 2 : iterator.length();
3199 4 : EXPECT_FALSE(decoder.ok());
3200 2 : }
3201 : };
3202 :
3203 : #define CHECK_BR_TABLE_LENGTH(...) \
3204 : { \
3205 : static byte code[] = {kExprBrTable, __VA_ARGS__}; \
3206 : CheckBrTableSize(code, code + sizeof(code)); \
3207 : }
3208 :
3209 : #define CHECK_BR_TABLE_ERROR(...) \
3210 : { \
3211 : static byte code[] = {kExprBrTable, __VA_ARGS__}; \
3212 : CheckBrTableError(code, code + sizeof(code)); \
3213 : }
3214 :
3215 15444 : TEST_F(BranchTableIteratorTest, count0) {
3216 1 : CHECK_BR_TABLE_LENGTH(0, U32V_1(1));
3217 1 : CHECK_BR_TABLE_LENGTH(0, U32V_2(200));
3218 1 : CHECK_BR_TABLE_LENGTH(0, U32V_3(30000));
3219 1 : CHECK_BR_TABLE_LENGTH(0, U32V_4(400000));
3220 :
3221 1 : CHECK_BR_TABLE_LENGTH(0, U32V_1(2));
3222 1 : CHECK_BR_TABLE_LENGTH(0, U32V_2(300));
3223 1 : CHECK_BR_TABLE_LENGTH(0, U32V_3(40000));
3224 1 : CHECK_BR_TABLE_LENGTH(0, U32V_4(500000));
3225 1 : }
3226 :
3227 15444 : TEST_F(BranchTableIteratorTest, count1) {
3228 1 : CHECK_BR_TABLE_LENGTH(1, U32V_1(1), U32V_1(6));
3229 1 : CHECK_BR_TABLE_LENGTH(1, U32V_2(200), U32V_1(8));
3230 1 : CHECK_BR_TABLE_LENGTH(1, U32V_3(30000), U32V_1(9));
3231 1 : CHECK_BR_TABLE_LENGTH(1, U32V_4(400000), U32V_1(11));
3232 :
3233 1 : CHECK_BR_TABLE_LENGTH(1, U32V_1(2), U32V_2(6));
3234 1 : CHECK_BR_TABLE_LENGTH(1, U32V_2(300), U32V_2(7));
3235 1 : CHECK_BR_TABLE_LENGTH(1, U32V_3(40000), U32V_2(8));
3236 1 : CHECK_BR_TABLE_LENGTH(1, U32V_4(500000), U32V_2(9));
3237 1 : }
3238 :
3239 15444 : TEST_F(BranchTableIteratorTest, error0) {
3240 1 : CHECK_BR_TABLE_ERROR(0);
3241 1 : CHECK_BR_TABLE_ERROR(1, U32V_1(33));
3242 1 : }
3243 :
3244 : #undef CHECK_BR_TABLE_LENGTH
3245 : #undef CHECK_BR_TABLE_ERROR
3246 :
3247 : struct PrintOpcodes {
3248 : const byte* start;
3249 : const byte* end;
3250 : };
3251 0 : std::ostream& operator<<(std::ostream& out, const PrintOpcodes& range) {
3252 : out << "First opcode: \""
3253 0 : << WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(*range.start))
3254 0 : << "\"\nall bytes: [";
3255 0 : for (const byte* b = range.start; b < range.end; ++b) {
3256 0 : out << (b == range.start ? "" : ", ") << uint32_t{*b} << "/"
3257 0 : << AsHex(*b, 2, true);
3258 : }
3259 0 : return out << "]";
3260 : }
3261 :
3262 9 : class WasmOpcodeLengthTest : public TestWithZone {
3263 : public:
3264 9 : WasmOpcodeLengthTest() : TestWithZone() {}
3265 :
3266 : template <typename... Bytes>
3267 320 : void ExpectLength(unsigned expected, Bytes... bytes) {
3268 320 : const byte code[] = {bytes..., 0, 0, 0, 0, 0, 0, 0, 0};
3269 640 : EXPECT_EQ(expected, OpcodeLength(code, code + sizeof(code)))
3270 0 : << PrintOpcodes{code, code + sizeof...(bytes)};
3271 320 : }
3272 : };
3273 :
3274 15444 : TEST_F(WasmOpcodeLengthTest, Statements) {
3275 1 : ExpectLength(1, kExprNop);
3276 1 : ExpectLength(1, kExprElse);
3277 1 : ExpectLength(1, kExprEnd);
3278 1 : ExpectLength(1, kExprSelect);
3279 1 : ExpectLength(1, kExprCatch);
3280 1 : ExpectLength(1, kExprRethrow);
3281 1 : ExpectLength(2, kExprBr);
3282 1 : ExpectLength(2, kExprBrIf);
3283 1 : ExpectLength(2, kExprThrow);
3284 1 : ExpectLength(3, kExprBrOnExn);
3285 1 : ExpectLength(2, kExprBlock, kLocalI32);
3286 1 : ExpectLength(2, kExprLoop, kLocalI32);
3287 1 : ExpectLength(2, kExprIf, kLocalI32);
3288 1 : ExpectLength(2, kExprTry, kLocalI32);
3289 1 : }
3290 :
3291 15444 : TEST_F(WasmOpcodeLengthTest, MiscExpressions) {
3292 1 : ExpectLength(5, kExprF32Const);
3293 1 : ExpectLength(9, kExprF64Const);
3294 1 : ExpectLength(1, kExprRefNull);
3295 1 : ExpectLength(2, kExprGetLocal);
3296 1 : ExpectLength(2, kExprSetLocal);
3297 1 : ExpectLength(2, kExprGetGlobal);
3298 1 : ExpectLength(2, kExprSetGlobal);
3299 1 : ExpectLength(2, kExprCallFunction);
3300 1 : ExpectLength(3, kExprCallIndirect);
3301 1 : }
3302 :
3303 15444 : TEST_F(WasmOpcodeLengthTest, I32Const) {
3304 1 : ExpectLength(2, kExprI32Const, U32V_1(1));
3305 1 : ExpectLength(3, kExprI32Const, U32V_2(999));
3306 1 : ExpectLength(4, kExprI32Const, U32V_3(9999));
3307 1 : ExpectLength(5, kExprI32Const, U32V_4(999999));
3308 1 : ExpectLength(6, kExprI32Const, U32V_5(99999999));
3309 1 : }
3310 :
3311 15444 : TEST_F(WasmOpcodeLengthTest, I64Const) {
3312 1 : ExpectLength(2, kExprI64Const, U32V_1(1));
3313 1 : ExpectLength(3, kExprI64Const, U32V_2(99));
3314 1 : ExpectLength(4, kExprI64Const, U32V_3(9999));
3315 1 : ExpectLength(5, kExprI64Const, U32V_4(99999));
3316 1 : ExpectLength(6, kExprI64Const, U32V_5(9999999));
3317 1 : ExpectLength(7, WASM_I64V_6(777777));
3318 1 : ExpectLength(8, WASM_I64V_7(7777777));
3319 1 : ExpectLength(9, WASM_I64V_8(77777777));
3320 1 : ExpectLength(10, WASM_I64V_9(777777777));
3321 1 : }
3322 :
3323 15444 : TEST_F(WasmOpcodeLengthTest, VariableLength) {
3324 1 : ExpectLength(2, kExprGetGlobal, U32V_1(1));
3325 1 : ExpectLength(3, kExprGetGlobal, U32V_2(33));
3326 1 : ExpectLength(4, kExprGetGlobal, U32V_3(44));
3327 1 : ExpectLength(5, kExprGetGlobal, U32V_4(66));
3328 1 : ExpectLength(6, kExprGetGlobal, U32V_5(77));
3329 1 : }
3330 :
3331 15444 : TEST_F(WasmOpcodeLengthTest, LoadsAndStores) {
3332 1 : ExpectLength(3, kExprI32LoadMem8S);
3333 1 : ExpectLength(3, kExprI32LoadMem8U);
3334 1 : ExpectLength(3, kExprI32LoadMem16S);
3335 1 : ExpectLength(3, kExprI32LoadMem16U);
3336 1 : ExpectLength(3, kExprI32LoadMem);
3337 1 : ExpectLength(3, kExprI64LoadMem8S);
3338 1 : ExpectLength(3, kExprI64LoadMem8U);
3339 1 : ExpectLength(3, kExprI64LoadMem16S);
3340 1 : ExpectLength(3, kExprI64LoadMem16U);
3341 1 : ExpectLength(3, kExprI64LoadMem32S);
3342 1 : ExpectLength(3, kExprI64LoadMem32U);
3343 1 : ExpectLength(3, kExprI64LoadMem);
3344 1 : ExpectLength(3, kExprF32LoadMem);
3345 1 : ExpectLength(3, kExprF64LoadMem);
3346 :
3347 1 : ExpectLength(3, kExprI32StoreMem8);
3348 1 : ExpectLength(3, kExprI32StoreMem16);
3349 1 : ExpectLength(3, kExprI32StoreMem);
3350 1 : ExpectLength(3, kExprI64StoreMem8);
3351 1 : ExpectLength(3, kExprI64StoreMem16);
3352 1 : ExpectLength(3, kExprI64StoreMem32);
3353 1 : ExpectLength(3, kExprI64StoreMem);
3354 1 : ExpectLength(3, kExprF32StoreMem);
3355 1 : ExpectLength(3, kExprF64StoreMem);
3356 1 : }
3357 :
3358 15444 : TEST_F(WasmOpcodeLengthTest, MiscMemExpressions) {
3359 1 : ExpectLength(2, kExprMemorySize);
3360 1 : ExpectLength(2, kExprMemoryGrow);
3361 1 : }
3362 :
3363 15444 : TEST_F(WasmOpcodeLengthTest, SimpleExpressions) {
3364 : #define SIMPLE_OPCODE(name, byte, sig) byte,
3365 : static constexpr uint8_t kSimpleOpcodes[] = {
3366 : FOREACH_SIMPLE_OPCODE(SIMPLE_OPCODE)};
3367 : #undef SIMPLE_OPCODE
3368 247 : for (uint8_t simple_opcode : kSimpleOpcodes) {
3369 123 : ExpectLength(1, simple_opcode);
3370 : }
3371 1 : }
3372 :
3373 15444 : TEST_F(WasmOpcodeLengthTest, SimdExpressions) {
3374 : #define TEST_SIMD(name, opcode, sig) \
3375 : ExpectLength(2, kSimdPrefix, static_cast<byte>(kExpr##name & 0xFF));
3376 1 : FOREACH_SIMD_0_OPERAND_OPCODE(TEST_SIMD)
3377 : #undef TEST_SIMD
3378 : #define TEST_SIMD(name, opcode, sig) \
3379 : ExpectLength(3, kSimdPrefix, static_cast<byte>(kExpr##name & 0xFF));
3380 1 : FOREACH_SIMD_1_OPERAND_OPCODE(TEST_SIMD)
3381 : #undef TEST_SIMD
3382 1 : ExpectLength(18, kSimdPrefix, static_cast<byte>(kExprS8x16Shuffle & 0xFF));
3383 : // test for bad simd opcode
3384 1 : ExpectLength(2, kSimdPrefix, 0xFF);
3385 1 : }
3386 :
3387 : using TypesOfLocals = ZoneVector<ValueType>;
3388 :
3389 21 : class LocalDeclDecoderTest : public TestWithZone {
3390 : public:
3391 : v8::internal::AccountingAllocator allocator;
3392 : WasmFeatures enabled_features_;
3393 :
3394 332 : size_t ExpectRun(TypesOfLocals map, size_t pos, ValueType expected,
3395 : size_t count) {
3396 4138 : for (size_t i = 0; i < count; i++) {
3397 3806 : EXPECT_EQ(expected, map[pos++]);
3398 : }
3399 332 : return pos;
3400 : }
3401 :
3402 : bool DecodeLocalDecls(BodyLocalDecls* decls, const byte* start,
3403 : const byte* end) {
3404 95 : return i::wasm::DecodeLocalDecls(enabled_features_, decls, start, end);
3405 : }
3406 : };
3407 :
3408 15444 : TEST_F(LocalDeclDecoderTest, EmptyLocals) {
3409 : BodyLocalDecls decls(zone());
3410 : bool result = DecodeLocalDecls(&decls, nullptr, nullptr);
3411 2 : EXPECT_FALSE(result);
3412 1 : }
3413 :
3414 15444 : TEST_F(LocalDeclDecoderTest, NoLocals) {
3415 : static const byte data[] = {0};
3416 : BodyLocalDecls decls(zone());
3417 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3418 1 : EXPECT_TRUE(result);
3419 1 : EXPECT_TRUE(decls.type_list.empty());
3420 1 : }
3421 :
3422 15444 : TEST_F(LocalDeclDecoderTest, OneLocal) {
3423 1 : WASM_FEATURE_SCOPE(anyref);
3424 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
3425 5 : ValueType type = kValueTypes[i];
3426 : const byte data[] = {1, 1,
3427 5 : static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
3428 : BodyLocalDecls decls(zone());
3429 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3430 5 : EXPECT_TRUE(result);
3431 10 : EXPECT_EQ(1u, decls.type_list.size());
3432 :
3433 : TypesOfLocals map = decls.type_list;
3434 5 : EXPECT_EQ(type, map[0]);
3435 : }
3436 1 : }
3437 :
3438 15444 : TEST_F(LocalDeclDecoderTest, FiveLocals) {
3439 1 : WASM_FEATURE_SCOPE(anyref);
3440 11 : for (size_t i = 0; i < arraysize(kValueTypes); i++) {
3441 5 : ValueType type = kValueTypes[i];
3442 : const byte data[] = {1, 5,
3443 5 : static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
3444 : BodyLocalDecls decls(zone());
3445 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3446 5 : EXPECT_TRUE(result);
3447 10 : EXPECT_EQ(sizeof(data), decls.encoded_size);
3448 10 : EXPECT_EQ(5u, decls.type_list.size());
3449 :
3450 : TypesOfLocals map = decls.type_list;
3451 10 : EXPECT_EQ(5u, map.size());
3452 10 : ExpectRun(map, 0, type, 5);
3453 : }
3454 1 : }
3455 :
3456 15444 : TEST_F(LocalDeclDecoderTest, MixedLocals) {
3457 7 : for (byte a = 0; a < 3; a++) {
3458 21 : for (byte b = 0; b < 3; b++) {
3459 63 : for (byte c = 0; c < 3; c++) {
3460 189 : for (byte d = 0; d < 3; d++) {
3461 : const byte data[] = {4, a, kLocalI32, b, kLocalI64,
3462 81 : c, kLocalF32, d, kLocalF64};
3463 : BodyLocalDecls decls(zone());
3464 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3465 81 : EXPECT_TRUE(result);
3466 162 : EXPECT_EQ(sizeof(data), decls.encoded_size);
3467 162 : EXPECT_EQ(static_cast<uint32_t>(a + b + c + d),
3468 0 : decls.type_list.size());
3469 :
3470 : TypesOfLocals map = decls.type_list;
3471 :
3472 : size_t pos = 0;
3473 243 : pos = ExpectRun(map, pos, kWasmI32, a);
3474 243 : pos = ExpectRun(map, pos, kWasmI64, b);
3475 243 : pos = ExpectRun(map, pos, kWasmF32, c);
3476 243 : pos = ExpectRun(map, pos, kWasmF64, d);
3477 : }
3478 : }
3479 : }
3480 : }
3481 1 : }
3482 :
3483 15444 : TEST_F(LocalDeclDecoderTest, UseEncoder) {
3484 1 : const byte* data = nullptr;
3485 1 : const byte* end = nullptr;
3486 : LocalDeclEncoder local_decls(zone());
3487 :
3488 1 : local_decls.AddLocals(5, kWasmF32);
3489 1 : local_decls.AddLocals(1337, kWasmI32);
3490 1 : local_decls.AddLocals(212, kWasmI64);
3491 1 : local_decls.Prepend(zone(), &data, &end);
3492 :
3493 : BodyLocalDecls decls(zone());
3494 1 : bool result = DecodeLocalDecls(&decls, data, end);
3495 1 : EXPECT_TRUE(result);
3496 2 : EXPECT_EQ(5u + 1337u + 212u, decls.type_list.size());
3497 :
3498 : TypesOfLocals map = decls.type_list;
3499 : size_t pos = 0;
3500 2 : pos = ExpectRun(map, pos, kWasmF32, 5);
3501 2 : pos = ExpectRun(map, pos, kWasmI32, 1337);
3502 2 : pos = ExpectRun(map, pos, kWasmI64, 212);
3503 1 : }
3504 :
3505 15444 : TEST_F(LocalDeclDecoderTest, ExceptRef) {
3506 1 : WASM_FEATURE_SCOPE(eh);
3507 1 : ValueType type = kWasmExceptRef;
3508 : const byte data[] = {1, 1,
3509 1 : static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
3510 : BodyLocalDecls decls(zone());
3511 : bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
3512 1 : EXPECT_TRUE(result);
3513 2 : EXPECT_EQ(1u, decls.type_list.size());
3514 :
3515 : TypesOfLocals map = decls.type_list;
3516 1 : EXPECT_EQ(type, map[0]);
3517 1 : }
3518 :
3519 8 : class BytecodeIteratorTest : public TestWithZone {};
3520 :
3521 15444 : TEST_F(BytecodeIteratorTest, SimpleForeach) {
3522 1 : byte code[] = {WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO)};
3523 1 : BytecodeIterator iter(code, code + sizeof(code));
3524 : WasmOpcode expected[] = {kExprI32Const, kExprIf, kExprI32Const,
3525 1 : kExprElse, kExprI32Const, kExprEnd};
3526 1 : size_t pos = 0;
3527 13 : for (WasmOpcode opcode : iter.opcodes()) {
3528 6 : if (pos >= arraysize(expected)) {
3529 0 : EXPECT_TRUE(false);
3530 0 : break;
3531 : }
3532 12 : EXPECT_EQ(expected[pos++], opcode);
3533 : }
3534 2 : EXPECT_EQ(arraysize(expected), pos);
3535 1 : }
3536 :
3537 15444 : TEST_F(BytecodeIteratorTest, ForeachTwice) {
3538 1 : byte code[] = {WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO)};
3539 1 : BytecodeIterator iter(code, code + sizeof(code));
3540 1 : int count = 0;
3541 :
3542 : count = 0;
3543 7 : for (WasmOpcode opcode : iter.opcodes()) {
3544 : USE(opcode);
3545 6 : count++;
3546 : }
3547 2 : EXPECT_EQ(6, count);
3548 :
3549 1 : count = 0;
3550 7 : for (WasmOpcode opcode : iter.opcodes()) {
3551 : USE(opcode);
3552 6 : count++;
3553 : }
3554 2 : EXPECT_EQ(6, count);
3555 1 : }
3556 :
3557 15444 : TEST_F(BytecodeIteratorTest, ForeachOffset) {
3558 1 : byte code[] = {WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO)};
3559 1 : BytecodeIterator iter(code, code + sizeof(code));
3560 1 : int count = 0;
3561 :
3562 : count = 0;
3563 7 : for (auto offset : iter.offsets()) {
3564 : USE(offset);
3565 6 : count++;
3566 : }
3567 2 : EXPECT_EQ(6, count);
3568 :
3569 1 : count = 0;
3570 7 : for (auto offset : iter.offsets()) {
3571 : USE(offset);
3572 6 : count++;
3573 : }
3574 2 : EXPECT_EQ(6, count);
3575 1 : }
3576 :
3577 15444 : TEST_F(BytecodeIteratorTest, WithLocalDecls) {
3578 1 : byte code[] = {1, 1, kLocalI32, WASM_I32V_1(9), WASM_I32V_1(11)};
3579 : BodyLocalDecls decls(zone());
3580 1 : BytecodeIterator iter(code, code + sizeof(code), &decls);
3581 :
3582 2 : EXPECT_EQ(3u, decls.encoded_size);
3583 2 : EXPECT_EQ(3u, iter.pc_offset());
3584 1 : EXPECT_TRUE(iter.has_next());
3585 2 : EXPECT_EQ(kExprI32Const, iter.current());
3586 1 : iter.next();
3587 1 : EXPECT_TRUE(iter.has_next());
3588 2 : EXPECT_EQ(kExprI32Const, iter.current());
3589 1 : iter.next();
3590 2 : EXPECT_FALSE(iter.has_next());
3591 1 : }
3592 :
3593 : #undef WASM_FEATURE_SCOPE
3594 : #undef B1
3595 : #undef B2
3596 : #undef B3
3597 : #undef WASM_IF_OP
3598 : #undef WASM_LOOP_OP
3599 : #undef WASM_BRV_IF_ZERO
3600 :
3601 : } // namespace function_body_decoder_unittest
3602 : } // namespace wasm
3603 : } // namespace internal
3604 9264 : } // namespace v8
|