Home | History | Annotate | Download | only in wasm
      1 // Copyright 2017 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 #ifndef V8_WASM_FUNCTION_BODY_DECODER_IMPL_H_
      6 #define V8_WASM_FUNCTION_BODY_DECODER_IMPL_H_
      7 
      8 // Do only include this header for implementing new Interface of the
      9 // WasmFullDecoder.
     10 
     11 #include "src/base/platform/elapsed-timer.h"
     12 #include "src/bit-vector.h"
     13 #include "src/wasm/decoder.h"
     14 #include "src/wasm/function-body-decoder.h"
     15 #include "src/wasm/wasm-features.h"
     16 #include "src/wasm/wasm-limits.h"
     17 #include "src/wasm/wasm-module.h"
     18 #include "src/wasm/wasm-opcodes.h"
     19 
     20 namespace v8 {
     21 namespace internal {
     22 namespace wasm {
     23 
     24 struct WasmGlobal;
     25 struct WasmException;
     26 
     27 #define TRACE(...)                                    \
     28   do {                                                \
     29     if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \
     30   } while (false)
     31 
     32 #define TRACE_INST_FORMAT "  @%-8d #%-20s|"
     33 
     34 // Return the evaluation of `condition` if validate==true, DCHECK that it's
     35 // true and always return true otherwise.
     36 #define VALIDATE(condition)       \
     37   (validate ? (condition) : [&] { \
     38     DCHECK(condition);            \
     39     return true;                  \
     40   }())
     41 
     42 #define RET_ON_PROTOTYPE_OPCODE(feat)                                          \
     43   DCHECK(!this->module_ || this->module_->origin == kWasmOrigin);              \
     44   if (!this->enabled_.feat) {                                                  \
     45     this->error("Invalid opcode (enable with --experimental-wasm-" #feat ")"); \
     46   } else {                                                                     \
     47     this->detected_->feat = true;                                              \
     48   }
     49 
     50 #define CHECK_PROTOTYPE_OPCODE(feat)                                           \
     51   DCHECK(!this->module_ || this->module_->origin == kWasmOrigin);              \
     52   if (!this->enabled_.feat) {                                                  \
     53     this->error("Invalid opcode (enable with --experimental-wasm-" #feat ")"); \
     54     break;                                                                     \
     55   } else {                                                                     \
     56     this->detected_->feat = true;                                              \
     57   }
     58 
     59 #define OPCODE_ERROR(opcode, message)                                 \
     60   (this->errorf(this->pc_, "%s: %s", WasmOpcodes::OpcodeName(opcode), \
     61                 (message)))
     62 
     63 #define ATOMIC_OP_LIST(V)                \
     64   V(I32AtomicLoad, Uint32)               \
     65   V(I64AtomicLoad, Uint64)               \
     66   V(I32AtomicLoad8U, Uint8)              \
     67   V(I32AtomicLoad16U, Uint16)            \
     68   V(I64AtomicLoad8U, Uint8)              \
     69   V(I64AtomicLoad16U, Uint16)            \
     70   V(I64AtomicLoad32U, Uint32)            \
     71   V(I32AtomicAdd, Uint32)                \
     72   V(I32AtomicAdd8U, Uint8)               \
     73   V(I32AtomicAdd16U, Uint16)             \
     74   V(I64AtomicAdd, Uint64)                \
     75   V(I64AtomicAdd8U, Uint8)               \
     76   V(I64AtomicAdd16U, Uint16)             \
     77   V(I64AtomicAdd32U, Uint32)             \
     78   V(I32AtomicSub, Uint32)                \
     79   V(I64AtomicSub, Uint64)                \
     80   V(I32AtomicSub8U, Uint8)               \
     81   V(I32AtomicSub16U, Uint16)             \
     82   V(I64AtomicSub8U, Uint8)               \
     83   V(I64AtomicSub16U, Uint16)             \
     84   V(I64AtomicSub32U, Uint32)             \
     85   V(I32AtomicAnd, Uint32)                \
     86   V(I64AtomicAnd, Uint64)                \
     87   V(I32AtomicAnd8U, Uint8)               \
     88   V(I32AtomicAnd16U, Uint16)             \
     89   V(I64AtomicAnd8U, Uint8)               \
     90   V(I64AtomicAnd16U, Uint16)             \
     91   V(I64AtomicAnd32U, Uint32)             \
     92   V(I32AtomicOr, Uint32)                 \
     93   V(I64AtomicOr, Uint64)                 \
     94   V(I32AtomicOr8U, Uint8)                \
     95   V(I32AtomicOr16U, Uint16)              \
     96   V(I64AtomicOr8U, Uint8)                \
     97   V(I64AtomicOr16U, Uint16)              \
     98   V(I64AtomicOr32U, Uint32)              \
     99   V(I32AtomicXor, Uint32)                \
    100   V(I64AtomicXor, Uint64)                \
    101   V(I32AtomicXor8U, Uint8)               \
    102   V(I32AtomicXor16U, Uint16)             \
    103   V(I64AtomicXor8U, Uint8)               \
    104   V(I64AtomicXor16U, Uint16)             \
    105   V(I64AtomicXor32U, Uint32)             \
    106   V(I32AtomicExchange, Uint32)           \
    107   V(I64AtomicExchange, Uint64)           \
    108   V(I32AtomicExchange8U, Uint8)          \
    109   V(I32AtomicExchange16U, Uint16)        \
    110   V(I64AtomicExchange8U, Uint8)          \
    111   V(I64AtomicExchange16U, Uint16)        \
    112   V(I64AtomicExchange32U, Uint32)        \
    113   V(I32AtomicCompareExchange, Uint32)    \
    114   V(I64AtomicCompareExchange, Uint64)    \
    115   V(I32AtomicCompareExchange8U, Uint8)   \
    116   V(I32AtomicCompareExchange16U, Uint16) \
    117   V(I64AtomicCompareExchange8U, Uint8)   \
    118   V(I64AtomicCompareExchange16U, Uint16) \
    119   V(I64AtomicCompareExchange32U, Uint32)
    120 
    121 #define ATOMIC_STORE_OP_LIST(V) \
    122   V(I32AtomicStore, Uint32)     \
    123   V(I64AtomicStore, Uint64)     \
    124   V(I32AtomicStore8U, Uint8)    \
    125   V(I32AtomicStore16U, Uint16)  \
    126   V(I64AtomicStore8U, Uint8)    \
    127   V(I64AtomicStore16U, Uint16)  \
    128   V(I64AtomicStore32U, Uint32)
    129 
    130 template <typename T, typename Allocator>
    131 Vector<T> vec2vec(std::vector<T, Allocator>& vec) {
    132   return Vector<T>(vec.data(), vec.size());
    133 }
    134 
    135 // Helpers for decoding different kinds of immediates which follow bytecodes.
    136 template <Decoder::ValidateFlag validate>
    137 struct LocalIndexImmediate {
    138   uint32_t index;
    139   ValueType type = kWasmStmt;
    140   unsigned length;
    141 
    142   inline LocalIndexImmediate(Decoder* decoder, const byte* pc) {
    143     index = decoder->read_u32v<validate>(pc + 1, &length, "local index");
    144   }
    145 };
    146 
    147 template <Decoder::ValidateFlag validate>
    148 struct ExceptionIndexImmediate {
    149   uint32_t index;
    150   const WasmException* exception = nullptr;
    151   unsigned length;
    152 
    153   inline ExceptionIndexImmediate(Decoder* decoder, const byte* pc) {
    154     index = decoder->read_u32v<validate>(pc + 1, &length, "exception index");
    155   }
    156 };
    157 
    158 template <Decoder::ValidateFlag validate>
    159 struct ImmI32Immediate {
    160   int32_t value;
    161   unsigned length;
    162   inline ImmI32Immediate(Decoder* decoder, const byte* pc) {
    163     value = decoder->read_i32v<validate>(pc + 1, &length, "immi32");
    164   }
    165 };
    166 
    167 template <Decoder::ValidateFlag validate>
    168 struct ImmI64Immediate {
    169   int64_t value;
    170   unsigned length;
    171   inline ImmI64Immediate(Decoder* decoder, const byte* pc) {
    172     value = decoder->read_i64v<validate>(pc + 1, &length, "immi64");
    173   }
    174 };
    175 
    176 template <Decoder::ValidateFlag validate>
    177 struct ImmF32Immediate {
    178   float value;
    179   unsigned length = 4;
    180   inline ImmF32Immediate(Decoder* decoder, const byte* pc) {
    181     // Avoid bit_cast because it might not preserve the signalling bit of a NaN.
    182     uint32_t tmp = decoder->read_u32<validate>(pc + 1, "immf32");
    183     memcpy(&value, &tmp, sizeof(value));
    184   }
    185 };
    186 
    187 template <Decoder::ValidateFlag validate>
    188 struct ImmF64Immediate {
    189   double value;
    190   unsigned length = 8;
    191   inline ImmF64Immediate(Decoder* decoder, const byte* pc) {
    192     // Avoid bit_cast because it might not preserve the signalling bit of a NaN.
    193     uint64_t tmp = decoder->read_u64<validate>(pc + 1, "immf64");
    194     memcpy(&value, &tmp, sizeof(value));
    195   }
    196 };
    197 
    198 template <Decoder::ValidateFlag validate>
    199 struct GlobalIndexImmediate {
    200   uint32_t index;
    201   ValueType type = kWasmStmt;
    202   const WasmGlobal* global = nullptr;
    203   unsigned length;
    204 
    205   inline GlobalIndexImmediate(Decoder* decoder, const byte* pc) {
    206     index = decoder->read_u32v<validate>(pc + 1, &length, "global index");
    207   }
    208 };
    209 
    210 template <Decoder::ValidateFlag validate>
    211 struct BlockTypeImmediate {
    212   unsigned length = 1;
    213   ValueType type = kWasmStmt;
    214   uint32_t sig_index = 0;
    215   FunctionSig* sig = nullptr;
    216 
    217   inline BlockTypeImmediate(const WasmFeatures& enabled, Decoder* decoder,
    218                             const byte* pc) {
    219     uint8_t val = decoder->read_u8<validate>(pc + 1, "block type");
    220     if (!decode_local_type(val, &type)) {
    221       // Handle multi-value blocks.
    222       if (!VALIDATE(enabled.mv)) {
    223         decoder->error(pc + 1, "invalid block type");
    224         return;
    225       }
    226       if (!VALIDATE(decoder->ok())) return;
    227       int32_t index =
    228           decoder->read_i32v<validate>(pc + 1, &length, "block arity");
    229       if (!VALIDATE(length > 0 && index >= 0)) {
    230         decoder->error(pc + 1, "invalid block type index");
    231         return;
    232       }
    233       sig_index = static_cast<uint32_t>(index);
    234     }
    235   }
    236 
    237   // Decode a byte representing a local type. Return {false} if the encoded
    238   // byte was invalid or the start of a type index.
    239   inline bool decode_local_type(uint8_t val, ValueType* result) {
    240     switch (static_cast<ValueTypeCode>(val)) {
    241       case kLocalVoid:
    242         *result = kWasmStmt;
    243         return true;
    244       case kLocalI32:
    245         *result = kWasmI32;
    246         return true;
    247       case kLocalI64:
    248         *result = kWasmI64;
    249         return true;
    250       case kLocalF32:
    251         *result = kWasmF32;
    252         return true;
    253       case kLocalF64:
    254         *result = kWasmF64;
    255         return true;
    256       case kLocalS128:
    257         *result = kWasmS128;
    258         return true;
    259       case kLocalAnyFunc:
    260         *result = kWasmAnyFunc;
    261         return true;
    262       case kLocalAnyRef:
    263         *result = kWasmAnyRef;
    264         return true;
    265       default:
    266         *result = kWasmVar;
    267         return false;
    268     }
    269   }
    270 
    271   uint32_t in_arity() const {
    272     if (type != kWasmVar) return 0;
    273     return static_cast<uint32_t>(sig->parameter_count());
    274   }
    275   uint32_t out_arity() const {
    276     if (type == kWasmStmt) return 0;
    277     if (type != kWasmVar) return 1;
    278     return static_cast<uint32_t>(sig->return_count());
    279   }
    280   ValueType in_type(uint32_t index) {
    281     DCHECK_EQ(kWasmVar, type);
    282     return sig->GetParam(index);
    283   }
    284   ValueType out_type(uint32_t index) {
    285     if (type == kWasmVar) return sig->GetReturn(index);
    286     DCHECK_NE(kWasmStmt, type);
    287     DCHECK_EQ(0, index);
    288     return type;
    289   }
    290 };
    291 
    292 template <Decoder::ValidateFlag validate>
    293 struct BreakDepthImmediate {
    294   uint32_t depth;
    295   unsigned length;
    296   inline BreakDepthImmediate(Decoder* decoder, const byte* pc) {
    297     depth = decoder->read_u32v<validate>(pc + 1, &length, "break depth");
    298   }
    299 };
    300 
    301 template <Decoder::ValidateFlag validate>
    302 struct CallIndirectImmediate {
    303   uint32_t table_index;
    304   uint32_t sig_index;
    305   FunctionSig* sig = nullptr;
    306   unsigned length = 0;
    307   inline CallIndirectImmediate(Decoder* decoder, const byte* pc) {
    308     unsigned len = 0;
    309     sig_index = decoder->read_u32v<validate>(pc + 1, &len, "signature index");
    310     if (!VALIDATE(decoder->ok())) return;
    311     table_index = decoder->read_u8<validate>(pc + 1 + len, "table index");
    312     if (!VALIDATE(table_index == 0)) {
    313       decoder->errorf(pc + 1 + len, "expected table index 0, found %u",
    314                       table_index);
    315     }
    316     length = 1 + len;
    317   }
    318 };
    319 
    320 template <Decoder::ValidateFlag validate>
    321 struct CallFunctionImmediate {
    322   uint32_t index;
    323   FunctionSig* sig = nullptr;
    324   unsigned length;
    325   inline CallFunctionImmediate(Decoder* decoder, const byte* pc) {
    326     index = decoder->read_u32v<validate>(pc + 1, &length, "function index");
    327   }
    328 };
    329 
    330 template <Decoder::ValidateFlag validate>
    331 struct MemoryIndexImmediate {
    332   uint32_t index;
    333   unsigned length = 1;
    334   inline MemoryIndexImmediate(Decoder* decoder, const byte* pc) {
    335     index = decoder->read_u8<validate>(pc + 1, "memory index");
    336     if (!VALIDATE(index == 0)) {
    337       decoder->errorf(pc + 1, "expected memory index 0, found %u", index);
    338     }
    339   }
    340 };
    341 
    342 template <Decoder::ValidateFlag validate>
    343 struct BranchTableImmediate {
    344   uint32_t table_count;
    345   const byte* start;
    346   const byte* table;
    347   inline BranchTableImmediate(Decoder* decoder, const byte* pc) {
    348     DCHECK_EQ(kExprBrTable, decoder->read_u8<validate>(pc, "opcode"));
    349     start = pc + 1;
    350     unsigned len = 0;
    351     table_count = decoder->read_u32v<validate>(pc + 1, &len, "table count");
    352     table = pc + 1 + len;
    353   }
    354 };
    355 
    356 // A helper to iterate over a branch table.
    357 template <Decoder::ValidateFlag validate>
    358 class BranchTableIterator {
    359  public:
    360   unsigned cur_index() { return index_; }
    361   bool has_next() { return VALIDATE(decoder_->ok()) && index_ <= table_count_; }
    362   uint32_t next() {
    363     DCHECK(has_next());
    364     index_++;
    365     unsigned length;
    366     uint32_t result =
    367         decoder_->read_u32v<validate>(pc_, &length, "branch table entry");
    368     pc_ += length;
    369     return result;
    370   }
    371   // length, including the length of the {BranchTableImmediate}, but not the
    372   // opcode.
    373   unsigned length() {
    374     while (has_next()) next();
    375     return static_cast<unsigned>(pc_ - start_);
    376   }
    377   const byte* pc() { return pc_; }
    378 
    379   BranchTableIterator(Decoder* decoder,
    380                       const BranchTableImmediate<validate>& imm)
    381       : decoder_(decoder),
    382         start_(imm.start),
    383         pc_(imm.table),
    384         table_count_(imm.table_count) {}
    385 
    386  private:
    387   Decoder* decoder_;
    388   const byte* start_;
    389   const byte* pc_;
    390   uint32_t index_ = 0;    // the current index.
    391   uint32_t table_count_;  // the count of entries, not including default.
    392 };
    393 
    394 template <Decoder::ValidateFlag validate>
    395 struct MemoryAccessImmediate {
    396   uint32_t alignment;
    397   uint32_t offset;
    398   unsigned length = 0;
    399   inline MemoryAccessImmediate(Decoder* decoder, const byte* pc,
    400                                uint32_t max_alignment) {
    401     unsigned alignment_length;
    402     alignment =
    403         decoder->read_u32v<validate>(pc + 1, &alignment_length, "alignment");
    404     if (!VALIDATE(alignment <= max_alignment)) {
    405       decoder->errorf(pc + 1,
    406                       "invalid alignment; expected maximum alignment is %u, "
    407                       "actual alignment is %u",
    408                       max_alignment, alignment);
    409     }
    410     if (!VALIDATE(decoder->ok())) return;
    411     unsigned offset_length;
    412     offset = decoder->read_u32v<validate>(pc + 1 + alignment_length,
    413                                           &offset_length, "offset");
    414     length = alignment_length + offset_length;
    415   }
    416 };
    417 
    418 // Immediate for SIMD lane operations.
    419 template <Decoder::ValidateFlag validate>
    420 struct SimdLaneImmediate {
    421   uint8_t lane;
    422   unsigned length = 1;
    423 
    424   inline SimdLaneImmediate(Decoder* decoder, const byte* pc) {
    425     lane = decoder->read_u8<validate>(pc + 2, "lane");
    426   }
    427 };
    428 
    429 // Immediate for SIMD shift operations.
    430 template <Decoder::ValidateFlag validate>
    431 struct SimdShiftImmediate {
    432   uint8_t shift;
    433   unsigned length = 1;
    434 
    435   inline SimdShiftImmediate(Decoder* decoder, const byte* pc) {
    436     shift = decoder->read_u8<validate>(pc + 2, "shift");
    437   }
    438 };
    439 
    440 // Immediate for SIMD S8x16 shuffle operations.
    441 template <Decoder::ValidateFlag validate>
    442 struct Simd8x16ShuffleImmediate {
    443   uint8_t shuffle[kSimd128Size] = {0};
    444 
    445   inline Simd8x16ShuffleImmediate(Decoder* decoder, const byte* pc) {
    446     for (uint32_t i = 0; i < kSimd128Size; ++i) {
    447       shuffle[i] = decoder->read_u8<validate>(pc + 2 + i, "shuffle");
    448       if (!VALIDATE(decoder->ok())) return;
    449     }
    450   }
    451 };
    452 
    453 // An entry on the value stack.
    454 struct ValueBase {
    455   const byte* pc;
    456   ValueType type;
    457 
    458   // Named constructors.
    459   static ValueBase Unreachable(const byte* pc) { return {pc, kWasmVar}; }
    460 
    461   static ValueBase New(const byte* pc, ValueType type) { return {pc, type}; }
    462 };
    463 
    464 template <typename Value>
    465 struct Merge {
    466   uint32_t arity;
    467   union {
    468     Value* array;
    469     Value first;
    470   } vals;  // Either multiple values or a single value.
    471 
    472   // Tracks whether this merge was ever reached. Uses precise reachability, like
    473   // Reachability::kReachable.
    474   bool reached;
    475 
    476   Merge(bool reached = false) : reached(reached) {}
    477 
    478   Value& operator[](uint32_t i) {
    479     DCHECK_GT(arity, i);
    480     return arity == 1 ? vals.first : vals.array[i];
    481   }
    482 };
    483 
    484 enum ControlKind : uint8_t {
    485   kControlIf,
    486   kControlIfElse,
    487   kControlBlock,
    488   kControlLoop,
    489   kControlTry,
    490   kControlTryCatch
    491 };
    492 
    493 enum Reachability : uint8_t {
    494   // reachable code.
    495   kReachable,
    496   // reachable code in unreachable block (implies normal validation).
    497   kSpecOnlyReachable,
    498   // code unreachable in its own block (implies polymorphic validation).
    499   kUnreachable
    500 };
    501 
    502 // An entry on the control stack (i.e. if, block, loop, or try).
    503 template <typename Value>
    504 struct ControlBase {
    505   ControlKind kind;
    506   uint32_t stack_depth;  // stack height at the beginning of the construct.
    507   const byte* pc;
    508   Reachability reachability = kReachable;
    509 
    510   // Values merged into the start or end of this control construct.
    511   Merge<Value> start_merge;
    512   Merge<Value> end_merge;
    513 
    514   ControlBase() = default;
    515   ControlBase(ControlKind kind, uint32_t stack_depth, const byte* pc)
    516       : kind(kind), stack_depth(stack_depth), pc(pc) {}
    517 
    518   // Check whether the current block is reachable.
    519   bool reachable() const { return reachability == kReachable; }
    520 
    521   // Check whether the rest of the block is unreachable.
    522   // Note that this is different from {!reachable()}, as there is also the
    523   // "indirect unreachable state", for which both {reachable()} and
    524   // {unreachable()} return false.
    525   bool unreachable() const { return reachability == kUnreachable; }
    526 
    527   // Return the reachability of new control structs started in this block.
    528   Reachability innerReachability() const {
    529     return reachability == kReachable ? kReachable : kSpecOnlyReachable;
    530   }
    531 
    532   bool is_if() const { return is_onearmed_if() || is_if_else(); }
    533   bool is_onearmed_if() const { return kind == kControlIf; }
    534   bool is_if_else() const { return kind == kControlIfElse; }
    535   bool is_block() const { return kind == kControlBlock; }
    536   bool is_loop() const { return kind == kControlLoop; }
    537   bool is_try() const { return is_incomplete_try() || is_try_catch(); }
    538   bool is_incomplete_try() const { return kind == kControlTry; }
    539   bool is_try_catch() const { return kind == kControlTryCatch; }
    540 
    541   inline Merge<Value>* br_merge() {
    542     return is_loop() ? &this->start_merge : &this->end_merge;
    543   }
    544 
    545   // Named constructors.
    546   static ControlBase Block(const byte* pc, uint32_t stack_depth) {
    547     return {kControlBlock, stack_depth, pc};
    548   }
    549 
    550   static ControlBase If(const byte* pc, uint32_t stack_depth) {
    551     return {kControlIf, stack_depth, pc};
    552   }
    553 
    554   static ControlBase Loop(const byte* pc, uint32_t stack_depth) {
    555     return {kControlLoop, stack_depth, pc};
    556   }
    557 
    558   static ControlBase Try(const byte* pc, uint32_t stack_depth) {
    559     return {kControlTry, stack_depth, pc};
    560   }
    561 };
    562 
    563 #define CONCRETE_NAMED_CONSTRUCTOR(concrete_type, abstract_type, name) \
    564   template <typename... Args>                                          \
    565   static concrete_type name(Args&&... args) {                          \
    566     concrete_type val;                                                 \
    567     static_cast<abstract_type&>(val) =                                 \
    568         abstract_type::name(std::forward<Args>(args)...);              \
    569     return val;                                                        \
    570   }
    571 
    572 // Provide the default named constructors, which default-initialize the
    573 // ConcreteType and the initialize the fields of ValueBase correctly.
    574 // Use like this:
    575 // struct Value : public ValueWithNamedConstructors<Value> { int new_field; };
    576 template <typename ConcreteType>
    577 struct ValueWithNamedConstructors : public ValueBase {
    578   // Named constructors.
    579   CONCRETE_NAMED_CONSTRUCTOR(ConcreteType, ValueBase, Unreachable)
    580   CONCRETE_NAMED_CONSTRUCTOR(ConcreteType, ValueBase, New)
    581 };
    582 
    583 // Provide the default named constructors, which default-initialize the
    584 // ConcreteType and the initialize the fields of ControlBase correctly.
    585 // Use like this:
    586 // struct Control : public ControlWithNamedConstructors<Control, Value> {
    587 //   int my_uninitialized_field;
    588 //   char* other_field = nullptr;
    589 // };
    590 template <typename ConcreteType, typename Value>
    591 struct ControlWithNamedConstructors : public ControlBase<Value> {
    592   // Named constructors.
    593   CONCRETE_NAMED_CONSTRUCTOR(ConcreteType, ControlBase<Value>, Block)
    594   CONCRETE_NAMED_CONSTRUCTOR(ConcreteType, ControlBase<Value>, If)
    595   CONCRETE_NAMED_CONSTRUCTOR(ConcreteType, ControlBase<Value>, Loop)
    596   CONCRETE_NAMED_CONSTRUCTOR(ConcreteType, ControlBase<Value>, Try)
    597 };
    598 
    599 // This is the list of callback functions that an interface for the
    600 // WasmFullDecoder should implement.
    601 // F(Name, args...)
    602 #define INTERFACE_FUNCTIONS(F)                                                \
    603   /* General: */                                                              \
    604   F(StartFunction)                                                            \
    605   F(StartFunctionBody, Control* block)                                        \
    606   F(FinishFunction)                                                           \
    607   F(OnFirstError)                                                             \
    608   F(NextInstruction, WasmOpcode)                                              \
    609   /* Control: */                                                              \
    610   F(Block, Control* block)                                                    \
    611   F(Loop, Control* block)                                                     \
    612   F(Try, Control* block)                                                      \
    613   F(If, const Value& cond, Control* if_block)                                 \
    614   F(FallThruTo, Control* c)                                                   \
    615   F(PopControl, Control* block)                                               \
    616   F(EndControl, Control* block)                                               \
    617   /* Instructions: */                                                         \
    618   F(UnOp, WasmOpcode opcode, FunctionSig*, const Value& value, Value* result) \
    619   F(BinOp, WasmOpcode opcode, FunctionSig*, const Value& lhs,                 \
    620     const Value& rhs, Value* result)                                          \
    621   F(I32Const, Value* result, int32_t value)                                   \
    622   F(I64Const, Value* result, int64_t value)                                   \
    623   F(F32Const, Value* result, float value)                                     \
    624   F(F64Const, Value* result, double value)                                    \
    625   F(RefNull, Value* result)                                                   \
    626   F(Drop, const Value& value)                                                 \
    627   F(DoReturn, Vector<Value> values, bool implicit)                            \
    628   F(GetLocal, Value* result, const LocalIndexImmediate<validate>& imm)        \
    629   F(SetLocal, const Value& value, const LocalIndexImmediate<validate>& imm)   \
    630   F(TeeLocal, const Value& value, Value* result,                              \
    631     const LocalIndexImmediate<validate>& imm)                                 \
    632   F(GetGlobal, Value* result, const GlobalIndexImmediate<validate>& imm)      \
    633   F(SetGlobal, const Value& value, const GlobalIndexImmediate<validate>& imm) \
    634   F(Unreachable)                                                              \
    635   F(Select, const Value& cond, const Value& fval, const Value& tval,          \
    636     Value* result)                                                            \
    637   F(Br, Control* target)                                                      \
    638   F(BrIf, const Value& cond, Control* target)                                 \
    639   F(BrTable, const BranchTableImmediate<validate>& imm, const Value& key)     \
    640   F(Else, Control* if_block)                                                  \
    641   F(LoadMem, LoadType type, const MemoryAccessImmediate<validate>& imm,       \
    642     const Value& index, Value* result)                                        \
    643   F(StoreMem, StoreType type, const MemoryAccessImmediate<validate>& imm,     \
    644     const Value& index, const Value& value)                                   \
    645   F(CurrentMemoryPages, Value* result)                                        \
    646   F(GrowMemory, const Value& value, Value* result)                            \
    647   F(CallDirect, const CallFunctionImmediate<validate>& imm,                   \
    648     const Value args[], Value returns[])                                      \
    649   F(CallIndirect, const Value& index,                                         \
    650     const CallIndirectImmediate<validate>& imm, const Value args[],           \
    651     Value returns[])                                                          \
    652   F(SimdOp, WasmOpcode opcode, Vector<Value> args, Value* result)             \
    653   F(SimdLaneOp, WasmOpcode opcode, const SimdLaneImmediate<validate>& imm,    \
    654     const Vector<Value> inputs, Value* result)                                \
    655   F(SimdShiftOp, WasmOpcode opcode, const SimdShiftImmediate<validate>& imm,  \
    656     const Value& input, Value* result)                                        \
    657   F(Simd8x16ShuffleOp, const Simd8x16ShuffleImmediate<validate>& imm,         \
    658     const Value& input0, const Value& input1, Value* result)                  \
    659   F(Throw, const ExceptionIndexImmediate<validate>&, Control* block,          \
    660     const Vector<Value>& args)                                                \
    661   F(CatchException, const ExceptionIndexImmediate<validate>& imm,             \
    662     Control* block, Vector<Value> caught_values)                              \
    663   F(AtomicOp, WasmOpcode opcode, Vector<Value> args,                          \
    664     const MemoryAccessImmediate<validate>& imm, Value* result)
    665 
    666 // Generic Wasm bytecode decoder with utilities for decoding immediates,
    667 // lengths, etc.
    668 template <Decoder::ValidateFlag validate>
    669 class WasmDecoder : public Decoder {
    670  public:
    671   WasmDecoder(const WasmModule* module, const WasmFeatures& enabled,
    672               WasmFeatures* detected, FunctionSig* sig, const byte* start,
    673               const byte* end, uint32_t buffer_offset = 0)
    674       : Decoder(start, end, buffer_offset),
    675         module_(module),
    676         enabled_(enabled),
    677         detected_(detected),
    678         sig_(sig),
    679         local_types_(nullptr) {}
    680   const WasmModule* module_;
    681   const WasmFeatures enabled_;
    682   WasmFeatures* detected_;
    683   FunctionSig* sig_;
    684 
    685   ZoneVector<ValueType>* local_types_;
    686 
    687   uint32_t total_locals() const {
    688     return local_types_ == nullptr
    689                ? 0
    690                : static_cast<uint32_t>(local_types_->size());
    691   }
    692 
    693   static bool DecodeLocals(const WasmFeatures& enabled, Decoder* decoder,
    694                            const FunctionSig* sig,
    695                            ZoneVector<ValueType>* type_list) {
    696     DCHECK_NOT_NULL(type_list);
    697     DCHECK_EQ(0, type_list->size());
    698     // Initialize from signature.
    699     if (sig != nullptr) {
    700       type_list->assign(sig->parameters().begin(), sig->parameters().end());
    701     }
    702     // Decode local declarations, if any.
    703     uint32_t entries = decoder->consume_u32v("local decls count");
    704     if (decoder->failed()) return false;
    705 
    706     TRACE("local decls count: %u\n", entries);
    707     while (entries-- > 0 && VALIDATE(decoder->ok()) && decoder->more()) {
    708       uint32_t count = decoder->consume_u32v("local count");
    709       if (decoder->failed()) return false;
    710 
    711       DCHECK_LE(type_list->size(), kV8MaxWasmFunctionLocals);
    712       if (count > kV8MaxWasmFunctionLocals - type_list->size()) {
    713         decoder->error(decoder->pc() - 1, "local count too large");
    714         return false;
    715       }
    716       byte code = decoder->consume_u8("local type");
    717       if (decoder->failed()) return false;
    718 
    719       ValueType type;
    720       switch (code) {
    721         case kLocalI32:
    722           type = kWasmI32;
    723           break;
    724         case kLocalI64:
    725           type = kWasmI64;
    726           break;
    727         case kLocalF32:
    728           type = kWasmF32;
    729           break;
    730         case kLocalF64:
    731           type = kWasmF64;
    732           break;
    733         case kLocalAnyRef:
    734           if (enabled.anyref) {
    735             type = kWasmAnyRef;
    736             break;
    737           }
    738           decoder->error(decoder->pc() - 1, "invalid local type");
    739           return false;
    740         case kLocalS128:
    741           if (enabled.simd) {
    742             type = kWasmS128;
    743             break;
    744           }
    745           V8_FALLTHROUGH;
    746         default:
    747           decoder->error(decoder->pc() - 1, "invalid local type");
    748           return false;
    749       }
    750       type_list->insert(type_list->end(), count, type);
    751     }
    752     DCHECK(decoder->ok());
    753     return true;
    754   }
    755 
    756   static BitVector* AnalyzeLoopAssignment(Decoder* decoder, const byte* pc,
    757                                           uint32_t locals_count, Zone* zone) {
    758     if (pc >= decoder->end()) return nullptr;
    759     if (*pc != kExprLoop) return nullptr;
    760 
    761     // The number of locals_count is augmented by 2 so that 'locals_count - 2'
    762     // can be used to track mem_size, and 'locals_count - 1' to track mem_start.
    763     BitVector* assigned = new (zone) BitVector(locals_count, zone);
    764     int depth = 0;
    765     // Iteratively process all AST nodes nested inside the loop.
    766     while (pc < decoder->end() && VALIDATE(decoder->ok())) {
    767       WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
    768       unsigned length = 1;
    769       switch (opcode) {
    770         case kExprLoop:
    771         case kExprIf:
    772         case kExprBlock:
    773         case kExprTry:
    774           length = OpcodeLength(decoder, pc);
    775           depth++;
    776           break;
    777         case kExprSetLocal:  // fallthru
    778         case kExprTeeLocal: {
    779           LocalIndexImmediate<Decoder::kValidate> imm(decoder, pc);
    780           if (assigned->length() > 0 &&
    781               imm.index < static_cast<uint32_t>(assigned->length())) {
    782             // Unverified code might have an out-of-bounds index.
    783             assigned->Add(imm.index);
    784           }
    785           length = 1 + imm.length;
    786           break;
    787         }
    788         case kExprGrowMemory:
    789         case kExprCallFunction:
    790         case kExprCallIndirect:
    791           // Add instance cache nodes to the assigned set.
    792           // TODO(titzer): make this more clear.
    793           assigned->Add(locals_count - 1);
    794           length = OpcodeLength(decoder, pc);
    795           break;
    796         case kExprEnd:
    797           depth--;
    798           break;
    799         default:
    800           length = OpcodeLength(decoder, pc);
    801           break;
    802       }
    803       if (depth <= 0) break;
    804       pc += length;
    805     }
    806     return VALIDATE(decoder->ok()) ? assigned : nullptr;
    807   }
    808 
    809   inline bool Validate(const byte* pc,
    810                        LocalIndexImmediate<Decoder::kValidate>& imm) {
    811     if (!VALIDATE(imm.index < total_locals())) {
    812       errorf(pc + 1, "invalid local index: %u", imm.index);
    813       return false;
    814     }
    815     imm.type = local_types_ ? local_types_->at(imm.index) : kWasmStmt;
    816     return true;
    817   }
    818 
    819   inline bool Validate(const byte* pc, ExceptionIndexImmediate<validate>& imm) {
    820     if (!VALIDATE(module_ != nullptr &&
    821                   imm.index < module_->exceptions.size())) {
    822       errorf(pc + 1, "Invalid exception index: %u", imm.index);
    823       return false;
    824     }
    825     imm.exception = &module_->exceptions[imm.index];
    826     return true;
    827   }
    828 
    829   inline bool Validate(const byte* pc, GlobalIndexImmediate<validate>& imm) {
    830     if (!VALIDATE(module_ != nullptr && imm.index < module_->globals.size())) {
    831       errorf(pc + 1, "invalid global index: %u", imm.index);
    832       return false;
    833     }
    834     imm.global = &module_->globals[imm.index];
    835     imm.type = imm.global->type;
    836     return true;
    837   }
    838 
    839   inline bool Complete(const byte* pc, CallFunctionImmediate<validate>& imm) {
    840     if (!VALIDATE(module_ != nullptr &&
    841                   imm.index < module_->functions.size())) {
    842       return false;
    843     }
    844     imm.sig = module_->functions[imm.index].sig;
    845     return true;
    846   }
    847 
    848   inline bool Validate(const byte* pc, CallFunctionImmediate<validate>& imm) {
    849     if (Complete(pc, imm)) {
    850       return true;
    851     }
    852     errorf(pc + 1, "invalid function index: %u", imm.index);
    853     return false;
    854   }
    855 
    856   inline bool Complete(const byte* pc, CallIndirectImmediate<validate>& imm) {
    857     if (!VALIDATE(module_ != nullptr &&
    858                   imm.sig_index < module_->signatures.size())) {
    859       return false;
    860     }
    861     imm.sig = module_->signatures[imm.sig_index];
    862     return true;
    863   }
    864 
    865   inline bool Validate(const byte* pc, CallIndirectImmediate<validate>& imm) {
    866     if (!VALIDATE(module_ != nullptr && !module_->tables.empty())) {
    867       error("function table has to exist to execute call_indirect");
    868       return false;
    869     }
    870     if (!Complete(pc, imm)) {
    871       errorf(pc + 1, "invalid signature index: #%u", imm.sig_index);
    872       return false;
    873     }
    874     return true;
    875   }
    876 
    877   inline bool Validate(const byte* pc, BreakDepthImmediate<validate>& imm,
    878                        size_t control_depth) {
    879     if (!VALIDATE(imm.depth < control_depth)) {
    880       errorf(pc + 1, "invalid break depth: %u", imm.depth);
    881       return false;
    882     }
    883     return true;
    884   }
    885 
    886   bool Validate(const byte* pc, BranchTableImmediate<validate>& imm,
    887                 size_t block_depth) {
    888     if (!VALIDATE(imm.table_count < kV8MaxWasmFunctionSize)) {
    889       errorf(pc + 1, "invalid table count (> max function size): %u",
    890              imm.table_count);
    891       return false;
    892     }
    893     return checkAvailable(imm.table_count);
    894   }
    895 
    896   inline bool Validate(const byte* pc, WasmOpcode opcode,
    897                        SimdLaneImmediate<validate>& imm) {
    898     uint8_t num_lanes = 0;
    899     switch (opcode) {
    900       case kExprF32x4ExtractLane:
    901       case kExprF32x4ReplaceLane:
    902       case kExprI32x4ExtractLane:
    903       case kExprI32x4ReplaceLane:
    904         num_lanes = 4;
    905         break;
    906       case kExprI16x8ExtractLane:
    907       case kExprI16x8ReplaceLane:
    908         num_lanes = 8;
    909         break;
    910       case kExprI8x16ExtractLane:
    911       case kExprI8x16ReplaceLane:
    912         num_lanes = 16;
    913         break;
    914       default:
    915         UNREACHABLE();
    916         break;
    917     }
    918     if (!VALIDATE(imm.lane >= 0 && imm.lane < num_lanes)) {
    919       error(pc_ + 2, "invalid lane index");
    920       return false;
    921     } else {
    922       return true;
    923     }
    924   }
    925 
    926   inline bool Validate(const byte* pc, WasmOpcode opcode,
    927                        SimdShiftImmediate<validate>& imm) {
    928     uint8_t max_shift = 0;
    929     switch (opcode) {
    930       case kExprI32x4Shl:
    931       case kExprI32x4ShrS:
    932       case kExprI32x4ShrU:
    933         max_shift = 32;
    934         break;
    935       case kExprI16x8Shl:
    936       case kExprI16x8ShrS:
    937       case kExprI16x8ShrU:
    938         max_shift = 16;
    939         break;
    940       case kExprI8x16Shl:
    941       case kExprI8x16ShrS:
    942       case kExprI8x16ShrU:
    943         max_shift = 8;
    944         break;
    945       default:
    946         UNREACHABLE();
    947         break;
    948     }
    949     if (!VALIDATE(imm.shift >= 0 && imm.shift < max_shift)) {
    950       error(pc_ + 2, "invalid shift amount");
    951       return false;
    952     } else {
    953       return true;
    954     }
    955   }
    956 
    957   inline bool Validate(const byte* pc,
    958                        Simd8x16ShuffleImmediate<validate>& imm) {
    959     uint8_t max_lane = 0;
    960     for (uint32_t i = 0; i < kSimd128Size; ++i) {
    961       max_lane = std::max(max_lane, imm.shuffle[i]);
    962     }
    963     // Shuffle indices must be in [0..31] for a 16 lane shuffle.
    964     if (!VALIDATE(max_lane <= 2 * kSimd128Size)) {
    965       error(pc_ + 2, "invalid shuffle mask");
    966       return false;
    967     }
    968     return true;
    969   }
    970 
    971   inline bool Complete(BlockTypeImmediate<validate>& imm) {
    972     if (imm.type != kWasmVar) return true;
    973     if (!VALIDATE((module_ && imm.sig_index < module_->signatures.size()))) {
    974       return false;
    975     }
    976     imm.sig = module_->signatures[imm.sig_index];
    977     return true;
    978   }
    979 
    980   inline bool Validate(BlockTypeImmediate<validate>& imm) {
    981     if (!Complete(imm)) {
    982       errorf(pc_, "block type index %u out of bounds (%zu signatures)",
    983              imm.sig_index, module_ ? module_->signatures.size() : 0);
    984       return false;
    985     }
    986     return true;
    987   }
    988 
    989   static unsigned OpcodeLength(Decoder* decoder, const byte* pc) {
    990     WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
    991     switch (opcode) {
    992 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
    993       FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
    994       FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
    995 #undef DECLARE_OPCODE_CASE
    996       {
    997         MemoryAccessImmediate<validate> imm(decoder, pc, UINT32_MAX);
    998         return 1 + imm.length;
    999       }
   1000       case kExprBr:
   1001       case kExprBrIf: {
   1002         BreakDepthImmediate<validate> imm(decoder, pc);
   1003         return 1 + imm.length;
   1004       }
   1005       case kExprSetGlobal:
   1006       case kExprGetGlobal: {
   1007         GlobalIndexImmediate<validate> imm(decoder, pc);
   1008         return 1 + imm.length;
   1009       }
   1010 
   1011       case kExprCallFunction: {
   1012         CallFunctionImmediate<validate> imm(decoder, pc);
   1013         return 1 + imm.length;
   1014       }
   1015       case kExprCallIndirect: {
   1016         CallIndirectImmediate<validate> imm(decoder, pc);
   1017         return 1 + imm.length;
   1018       }
   1019 
   1020       case kExprTry:
   1021       case kExprIf:  // fall through
   1022       case kExprLoop:
   1023       case kExprBlock: {
   1024         BlockTypeImmediate<validate> imm(kAllWasmFeatures, decoder, pc);
   1025         return 1 + imm.length;
   1026       }
   1027 
   1028       case kExprThrow:
   1029       case kExprCatch: {
   1030         ExceptionIndexImmediate<validate> imm(decoder, pc);
   1031         return 1 + imm.length;
   1032       }
   1033 
   1034       case kExprSetLocal:
   1035       case kExprTeeLocal:
   1036       case kExprGetLocal: {
   1037         LocalIndexImmediate<Decoder::kValidate> imm(decoder, pc);
   1038         return 1 + imm.length;
   1039       }
   1040       case kExprBrTable: {
   1041         BranchTableImmediate<validate> imm(decoder, pc);
   1042         BranchTableIterator<validate> iterator(decoder, imm);
   1043         return 1 + iterator.length();
   1044       }
   1045       case kExprI32Const: {
   1046         ImmI32Immediate<validate> imm(decoder, pc);
   1047         return 1 + imm.length;
   1048       }
   1049       case kExprI64Const: {
   1050         ImmI64Immediate<validate> imm(decoder, pc);
   1051         return 1 + imm.length;
   1052       }
   1053       case kExprRefNull: {
   1054         return 1;
   1055       }
   1056       case kExprGrowMemory:
   1057       case kExprMemorySize: {
   1058         MemoryIndexImmediate<validate> imm(decoder, pc);
   1059         return 1 + imm.length;
   1060       }
   1061       case kExprF32Const:
   1062         return 5;
   1063       case kExprF64Const:
   1064         return 9;
   1065       case kNumericPrefix:
   1066         return 2;
   1067       case kSimdPrefix: {
   1068         byte simd_index = decoder->read_u8<validate>(pc + 1, "simd_index");
   1069         WasmOpcode opcode =
   1070             static_cast<WasmOpcode>(kSimdPrefix << 8 | simd_index);
   1071         switch (opcode) {
   1072 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
   1073           FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
   1074 #undef DECLARE_OPCODE_CASE
   1075           return 2;
   1076 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
   1077           FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
   1078 #undef DECLARE_OPCODE_CASE
   1079           return 3;
   1080 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
   1081           FOREACH_SIMD_MEM_OPCODE(DECLARE_OPCODE_CASE)
   1082 #undef DECLARE_OPCODE_CASE
   1083           {
   1084             MemoryAccessImmediate<validate> imm(decoder, pc + 1, UINT32_MAX);
   1085             return 2 + imm.length;
   1086           }
   1087           // Shuffles require a byte per lane, or 16 immediate bytes.
   1088           case kExprS8x16Shuffle:
   1089             return 2 + kSimd128Size;
   1090           default:
   1091             decoder->error(pc, "invalid SIMD opcode");
   1092             return 2;
   1093         }
   1094       }
   1095       case kAtomicPrefix: {
   1096         byte atomic_index = decoder->read_u8<validate>(pc + 1, "atomic_index");
   1097         WasmOpcode opcode =
   1098             static_cast<WasmOpcode>(kAtomicPrefix << 8 | atomic_index);
   1099         switch (opcode) {
   1100 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
   1101           FOREACH_ATOMIC_OPCODE(DECLARE_OPCODE_CASE)
   1102 #undef DECLARE_OPCODE_CASE
   1103           {
   1104             MemoryAccessImmediate<validate> imm(decoder, pc + 1, UINT32_MAX);
   1105             return 2 + imm.length;
   1106           }
   1107           default:
   1108             decoder->error(pc, "invalid Atomics opcode");
   1109             return 2;
   1110         }
   1111       }
   1112       default:
   1113         return 1;
   1114     }
   1115   }
   1116 
   1117   std::pair<uint32_t, uint32_t> StackEffect(const byte* pc) {
   1118     WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
   1119     // Handle "simple" opcodes with a fixed signature first.
   1120     FunctionSig* sig = WasmOpcodes::Signature(opcode);
   1121     if (!sig) sig = WasmOpcodes::AsmjsSignature(opcode);
   1122     if (sig) return {sig->parameter_count(), sig->return_count()};
   1123 
   1124 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
   1125     // clang-format off
   1126     switch (opcode) {
   1127       case kExprSelect:
   1128         return {3, 1};
   1129       FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
   1130         return {2, 0};
   1131       FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
   1132       case kExprTeeLocal:
   1133       case kExprGrowMemory:
   1134         return {1, 1};
   1135       case kExprSetLocal:
   1136       case kExprSetGlobal:
   1137       case kExprDrop:
   1138       case kExprBrIf:
   1139       case kExprBrTable:
   1140       case kExprIf:
   1141         return {1, 0};
   1142       case kExprGetLocal:
   1143       case kExprGetGlobal:
   1144       case kExprI32Const:
   1145       case kExprI64Const:
   1146       case kExprF32Const:
   1147       case kExprF64Const:
   1148       case kExprRefNull:
   1149       case kExprMemorySize:
   1150         return {0, 1};
   1151       case kExprCallFunction: {
   1152         CallFunctionImmediate<validate> imm(this, pc);
   1153         CHECK(Complete(pc, imm));
   1154         return {imm.sig->parameter_count(), imm.sig->return_count()};
   1155       }
   1156       case kExprCallIndirect: {
   1157         CallIndirectImmediate<validate> imm(this, pc);
   1158         CHECK(Complete(pc, imm));
   1159         // Indirect calls pop an additional argument for the table index.
   1160         return {imm.sig->parameter_count() + 1,
   1161                 imm.sig->return_count()};
   1162       }
   1163       case kExprBr:
   1164       case kExprBlock:
   1165       case kExprLoop:
   1166       case kExprEnd:
   1167       case kExprElse:
   1168       case kExprNop:
   1169       case kExprReturn:
   1170       case kExprUnreachable:
   1171         return {0, 0};
   1172       case kNumericPrefix:
   1173       case kAtomicPrefix:
   1174       case kSimdPrefix: {
   1175         opcode = static_cast<WasmOpcode>(opcode << 8 | *(pc + 1));
   1176         switch (opcode) {
   1177           FOREACH_SIMD_1_OPERAND_1_PARAM_OPCODE(DECLARE_OPCODE_CASE)
   1178             return {1, 1};
   1179           FOREACH_SIMD_1_OPERAND_2_PARAM_OPCODE(DECLARE_OPCODE_CASE)
   1180           FOREACH_SIMD_MASK_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
   1181             return {2, 1};
   1182           default: {
   1183             sig = WasmOpcodes::Signature(opcode);
   1184             if (sig) {
   1185               return {sig->parameter_count(), sig->return_count()};
   1186             }
   1187           }
   1188         }
   1189         V8_FALLTHROUGH;
   1190       }
   1191       default:
   1192         V8_Fatal(__FILE__, __LINE__, "unimplemented opcode: %x (%s)", opcode,
   1193                  WasmOpcodes::OpcodeName(opcode));
   1194         return {0, 0};
   1195     }
   1196 #undef DECLARE_OPCODE_CASE
   1197     // clang-format on
   1198   }
   1199 };
   1200 
   1201 #define CALL_INTERFACE(name, ...) interface_.name(this, ##__VA_ARGS__)
   1202 #define CALL_INTERFACE_IF_REACHABLE(name, ...)                 \
   1203   do {                                                         \
   1204     DCHECK(!control_.empty());                                 \
   1205     if (VALIDATE(this->ok()) && control_.back().reachable()) { \
   1206       interface_.name(this, ##__VA_ARGS__);                    \
   1207     }                                                          \
   1208   } while (false)
   1209 #define CALL_INTERFACE_IF_PARENT_REACHABLE(name, ...)           \
   1210   do {                                                          \
   1211     DCHECK(!control_.empty());                                  \
   1212     if (VALIDATE(this->ok()) &&                                 \
   1213         (control_.size() == 1 || control_at(1)->reachable())) { \
   1214       interface_.name(this, ##__VA_ARGS__);                     \
   1215     }                                                           \
   1216   } while (false)
   1217 
   1218 template <Decoder::ValidateFlag validate, typename Interface>
   1219 class WasmFullDecoder : public WasmDecoder<validate> {
   1220   using Value = typename Interface::Value;
   1221   using Control = typename Interface::Control;
   1222   using MergeValues = Merge<Value>;
   1223 
   1224   // All Value types should be trivially copyable for performance. We push, pop,
   1225   // and store them in local variables.
   1226   ASSERT_TRIVIALLY_COPYABLE(Value);
   1227 
   1228  public:
   1229   template <typename... InterfaceArgs>
   1230   WasmFullDecoder(Zone* zone, const WasmModule* module,
   1231                   const WasmFeatures& enabled, WasmFeatures* detected,
   1232                   const FunctionBody& body, InterfaceArgs&&... interface_args)
   1233       : WasmDecoder<validate>(module, enabled, detected, body.sig, body.start,
   1234                               body.end, body.offset),
   1235         zone_(zone),
   1236         interface_(std::forward<InterfaceArgs>(interface_args)...),
   1237         local_type_vec_(zone),
   1238         stack_(zone),
   1239         control_(zone),
   1240         args_(zone),
   1241         last_end_found_(false) {
   1242     this->local_types_ = &local_type_vec_;
   1243   }
   1244 
   1245   Interface& interface() { return interface_; }
   1246 
   1247   bool Decode() {
   1248     DCHECK(stack_.empty());
   1249     DCHECK(control_.empty());
   1250 
   1251     base::ElapsedTimer decode_timer;
   1252     if (FLAG_trace_wasm_decode_time) {
   1253       decode_timer.Start();
   1254     }
   1255 
   1256     if (this->end_ < this->pc_) {
   1257       this->error("function body end < start");
   1258       return false;
   1259     }
   1260 
   1261     DCHECK_EQ(0, this->local_types_->size());
   1262     WasmDecoder<validate>::DecodeLocals(this->enabled_, this, this->sig_,
   1263                                         this->local_types_);
   1264     CALL_INTERFACE(StartFunction);
   1265     DecodeFunctionBody();
   1266     if (!this->failed()) CALL_INTERFACE(FinishFunction);
   1267 
   1268     if (this->failed()) return this->TraceFailed();
   1269 
   1270     if (!control_.empty()) {
   1271       // Generate a better error message whether the unterminated control
   1272       // structure is the function body block or an innner structure.
   1273       if (control_.size() > 1) {
   1274         this->error(control_.back().pc, "unterminated control structure");
   1275       } else {
   1276         this->error("function body must end with \"end\" opcode");
   1277       }
   1278       return TraceFailed();
   1279     }
   1280 
   1281     if (!last_end_found_) {
   1282       this->error("function body must end with \"end\" opcode");
   1283       return false;
   1284     }
   1285 
   1286     if (FLAG_trace_wasm_decode_time) {
   1287       double ms = decode_timer.Elapsed().InMillisecondsF();
   1288       PrintF("wasm-decode %s (%0.3f ms)\n\n",
   1289              VALIDATE(this->ok()) ? "ok" : "failed", ms);
   1290     } else {
   1291       TRACE("wasm-decode %s\n\n", VALIDATE(this->ok()) ? "ok" : "failed");
   1292     }
   1293 
   1294     return true;
   1295   }
   1296 
   1297   bool TraceFailed() {
   1298     TRACE("wasm-error module+%-6d func+%d: %s\n\n", this->error_offset_,
   1299           this->GetBufferRelativeOffset(this->error_offset_),
   1300           this->error_msg_.c_str());
   1301     return false;
   1302   }
   1303 
   1304   const char* SafeOpcodeNameAt(const byte* pc) {
   1305     if (pc >= this->end_) return "<end>";
   1306     return WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(*pc));
   1307   }
   1308 
   1309   inline Zone* zone() const { return zone_; }
   1310 
   1311   inline uint32_t NumLocals() {
   1312     return static_cast<uint32_t>(local_type_vec_.size());
   1313   }
   1314 
   1315   inline ValueType GetLocalType(uint32_t index) {
   1316     return local_type_vec_[index];
   1317   }
   1318 
   1319   inline WasmCodePosition position() {
   1320     int offset = static_cast<int>(this->pc_ - this->start_);
   1321     DCHECK_EQ(this->pc_ - this->start_, offset);  // overflows cannot happen
   1322     return offset;
   1323   }
   1324 
   1325   inline uint32_t control_depth() const {
   1326     return static_cast<uint32_t>(control_.size());
   1327   }
   1328 
   1329   inline Control* control_at(uint32_t depth) {
   1330     DCHECK_GT(control_.size(), depth);
   1331     return &control_.back() - depth;
   1332   }
   1333 
   1334   inline uint32_t stack_size() const {
   1335     DCHECK_GE(kMaxUInt32, stack_.size());
   1336     return static_cast<uint32_t>(stack_.size());
   1337   }
   1338 
   1339   inline Value* stack_value(uint32_t depth) {
   1340     DCHECK_GT(stack_.size(), depth);
   1341     return &stack_[stack_.size() - depth - 1];
   1342   }
   1343 
   1344   inline Value& GetMergeValueFromStack(
   1345       Control* c, Merge<Value>* merge, uint32_t i) {
   1346     DCHECK(merge == &c->start_merge || merge == &c->end_merge);
   1347     DCHECK_GT(merge->arity, i);
   1348     DCHECK_GE(stack_.size(), c->stack_depth + merge->arity);
   1349     return stack_[stack_.size() - merge->arity + i];
   1350   }
   1351 
   1352  private:
   1353   static constexpr size_t kErrorMsgSize = 128;
   1354 
   1355   Zone* zone_;
   1356 
   1357   Interface interface_;
   1358 
   1359   ZoneVector<ValueType> local_type_vec_;  // types of local variables.
   1360   ZoneVector<Value> stack_;               // stack of values.
   1361   ZoneVector<Control> control_;           // stack of blocks, loops, and ifs.
   1362   ZoneVector<Value> args_;                // parameters of current block or call
   1363   bool last_end_found_;
   1364 
   1365   bool CheckHasMemory() {
   1366     if (!VALIDATE(this->module_->has_memory)) {
   1367       this->error(this->pc_ - 1, "memory instruction with no memory");
   1368       return false;
   1369     }
   1370     return true;
   1371   }
   1372 
   1373   bool CheckHasSharedMemory() {
   1374     if (!VALIDATE(this->module_->has_shared_memory)) {
   1375       this->error(this->pc_ - 1, "Atomic opcodes used without shared memory");
   1376       return false;
   1377     }
   1378     return true;
   1379   }
   1380 
   1381   class TraceLine {
   1382    public:
   1383     static constexpr int kMaxLen = 512;
   1384     ~TraceLine() {
   1385       if (!FLAG_trace_wasm_decoder) return;
   1386       PrintF("%.*s\n", len_, buffer_);
   1387     }
   1388 
   1389     // Appends a formatted string.
   1390     PRINTF_FORMAT(2, 3)
   1391     void Append(const char* format, ...) {
   1392       if (!FLAG_trace_wasm_decoder) return;
   1393       va_list va_args;
   1394       va_start(va_args, format);
   1395       size_t remaining_len = kMaxLen - len_;
   1396       Vector<char> remaining_msg_space(buffer_ + len_, remaining_len);
   1397       int len = VSNPrintF(remaining_msg_space, format, va_args);
   1398       va_end(va_args);
   1399       len_ += len < 0 ? remaining_len : len;
   1400     }
   1401 
   1402    private:
   1403     char buffer_[kMaxLen];
   1404     int len_ = 0;
   1405   };
   1406 
   1407   // Decodes the body of a function.
   1408   void DecodeFunctionBody() {
   1409     TRACE("wasm-decode %p...%p (module+%u, %d bytes)\n",
   1410           reinterpret_cast<const void*>(this->start()),
   1411           reinterpret_cast<const void*>(this->end()), this->pc_offset(),
   1412           static_cast<int>(this->end() - this->start()));
   1413 
   1414     // Set up initial function block.
   1415     {
   1416       auto* c = PushBlock();
   1417       InitMerge(&c->start_merge, 0, [](uint32_t) -> Value { UNREACHABLE(); });
   1418       InitMerge(&c->end_merge,
   1419                 static_cast<uint32_t>(this->sig_->return_count()),
   1420                 [&] (uint32_t i) {
   1421                     return Value::New(this->pc_, this->sig_->GetReturn(i)); });
   1422       CALL_INTERFACE(StartFunctionBody, c);
   1423     }
   1424 
   1425     while (this->pc_ < this->end_) {  // decoding loop.
   1426       unsigned len = 1;
   1427       WasmOpcode opcode = static_cast<WasmOpcode>(*this->pc_);
   1428 
   1429       CALL_INTERFACE_IF_REACHABLE(NextInstruction, opcode);
   1430 
   1431 #if DEBUG
   1432       TraceLine trace_msg;
   1433 #define TRACE_PART(...) trace_msg.Append(__VA_ARGS__)
   1434       if (!WasmOpcodes::IsPrefixOpcode(opcode)) {
   1435         TRACE_PART(TRACE_INST_FORMAT, startrel(this->pc_),
   1436                    WasmOpcodes::OpcodeName(opcode));
   1437       }
   1438 #else
   1439 #define TRACE_PART(...)
   1440 #endif
   1441 
   1442       FunctionSig* sig = const_cast<FunctionSig*>(kSimpleOpcodeSigs[opcode]);
   1443       if (sig) {
   1444         BuildSimpleOperator(opcode, sig);
   1445       } else {
   1446         // Complex bytecode.
   1447         switch (opcode) {
   1448           case kExprNop:
   1449             break;
   1450           case kExprBlock: {
   1451             BlockTypeImmediate<validate> imm(this->enabled_, this, this->pc_);
   1452             if (!this->Validate(imm)) break;
   1453             PopArgs(imm.sig);
   1454             auto* block = PushBlock();
   1455             SetBlockType(block, imm);
   1456             CALL_INTERFACE_IF_REACHABLE(Block, block);
   1457             PushMergeValues(block, &block->start_merge);
   1458             len = 1 + imm.length;
   1459             break;
   1460           }
   1461           case kExprRethrow: {
   1462             // TODO(kschimpf): Implement.
   1463             CHECK_PROTOTYPE_OPCODE(eh);
   1464             OPCODE_ERROR(opcode, "not implemented yet");
   1465             break;
   1466           }
   1467           case kExprThrow: {
   1468             CHECK_PROTOTYPE_OPCODE(eh);
   1469             ExceptionIndexImmediate<Decoder::kValidate> imm(this, this->pc_);
   1470             len = 1 + imm.length;
   1471             if (!this->Validate(this->pc_, imm)) break;
   1472             PopArgs(imm.exception->ToFunctionSig());
   1473             CALL_INTERFACE_IF_REACHABLE(Throw, imm, &control_.back(),
   1474                                         vec2vec(args_));
   1475             EndControl();
   1476             break;
   1477           }
   1478           case kExprTry: {
   1479             CHECK_PROTOTYPE_OPCODE(eh);
   1480             BlockTypeImmediate<validate> imm(this->enabled_, this, this->pc_);
   1481             if (!this->Validate(imm)) break;
   1482             PopArgs(imm.sig);
   1483             auto* try_block = PushTry();
   1484             SetBlockType(try_block, imm);
   1485             len = 1 + imm.length;
   1486             CALL_INTERFACE_IF_REACHABLE(Try, try_block);
   1487             PushMergeValues(try_block, &try_block->start_merge);
   1488             break;
   1489           }
   1490           case kExprCatch: {
   1491             // TODO(kschimpf): Fix to use type signature of exception.
   1492             CHECK_PROTOTYPE_OPCODE(eh);
   1493             ExceptionIndexImmediate<Decoder::kValidate> imm(this, this->pc_);
   1494             len = 1 + imm.length;
   1495 
   1496             if (!this->Validate(this->pc_, imm)) break;
   1497 
   1498             if (!VALIDATE(!control_.empty())) {
   1499               this->error("catch does not match any try");
   1500               break;
   1501             }
   1502 
   1503             Control* c = &control_.back();
   1504             if (!VALIDATE(c->is_try())) {
   1505               this->error("catch does not match any try");
   1506               break;
   1507             }
   1508 
   1509             if (!VALIDATE(c->is_incomplete_try())) {
   1510               OPCODE_ERROR(opcode, "multiple catch blocks not implemented");
   1511               break;
   1512             }
   1513             c->kind = kControlTryCatch;
   1514             FallThruTo(c);
   1515             stack_.resize(c->stack_depth);
   1516             const WasmExceptionSig* sig = imm.exception->sig;
   1517             for (size_t i = 0, e = sig->parameter_count(); i < e; ++i) {
   1518               Push(sig->GetParam(i));
   1519             }
   1520             Vector<Value> values(stack_.data() + c->stack_depth,
   1521                                  sig->parameter_count());
   1522             CALL_INTERFACE_IF_PARENT_REACHABLE(CatchException, imm, c, values);
   1523             c->reachability = control_at(1)->innerReachability();
   1524             break;
   1525           }
   1526           case kExprCatchAll: {
   1527             // TODO(kschimpf): Implement.
   1528             CHECK_PROTOTYPE_OPCODE(eh);
   1529             OPCODE_ERROR(opcode, "not implemented yet");
   1530             break;
   1531           }
   1532           case kExprLoop: {
   1533             BlockTypeImmediate<validate> imm(this->enabled_, this, this->pc_);
   1534             if (!this->Validate(imm)) break;
   1535             PopArgs(imm.sig);
   1536             auto* block = PushLoop();
   1537             SetBlockType(&control_.back(), imm);
   1538             len = 1 + imm.length;
   1539             CALL_INTERFACE_IF_REACHABLE(Loop, block);
   1540             PushMergeValues(block, &block->start_merge);
   1541             break;
   1542           }
   1543           case kExprIf: {
   1544             BlockTypeImmediate<validate> imm(this->enabled_, this, this->pc_);
   1545             if (!this->Validate(imm)) break;
   1546             auto cond = Pop(0, kWasmI32);
   1547             PopArgs(imm.sig);
   1548             if (!VALIDATE(this->ok())) break;
   1549             auto* if_block = PushIf();
   1550             SetBlockType(if_block, imm);
   1551             CALL_INTERFACE_IF_REACHABLE(If, cond, if_block);
   1552             len = 1 + imm.length;
   1553             PushMergeValues(if_block, &if_block->start_merge);
   1554             break;
   1555           }
   1556           case kExprElse: {
   1557             if (!VALIDATE(!control_.empty())) {
   1558               this->error("else does not match any if");
   1559               break;
   1560             }
   1561             Control* c = &control_.back();
   1562             if (!VALIDATE(c->is_if())) {
   1563               this->error(this->pc_, "else does not match an if");
   1564               break;
   1565             }
   1566             if (c->is_if_else()) {
   1567               this->error(this->pc_, "else already present for if");
   1568               break;
   1569             }
   1570             FallThruTo(c);
   1571             c->kind = kControlIfElse;
   1572             CALL_INTERFACE_IF_PARENT_REACHABLE(Else, c);
   1573             PushMergeValues(c, &c->start_merge);
   1574             c->reachability = control_at(1)->innerReachability();
   1575             break;
   1576           }
   1577           case kExprEnd: {
   1578             if (!VALIDATE(!control_.empty())) {
   1579               this->error("end does not match any if, try, or block");
   1580               return;
   1581             }
   1582             Control* c = &control_.back();
   1583             if (!VALIDATE(!c->is_incomplete_try())) {
   1584               this->error(this->pc_, "missing catch in try");
   1585               break;
   1586             }
   1587             if (c->is_onearmed_if()) {
   1588               // Emulate empty else arm.
   1589               FallThruTo(c);
   1590               if (this->failed()) break;
   1591               CALL_INTERFACE_IF_PARENT_REACHABLE(Else, c);
   1592               PushMergeValues(c, &c->start_merge);
   1593               c->reachability = control_at(1)->innerReachability();
   1594             }
   1595 
   1596             FallThruTo(c);
   1597             // A loop just leaves the values on the stack.
   1598             if (!c->is_loop()) PushMergeValues(c, &c->end_merge);
   1599 
   1600             if (control_.size() == 1) {
   1601               // If at the last (implicit) control, check we are at end.
   1602               if (!VALIDATE(this->pc_ + 1 == this->end_)) {
   1603                 this->error(this->pc_ + 1, "trailing code after function end");
   1604                 break;
   1605               }
   1606               last_end_found_ = true;
   1607               // The result of the block is the return value.
   1608               TRACE_PART("\n" TRACE_INST_FORMAT, startrel(this->pc_),
   1609                          "(implicit) return");
   1610               DoReturn(c, true);
   1611             }
   1612 
   1613             PopControl(c);
   1614             break;
   1615           }
   1616           case kExprSelect: {
   1617             auto cond = Pop(2, kWasmI32);
   1618             auto fval = Pop();
   1619             auto tval = Pop(0, fval.type);
   1620             auto* result = Push(tval.type == kWasmVar ? fval.type : tval.type);
   1621             CALL_INTERFACE_IF_REACHABLE(Select, cond, fval, tval, result);
   1622             break;
   1623           }
   1624           case kExprBr: {
   1625             BreakDepthImmediate<validate> imm(this, this->pc_);
   1626             if (!this->Validate(this->pc_, imm, control_.size())) break;
   1627             Control* c = control_at(imm.depth);
   1628             if (!TypeCheckBreak(c)) break;
   1629             if (control_.back().reachable()) {
   1630               CALL_INTERFACE(Br, c);
   1631               c->br_merge()->reached = true;
   1632             }
   1633             len = 1 + imm.length;
   1634             EndControl();
   1635             break;
   1636           }
   1637           case kExprBrIf: {
   1638             BreakDepthImmediate<validate> imm(this, this->pc_);
   1639             auto cond = Pop(0, kWasmI32);
   1640             if (this->failed()) break;
   1641             if (!this->Validate(this->pc_, imm, control_.size())) break;
   1642             Control* c = control_at(imm.depth);
   1643             if (!TypeCheckBreak(c)) break;
   1644             if (control_.back().reachable()) {
   1645               CALL_INTERFACE(BrIf, cond, c);
   1646               c->br_merge()->reached = true;
   1647             }
   1648             len = 1 + imm.length;
   1649             break;
   1650           }
   1651           case kExprBrTable: {
   1652             BranchTableImmediate<validate> imm(this, this->pc_);
   1653             BranchTableIterator<validate> iterator(this, imm);
   1654             auto key = Pop(0, kWasmI32);
   1655             if (this->failed()) break;
   1656             if (!this->Validate(this->pc_, imm, control_.size())) break;
   1657             uint32_t br_arity = 0;
   1658             std::vector<bool> br_targets(control_.size());
   1659             while (iterator.has_next()) {
   1660               const uint32_t i = iterator.cur_index();
   1661               const byte* pos = iterator.pc();
   1662               uint32_t target = iterator.next();
   1663               if (!VALIDATE(target < control_.size())) {
   1664                 this->errorf(pos,
   1665                              "improper branch in br_table target %u (depth %u)",
   1666                              i, target);
   1667                 break;
   1668               }
   1669               // Avoid redundant break target checks.
   1670               if (br_targets[target]) continue;
   1671               br_targets[target] = true;
   1672               // Check that label types match up.
   1673               Control* c = control_at(target);
   1674               uint32_t arity = c->br_merge()->arity;
   1675               if (i == 0) {
   1676                 br_arity = arity;
   1677               } else if (!VALIDATE(br_arity == arity)) {
   1678                 this->errorf(pos,
   1679                              "inconsistent arity in br_table target %u"
   1680                              " (previous was %u, this one %u)",
   1681                              i, br_arity, arity);
   1682               }
   1683               if (!TypeCheckBreak(c)) break;
   1684             }
   1685             if (this->failed()) break;
   1686 
   1687             if (control_.back().reachable()) {
   1688               CALL_INTERFACE(BrTable, imm, key);
   1689 
   1690               for (uint32_t depth = control_depth(); depth-- > 0;) {
   1691                 if (!br_targets[depth]) continue;
   1692                 control_at(depth)->br_merge()->reached = true;
   1693               }
   1694             }
   1695 
   1696             len = 1 + iterator.length();
   1697             EndControl();
   1698             break;
   1699           }
   1700           case kExprReturn: {
   1701             DoReturn(&control_.back(), false);
   1702             break;
   1703           }
   1704           case kExprUnreachable: {
   1705             CALL_INTERFACE_IF_REACHABLE(Unreachable);
   1706             EndControl();
   1707             break;
   1708           }
   1709           case kExprI32Const: {
   1710             ImmI32Immediate<validate> imm(this, this->pc_);
   1711             auto* value = Push(kWasmI32);
   1712             CALL_INTERFACE_IF_REACHABLE(I32Const, value, imm.value);
   1713             len = 1 + imm.length;
   1714             break;
   1715           }
   1716           case kExprI64Const: {
   1717             ImmI64Immediate<validate> imm(this, this->pc_);
   1718             auto* value = Push(kWasmI64);
   1719             CALL_INTERFACE_IF_REACHABLE(I64Const, value, imm.value);
   1720             len = 1 + imm.length;
   1721             break;
   1722           }
   1723           case kExprF32Const: {
   1724             ImmF32Immediate<validate> imm(this, this->pc_);
   1725             auto* value = Push(kWasmF32);
   1726             CALL_INTERFACE_IF_REACHABLE(F32Const, value, imm.value);
   1727             len = 1 + imm.length;
   1728             break;
   1729           }
   1730           case kExprF64Const: {
   1731             ImmF64Immediate<validate> imm(this, this->pc_);
   1732             auto* value = Push(kWasmF64);
   1733             CALL_INTERFACE_IF_REACHABLE(F64Const, value, imm.value);
   1734             len = 1 + imm.length;
   1735             break;
   1736           }
   1737           case kExprRefNull: {
   1738             CHECK_PROTOTYPE_OPCODE(anyref);
   1739             auto* value = Push(kWasmAnyRef);
   1740             CALL_INTERFACE_IF_REACHABLE(RefNull, value);
   1741             len = 1;
   1742             break;
   1743           }
   1744           case kExprGetLocal: {
   1745             LocalIndexImmediate<Decoder::kValidate> imm(this, this->pc_);
   1746             if (!this->Validate(this->pc_, imm)) break;
   1747             auto* value = Push(imm.type);
   1748             CALL_INTERFACE_IF_REACHABLE(GetLocal, value, imm);
   1749             len = 1 + imm.length;
   1750             break;
   1751           }
   1752           case kExprSetLocal: {
   1753             LocalIndexImmediate<Decoder::kValidate> imm(this, this->pc_);
   1754             if (!this->Validate(this->pc_, imm)) break;
   1755             auto value = Pop(0, local_type_vec_[imm.index]);
   1756             CALL_INTERFACE_IF_REACHABLE(SetLocal, value, imm);
   1757             len = 1 + imm.length;
   1758             break;
   1759           }
   1760           case kExprTeeLocal: {
   1761             LocalIndexImmediate<Decoder::kValidate> imm(this, this->pc_);
   1762             if (!this->Validate(this->pc_, imm)) break;
   1763             auto value = Pop(0, local_type_vec_[imm.index]);
   1764             auto* result = Push(value.type);
   1765             CALL_INTERFACE_IF_REACHABLE(TeeLocal, value, result, imm);
   1766             len = 1 + imm.length;
   1767             break;
   1768           }
   1769           case kExprDrop: {
   1770             auto value = Pop();
   1771             CALL_INTERFACE_IF_REACHABLE(Drop, value);
   1772             break;
   1773           }
   1774           case kExprGetGlobal: {
   1775             GlobalIndexImmediate<validate> imm(this, this->pc_);
   1776             len = 1 + imm.length;
   1777             if (!this->Validate(this->pc_, imm)) break;
   1778             auto* result = Push(imm.type);
   1779             CALL_INTERFACE_IF_REACHABLE(GetGlobal, result, imm);
   1780             break;
   1781           }
   1782           case kExprSetGlobal: {
   1783             GlobalIndexImmediate<validate> imm(this, this->pc_);
   1784             len = 1 + imm.length;
   1785             if (!this->Validate(this->pc_, imm)) break;
   1786             if (!VALIDATE(imm.global->mutability)) {
   1787               this->errorf(this->pc_, "immutable global #%u cannot be assigned",
   1788                            imm.index);
   1789               break;
   1790             }
   1791             auto value = Pop(0, imm.type);
   1792             CALL_INTERFACE_IF_REACHABLE(SetGlobal, value, imm);
   1793             break;
   1794           }
   1795           case kExprI32LoadMem8S:
   1796             len = 1 + DecodeLoadMem(LoadType::kI32Load8S);
   1797             break;
   1798           case kExprI32LoadMem8U:
   1799             len = 1 + DecodeLoadMem(LoadType::kI32Load8U);
   1800             break;
   1801           case kExprI32LoadMem16S:
   1802             len = 1 + DecodeLoadMem(LoadType::kI32Load16S);
   1803             break;
   1804           case kExprI32LoadMem16U:
   1805             len = 1 + DecodeLoadMem(LoadType::kI32Load16U);
   1806             break;
   1807           case kExprI32LoadMem:
   1808             len = 1 + DecodeLoadMem(LoadType::kI32Load);
   1809             break;
   1810           case kExprI64LoadMem8S:
   1811             len = 1 + DecodeLoadMem(LoadType::kI64Load8S);
   1812             break;
   1813           case kExprI64LoadMem8U:
   1814             len = 1 + DecodeLoadMem(LoadType::kI64Load8U);
   1815             break;
   1816           case kExprI64LoadMem16S:
   1817             len = 1 + DecodeLoadMem(LoadType::kI64Load16S);
   1818             break;
   1819           case kExprI64LoadMem16U:
   1820             len = 1 + DecodeLoadMem(LoadType::kI64Load16U);
   1821             break;
   1822           case kExprI64LoadMem32S:
   1823             len = 1 + DecodeLoadMem(LoadType::kI64Load32S);
   1824             break;
   1825           case kExprI64LoadMem32U:
   1826             len = 1 + DecodeLoadMem(LoadType::kI64Load32U);
   1827             break;
   1828           case kExprI64LoadMem:
   1829             len = 1 + DecodeLoadMem(LoadType::kI64Load);
   1830             break;
   1831           case kExprF32LoadMem:
   1832             len = 1 + DecodeLoadMem(LoadType::kF32Load);
   1833             break;
   1834           case kExprF64LoadMem:
   1835             len = 1 + DecodeLoadMem(LoadType::kF64Load);
   1836             break;
   1837           case kExprI32StoreMem8:
   1838             len = 1 + DecodeStoreMem(StoreType::kI32Store8);
   1839             break;
   1840           case kExprI32StoreMem16:
   1841             len = 1 + DecodeStoreMem(StoreType::kI32Store16);
   1842             break;
   1843           case kExprI32StoreMem:
   1844             len = 1 + DecodeStoreMem(StoreType::kI32Store);
   1845             break;
   1846           case kExprI64StoreMem8:
   1847             len = 1 + DecodeStoreMem(StoreType::kI64Store8);
   1848             break;
   1849           case kExprI64StoreMem16:
   1850             len = 1 + DecodeStoreMem(StoreType::kI64Store16);
   1851             break;
   1852           case kExprI64StoreMem32:
   1853             len = 1 + DecodeStoreMem(StoreType::kI64Store32);
   1854             break;
   1855           case kExprI64StoreMem:
   1856             len = 1 + DecodeStoreMem(StoreType::kI64Store);
   1857             break;
   1858           case kExprF32StoreMem:
   1859             len = 1 + DecodeStoreMem(StoreType::kF32Store);
   1860             break;
   1861           case kExprF64StoreMem:
   1862             len = 1 + DecodeStoreMem(StoreType::kF64Store);
   1863             break;
   1864           case kExprGrowMemory: {
   1865             if (!CheckHasMemory()) break;
   1866             MemoryIndexImmediate<validate> imm(this, this->pc_);
   1867             len = 1 + imm.length;
   1868             DCHECK_NOT_NULL(this->module_);
   1869             if (!VALIDATE(this->module_->origin == kWasmOrigin)) {
   1870               this->error("grow_memory is not supported for asmjs modules");
   1871               break;
   1872             }
   1873             auto value = Pop(0, kWasmI32);
   1874             auto* result = Push(kWasmI32);
   1875             CALL_INTERFACE_IF_REACHABLE(GrowMemory, value, result);
   1876             break;
   1877           }
   1878           case kExprMemorySize: {
   1879             if (!CheckHasMemory()) break;
   1880             MemoryIndexImmediate<validate> imm(this, this->pc_);
   1881             auto* result = Push(kWasmI32);
   1882             len = 1 + imm.length;
   1883             CALL_INTERFACE_IF_REACHABLE(CurrentMemoryPages, result);
   1884             break;
   1885           }
   1886           case kExprCallFunction: {
   1887             CallFunctionImmediate<validate> imm(this, this->pc_);
   1888             len = 1 + imm.length;
   1889             if (!this->Validate(this->pc_, imm)) break;
   1890             // TODO(clemensh): Better memory management.
   1891             PopArgs(imm.sig);
   1892             auto* returns = PushReturns(imm.sig);
   1893             CALL_INTERFACE_IF_REACHABLE(CallDirect, imm, args_.data(), returns);
   1894             break;
   1895           }
   1896           case kExprCallIndirect: {
   1897             CallIndirectImmediate<validate> imm(this, this->pc_);
   1898             len = 1 + imm.length;
   1899             if (!this->Validate(this->pc_, imm)) break;
   1900             auto index = Pop(0, kWasmI32);
   1901             PopArgs(imm.sig);
   1902             auto* returns = PushReturns(imm.sig);
   1903             CALL_INTERFACE_IF_REACHABLE(CallIndirect, index, imm, args_.data(),
   1904                                         returns);
   1905             break;
   1906           }
   1907           case kNumericPrefix: {
   1908             CHECK_PROTOTYPE_OPCODE(sat_f2i_conversions);
   1909             ++len;
   1910             byte numeric_index = this->template read_u8<validate>(
   1911                 this->pc_ + 1, "numeric index");
   1912             opcode = static_cast<WasmOpcode>(opcode << 8 | numeric_index);
   1913             TRACE_PART(TRACE_INST_FORMAT, startrel(this->pc_),
   1914                        WasmOpcodes::OpcodeName(opcode));
   1915             sig = WasmOpcodes::Signature(opcode);
   1916             if (sig == nullptr) {
   1917               this->errorf(this->pc_, "Unrecognized numeric opcode: %x\n",
   1918                            opcode);
   1919               return;
   1920             }
   1921             BuildSimpleOperator(opcode, sig);
   1922             break;
   1923           }
   1924           case kSimdPrefix: {
   1925             CHECK_PROTOTYPE_OPCODE(simd);
   1926             len++;
   1927             byte simd_index =
   1928                 this->template read_u8<validate>(this->pc_ + 1, "simd index");
   1929             opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index);
   1930             TRACE_PART(TRACE_INST_FORMAT, startrel(this->pc_),
   1931                        WasmOpcodes::OpcodeName(opcode));
   1932             len += DecodeSimdOpcode(opcode);
   1933             break;
   1934           }
   1935           case kAtomicPrefix: {
   1936             CHECK_PROTOTYPE_OPCODE(threads);
   1937             if (!CheckHasSharedMemory()) break;
   1938             len++;
   1939             byte atomic_index =
   1940                 this->template read_u8<validate>(this->pc_ + 1, "atomic index");
   1941             opcode = static_cast<WasmOpcode>(opcode << 8 | atomic_index);
   1942             TRACE_PART(TRACE_INST_FORMAT, startrel(this->pc_),
   1943                        WasmOpcodes::OpcodeName(opcode));
   1944             len += DecodeAtomicOpcode(opcode);
   1945             break;
   1946           }
   1947 // Note that prototype opcodes are not handled in the fastpath
   1948 // above this switch, to avoid checking a feature flag.
   1949 #define SIMPLE_PROTOTYPE_CASE(name, opc, sig) \
   1950   case kExpr##name: /* fallthrough */
   1951             FOREACH_SIMPLE_PROTOTYPE_OPCODE(SIMPLE_PROTOTYPE_CASE)
   1952 #undef SIMPLE_PROTOTYPE_CASE
   1953             BuildSimplePrototypeOperator(opcode);
   1954             break;
   1955           default: {
   1956             // Deal with special asmjs opcodes.
   1957             if (this->module_ != nullptr &&
   1958                 this->module_->origin == kAsmJsOrigin) {
   1959               sig = WasmOpcodes::AsmjsSignature(opcode);
   1960               if (sig) {
   1961                 BuildSimpleOperator(opcode, sig);
   1962               }
   1963             } else {
   1964               this->error("Invalid opcode");
   1965               return;
   1966             }
   1967           }
   1968         }
   1969       }
   1970 
   1971 #if DEBUG
   1972       if (FLAG_trace_wasm_decoder) {
   1973         TRACE_PART(" ");
   1974         for (Control& c : control_) {
   1975           switch (c.kind) {
   1976             case kControlIf:
   1977               TRACE_PART("I");
   1978               break;
   1979             case kControlBlock:
   1980               TRACE_PART("B");
   1981               break;
   1982             case kControlLoop:
   1983               TRACE_PART("L");
   1984               break;
   1985             case kControlTry:
   1986               TRACE_PART("T");
   1987               break;
   1988             default:
   1989               break;
   1990           }
   1991           if (c.start_merge.arity) TRACE_PART("%u-", c.start_merge.arity);
   1992           TRACE_PART("%u", c.end_merge.arity);
   1993           if (!c.reachable()) TRACE_PART("%c", c.unreachable() ? '*' : '#');
   1994         }
   1995         TRACE_PART(" | ");
   1996         for (size_t i = 0; i < stack_.size(); ++i) {
   1997           auto& val = stack_[i];
   1998           WasmOpcode opcode = static_cast<WasmOpcode>(*val.pc);
   1999           if (WasmOpcodes::IsPrefixOpcode(opcode)) {
   2000             opcode = static_cast<WasmOpcode>(opcode << 8 | *(val.pc + 1));
   2001           }
   2002           TRACE_PART(" %c@%d:%s", ValueTypes::ShortNameOf(val.type),
   2003                      static_cast<int>(val.pc - this->start_),
   2004                      WasmOpcodes::OpcodeName(opcode));
   2005           // If the decoder failed, don't try to decode the immediates, as this
   2006           // can trigger a DCHECK failure.
   2007           if (this->failed()) continue;
   2008           switch (opcode) {
   2009             case kExprI32Const: {
   2010               ImmI32Immediate<Decoder::kNoValidate> imm(this, val.pc);
   2011               TRACE_PART("[%d]", imm.value);
   2012               break;
   2013             }
   2014             case kExprGetLocal:
   2015             case kExprSetLocal:
   2016             case kExprTeeLocal: {
   2017               LocalIndexImmediate<Decoder::kNoValidate> imm(this, val.pc);
   2018               TRACE_PART("[%u]", imm.index);
   2019               break;
   2020             }
   2021             case kExprGetGlobal:
   2022             case kExprSetGlobal: {
   2023               GlobalIndexImmediate<Decoder::kNoValidate> imm(this, val.pc);
   2024               TRACE_PART("[%u]", imm.index);
   2025               break;
   2026             }
   2027             default:
   2028               break;
   2029           }
   2030         }
   2031       }
   2032 #endif
   2033       this->pc_ += len;
   2034     }  // end decode loop
   2035     if (!VALIDATE(this->pc_ == this->end_) && this->ok()) {
   2036       this->error("Beyond end of code");
   2037     }
   2038   }
   2039 
   2040   void EndControl() {
   2041     DCHECK(!control_.empty());
   2042     auto* current = &control_.back();
   2043     stack_.resize(current->stack_depth);
   2044     CALL_INTERFACE_IF_REACHABLE(EndControl, current);
   2045     current->reachability = kUnreachable;
   2046   }
   2047 
   2048   template<typename func>
   2049   void InitMerge(Merge<Value>* merge, uint32_t arity, func get_val) {
   2050     merge->arity = arity;
   2051     if (arity == 1) {
   2052       merge->vals.first = get_val(0);
   2053     } else if (arity > 1) {
   2054       merge->vals.array = zone_->NewArray<Value>(arity);
   2055       for (unsigned i = 0; i < arity; i++) {
   2056         merge->vals.array[i] = get_val(i);
   2057       }
   2058     }
   2059   }
   2060 
   2061   void SetBlockType(Control* c, BlockTypeImmediate<validate>& imm) {
   2062     DCHECK_EQ(imm.in_arity(), this->args_.size());
   2063     const byte* pc = this->pc_;
   2064     Value* args = this->args_.data();
   2065     InitMerge(&c->end_merge, imm.out_arity(), [pc, &imm](uint32_t i) {
   2066       return Value::New(pc, imm.out_type(i));
   2067     });
   2068     InitMerge(&c->start_merge, imm.in_arity(),
   2069               [args](uint32_t i) { return args[i]; });
   2070   }
   2071 
   2072   // Pops arguments as required by signature into {args_}.
   2073   V8_INLINE void PopArgs(FunctionSig* sig) {
   2074     int count = sig ? static_cast<int>(sig->parameter_count()) : 0;
   2075     args_.resize(count);
   2076     for (int i = count - 1; i >= 0; --i) {
   2077       args_[i] = Pop(i, sig->GetParam(i));
   2078     }
   2079   }
   2080 
   2081   ValueType GetReturnType(FunctionSig* sig) {
   2082     DCHECK_GE(1, sig->return_count());
   2083     return sig->return_count() == 0 ? kWasmStmt : sig->GetReturn();
   2084   }
   2085 
   2086   Control* PushControl(Control&& new_control) {
   2087     Reachability reachability =
   2088         control_.empty() ? kReachable : control_.back().innerReachability();
   2089     control_.emplace_back(std::move(new_control));
   2090     Control* c = &control_.back();
   2091     c->reachability = reachability;
   2092     c->start_merge.reached = c->reachable();
   2093     return c;
   2094   }
   2095 
   2096   Control* PushBlock() {
   2097     return PushControl(Control::Block(this->pc_, stack_size()));
   2098   }
   2099   Control* PushLoop() {
   2100     return PushControl(Control::Loop(this->pc_, stack_size()));
   2101   }
   2102   Control* PushIf() {
   2103     return PushControl(Control::If(this->pc_, stack_size()));
   2104   }
   2105   Control* PushTry() {
   2106     // current_catch_ = static_cast<int32_t>(control_.size() - 1);
   2107     return PushControl(Control::Try(this->pc_, stack_size()));
   2108   }
   2109 
   2110   void PopControl(Control* c) {
   2111     DCHECK_EQ(c, &control_.back());
   2112     CALL_INTERFACE_IF_PARENT_REACHABLE(PopControl, c);
   2113     bool reached = c->end_merge.reached;
   2114     control_.pop_back();
   2115     // If the parent block was reachable before, but the popped control does not
   2116     // return to here, this block becomes indirectly unreachable.
   2117     if (!control_.empty() && !reached && control_.back().reachable()) {
   2118       control_.back().reachability = kSpecOnlyReachable;
   2119     }
   2120   }
   2121 
   2122   int DecodeLoadMem(LoadType type, int prefix_len = 0) {
   2123     if (!CheckHasMemory()) return 0;
   2124     MemoryAccessImmediate<validate> imm(this, this->pc_ + prefix_len,
   2125                                         type.size_log_2());
   2126     auto index = Pop(0, kWasmI32);
   2127     auto* result = Push(type.value_type());
   2128     CALL_INTERFACE_IF_REACHABLE(LoadMem, type, imm, index, result);
   2129     return imm.length;
   2130   }
   2131 
   2132   int DecodeStoreMem(StoreType store, int prefix_len = 0) {
   2133     if (!CheckHasMemory()) return 0;
   2134     MemoryAccessImmediate<validate> imm(this, this->pc_ + prefix_len,
   2135                                         store.size_log_2());
   2136     auto value = Pop(1, store.value_type());
   2137     auto index = Pop(0, kWasmI32);
   2138     CALL_INTERFACE_IF_REACHABLE(StoreMem, store, imm, index, value);
   2139     return imm.length;
   2140   }
   2141 
   2142   unsigned SimdExtractLane(WasmOpcode opcode, ValueType type) {
   2143     SimdLaneImmediate<validate> imm(this, this->pc_);
   2144     if (this->Validate(this->pc_, opcode, imm)) {
   2145       Value inputs[] = {Pop(0, kWasmS128)};
   2146       auto* result = Push(type);
   2147       CALL_INTERFACE_IF_REACHABLE(SimdLaneOp, opcode, imm, ArrayVector(inputs),
   2148                                   result);
   2149     }
   2150     return imm.length;
   2151   }
   2152 
   2153   unsigned SimdReplaceLane(WasmOpcode opcode, ValueType type) {
   2154     SimdLaneImmediate<validate> imm(this, this->pc_);
   2155     if (this->Validate(this->pc_, opcode, imm)) {
   2156       Value inputs[2];
   2157       inputs[1] = Pop(1, type);
   2158       inputs[0] = Pop(0, kWasmS128);
   2159       auto* result = Push(kWasmS128);
   2160       CALL_INTERFACE_IF_REACHABLE(SimdLaneOp, opcode, imm, ArrayVector(inputs),
   2161                                   result);
   2162     }
   2163     return imm.length;
   2164   }
   2165 
   2166   unsigned SimdShiftOp(WasmOpcode opcode) {
   2167     SimdShiftImmediate<validate> imm(this, this->pc_);
   2168     if (this->Validate(this->pc_, opcode, imm)) {
   2169       auto input = Pop(0, kWasmS128);
   2170       auto* result = Push(kWasmS128);
   2171       CALL_INTERFACE_IF_REACHABLE(SimdShiftOp, opcode, imm, input, result);
   2172     }
   2173     return imm.length;
   2174   }
   2175 
   2176   unsigned Simd8x16ShuffleOp() {
   2177     Simd8x16ShuffleImmediate<validate> imm(this, this->pc_);
   2178     if (this->Validate(this->pc_, imm)) {
   2179       auto input1 = Pop(1, kWasmS128);
   2180       auto input0 = Pop(0, kWasmS128);
   2181       auto* result = Push(kWasmS128);
   2182       CALL_INTERFACE_IF_REACHABLE(Simd8x16ShuffleOp, imm, input0, input1,
   2183                                   result);
   2184     }
   2185     return 16;
   2186   }
   2187 
   2188   unsigned DecodeSimdOpcode(WasmOpcode opcode) {
   2189     unsigned len = 0;
   2190     switch (opcode) {
   2191       case kExprF32x4ExtractLane: {
   2192         len = SimdExtractLane(opcode, kWasmF32);
   2193         break;
   2194       }
   2195       case kExprI32x4ExtractLane:
   2196       case kExprI16x8ExtractLane:
   2197       case kExprI8x16ExtractLane: {
   2198         len = SimdExtractLane(opcode, kWasmI32);
   2199         break;
   2200       }
   2201       case kExprF32x4ReplaceLane: {
   2202         len = SimdReplaceLane(opcode, kWasmF32);
   2203         break;
   2204       }
   2205       case kExprI32x4ReplaceLane:
   2206       case kExprI16x8ReplaceLane:
   2207       case kExprI8x16ReplaceLane: {
   2208         len = SimdReplaceLane(opcode, kWasmI32);
   2209         break;
   2210       }
   2211       case kExprI32x4Shl:
   2212       case kExprI32x4ShrS:
   2213       case kExprI32x4ShrU:
   2214       case kExprI16x8Shl:
   2215       case kExprI16x8ShrS:
   2216       case kExprI16x8ShrU:
   2217       case kExprI8x16Shl:
   2218       case kExprI8x16ShrS:
   2219       case kExprI8x16ShrU: {
   2220         len = SimdShiftOp(opcode);
   2221         break;
   2222       }
   2223       case kExprS8x16Shuffle: {
   2224         len = Simd8x16ShuffleOp();
   2225         break;
   2226       }
   2227       case kExprS128LoadMem:
   2228         len = DecodeLoadMem(LoadType::kS128Load, 1);
   2229         break;
   2230       case kExprS128StoreMem:
   2231         len = DecodeStoreMem(StoreType::kS128Store, 1);
   2232         break;
   2233       default: {
   2234         FunctionSig* sig = WasmOpcodes::Signature(opcode);
   2235         if (!VALIDATE(sig != nullptr)) {
   2236           this->error("invalid simd opcode");
   2237           break;
   2238         }
   2239         PopArgs(sig);
   2240         auto* results =
   2241             sig->return_count() == 0 ? nullptr : Push(GetReturnType(sig));
   2242         CALL_INTERFACE_IF_REACHABLE(SimdOp, opcode, vec2vec(args_), results);
   2243       }
   2244     }
   2245     return len;
   2246   }
   2247 
   2248   unsigned DecodeAtomicOpcode(WasmOpcode opcode) {
   2249     unsigned len = 0;
   2250     ValueType ret_type;
   2251     FunctionSig* sig = WasmOpcodes::Signature(opcode);
   2252     if (sig != nullptr) {
   2253       MachineType memtype;
   2254       switch (opcode) {
   2255 #define CASE_ATOMIC_STORE_OP(Name, Type) \
   2256   case kExpr##Name: {                    \
   2257     memtype = MachineType::Type();       \
   2258     ret_type = kWasmStmt;                \
   2259     break;                               \
   2260   }
   2261         ATOMIC_STORE_OP_LIST(CASE_ATOMIC_STORE_OP)
   2262 #undef CASE_ATOMIC_OP
   2263 #define CASE_ATOMIC_OP(Name, Type) \
   2264   case kExpr##Name: {              \
   2265     memtype = MachineType::Type(); \
   2266     ret_type = GetReturnType(sig); \
   2267     break;                         \
   2268   }
   2269         ATOMIC_OP_LIST(CASE_ATOMIC_OP)
   2270 #undef CASE_ATOMIC_OP
   2271         default:
   2272           this->error("invalid atomic opcode");
   2273           return 0;
   2274       }
   2275       MemoryAccessImmediate<validate> imm(
   2276           this, this->pc_ + 1, ElementSizeLog2Of(memtype.representation()));
   2277       len += imm.length;
   2278       PopArgs(sig);
   2279       auto result = ret_type == kWasmStmt ? nullptr : Push(GetReturnType(sig));
   2280       CALL_INTERFACE_IF_REACHABLE(AtomicOp, opcode, vec2vec(args_), imm,
   2281                                   result);
   2282     } else {
   2283       this->error("invalid atomic opcode");
   2284     }
   2285     return len;
   2286   }
   2287 
   2288   void DoReturn(Control* c, bool implicit) {
   2289     int return_count = static_cast<int>(this->sig_->return_count());
   2290     args_.resize(return_count);
   2291 
   2292     // Pop return values off the stack in reverse order.
   2293     for (int i = return_count - 1; i >= 0; --i) {
   2294       args_[i] = Pop(i, this->sig_->GetReturn(i));
   2295     }
   2296 
   2297     // Simulate that an implicit return morally comes after the current block.
   2298     if (implicit && c->end_merge.reached) c->reachability = kReachable;
   2299     CALL_INTERFACE_IF_REACHABLE(DoReturn, vec2vec(args_), implicit);
   2300 
   2301     EndControl();
   2302   }
   2303 
   2304   inline Value* Push(ValueType type) {
   2305     DCHECK_NE(kWasmStmt, type);
   2306     stack_.push_back(Value::New(this->pc_, type));
   2307     return &stack_.back();
   2308   }
   2309 
   2310   void PushMergeValues(Control* c, Merge<Value>* merge) {
   2311     DCHECK_EQ(c, &control_.back());
   2312     DCHECK(merge == &c->start_merge || merge == &c->end_merge);
   2313     stack_.resize(c->stack_depth);
   2314     if (merge->arity == 1) {
   2315       stack_.push_back(merge->vals.first);
   2316     } else {
   2317       for (unsigned i = 0; i < merge->arity; i++) {
   2318         stack_.push_back(merge->vals.array[i]);
   2319       }
   2320     }
   2321     DCHECK_EQ(c->stack_depth + merge->arity, stack_.size());
   2322   }
   2323 
   2324   Value* PushReturns(FunctionSig* sig) {
   2325     size_t return_count = sig->return_count();
   2326     if (return_count == 0) return nullptr;
   2327     size_t old_size = stack_.size();
   2328     for (size_t i = 0; i < return_count; ++i) {
   2329       Push(sig->GetReturn(i));
   2330     }
   2331     return stack_.data() + old_size;
   2332   }
   2333 
   2334   Value Pop(int index, ValueType expected) {
   2335     auto val = Pop();
   2336     if (!VALIDATE(val.type == expected || val.type == kWasmVar ||
   2337                   expected == kWasmVar)) {
   2338       this->errorf(val.pc, "%s[%d] expected type %s, found %s of type %s",
   2339                    SafeOpcodeNameAt(this->pc_), index,
   2340                    ValueTypes::TypeName(expected), SafeOpcodeNameAt(val.pc),
   2341                    ValueTypes::TypeName(val.type));
   2342     }
   2343     return val;
   2344   }
   2345 
   2346   Value Pop() {
   2347     DCHECK(!control_.empty());
   2348     uint32_t limit = control_.back().stack_depth;
   2349     if (stack_.size() <= limit) {
   2350       // Popping past the current control start in reachable code.
   2351       if (!VALIDATE(control_.back().unreachable())) {
   2352         this->errorf(this->pc_, "%s found empty stack",
   2353                      SafeOpcodeNameAt(this->pc_));
   2354       }
   2355       return Value::Unreachable(this->pc_);
   2356     }
   2357     auto val = stack_.back();
   2358     stack_.pop_back();
   2359     return val;
   2360   }
   2361 
   2362   int startrel(const byte* ptr) { return static_cast<int>(ptr - this->start_); }
   2363 
   2364   void FallThruTo(Control* c) {
   2365     DCHECK_EQ(c, &control_.back());
   2366     if (!TypeCheckFallThru(c)) return;
   2367     if (!c->reachable()) return;
   2368 
   2369     if (!c->is_loop()) CALL_INTERFACE(FallThruTo, c);
   2370     c->end_merge.reached = true;
   2371   }
   2372 
   2373   bool TypeCheckMergeValues(Control* c, Merge<Value>* merge) {
   2374     DCHECK(merge == &c->start_merge || merge == &c->end_merge);
   2375     DCHECK_GE(stack_.size(), c->stack_depth + merge->arity);
   2376     // Typecheck the topmost {merge->arity} values on the stack.
   2377     for (uint32_t i = 0; i < merge->arity; ++i) {
   2378       auto& val = GetMergeValueFromStack(c, merge, i);
   2379       auto& old = (*merge)[i];
   2380       if (val.type != old.type) {
   2381         // If {val.type} is polymorphic, which results from unreachable, make
   2382         // it more specific by using the merge value's expected type.
   2383         // If it is not polymorphic, this is a type error.
   2384         if (!VALIDATE(val.type == kWasmVar)) {
   2385           this->errorf(
   2386               this->pc_, "type error in merge[%u] (expected %s, got %s)", i,
   2387               ValueTypes::TypeName(old.type), ValueTypes::TypeName(val.type));
   2388           return false;
   2389         }
   2390         val.type = old.type;
   2391       }
   2392     }
   2393 
   2394     return true;
   2395   }
   2396 
   2397   bool TypeCheckFallThru(Control* c) {
   2398     DCHECK_EQ(c, &control_.back());
   2399     if (!validate) return true;
   2400     uint32_t expected = c->end_merge.arity;
   2401     DCHECK_GE(stack_.size(), c->stack_depth);
   2402     uint32_t actual = static_cast<uint32_t>(stack_.size()) - c->stack_depth;
   2403     // Fallthrus must match the arity of the control exactly.
   2404     if (!InsertUnreachablesIfNecessary(expected, actual) || actual > expected) {
   2405       this->errorf(
   2406           this->pc_,
   2407           "expected %u elements on the stack for fallthru to @%d, found %u",
   2408           expected, startrel(c->pc), actual);
   2409       return false;
   2410     }
   2411 
   2412     return TypeCheckMergeValues(c, &c->end_merge);
   2413   }
   2414 
   2415   bool TypeCheckBreak(Control* c) {
   2416     // Breaks must have at least the number of values expected; can have more.
   2417     uint32_t expected = c->br_merge()->arity;
   2418     DCHECK_GE(stack_.size(), control_.back().stack_depth);
   2419     uint32_t actual =
   2420         static_cast<uint32_t>(stack_.size()) - control_.back().stack_depth;
   2421     if (!InsertUnreachablesIfNecessary(expected, actual)) {
   2422       this->errorf(this->pc_,
   2423                    "expected %u elements on the stack for br to @%d, found %u",
   2424                    expected, startrel(c->pc), actual);
   2425       return false;
   2426     }
   2427     return TypeCheckMergeValues(c, c->br_merge());
   2428   }
   2429 
   2430   inline bool InsertUnreachablesIfNecessary(uint32_t expected,
   2431                                             uint32_t actual) {
   2432     if (V8_LIKELY(actual >= expected)) {
   2433       return true;  // enough actual values are there.
   2434     }
   2435     if (!VALIDATE(control_.back().unreachable())) {
   2436       // There aren't enough values on the stack.
   2437       return false;
   2438     }
   2439     // A slow path. When the actual number of values on the stack is less
   2440     // than the expected number of values and the current control is
   2441     // unreachable, insert unreachable values below the actual values.
   2442     // This simplifies {TypeCheckMergeValues}.
   2443     auto pos = stack_.begin() + (stack_.size() - actual);
   2444     stack_.insert(pos, (expected - actual), Value::Unreachable(this->pc_));
   2445     return true;
   2446   }
   2447 
   2448   virtual void onFirstError() {
   2449     this->end_ = this->pc_;  // Terminate decoding loop.
   2450     TRACE(" !%s\n", this->error_msg_.c_str());
   2451     CALL_INTERFACE(OnFirstError);
   2452   }
   2453 
   2454   void BuildSimplePrototypeOperator(WasmOpcode opcode) {
   2455     if (WasmOpcodes::IsSignExtensionOpcode(opcode)) {
   2456       RET_ON_PROTOTYPE_OPCODE(se);
   2457     }
   2458     if (WasmOpcodes::IsAnyRefOpcode(opcode)) {
   2459       RET_ON_PROTOTYPE_OPCODE(anyref);
   2460     }
   2461     FunctionSig* sig = WasmOpcodes::Signature(opcode);
   2462     BuildSimpleOperator(opcode, sig);
   2463   }
   2464 
   2465   inline void BuildSimpleOperator(WasmOpcode opcode, FunctionSig* sig) {
   2466     switch (sig->parameter_count()) {
   2467       case 1: {
   2468         auto val = Pop(0, sig->GetParam(0));
   2469         auto* ret =
   2470             sig->return_count() == 0 ? nullptr : Push(sig->GetReturn(0));
   2471         CALL_INTERFACE_IF_REACHABLE(UnOp, opcode, sig, val, ret);
   2472         break;
   2473       }
   2474       case 2: {
   2475         auto rval = Pop(1, sig->GetParam(1));
   2476         auto lval = Pop(0, sig->GetParam(0));
   2477         auto* ret =
   2478             sig->return_count() == 0 ? nullptr : Push(sig->GetReturn(0));
   2479         CALL_INTERFACE_IF_REACHABLE(BinOp, opcode, sig, lval, rval, ret);
   2480         break;
   2481       }
   2482       default:
   2483         UNREACHABLE();
   2484     }
   2485   }
   2486 };
   2487 
   2488 #undef CALL_INTERFACE
   2489 #undef CALL_INTERFACE_IF_REACHABLE
   2490 #undef CALL_INTERFACE_IF_PARENT_REACHABLE
   2491 
   2492 class EmptyInterface {
   2493  public:
   2494   static constexpr Decoder::ValidateFlag validate = Decoder::kValidate;
   2495   using Value = ValueBase;
   2496   using Control = ControlBase<Value>;
   2497   using FullDecoder = WasmFullDecoder<validate, EmptyInterface>;
   2498 
   2499 #define DEFINE_EMPTY_CALLBACK(name, ...) \
   2500   void name(FullDecoder* decoder, ##__VA_ARGS__) {}
   2501   INTERFACE_FUNCTIONS(DEFINE_EMPTY_CALLBACK)
   2502 #undef DEFINE_EMPTY_CALLBACK
   2503 };
   2504 
   2505 #undef TRACE
   2506 #undef TRACE_INST_FORMAT
   2507 #undef VALIDATE
   2508 #undef CHECK_PROTOTYPE_OPCODE
   2509 #undef OPCODE_ERROR
   2510 
   2511 }  // namespace wasm
   2512 }  // namespace internal
   2513 }  // namespace v8
   2514 
   2515 #endif  // V8_WASM_FUNCTION_BODY_DECODER_IMPL_H_
   2516