LCOV - code coverage report
Current view: top level - test/unittests/wasm - function-body-decoder-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2063 2077 99.3 %
Date: 2019-02-19 Functions: 600 884 67.9 %

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

Generated by: LCOV version 1.10