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