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: 1912 1925 99.3 %
Date: 2019-04-17 Functions: 601 876 68.6 %

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

Generated by: LCOV version 1.10