// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_WASM_FUNCTION_BODY_DECODER_IMPL_H_
#define V8_WASM_FUNCTION_BODY_DECODER_IMPL_H_

// Do only include this header for implementing new Interface of the
// WasmFullDecoder.

#include <inttypes.h>

#include "src/base/platform/elapsed-timer.h"
#include "src/base/small-vector.h"
#include "src/utils/bit-vector.h"
#include "src/wasm/decoder.h"
#include "src/wasm/function-body-decoder.h"
#include "src/wasm/value-type.h"
#include "src/wasm/wasm-features.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-opcodes.h"
#include "src/wasm/wasm-subtyping.h"

namespace v8 {
namespace internal {
namespace wasm {

struct WasmGlobal;
struct WasmException;

#define TRACE(...)                                    \
  do {                                                \
    if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \
  } while (false)

#define TRACE_INST_FORMAT "  @%-8d #%-20s|"

// Return the evaluation of `condition` if validate==true, DCHECK that it's
// true and always return true otherwise.
#define VALIDATE(condition)                \
  (validate ? V8_LIKELY(condition) : [&] { \
    DCHECK(condition);                     \
    return true;                           \
  }())

#define CHECK_PROTOTYPE_OPCODE(feat)                                       \
  DCHECK(this->module_->origin == kWasmOrigin);                            \
  if (!VALIDATE(this->enabled_.has_##feat())) {                            \
    this->DecodeError(                                                     \
        "Invalid opcode 0x%x (enable with --experimental-wasm-" #feat ")", \
        opcode);                                                           \
    return 0;                                                              \
  }                                                                        \
  this->detected_->Add(kFeature_##feat);

#define ATOMIC_OP_LIST(V)                \
  V(AtomicNotify, Uint32)                \
  V(I32AtomicWait, Uint32)               \
  V(I64AtomicWait, Uint64)               \
  V(I32AtomicLoad, Uint32)               \
  V(I64AtomicLoad, Uint64)               \
  V(I32AtomicLoad8U, Uint8)              \
  V(I32AtomicLoad16U, Uint16)            \
  V(I64AtomicLoad8U, Uint8)              \
  V(I64AtomicLoad16U, Uint16)            \
  V(I64AtomicLoad32U, Uint32)            \
  V(I32AtomicAdd, Uint32)                \
  V(I32AtomicAdd8U, Uint8)               \
  V(I32AtomicAdd16U, Uint16)             \
  V(I64AtomicAdd, Uint64)                \
  V(I64AtomicAdd8U, Uint8)               \
  V(I64AtomicAdd16U, Uint16)             \
  V(I64AtomicAdd32U, Uint32)             \
  V(I32AtomicSub, Uint32)                \
  V(I64AtomicSub, Uint64)                \
  V(I32AtomicSub8U, Uint8)               \
  V(I32AtomicSub16U, Uint16)             \
  V(I64AtomicSub8U, Uint8)               \
  V(I64AtomicSub16U, Uint16)             \
  V(I64AtomicSub32U, Uint32)             \
  V(I32AtomicAnd, Uint32)                \
  V(I64AtomicAnd, Uint64)                \
  V(I32AtomicAnd8U, Uint8)               \
  V(I32AtomicAnd16U, Uint16)             \
  V(I64AtomicAnd8U, Uint8)               \
  V(I64AtomicAnd16U, Uint16)             \
  V(I64AtomicAnd32U, Uint32)             \
  V(I32AtomicOr, Uint32)                 \
  V(I64AtomicOr, Uint64)                 \
  V(I32AtomicOr8U, Uint8)                \
  V(I32AtomicOr16U, Uint16)              \
  V(I64AtomicOr8U, Uint8)                \
  V(I64AtomicOr16U, Uint16)              \
  V(I64AtomicOr32U, Uint32)              \
  V(I32AtomicXor, Uint32)                \
  V(I64AtomicXor, Uint64)                \
  V(I32AtomicXor8U, Uint8)               \
  V(I32AtomicXor16U, Uint16)             \
  V(I64AtomicXor8U, Uint8)               \
  V(I64AtomicXor16U, Uint16)             \
  V(I64AtomicXor32U, Uint32)             \
  V(I32AtomicExchange, Uint32)           \
  V(I64AtomicExchange, Uint64)           \
  V(I32AtomicExchange8U, Uint8)          \
  V(I32AtomicExchange16U, Uint16)        \
  V(I64AtomicExchange8U, Uint8)          \
  V(I64AtomicExchange16U, Uint16)        \
  V(I64AtomicExchange32U, Uint32)        \
  V(I32AtomicCompareExchange, Uint32)    \
  V(I64AtomicCompareExchange, Uint64)    \
  V(I32AtomicCompareExchange8U, Uint8)   \
  V(I32AtomicCompareExchange16U, Uint16) \
  V(I64AtomicCompareExchange8U, Uint8)   \
  V(I64AtomicCompareExchange16U, Uint16) \
  V(I64AtomicCompareExchange32U, Uint32)

#define ATOMIC_STORE_OP_LIST(V) \
  V(I32AtomicStore, Uint32)     \
  V(I64AtomicStore, Uint64)     \
  V(I32AtomicStore8U, Uint8)    \
  V(I32AtomicStore16U, Uint16)  \
  V(I64AtomicStore8U, Uint8)    \
  V(I64AtomicStore16U, Uint16)  \
  V(I64AtomicStore32U, Uint32)

// Decoder error with explicit PC and format arguments.
template <Decoder::ValidateFlag validate, typename... Args>
void DecodeError(Decoder* decoder, const byte* pc, const char* str,
                 Args&&... args) {
  CHECK(validate == Decoder::kFullValidation ||
        validate == Decoder::kBooleanValidation);
  STATIC_ASSERT(sizeof...(Args) > 0);
  if (validate == Decoder::kBooleanValidation) {
    decoder->MarkError();
  } else {
    decoder->errorf(pc, str, std::forward<Args>(args)...);
  }
}

// Decoder error with explicit PC and no format arguments.
template <Decoder::ValidateFlag validate>
void DecodeError(Decoder* decoder, const byte* pc, const char* str) {
  CHECK(validate == Decoder::kFullValidation ||
        validate == Decoder::kBooleanValidation);
  if (validate == Decoder::kBooleanValidation) {
    decoder->MarkError();
  } else {
    decoder->error(pc, str);
  }
}

// Decoder error without explicit PC, but with format arguments.
template <Decoder::ValidateFlag validate, typename... Args>
void DecodeError(Decoder* decoder, const char* str, Args&&... args) {
  CHECK(validate == Decoder::kFullValidation ||
        validate == Decoder::kBooleanValidation);
  STATIC_ASSERT(sizeof...(Args) > 0);
  if (validate == Decoder::kBooleanValidation) {
    decoder->MarkError();
  } else {
    decoder->errorf(str, std::forward<Args>(args)...);
  }
}

// Decoder error without explicit PC and without format arguments.
template <Decoder::ValidateFlag validate>
void DecodeError(Decoder* decoder, const char* str) {
  CHECK(validate == Decoder::kFullValidation ||
        validate == Decoder::kBooleanValidation);
  if (validate == Decoder::kBooleanValidation) {
    decoder->MarkError();
  } else {
    decoder->error(str);
  }
}

namespace value_type_reader {

V8_INLINE WasmFeature feature_for_heap_type(HeapType heap_type) {
  switch (heap_type.representation()) {
    case HeapType::kFunc:
    case HeapType::kExtern:
      return WasmFeature::kFeature_reftypes;
    case HeapType::kExn:
      return WasmFeature::kFeature_eh;
    case HeapType::kEq:
    case HeapType::kI31:
      return WasmFeature::kFeature_gc;
    default:
      UNREACHABLE();
  }
}

template <Decoder::ValidateFlag validate>
HeapType read_heap_type(Decoder* decoder, const byte* pc,
                        uint32_t* const length, const WasmFeatures& enabled) {
  int64_t heap_index = decoder->read_i33v<validate>(pc, length, "heap type");
  if (heap_index < 0) {
    int64_t min_1_byte_leb128 = -64;
    if (heap_index < min_1_byte_leb128) {
      DecodeError<validate>(decoder, pc, "Unknown heap type %" PRId64,
                            heap_index);
      return HeapType(HeapType::kBottom);
    }
    uint8_t uint_7_mask = 0x7F;
    uint8_t code = static_cast<ValueTypeCode>(heap_index) & uint_7_mask;
    switch (code) {
      case kFuncRefCode:
      case kExnRefCode:
      case kEqRefCode:
      case kExternRefCode:
      case kI31RefCode: {
        HeapType result = HeapType::from_code(code);
        if (!VALIDATE(enabled.contains(feature_for_heap_type(result)))) {
          DecodeError<validate>(
              decoder, pc,
              "invalid heap type '%s', enable with --experimental-wasm-%s",
              result.name().c_str(),
              WasmFeatures::name_for_feature(feature_for_heap_type(result)));
          return HeapType(HeapType::kBottom);
        }
        return result;
      }
      default:
        DecodeError<validate>(decoder, pc, "Unknown heap type %" PRId64,
                              heap_index);
        return HeapType(HeapType::kBottom);
    }
    UNREACHABLE();
  } else {
    if (!VALIDATE(enabled.has_typed_funcref())) {
      DecodeError<validate>(decoder, pc,
                            "Invalid indexed heap type, enable with "
                            "--experimental-wasm-typed-funcref");
      return HeapType(HeapType::kBottom);
    }
    uint32_t type_index = static_cast<uint32_t>(heap_index);
    if (!VALIDATE(type_index < kV8MaxWasmTypes)) {
      DecodeError<validate>(
          decoder, pc,
          "Type index %u is greater than the maximum number %zu "
          "of type definitions supported by V8",
          type_index, kV8MaxWasmTypes);
      return HeapType(HeapType::kBottom);
    }
    return HeapType(type_index);
  }
}

// Read a value type starting at address 'pc' in 'decoder'.
// No bytes are consumed. The result is written into the 'result' parameter.
// Returns the amount of bytes read, or 0 if decoding failed.
// Registers an error if the type opcode is invalid iff validate is set.
template <Decoder::ValidateFlag validate>
ValueType read_value_type(Decoder* decoder, const byte* pc,
                          uint32_t* const length, const WasmFeatures& enabled) {
  *length = 1;
  byte val = decoder->read_u8<validate>(pc, "value type opcode");
  if (decoder->failed()) {
    return kWasmBottom;
  }
  ValueTypeCode code = static_cast<ValueTypeCode>(val);
  switch (code) {
    case kFuncRefCode:
    case kExnRefCode:
    case kEqRefCode:
    case kExternRefCode:
    case kI31RefCode: {
      HeapType heap_type = HeapType::from_code(code);
      ValueType result = ValueType::Ref(
          heap_type, code == kI31RefCode ? kNonNullable : kNullable);
      if (!VALIDATE(enabled.contains(feature_for_heap_type(heap_type)))) {
        DecodeError<validate>(
            decoder, pc,
            "invalid value type '%s', enable with --experimental-wasm-%s",
            result.name().c_str(),
            WasmFeatures::name_for_feature(feature_for_heap_type(heap_type)));
        return kWasmBottom;
      }
      return result;
    }
    case kI32Code:
      return kWasmI32;
    case kI64Code:
      return kWasmI64;
    case kF32Code:
      return kWasmF32;
    case kF64Code:
      return kWasmF64;
    case kRefCode:
    case kOptRefCode: {
      Nullability nullability = code == kOptRefCode ? kNullable : kNonNullable;
      if (!VALIDATE(enabled.has_typed_funcref())) {
        DecodeError<validate>(decoder, pc,
                              "Invalid type '(ref%s <heaptype>)', enable with "
                              "--experimental-wasm-typed-funcref",
                              nullability == kNullable ? " null" : "");
        return kWasmBottom;
      }
      HeapType heap_type =
          read_heap_type<validate>(decoder, pc + 1, length, enabled);
      *length += 1;
      return heap_type.is_bottom() ? kWasmBottom
                                   : ValueType::Ref(heap_type, nullability);
    }
    case kRttCode: {
      if (!VALIDATE(enabled.has_gc())) {
        DecodeError<validate>(
            decoder, pc,
            "invalid value type 'rtt', enable with --experimental-wasm-gc");
        return kWasmBottom;
      }
      uint32_t depth_length;
      uint32_t depth =
          decoder->read_u32v<validate>(pc + 1, &depth_length, "depth");
      if (!VALIDATE(depth <= kV8MaxRttSubtypingDepth)) {
        DecodeError<validate>(
            decoder, pc,
            "subtyping depth %u is greater than the maximum depth "
            "%u supported by V8",
            depth, kV8MaxRttSubtypingDepth);
        return kWasmBottom;
      }
      HeapType heap_type = read_heap_type<validate>(
          decoder, pc + depth_length + 1, length, enabled);
      *length += depth_length + 1;
      return heap_type.is_bottom() ? kWasmBottom
                                   : ValueType::Rtt(heap_type, depth);
    }
    case kS128Code: {
      if (!VALIDATE(enabled.has_simd())) {
        DecodeError<validate>(
            decoder, pc,
            "invalid value type 's128', enable with --experimental-wasm-simd");
        return kWasmBottom;
      }
      return kWasmS128;
    }
    // Although these codes are included in ValueTypeCode, they technically
    // do not correspond to value types and are only used in specific
    // contexts. The caller of this function is responsible for handling them.
    case kVoidCode:
    case kI8Code:
    case kI16Code:
      return kWasmBottom;
  }
  // Anything that doesn't match an enumeration value is an invalid type code.
  return kWasmBottom;
}
}  // namespace value_type_reader

// Helpers for decoding different kinds of immediates which follow bytecodes.
template <Decoder::ValidateFlag validate>
struct LocalIndexImmediate {
  uint32_t index;
  uint32_t length;

  inline LocalIndexImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "local index");
  }
};

template <Decoder::ValidateFlag validate>
struct ExceptionIndexImmediate {
  uint32_t index;
  const WasmException* exception = nullptr;
  uint32_t length;

  inline ExceptionIndexImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "exception index");
  }
};

template <Decoder::ValidateFlag validate>
struct ImmI32Immediate {
  int32_t value;
  uint32_t length;
  inline ImmI32Immediate(Decoder* decoder, const byte* pc) {
    value = decoder->read_i32v<validate>(pc, &length, "immi32");
  }
};

template <Decoder::ValidateFlag validate>
struct ImmI64Immediate {
  int64_t value;
  uint32_t length;
  inline ImmI64Immediate(Decoder* decoder, const byte* pc) {
    value = decoder->read_i64v<validate>(pc, &length, "immi64");
  }
};

template <Decoder::ValidateFlag validate>
struct ImmF32Immediate {
  float value;
  uint32_t length = 4;
  inline ImmF32Immediate(Decoder* decoder, const byte* pc) {
    // We can't use bit_cast here because calling any helper function that
    // returns a float would potentially flip NaN bits per C++ semantics, so we
    // have to inline the memcpy call directly.
    uint32_t tmp = decoder->read_u32<validate>(pc, "immf32");
    memcpy(&value, &tmp, sizeof(value));
  }
};

template <Decoder::ValidateFlag validate>
struct ImmF64Immediate {
  double value;
  uint32_t length = 8;
  inline ImmF64Immediate(Decoder* decoder, const byte* pc) {
    // Avoid bit_cast because it might not preserve the signalling bit of a NaN.
    uint64_t tmp = decoder->read_u64<validate>(pc, "immf64");
    memcpy(&value, &tmp, sizeof(value));
  }
};

template <Decoder::ValidateFlag validate>
struct GlobalIndexImmediate {
  uint32_t index;
  ValueType type = kWasmStmt;
  const WasmGlobal* global = nullptr;
  uint32_t length;

  inline GlobalIndexImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "global index");
  }
};

template <Decoder::ValidateFlag validate>
struct SelectTypeImmediate {
  uint32_t length;
  ValueType type;

  inline SelectTypeImmediate(const WasmFeatures& enabled, Decoder* decoder,
                             const byte* pc) {
    uint8_t num_types =
        decoder->read_u32v<validate>(pc, &length, "number of select types");
    if (!VALIDATE(num_types == 1)) {
      DecodeError<validate>(
          decoder, pc + 1,
          "Invalid number of types. Select accepts exactly one type");
      return;
    }
    uint32_t type_length;
    type = value_type_reader::read_value_type<validate>(decoder, pc + length,
                                                        &type_length, enabled);
    length += type_length;
    if (!VALIDATE(type != kWasmBottom)) {
      DecodeError<validate>(decoder, pc + 1, "invalid select type");
    }
  }
};

template <Decoder::ValidateFlag validate>
struct BlockTypeImmediate {
  uint32_t length = 1;
  ValueType type = kWasmStmt;
  uint32_t sig_index = 0;
  const FunctionSig* sig = nullptr;

  inline BlockTypeImmediate(const WasmFeatures& enabled, Decoder* decoder,
                            const byte* pc) {
    int64_t block_type =
        decoder->read_i33v<validate>(pc, &length, "block type");
    if (block_type < 0) {
      constexpr int64_t kVoidCode_i64_extended = (~int64_t{0x7F}) | kVoidCode;
      if (block_type == kVoidCode_i64_extended) return;
      type = value_type_reader::read_value_type<validate>(decoder, pc, &length,
                                                          enabled);
      if (!VALIDATE(type != kWasmBottom)) {
        DecodeError<validate>(decoder, pc, "Invalid block type %" PRId64,
                              block_type);
      }
    } else {
      if (!VALIDATE(enabled.has_mv())) {
        DecodeError<validate>(decoder, pc,
                              "invalid block type %" PRId64
                              ", enable with --experimental-wasm-mv",
                              block_type);
        return;
      }
      type = kWasmBottom;
      sig_index = static_cast<uint32_t>(block_type);
    }
  }

  uint32_t in_arity() const {
    if (type != kWasmBottom) return 0;
    return static_cast<uint32_t>(sig->parameter_count());
  }
  uint32_t out_arity() const {
    if (type == kWasmStmt) return 0;
    if (type != kWasmBottom) return 1;
    return static_cast<uint32_t>(sig->return_count());
  }
  ValueType in_type(uint32_t index) {
    DCHECK_EQ(kWasmBottom, type);
    return sig->GetParam(index);
  }
  ValueType out_type(uint32_t index) {
    if (type == kWasmBottom) return sig->GetReturn(index);
    DCHECK_NE(kWasmStmt, type);
    DCHECK_EQ(0, index);
    return type;
  }
};

template <Decoder::ValidateFlag validate>
struct BranchDepthImmediate {
  uint32_t depth;
  uint32_t length;
  inline BranchDepthImmediate(Decoder* decoder, const byte* pc) {
    depth = decoder->read_u32v<validate>(pc, &length, "branch depth");
  }
};

template <Decoder::ValidateFlag validate>
struct BranchOnExceptionImmediate {
  BranchDepthImmediate<validate> depth;
  ExceptionIndexImmediate<validate> index;
  uint32_t length = 0;
  inline BranchOnExceptionImmediate(Decoder* decoder, const byte* pc)
      : depth(BranchDepthImmediate<validate>(decoder, pc)),
        index(ExceptionIndexImmediate<validate>(decoder, pc + depth.length)) {
    length = depth.length + index.length;
  }
};

template <Decoder::ValidateFlag validate>
struct FunctionIndexImmediate {
  uint32_t index = 0;
  uint32_t length = 1;
  inline FunctionIndexImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "function index");
  }
};

template <Decoder::ValidateFlag validate>
struct MemoryIndexImmediate {
  uint32_t index = 0;
  uint32_t length = 1;
  inline MemoryIndexImmediate() = default;
  inline MemoryIndexImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u8<validate>(pc, "memory index");
    if (!VALIDATE(index == 0)) {
      DecodeError<validate>(decoder, pc, "expected memory index 0, found %u",
                            index);
    }
  }
};

template <Decoder::ValidateFlag validate>
struct TableIndexImmediate {
  uint32_t index = 0;
  uint32_t length = 1;
  inline TableIndexImmediate() = default;
  inline TableIndexImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "table index");
  }
};

// TODO(jkummerow): Introduce a common superclass for StructIndexImmediate and
// ArrayIndexImmediate? Maybe even FunctionIndexImmediate too?
template <Decoder::ValidateFlag validate>
struct StructIndexImmediate {
  uint32_t index = 0;
  uint32_t length = 0;
  const StructType* struct_type = nullptr;
  inline StructIndexImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "struct index");
  }
};

template <Decoder::ValidateFlag validate>
struct FieldIndexImmediate {
  StructIndexImmediate<validate> struct_index;
  uint32_t index = 0;
  uint32_t length = 0;
  inline FieldIndexImmediate(Decoder* decoder, const byte* pc)
      : struct_index(decoder, pc) {
    index = decoder->read_u32v<validate>(pc + struct_index.length, &length,
                                         "field index");
    length += struct_index.length;
  }
};

template <Decoder::ValidateFlag validate>
struct ArrayIndexImmediate {
  uint32_t index = 0;
  uint32_t length = 0;
  const ArrayType* array_type = nullptr;
  inline ArrayIndexImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "array index");
  }
};

template <Decoder::ValidateFlag validate>
struct CallIndirectImmediate {
  uint32_t table_index;
  uint32_t sig_index;
  const FunctionSig* sig = nullptr;
  uint32_t length = 0;
  inline CallIndirectImmediate(const WasmFeatures enabled, Decoder* decoder,
                               const byte* pc) {
    uint32_t len = 0;
    sig_index = decoder->read_u32v<validate>(pc, &len, "signature index");
    TableIndexImmediate<validate> table(decoder, pc + len);
    if (!VALIDATE((table.index == 0 && table.length == 1) ||
                  enabled.has_reftypes())) {
      DecodeError<validate>(decoder, pc + len,
                            "expected table index 0, found %u", table.index);
    }
    table_index = table.index;
    length = len + table.length;
  }
};

template <Decoder::ValidateFlag validate>
struct CallFunctionImmediate {
  uint32_t index;
  const FunctionSig* sig = nullptr;
  uint32_t length;
  inline CallFunctionImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "function index");
  }
};

template <Decoder::ValidateFlag validate>
struct BranchTableImmediate {
  uint32_t table_count;
  const byte* start;
  const byte* table;
  inline BranchTableImmediate(Decoder* decoder, const byte* pc) {
    start = pc;
    uint32_t len = 0;
    table_count = decoder->read_u32v<validate>(pc, &len, "table count");
    table = pc + len;
  }
};

// A helper to iterate over a branch table.
template <Decoder::ValidateFlag validate>
class BranchTableIterator {
 public:
  uint32_t cur_index() { return index_; }
  bool has_next() { return VALIDATE(decoder_->ok()) && index_ <= table_count_; }
  uint32_t next() {
    DCHECK(has_next());
    index_++;
    uint32_t length;
    uint32_t result =
        decoder_->read_u32v<validate>(pc_, &length, "branch table entry");
    pc_ += length;
    return result;
  }
  // length, including the length of the {BranchTableImmediate}, but not the
  // opcode.
  uint32_t length() {
    while (has_next()) next();
    return static_cast<uint32_t>(pc_ - start_);
  }
  const byte* pc() { return pc_; }

  BranchTableIterator(Decoder* decoder,
                      const BranchTableImmediate<validate>& imm)
      : decoder_(decoder),
        start_(imm.start),
        pc_(imm.table),
        table_count_(imm.table_count) {}

 private:
  Decoder* const decoder_;
  const byte* start_;
  const byte* pc_;
  uint32_t index_ = 0;          // the current index.
  const uint32_t table_count_;  // the count of entries, not including default.
};

template <Decoder::ValidateFlag validate>
struct MemoryAccessImmediate {
  uint32_t alignment;
  uint32_t offset;
  uint32_t length = 0;
  inline MemoryAccessImmediate(Decoder* decoder, const byte* pc,
                               uint32_t max_alignment) {
    uint32_t alignment_length;
    alignment =
        decoder->read_u32v<validate>(pc, &alignment_length, "alignment");
    if (!VALIDATE(alignment <= max_alignment)) {
      DecodeError<validate>(
          decoder, pc,
          "invalid alignment; expected maximum alignment is %u, "
          "actual alignment is %u",
          max_alignment, alignment);
    }
    uint32_t offset_length;
    offset = decoder->read_u32v<validate>(pc + alignment_length, &offset_length,
                                          "offset");
    length = alignment_length + offset_length;
  }
};

// Immediate for SIMD lane operations.
template <Decoder::ValidateFlag validate>
struct SimdLaneImmediate {
  uint8_t lane;
  uint32_t length = 1;

  inline SimdLaneImmediate(Decoder* decoder, const byte* pc) {
    lane = decoder->read_u8<validate>(pc, "lane");
  }
};

// Immediate for SIMD S8x16 shuffle operations.
template <Decoder::ValidateFlag validate>
struct Simd128Immediate {
  uint8_t value[kSimd128Size] = {0};

  inline Simd128Immediate(Decoder* decoder, const byte* pc) {
    for (uint32_t i = 0; i < kSimd128Size; ++i) {
      value[i] = decoder->read_u8<validate>(pc + i, "value");
    }
  }
};

template <Decoder::ValidateFlag validate>
struct MemoryInitImmediate {
  uint32_t data_segment_index = 0;
  MemoryIndexImmediate<validate> memory;
  unsigned length = 0;

  inline MemoryInitImmediate(Decoder* decoder, const byte* pc) {
    uint32_t len = 0;
    data_segment_index =
        decoder->read_u32v<validate>(pc, &len, "data segment index");
    memory = MemoryIndexImmediate<validate>(decoder, pc + len);
    length = len + memory.length;
  }
};

template <Decoder::ValidateFlag validate>
struct DataDropImmediate {
  uint32_t index;
  unsigned length;

  inline DataDropImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "data segment index");
  }
};

template <Decoder::ValidateFlag validate>
struct MemoryCopyImmediate {
  MemoryIndexImmediate<validate> memory_src;
  MemoryIndexImmediate<validate> memory_dst;
  unsigned length = 0;

  inline MemoryCopyImmediate(Decoder* decoder, const byte* pc) {
    memory_src = MemoryIndexImmediate<validate>(decoder, pc);
    memory_dst =
        MemoryIndexImmediate<validate>(decoder, pc + memory_src.length);
    length = memory_src.length + memory_dst.length;
  }
};

template <Decoder::ValidateFlag validate>
struct TableInitImmediate {
  uint32_t elem_segment_index = 0;
  TableIndexImmediate<validate> table;
  unsigned length = 0;

  inline TableInitImmediate(Decoder* decoder, const byte* pc) {
    uint32_t len = 0;
    elem_segment_index =
        decoder->read_u32v<validate>(pc, &len, "elem segment index");
    table = TableIndexImmediate<validate>(decoder, pc + len);
    length = len + table.length;
  }
};

template <Decoder::ValidateFlag validate>
struct ElemDropImmediate {
  uint32_t index;
  unsigned length;

  inline ElemDropImmediate(Decoder* decoder, const byte* pc) {
    index = decoder->read_u32v<validate>(pc, &length, "elem segment index");
  }
};

template <Decoder::ValidateFlag validate>
struct TableCopyImmediate {
  TableIndexImmediate<validate> table_dst;
  TableIndexImmediate<validate> table_src;
  unsigned length = 0;

  inline TableCopyImmediate(Decoder* decoder, const byte* pc) {
    table_dst = TableIndexImmediate<validate>(decoder, pc);
    table_src = TableIndexImmediate<validate>(decoder, pc + table_dst.length);
    length = table_src.length + table_dst.length;
  }
};

template <Decoder::ValidateFlag validate>
struct HeapTypeImmediate {
  uint32_t length = 1;
  HeapType type = HeapType(HeapType::kBottom);
  inline HeapTypeImmediate(const WasmFeatures& enabled, Decoder* decoder,
                           const byte* pc) {
    type = value_type_reader::read_heap_type<validate>(decoder, pc, &length,
                                                       enabled);
  }
};

template <Decoder::ValidateFlag validate>
struct PcForErrors {
  PcForErrors(const byte* /* pc */) {}

  const byte* pc() const { return nullptr; }
};

template <>
struct PcForErrors<Decoder::kFullValidation> {
  const byte* pc_for_errors = nullptr;

  PcForErrors(const byte* pc) : pc_for_errors(pc) {}

  const byte* pc() const { return pc_for_errors; }
};

// An entry on the value stack.
template <Decoder::ValidateFlag validate>
struct ValueBase : public PcForErrors<validate> {
  ValueType type = kWasmStmt;

  ValueBase(const byte* pc, ValueType type)
      : PcForErrors<validate>(pc), type(type) {}
};

template <typename Value>
struct Merge {
  uint32_t arity = 0;
  union {  // Either multiple values or a single value.
    Value* array;
    Value first;
  } vals = {nullptr};  // Initialize {array} with {nullptr}.

  // Tracks whether this merge was ever reached. Uses precise reachability, like
  // Reachability::kReachable.
  bool reached;

  explicit Merge(bool reached = false) : reached(reached) {}

  Value& operator[](uint32_t i) {
    DCHECK_GT(arity, i);
    return arity == 1 ? vals.first : vals.array[i];
  }
};

enum ControlKind : uint8_t {
  kControlIf,
  kControlIfElse,
  kControlBlock,
  kControlLoop,
  kControlLet,
  kControlTry,
  kControlTryCatch
};

enum Reachability : uint8_t {
  // reachable code.
  kReachable,
  // reachable code in unreachable block (implies normal validation).
  kSpecOnlyReachable,
  // code unreachable in its own block (implies polymorphic validation).
  kUnreachable
};

// An entry on the control stack (i.e. if, block, loop, or try).
template <typename Value, Decoder::ValidateFlag validate>
struct ControlBase : public PcForErrors<validate> {
  ControlKind kind = kControlBlock;
  uint32_t locals_count = 0;
  uint32_t stack_depth = 0;  // stack height at the beginning of the construct.
  Reachability reachability = kReachable;

  // Values merged into the start or end of this control construct.
  Merge<Value> start_merge;
  Merge<Value> end_merge;

  MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(ControlBase);

  ControlBase(ControlKind kind, uint32_t locals_count, uint32_t stack_depth,
              const uint8_t* pc, Reachability reachability)
      : PcForErrors<validate>(pc),
        kind(kind),
        locals_count(locals_count),
        stack_depth(stack_depth),
        reachability(reachability),
        start_merge(reachability == kReachable) {
    DCHECK(kind == kControlLet || locals_count == 0);
  }

  // Check whether the current block is reachable.
  bool reachable() const { return reachability == kReachable; }

  // Check whether the rest of the block is unreachable.
  // Note that this is different from {!reachable()}, as there is also the
  // "indirect unreachable state", for which both {reachable()} and
  // {unreachable()} return false.
  bool unreachable() const { return reachability == kUnreachable; }

  // Return the reachability of new control structs started in this block.
  Reachability innerReachability() const {
    return reachability == kReachable ? kReachable : kSpecOnlyReachable;
  }

  bool is_if() const { return is_onearmed_if() || is_if_else(); }
  bool is_onearmed_if() const { return kind == kControlIf; }
  bool is_if_else() const { return kind == kControlIfElse; }
  bool is_block() const { return kind == kControlBlock; }
  bool is_let() const { return kind == kControlLet; }
  bool is_loop() const { return kind == kControlLoop; }
  bool is_incomplete_try() const { return kind == kControlTry; }
  bool is_try_catch() const { return kind == kControlTryCatch; }
  bool is_try() const { return is_incomplete_try() || is_try_catch(); }

  inline Merge<Value>* br_merge() {
    return is_loop() ? &this->start_merge : &this->end_merge;
  }
};

// This is the list of callback functions that an interface for the
// WasmFullDecoder should implement.
// F(Name, args...)
#define INTERFACE_FUNCTIONS(F)                                                 \
  /* General: */                                                               \
  F(StartFunction)                                                             \
  F(StartFunctionBody, Control* block)                                         \
  F(FinishFunction)                                                            \
  F(OnFirstError)                                                              \
  F(NextInstruction, WasmOpcode)                                               \
  /* Control: */                                                               \
  F(Block, Control* block)                                                     \
  F(Loop, Control* block)                                                      \
  F(Try, Control* block)                                                       \
  F(Catch, Control* block, Value* exception)                                   \
  F(If, const Value& cond, Control* if_block)                                  \
  F(FallThruTo, Control* c)                                                    \
  F(PopControl, Control* block)                                                \
  F(EndControl, Control* block)                                                \
  /* Instructions: */                                                          \
  F(UnOp, WasmOpcode opcode, const Value& value, Value* result)                \
  F(BinOp, WasmOpcode opcode, const Value& lhs, const Value& rhs,              \
    Value* result)                                                             \
  F(I32Const, Value* result, int32_t value)                                    \
  F(I64Const, Value* result, int64_t value)                                    \
  F(F32Const, Value* result, float value)                                      \
  F(F64Const, Value* result, double value)                                     \
  F(RefNull, ValueType type, Value* result)                                    \
  F(RefFunc, uint32_t function_index, Value* result)                           \
  F(RefAsNonNull, const Value& arg, Value* result)                             \
  F(Drop, const Value& value)                                                  \
  F(DoReturn, Vector<Value> values)                                            \
  F(LocalGet, Value* result, const LocalIndexImmediate<validate>& imm)         \
  F(LocalSet, const Value& value, const LocalIndexImmediate<validate>& imm)    \
  F(LocalTee, const Value& value, Value* result,                               \
    const LocalIndexImmediate<validate>& imm)                                  \
  F(AllocateLocals, Vector<Value> local_values)                                \
  F(DeallocateLocals, uint32_t count)                                          \
  F(GlobalGet, Value* result, const GlobalIndexImmediate<validate>& imm)       \
  F(GlobalSet, const Value& value, const GlobalIndexImmediate<validate>& imm)  \
  F(TableGet, const Value& index, Value* result,                               \
    const TableIndexImmediate<validate>& imm)                                  \
  F(TableSet, const Value& index, const Value& value,                          \
    const TableIndexImmediate<validate>& imm)                                  \
  F(Unreachable)                                                               \
  F(Select, const Value& cond, const Value& fval, const Value& tval,           \
    Value* result)                                                             \
  F(Br, Control* target)                                                       \
  F(BrIf, const Value& cond, uint32_t depth)                                   \
  F(BrTable, const BranchTableImmediate<validate>& imm, const Value& key)      \
  F(Else, Control* if_block)                                                   \
  F(LoadMem, LoadType type, const MemoryAccessImmediate<validate>& imm,        \
    const Value& index, Value* result)                                         \
  F(LoadTransform, LoadType type, LoadTransformationKind transform,            \
    const MemoryAccessImmediate<validate>& imm, const Value& index,            \
    Value* result)                                                             \
  F(LoadLane, LoadType type, const Value& value, const Value& index,           \
    const MemoryAccessImmediate<validate>& imm, const uint8_t laneidx,         \
    Value* result)                                                             \
  F(StoreMem, StoreType type, const MemoryAccessImmediate<validate>& imm,      \
    const Value& index, const Value& value)                                    \
  F(StoreLane, StoreType type, const MemoryAccessImmediate<validate>& imm,     \
    const Value& index, const Value& value, const uint8_t laneidx)             \
  F(CurrentMemoryPages, Value* result)                                         \
  F(MemoryGrow, const Value& value, Value* result)                             \
  F(CallDirect, const CallFunctionImmediate<validate>& imm,                    \
    const Value args[], Value returns[])                                       \
  F(CallIndirect, const Value& index,                                          \
    const CallIndirectImmediate<validate>& imm, const Value args[],            \
    Value returns[])                                                           \
  F(CallRef, const Value& func_ref, const FunctionSig* sig,                    \
    uint32_t sig_index, const Value args[], const Value returns[])             \
  F(ReturnCallRef, const Value& func_ref, const FunctionSig* sig,              \
    uint32_t sig_index, const Value args[])                                    \
  F(ReturnCall, const CallFunctionImmediate<validate>& imm,                    \
    const Value args[])                                                        \
  F(ReturnCallIndirect, const Value& index,                                    \
    const CallIndirectImmediate<validate>& imm, const Value args[])            \
  F(BrOnNull, const Value& ref_object, uint32_t depth)                         \
  F(SimdOp, WasmOpcode opcode, Vector<Value> args, Value* result)              \
  F(SimdLaneOp, WasmOpcode opcode, const SimdLaneImmediate<validate>& imm,     \
    const Vector<Value> inputs, Value* result)                                 \
  F(S128Const, const Simd128Immediate<validate>& imm, Value* result)           \
  F(Simd8x16ShuffleOp, const Simd128Immediate<validate>& imm,                  \
    const Value& input0, const Value& input1, Value* result)                   \
  F(Throw, const ExceptionIndexImmediate<validate>& imm,                       \
    const Vector<Value>& args)                                                 \
  F(Rethrow, const Value& exception)                                           \
  F(BrOnException, const Value& exception,                                     \
    const ExceptionIndexImmediate<validate>& imm, uint32_t depth,              \
    Vector<Value> values)                                                      \
  F(AtomicOp, WasmOpcode opcode, Vector<Value> args,                           \
    const MemoryAccessImmediate<validate>& imm, Value* result)                 \
  F(AtomicFence)                                                               \
  F(MemoryInit, const MemoryInitImmediate<validate>& imm, const Value& dst,    \
    const Value& src, const Value& size)                                       \
  F(DataDrop, const DataDropImmediate<validate>& imm)                          \
  F(MemoryCopy, const MemoryCopyImmediate<validate>& imm, const Value& dst,    \
    const Value& src, const Value& size)                                       \
  F(MemoryFill, const MemoryIndexImmediate<validate>& imm, const Value& dst,   \
    const Value& value, const Value& size)                                     \
  F(TableInit, const TableInitImmediate<validate>& imm, Vector<Value> args)    \
  F(ElemDrop, const ElemDropImmediate<validate>& imm)                          \
  F(TableCopy, const TableCopyImmediate<validate>& imm, Vector<Value> args)    \
  F(TableGrow, const TableIndexImmediate<validate>& imm, const Value& value,   \
    const Value& delta, Value* result)                                         \
  F(TableSize, const TableIndexImmediate<validate>& imm, Value* result)        \
  F(TableFill, const TableIndexImmediate<validate>& imm, const Value& start,   \
    const Value& value, const Value& count)                                    \
  F(StructNewWithRtt, const StructIndexImmediate<validate>& imm,               \
    const Value& rtt, const Value args[], Value* result)                       \
  F(StructNewDefault, const StructIndexImmediate<validate>& imm,               \
    const Value& rtt, Value* result)                                           \
  F(StructGet, const Value& struct_object,                                     \
    const FieldIndexImmediate<validate>& field, bool is_signed, Value* result) \
  F(StructSet, const Value& struct_object,                                     \
    const FieldIndexImmediate<validate>& field, const Value& field_value)      \
  F(ArrayNewWithRtt, const ArrayIndexImmediate<validate>& imm,                 \
    const Value& length, const Value& initial_value, const Value& rtt,         \
    Value* result)                                                             \
  F(ArrayNewDefault, const ArrayIndexImmediate<validate>& imm,                 \
    const Value& length, const Value& rtt, Value* result)                      \
  F(ArrayGet, const Value& array_obj,                                          \
    const ArrayIndexImmediate<validate>& imm, const Value& index,              \
    bool is_signed, Value* result)                                             \
  F(ArraySet, const Value& array_obj,                                          \
    const ArrayIndexImmediate<validate>& imm, const Value& index,              \
    const Value& value)                                                        \
  F(ArrayLen, const Value& array_obj, Value* result)                           \
  F(I31New, const Value& input, Value* result)                                 \
  F(I31GetS, const Value& input, Value* result)                                \
  F(I31GetU, const Value& input, Value* result)                                \
  F(RttCanon, const HeapTypeImmediate<validate>& imm, Value* result)           \
  F(RttSub, const HeapTypeImmediate<validate>& imm, const Value& parent,       \
    Value* result)                                                             \
  F(RefTest, const Value& obj, const Value& rtt, Value* result)                \
  F(RefCast, const Value& obj, const Value& rtt, Value* result)                \
  F(BrOnCast, const Value& obj, const Value& rtt, Value* result_on_branch,     \
    uint32_t depth)                                                            \
  F(PassThrough, const Value& from, Value* to)

// Generic Wasm bytecode decoder with utilities for decoding immediates,
// lengths, etc.
template <Decoder::ValidateFlag validate>
class WasmDecoder : public Decoder {
 public:
  WasmDecoder(Zone* zone, const WasmModule* module, const WasmFeatures& enabled,
              WasmFeatures* detected, const FunctionSig* sig, const byte* start,
              const byte* end, uint32_t buffer_offset = 0)
      : Decoder(start, end, buffer_offset),
        local_types_(zone),
        module_(module),
        enabled_(enabled),
        detected_(detected),
        sig_(sig) {}

  Zone* zone() const { return local_types_.get_allocator().zone(); }

  uint32_t num_locals() const {
    DCHECK_EQ(num_locals_, local_types_.size());
    return num_locals_;
  }

  ValueType local_type(uint32_t index) const { return local_types_[index]; }

  void InitializeLocalsFromSig() {
    DCHECK_NOT_NULL(sig_);
    DCHECK_EQ(0, this->local_types_.size());
    local_types_.assign(sig_->parameters().begin(), sig_->parameters().end());
    num_locals_ = static_cast<uint32_t>(sig_->parameters().size());
  }

  // Decodes local definitions in the current decoder.
  // Returns true iff locals are found.
  // Writes the total length of decoded locals in 'total_length'.
  // If insert_position is present, the decoded locals will be inserted into the
  // 'local_types_' of this decoder. Otherwise, this function is used just to
  // check validity and determine the encoding length of the locals in bytes.
  // The decoder's pc is not advanced. If no locals are found (i.e., no
  // compressed uint32 is found at pc), this will exit as 'false' and without an
  // error.
  bool DecodeLocals(const byte* pc, uint32_t* total_length,
                    const base::Optional<uint32_t> insert_position) {
    uint32_t length;
    *total_length = 0;

    // The 'else' value is useless, we pass it for convenience.
    auto insert_iterator = insert_position.has_value()
                               ? local_types_.begin() + insert_position.value()
                               : local_types_.begin();

    // Decode local declarations, if any.
    uint32_t entries =
        read_u32v<kFullValidation>(pc, &length, "local decls count");
    if (!VALIDATE(ok())) {
      DecodeError(pc + *total_length, "invalid local decls count");
      return false;
    }

    *total_length += length;
    TRACE("local decls count: %u\n", entries);

    while (entries-- > 0) {
      if (!VALIDATE(more())) {
        DecodeError(end(),
                    "expected more local decls but reached end of input");
        return false;
      }
      uint32_t count = read_u32v<kFullValidation>(pc + *total_length, &length,
                                                  "local count");
      if (!VALIDATE(ok())) {
        DecodeError(pc + *total_length, "invalid local count");
        return false;
      }
      DCHECK_LE(local_types_.size(), kV8MaxWasmFunctionLocals);
      if (!VALIDATE(count <= kV8MaxWasmFunctionLocals - local_types_.size())) {
        DecodeError(pc + *total_length, "local count too large");
        return false;
      }
      *total_length += length;

      ValueType type = value_type_reader::read_value_type<kFullValidation>(
          this, pc + *total_length, &length, enabled_);
      if (!VALIDATE(type != kWasmBottom)) {
        DecodeError(pc + *total_length, "invalid local type");
        return false;
      }
      *total_length += length;

      if (insert_position.has_value()) {
        // Move the insertion iterator to the end of the newly inserted locals.
        insert_iterator =
            local_types_.insert(insert_iterator, count, type) + count;
        num_locals_ += count;
      }
    }
    DCHECK(ok());
    return true;
  }

  // Shorthand that forwards to the {DecodeError} functions above, passing our
  // {validate} flag.
  template <typename... Args>
  void DecodeError(Args... args) {
    wasm::DecodeError<validate>(this, std::forward<Args>(args)...);
  }

  static BitVector* AnalyzeLoopAssignment(WasmDecoder* decoder, const byte* pc,
                                          uint32_t locals_count, Zone* zone) {
    if (pc >= decoder->end()) return nullptr;
    if (*pc != kExprLoop) return nullptr;

    // The number of locals_count is augmented by 2 so that 'locals_count - 2'
    // can be used to track mem_size, and 'locals_count - 1' to track mem_start.
    BitVector* assigned = zone->New<BitVector>(locals_count, zone);
    int depth = 0;
    // Iteratively process all AST nodes nested inside the loop.
    while (pc < decoder->end() && VALIDATE(decoder->ok())) {
      WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
      uint32_t length = 1;
      switch (opcode) {
        case kExprLoop:
        case kExprIf:
        case kExprBlock:
        case kExprTry:
          length = OpcodeLength(decoder, pc);
          depth++;
          break;
        case kExprLocalSet:  // fallthru
        case kExprLocalTee: {
          LocalIndexImmediate<validate> imm(decoder, pc + 1);
          if (assigned->length() > 0 &&
              imm.index < static_cast<uint32_t>(assigned->length())) {
            // Unverified code might have an out-of-bounds index.
            assigned->Add(imm.index);
          }
          length = 1 + imm.length;
          break;
        }
        case kExprMemoryGrow:
        case kExprCallFunction:
        case kExprCallIndirect:
        case kExprReturnCall:
        case kExprReturnCallIndirect:
          // Add instance cache nodes to the assigned set.
          // TODO(titzer): make this more clear.
          assigned->Add(locals_count - 1);
          length = OpcodeLength(decoder, pc);
          break;
        case kExprEnd:
          depth--;
          break;
        default:
          length = OpcodeLength(decoder, pc);
          break;
      }
      if (depth <= 0) break;
      pc += length;
    }
    return VALIDATE(decoder->ok()) ? assigned : nullptr;
  }

  inline bool Validate(const byte* pc, LocalIndexImmediate<validate>& imm) {
    if (!VALIDATE(imm.index < num_locals())) {
      DecodeError(pc, "invalid local index: %u", imm.index);
      return false;
    }
    return true;
  }

  inline bool Complete(ExceptionIndexImmediate<validate>& imm) {
    if (!VALIDATE(imm.index < module_->exceptions.size())) return false;
    imm.exception = &module_->exceptions[imm.index];
    return true;
  }

  inline bool Validate(const byte* pc, ExceptionIndexImmediate<validate>& imm) {
    if (!Complete(imm)) {
      DecodeError(pc, "Invalid exception index: %u", imm.index);
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, GlobalIndexImmediate<validate>& imm) {
    if (!VALIDATE(imm.index < module_->globals.size())) {
      DecodeError(pc, "invalid global index: %u", imm.index);
      return false;
    }
    imm.global = &module_->globals[imm.index];
    imm.type = imm.global->type;
    return true;
  }

  inline bool Complete(StructIndexImmediate<validate>& imm) {
    if (!VALIDATE(module_->has_struct(imm.index))) return false;
    imm.struct_type = module_->struct_type(imm.index);
    return true;
  }

  inline bool Validate(const byte* pc, StructIndexImmediate<validate>& imm) {
    if (Complete(imm)) return true;
    DecodeError(pc, "invalid struct index: %u", imm.index);
    return false;
  }

  inline bool Validate(const byte* pc, FieldIndexImmediate<validate>& imm) {
    if (!Validate(pc, imm.struct_index)) return false;
    if (!VALIDATE(imm.index < imm.struct_index.struct_type->field_count())) {
      DecodeError(pc + imm.struct_index.length, "invalid field index: %u",
                  imm.index);
      return false;
    }
    return true;
  }

  inline bool Complete(ArrayIndexImmediate<validate>& imm) {
    if (!VALIDATE(module_->has_array(imm.index))) return false;
    imm.array_type = module_->array_type(imm.index);
    return true;
  }

  inline bool Validate(const byte* pc, ArrayIndexImmediate<validate>& imm) {
    if (!Complete(imm)) {
      DecodeError(pc, "invalid array index: %u", imm.index);
      return false;
    }
    return true;
  }

  inline bool CanReturnCall(const FunctionSig* target_sig) {
    if (target_sig == nullptr) return false;
    size_t num_returns = sig_->return_count();
    if (num_returns != target_sig->return_count()) return false;
    for (size_t i = 0; i < num_returns; ++i) {
      if (sig_->GetReturn(i) != target_sig->GetReturn(i)) return false;
    }
    return true;
  }

  inline bool Complete(CallFunctionImmediate<validate>& imm) {
    if (!VALIDATE(imm.index < module_->functions.size())) return false;
    imm.sig = module_->functions[imm.index].sig;
    if (imm.sig->return_count() > 1) {
      this->detected_->Add(kFeature_mv);
    }
    return true;
  }

  inline bool Validate(const byte* pc, CallFunctionImmediate<validate>& imm) {
    if (!Complete(imm)) {
      DecodeError(pc, "invalid function index: %u", imm.index);
      return false;
    }
    return true;
  }

  inline bool Complete(CallIndirectImmediate<validate>& imm) {
    if (!VALIDATE(module_->has_signature(imm.sig_index))) return false;
    imm.sig = module_->signature(imm.sig_index);
    if (imm.sig->return_count() > 1) {
      this->detected_->Add(kFeature_mv);
    }
    return true;
  }

  inline bool Validate(const byte* pc, CallIndirectImmediate<validate>& imm) {
    if (!VALIDATE(imm.table_index < module_->tables.size())) {
      DecodeError(pc, "call_indirect: table index immediate out of bounds");
      return false;
    }
    ValueType table_type = module_->tables[imm.table_index].type;
    if (!VALIDATE(IsSubtypeOf(table_type, kWasmFuncRef, module_))) {
      DecodeError(
          pc, "call_indirect: immediate table #%u is not of a function type",
          imm.table_index);
      return false;
    }
    if (!Complete(imm)) {
      DecodeError(pc, "invalid signature index: #%u", imm.sig_index);
      return false;
    }
    // Check that the dynamic signature for this call is a subtype of the static
    // type of the table the function is defined in.
    ValueType immediate_type = ValueType::Ref(imm.sig_index, kNonNullable);
    if (!VALIDATE(IsSubtypeOf(immediate_type, table_type, module_))) {
      DecodeError(pc,
                  "call_indirect: Immediate signature #%u is not a subtype of "
                  "immediate table #%u",
                  imm.sig_index, imm.table_index);
    }
    return true;
  }

  inline bool Validate(const byte* pc, BranchDepthImmediate<validate>& imm,
                       size_t control_depth) {
    if (!VALIDATE(imm.depth < control_depth)) {
      DecodeError(pc, "invalid branch depth: %u", imm.depth);
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, BranchTableImmediate<validate>& imm,
                       size_t block_depth) {
    if (!VALIDATE(imm.table_count <= kV8MaxWasmFunctionBrTableSize)) {
      DecodeError(pc, "invalid table count (> max br_table size): %u",
                  imm.table_count);
      return false;
    }
    return checkAvailable(imm.table_count);
  }

  inline bool Validate(const byte* pc,
                       BranchOnExceptionImmediate<validate>& imm,
                       size_t control_size) {
    return Validate(pc, imm.depth, control_size) &&
           Validate(pc + imm.depth.length, imm.index);
  }

  inline bool Validate(const byte* pc, WasmOpcode opcode,
                       SimdLaneImmediate<validate>& imm) {
    uint8_t num_lanes = 0;
    switch (opcode) {
      case kExprF64x2ExtractLane:
      case kExprF64x2ReplaceLane:
      case kExprI64x2ExtractLane:
      case kExprI64x2ReplaceLane:
        num_lanes = 2;
        break;
      case kExprF32x4ExtractLane:
      case kExprF32x4ReplaceLane:
      case kExprI32x4ExtractLane:
      case kExprI32x4ReplaceLane:
        num_lanes = 4;
        break;
      case kExprI16x8ExtractLaneS:
      case kExprI16x8ExtractLaneU:
      case kExprI16x8ReplaceLane:
        num_lanes = 8;
        break;
      case kExprI8x16ExtractLaneS:
      case kExprI8x16ExtractLaneU:
      case kExprI8x16ReplaceLane:
        num_lanes = 16;
        break;
      default:
        UNREACHABLE();
        break;
    }
    if (!VALIDATE(imm.lane >= 0 && imm.lane < num_lanes)) {
      DecodeError(pc, "invalid lane index");
      return false;
    } else {
      return true;
    }
  }

  inline bool Validate(const byte* pc, Simd128Immediate<validate>& imm) {
    uint8_t max_lane = 0;
    for (uint32_t i = 0; i < kSimd128Size; ++i) {
      max_lane = std::max(max_lane, imm.value[i]);
    }
    // Shuffle indices must be in [0..31] for a 16 lane shuffle.
    if (!VALIDATE(max_lane < 2 * kSimd128Size)) {
      DecodeError(pc, "invalid shuffle mask");
      return false;
    }
    return true;
  }

  inline bool Complete(BlockTypeImmediate<validate>& imm) {
    if (imm.type != kWasmBottom) return true;
    if (!VALIDATE(module_->has_signature(imm.sig_index))) return false;
    imm.sig = module_->signature(imm.sig_index);
    if (imm.sig->return_count() > 1) {
      this->detected_->Add(kFeature_mv);
    }
    return true;
  }

  inline bool Validate(const byte* pc, BlockTypeImmediate<validate>& imm) {
    if (!Complete(imm)) {
      DecodeError(pc, "block type index %u out of bounds (%zu types)",
                  imm.sig_index, module_->types.size());
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, FunctionIndexImmediate<validate>& imm) {
    if (!VALIDATE(imm.index < module_->functions.size())) {
      DecodeError(pc, "invalid function index: %u", imm.index);
      return false;
    }
    if (!VALIDATE(module_->functions[imm.index].declared)) {
      DecodeError(pc, "undeclared reference to function #%u", imm.index);
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, MemoryIndexImmediate<validate>& imm) {
    if (!VALIDATE(module_->has_memory)) {
      DecodeError(pc, "memory instruction with no memory");
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, MemoryInitImmediate<validate>& imm) {
    if (!VALIDATE(imm.data_segment_index <
                  module_->num_declared_data_segments)) {
      DecodeError(pc, "invalid data segment index: %u", imm.data_segment_index);
      return false;
    }
    if (!Validate(pc + imm.length - imm.memory.length, imm.memory))
      return false;
    return true;
  }

  inline bool Validate(const byte* pc, DataDropImmediate<validate>& imm) {
    if (!VALIDATE(imm.index < module_->num_declared_data_segments)) {
      DecodeError(pc, "invalid data segment index: %u", imm.index);
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, MemoryCopyImmediate<validate>& imm) {
    return Validate(pc, imm.memory_src) &&
           Validate(pc + imm.memory_src.length, imm.memory_dst);
  }

  inline bool Validate(const byte* pc, TableIndexImmediate<validate>& imm) {
    if (!VALIDATE(imm.index < module_->tables.size())) {
      DecodeError(pc, "invalid table index: %u", imm.index);
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, TableInitImmediate<validate>& imm) {
    if (!VALIDATE(imm.elem_segment_index < module_->elem_segments.size())) {
      DecodeError(pc, "invalid element segment index: %u",
                  imm.elem_segment_index);
      return false;
    }
    if (!Validate(pc + imm.length - imm.table.length, imm.table)) {
      return false;
    }
    ValueType elem_type = module_->elem_segments[imm.elem_segment_index].type;
    if (!VALIDATE(IsSubtypeOf(elem_type, module_->tables[imm.table.index].type,
                              module_))) {
      DecodeError(pc, "table %u is not a super-type of %s", imm.table.index,
                  elem_type.name().c_str());
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, ElemDropImmediate<validate>& imm) {
    if (!VALIDATE(imm.index < module_->elem_segments.size())) {
      DecodeError(pc, "invalid element segment index: %u", imm.index);
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, TableCopyImmediate<validate>& imm) {
    if (!Validate(pc, imm.table_src)) return false;
    if (!Validate(pc + imm.table_src.length, imm.table_dst)) return false;
    ValueType src_type = module_->tables[imm.table_src.index].type;
    if (!VALIDATE(IsSubtypeOf(
            src_type, module_->tables[imm.table_dst.index].type, module_))) {
      DecodeError(pc, "table %u is not a super-type of %s", imm.table_dst.index,
                  src_type.name().c_str());
      return false;
    }
    return true;
  }

  inline bool Validate(const byte* pc, HeapTypeImmediate<validate>& imm) {
    if (!VALIDATE(!imm.type.is_bottom())) {
      DecodeError(pc, "invalid heap type");
      return false;
    }
    if (!VALIDATE(imm.type.is_generic() ||
                  module_->has_type(imm.type.ref_index()))) {
      DecodeError(pc, "Type index %u is out of bounds", imm.type.ref_index());
      return false;
    }
    return true;
  }

  static uint32_t OpcodeLength(WasmDecoder* decoder, const byte* pc) {
    WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
    switch (opcode) {
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
      FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
      FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
#undef DECLARE_OPCODE_CASE
      {
        MemoryAccessImmediate<validate> imm(decoder, pc + 1, UINT32_MAX);
        return 1 + imm.length;
      }
      case kExprBr:
      case kExprBrIf: {
        BranchDepthImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprGlobalGet:
      case kExprGlobalSet: {
        GlobalIndexImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprTableGet:
      case kExprTableSet: {
        TableIndexImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprCallFunction:
      case kExprReturnCall: {
        CallFunctionImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprCallIndirect:
      case kExprReturnCallIndirect: {
        CallIndirectImmediate<validate> imm(WasmFeatures::All(), decoder,
                                            pc + 1);
        return 1 + imm.length;
      }

      case kExprTry:
      case kExprIf:  // fall through
      case kExprLoop:
      case kExprBlock: {
        BlockTypeImmediate<validate> imm(WasmFeatures::All(), decoder, pc + 1);
        return 1 + imm.length;
      }

      case kExprLet: {
        BlockTypeImmediate<validate> imm(WasmFeatures::All(), decoder, pc + 1);
        uint32_t locals_length;
        bool locals_result =
            decoder->DecodeLocals(decoder->pc() + 1 + imm.length,
                                  &locals_length, base::Optional<uint32_t>());
        return 1 + imm.length + (locals_result ? locals_length : 0);
      }

      case kExprThrow: {
        ExceptionIndexImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }

      case kExprBrOnExn: {
        BranchOnExceptionImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }

      case kExprBrOnNull: {
        BranchDepthImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }

      case kExprLocalGet:
      case kExprLocalSet:
      case kExprLocalTee: {
        LocalIndexImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprSelectWithType: {
        SelectTypeImmediate<validate> imm(WasmFeatures::All(), decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprBrTable: {
        BranchTableImmediate<validate> imm(decoder, pc + 1);
        BranchTableIterator<validate> iterator(decoder, imm);
        return 1 + iterator.length();
      }
      case kExprI32Const: {
        ImmI32Immediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprI64Const: {
        ImmI64Immediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprRefNull: {
        HeapTypeImmediate<validate> imm(WasmFeatures::All(), decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprRefIsNull: {
        return 1;
      }
      case kExprRefFunc: {
        FunctionIndexImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprMemoryGrow:
      case kExprMemorySize: {
        MemoryIndexImmediate<validate> imm(decoder, pc + 1);
        return 1 + imm.length;
      }
      case kExprF32Const:
        return 5;
      case kExprF64Const:
        return 9;
      case kNumericPrefix: {
        uint32_t length = 0;
        opcode = decoder->read_prefixed_opcode<validate>(pc, &length);
        switch (opcode) {
          case kExprI32SConvertSatF32:
          case kExprI32UConvertSatF32:
          case kExprI32SConvertSatF64:
          case kExprI32UConvertSatF64:
          case kExprI64SConvertSatF32:
          case kExprI64UConvertSatF32:
          case kExprI64SConvertSatF64:
          case kExprI64UConvertSatF64:
            return length;
          case kExprMemoryInit: {
            MemoryInitImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprDataDrop: {
            DataDropImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprMemoryCopy: {
            MemoryCopyImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprMemoryFill: {
            MemoryIndexImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprTableInit: {
            TableInitImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprElemDrop: {
            ElemDropImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprTableCopy: {
            TableCopyImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprTableGrow:
          case kExprTableSize:
          case kExprTableFill: {
            TableIndexImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          default:
            decoder->DecodeError(pc, "invalid numeric opcode");
            return length;
        }
      }
      case kSimdPrefix: {
        uint32_t length = 0;
        opcode = decoder->read_prefixed_opcode<validate>(pc, &length);
        switch (opcode) {
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
          FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
#undef DECLARE_OPCODE_CASE
          return length;
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
          FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
#undef DECLARE_OPCODE_CASE
          return length + 1;
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
          FOREACH_SIMD_MEM_OPCODE(DECLARE_OPCODE_CASE)
#undef DECLARE_OPCODE_CASE
          {
            MemoryAccessImmediate<validate> imm(decoder, pc + length,
                                                UINT32_MAX);
            return length + imm.length;
          }
          case kExprS128Load8Lane:
          case kExprS128Load16Lane:
          case kExprS128Load32Lane:
          case kExprS128Load64Lane:
          case kExprS128Store8Lane:
          case kExprS128Store16Lane:
          case kExprS128Store32Lane:
          case kExprS128Store64Lane: {
            MemoryAccessImmediate<validate> imm(decoder, pc + length,
                                                UINT32_MAX);
            // 1 more byte for lane index immediate.
            return length + imm.length + 1;
          }
          // Shuffles require a byte per lane, or 16 immediate bytes.
          case kExprS128Const:
          case kExprI8x16Shuffle:
            return length + kSimd128Size;
          default:
            decoder->DecodeError(pc, "invalid SIMD opcode");
            return length;
        }
      }
      case kAtomicPrefix: {
        uint32_t length = 0;
        opcode = decoder->read_prefixed_opcode<validate>(pc, &length,
                                                         "atomic_index");
        switch (opcode) {
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
          FOREACH_ATOMIC_OPCODE(DECLARE_OPCODE_CASE)
#undef DECLARE_OPCODE_CASE
          {
            MemoryAccessImmediate<validate> imm(decoder, pc + length,
                                                UINT32_MAX);
            return length + imm.length;
          }
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
          FOREACH_ATOMIC_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
#undef DECLARE_OPCODE_CASE
          {
            return length + 1;
          }
          default:
            decoder->DecodeError(pc, "invalid Atomics opcode");
            return length;
        }
      }
      case kGCPrefix: {
        uint32_t length = 0;
        opcode =
            decoder->read_prefixed_opcode<validate>(pc, &length, "gc_index");
        switch (opcode) {
          case kExprStructNewWithRtt:
          case kExprStructNewDefault: {
            StructIndexImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprStructGet:
          case kExprStructGetS:
          case kExprStructGetU:
          case kExprStructSet: {
            FieldIndexImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprArrayNewWithRtt:
          case kExprArrayNewDefault:
          case kExprArrayGet:
          case kExprArrayGetS:
          case kExprArrayGetU:
          case kExprArraySet:
          case kExprArrayLen: {
            ArrayIndexImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprBrOnCast: {
            BranchDepthImmediate<validate> imm(decoder, pc + length);
            return length + imm.length;
          }
          case kExprRttCanon:
          case kExprRttSub: {
            // TODO(7748): Account for rtt.sub's additional immediates if
            // they stick.
            HeapTypeImmediate<validate> imm(WasmFeatures::All(), decoder,
                                            pc + length);
            return length + imm.length;
          }

          case kExprI31New:
          case kExprI31GetS:
          case kExprI31GetU:
            return length;
          case kExprRefTest:
          case kExprRefCast: {
            HeapTypeImmediate<validate> ht1(WasmFeatures::All(), decoder,
                                            pc + length);
            HeapTypeImmediate<validate> ht2(WasmFeatures::All(), decoder,
                                            pc + length + ht1.length);
            return length + ht1.length + ht2.length;
          }

          default:
            // This is unreachable except for malformed modules.
            decoder->DecodeError(pc, "invalid gc opcode");
            return length;
        }
      }
      default:
        return 1;
    }
  }

  // TODO(clemensb): This is only used by the interpreter; move there.
  V8_EXPORT_PRIVATE std::pair<uint32_t, uint32_t> StackEffect(const byte* pc) {
    WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
    // Handle "simple" opcodes with a fixed signature first.
    const FunctionSig* sig = WasmOpcodes::Signature(opcode);
    if (!sig) sig = WasmOpcodes::AsmjsSignature(opcode);
    if (sig) return {sig->parameter_count(), sig->return_count()};

#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
    // clang-format off
    switch (opcode) {
      case kExprSelect:
      case kExprSelectWithType:
        return {3, 1};
      case kExprTableSet:
      FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
        return {2, 0};
      FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
      case kExprTableGet:
      case kExprLocalTee:
      case kExprMemoryGrow:
      case kExprRefAsNonNull:
      case kExprBrOnNull:
      case kExprRefIsNull:
        return {1, 1};
      case kExprLocalSet:
      case kExprGlobalSet:
      case kExprDrop:
      case kExprBrIf:
      case kExprBrTable:
      case kExprIf:
      case kExprRethrow:
        return {1, 0};
      case kExprLocalGet:
      case kExprGlobalGet:
      case kExprI32Const:
      case kExprI64Const:
      case kExprF32Const:
      case kExprF64Const:
      case kExprRefNull:
      case kExprRefFunc:
      case kExprMemorySize:
        return {0, 1};
      case kExprCallFunction: {
        CallFunctionImmediate<validate> imm(this, pc + 1);
        CHECK(Complete(imm));
        return {imm.sig->parameter_count(), imm.sig->return_count()};
      }
      case kExprCallIndirect: {
        CallIndirectImmediate<validate> imm(this->enabled_, this, pc + 1);
        CHECK(Complete(imm));
        // Indirect calls pop an additional argument for the table index.
        return {imm.sig->parameter_count() + 1,
                imm.sig->return_count()};
      }
      case kExprThrow: {
        ExceptionIndexImmediate<validate> imm(this, pc + 1);
        CHECK(Complete(imm));
        DCHECK_EQ(0, imm.exception->sig->return_count());
        return {imm.exception->sig->parameter_count(), 0};
      }
      case kExprBr:
      case kExprBlock:
      case kExprLoop:
      case kExprEnd:
      case kExprElse:
      case kExprTry:
      case kExprCatch:
      case kExprBrOnExn:
      case kExprNop:
      case kExprReturn:
      case kExprReturnCall:
      case kExprReturnCallIndirect:
      case kExprUnreachable:
        return {0, 0};
      case kExprLet:
        // TODO(7748): Implement
        return {0, 0};
      case kNumericPrefix:
      case kAtomicPrefix:
      case kSimdPrefix: {
        opcode = this->read_prefixed_opcode<validate>(pc);
        switch (opcode) {
          FOREACH_SIMD_1_OPERAND_1_PARAM_OPCODE(DECLARE_OPCODE_CASE)
            return {1, 1};
          FOREACH_SIMD_1_OPERAND_2_PARAM_OPCODE(DECLARE_OPCODE_CASE)
          FOREACH_SIMD_MASK_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
            return {2, 1};
          FOREACH_SIMD_CONST_OPCODE(DECLARE_OPCODE_CASE)
            return {0, 1};
          default: {
            sig = WasmOpcodes::Signature(opcode);
            if (sig) {
              return {sig->parameter_count(), sig->return_count()};
            } else {
              UNREACHABLE();
            }
          }
        }
      }
      case kGCPrefix: {
        opcode = this->read_prefixed_opcode<validate>(pc);
        switch (opcode) {
          case kExprStructNewDefault:
          case kExprStructGet:
          case kExprStructGetS:
          case kExprStructGetU:
          case kExprI31New:
          case kExprI31GetS:
          case kExprI31GetU:
          case kExprArrayLen:
          case kExprRttSub:
            return {1, 1};
          case kExprStructSet:
            return {2, 0};
          case kExprArrayNewDefault:
          case kExprArrayGet:
          case kExprArrayGetS:
          case kExprArrayGetU:
          case kExprRefTest:
          case kExprRefCast:
          case kExprBrOnCast:
            return {2, 1};
          case kExprArraySet:
            return {3, 0};
          case kExprRttCanon:
            return {0, 1};
          case kExprArrayNewWithRtt:
            return {3, 1};
          case kExprStructNewWithRtt: {
            StructIndexImmediate<validate> imm(this, this->pc_ + 2);
            this->Complete(imm);
            return {imm.struct_type->field_count() + 1, 1};
          }
          default:
            UNREACHABLE();
        }
      }
      default:
        FATAL("unimplemented opcode: %x (%s)", opcode,
              WasmOpcodes::OpcodeName(opcode));
        return {0, 0};
    }
#undef DECLARE_OPCODE_CASE
    // clang-format on
  }

  // The {Zone} is implicitly stored in the {ZoneAllocator} which is part of
  // this {ZoneVector}. Hence save one field and just get it from there if
  // needed (see {zone()} accessor below).
  ZoneVector<ValueType> local_types_;

  // Cached value, for speed (yes, it's measurably faster to load this value
  // than to load the start and end pointer from a vector, subtract and shift).
  uint32_t num_locals_ = 0;

  const WasmModule* module_;
  const WasmFeatures enabled_;
  WasmFeatures* detected_;
  const FunctionSig* sig_;
};

#define CALL_INTERFACE(name, ...) interface_.name(this, ##__VA_ARGS__)
#define CALL_INTERFACE_IF_REACHABLE(name, ...)            \
  do {                                                    \
    DCHECK(!control_.empty());                            \
    DCHECK_EQ(current_code_reachable_,                    \
              this->ok() && control_.back().reachable()); \
    if (current_code_reachable_) {                        \
      interface_.name(this, ##__VA_ARGS__);               \
    }                                                     \
  } while (false)
#define CALL_INTERFACE_IF_PARENT_REACHABLE(name, ...)           \
  do {                                                          \
    DCHECK(!control_.empty());                                  \
    if (VALIDATE(this->ok()) &&                                 \
        (control_.size() == 1 || control_at(1)->reachable())) { \
      interface_.name(this, ##__VA_ARGS__);                     \
    }                                                           \
  } while (false)

template <Decoder::ValidateFlag validate, typename Interface>
class WasmFullDecoder : public WasmDecoder<validate> {
  using Value = typename Interface::Value;
  using Control = typename Interface::Control;
  using ArgVector = base::SmallVector<Value, 8>;

  // All Value types should be trivially copyable for performance. We push, pop,
  // and store them in local variables.
  ASSERT_TRIVIALLY_COPYABLE(Value);

 public:
  template <typename... InterfaceArgs>
  WasmFullDecoder(Zone* zone, const WasmModule* module,
                  const WasmFeatures& enabled, WasmFeatures* detected,
                  const FunctionBody& body, InterfaceArgs&&... interface_args)
      : WasmDecoder<validate>(zone, module, enabled, detected, body.sig,
                              body.start, body.end, body.offset),
        interface_(std::forward<InterfaceArgs>(interface_args)...),
        control_(zone) {}

  Interface& interface() { return interface_; }

  bool Decode() {
    DCHECK_EQ(stack_end_, stack_);
    DCHECK(control_.empty());
    DCHECK_LE(this->pc_, this->end_);
    DCHECK_EQ(this->num_locals(), 0);

    this->InitializeLocalsFromSig();
    uint32_t params_count = static_cast<uint32_t>(this->num_locals());
    uint32_t locals_length;
    this->DecodeLocals(this->pc(), &locals_length, params_count);
    this->consume_bytes(locals_length);
    for (uint32_t index = params_count; index < this->num_locals(); index++) {
      if (!VALIDATE(this->local_type(index).is_defaultable())) {
        this->DecodeError(
            "Cannot define function-level local of non-defaultable type %s",
            this->local_type(index).name().c_str());
        return this->TraceFailed();
      }
    }

    CALL_INTERFACE(StartFunction);
    DecodeFunctionBody();
    if (this->failed()) return TraceFailed();

    if (!VALIDATE(control_.empty())) {
      if (control_.size() > 1) {
        this->DecodeError(control_.back().pc(),
                          "unterminated control structure");
      } else {
        this->DecodeError("function body must end with \"end\" opcode");
      }
      return TraceFailed();
    }
    CALL_INTERFACE(FinishFunction);
    if (this->failed()) return TraceFailed();

    TRACE("wasm-decode ok\n\n");
    return true;
  }

  bool TraceFailed() {
    if (this->error_.offset()) {
      TRACE("wasm-error module+%-6d func+%d: %s\n\n", this->error_.offset(),
            this->GetBufferRelativeOffset(this->error_.offset()),
            this->error_.message().c_str());
    } else {
      TRACE("wasm-error: %s\n\n", this->error_.message().c_str());
    }
    return false;
  }

  const char* SafeOpcodeNameAt(const byte* pc) {
    if (!pc) return "<null>";
    if (pc >= this->end_) return "<end>";
    WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
    if (!WasmOpcodes::IsPrefixOpcode(opcode)) {
      return WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(opcode));
    }
    opcode = this->template read_prefixed_opcode<Decoder::kFullValidation>(pc);
    return WasmOpcodes::OpcodeName(opcode);
  }

  inline WasmCodePosition position() {
    int offset = static_cast<int>(this->pc_ - this->start_);
    DCHECK_EQ(this->pc_ - this->start_, offset);  // overflows cannot happen
    return offset;
  }

  inline uint32_t control_depth() const {
    return static_cast<uint32_t>(control_.size());
  }

  inline Control* control_at(uint32_t depth) {
    DCHECK_GT(control_.size(), depth);
    return &control_.back() - depth;
  }

  inline uint32_t stack_size() const {
    DCHECK_GE(stack_end_, stack_);
    DCHECK_GE(kMaxUInt32, stack_end_ - stack_);
    return static_cast<uint32_t>(stack_end_ - stack_);
  }

  inline Value* stack_value(uint32_t depth) {
    DCHECK_LT(0, depth);
    DCHECK_GE(stack_size(), depth);
    return stack_end_ - depth;
  }

  void SetSucceedingCodeDynamicallyUnreachable() {
    Control* current = &control_.back();
    if (current->reachable()) {
      current->reachability = kSpecOnlyReachable;
      current_code_reachable_ = false;
    }
  }

 private:
  Interface interface_;

  // The value stack, stored as individual pointers for maximum performance.
  Value* stack_ = nullptr;
  Value* stack_end_ = nullptr;
  Value* stack_capacity_end_ = nullptr;
  ASSERT_TRIVIALLY_COPYABLE(Value);

  // stack of blocks, loops, and ifs.
  ZoneVector<Control> control_;

  // Controls whether code should be generated for the current block (basically
  // a cache for {ok() && control_.back().reachable()}).
  bool current_code_reachable_ = true;

  static Value UnreachableValue(const uint8_t* pc) {
    return Value{pc, kWasmBottom};
  }

  bool CheckHasMemory() {
    if (!VALIDATE(this->module_->has_memory)) {
      this->DecodeError(this->pc_ - 1, "memory instruction with no memory");
      return false;
    }
    return true;
  }

  bool CheckSimdPostMvp(WasmOpcode opcode) {
    if (!FLAG_wasm_simd_post_mvp && WasmOpcodes::IsSimdPostMvpOpcode(opcode)) {
      this->DecodeError(
          "simd opcode not available, enable with --wasm-simd-post-mvp");
      return false;
    }
    return true;
  }

#ifdef DEBUG
  class TraceLine {
   public:
    explicit TraceLine(WasmFullDecoder* decoder) : decoder_(decoder) {
      WasmOpcode opcode = static_cast<WasmOpcode>(*decoder->pc());
      if (!WasmOpcodes::IsPrefixOpcode(opcode)) AppendOpcode(opcode);
    }

    void AppendOpcode(WasmOpcode opcode) {
      DCHECK(!WasmOpcodes::IsPrefixOpcode(opcode));
      Append(TRACE_INST_FORMAT, decoder_->startrel(decoder_->pc_),
             WasmOpcodes::OpcodeName(opcode));
    }

    ~TraceLine() {
      if (!FLAG_trace_wasm_decoder) return;
      AppendStackState();
      PrintF("%.*s\n", len_, buffer_);
    }

    // Appends a formatted string.
    PRINTF_FORMAT(2, 3)
    void Append(const char* format, ...) {
      if (!FLAG_trace_wasm_decoder) return;
      va_list va_args;
      va_start(va_args, format);
      size_t remaining_len = kMaxLen - len_;
      Vector<char> remaining_msg_space(buffer_ + len_, remaining_len);
      int len = VSNPrintF(remaining_msg_space, format, va_args);
      va_end(va_args);
      len_ += len < 0 ? remaining_len : len;
    }

   private:
    void AppendStackState() {
      DCHECK(FLAG_trace_wasm_decoder);
      Append(" ");
      for (Control& c : decoder_->control_) {
        switch (c.kind) {
          case kControlIf:
            Append("I");
            break;
          case kControlBlock:
            Append("B");
            break;
          case kControlLoop:
            Append("L");
            break;
          case kControlTry:
            Append("T");
            break;
          case kControlIfElse:
          case kControlTryCatch:
          case kControlLet:  // TODO(7748): Implement
            break;
        }
        if (c.start_merge.arity) Append("%u-", c.start_merge.arity);
        Append("%u", c.end_merge.arity);
        if (!c.reachable()) Append("%c", c.unreachable() ? '*' : '#');
      }
      Append(" | ");
      for (size_t i = 0; i < decoder_->stack_size(); ++i) {
        Value& val = decoder_->stack_[i];
        Append(" %c", val.type.short_name());
      }
    }

    static constexpr int kMaxLen = 512;

    char buffer_[kMaxLen];
    int len_ = 0;
    WasmFullDecoder* const decoder_;
  };
#else
  class TraceLine {
   public:
    explicit TraceLine(WasmFullDecoder*) {}

    void AppendOpcode(WasmOpcode) {}

    PRINTF_FORMAT(2, 3)
    void Append(const char* format, ...) {}
  };
#endif

#define DECODE(name)                                                     \
  static int Decode##name(WasmFullDecoder* decoder, WasmOpcode opcode) { \
    TraceLine trace_msg(decoder);                                        \
    return decoder->Decode##name##Impl(&trace_msg, opcode);              \
  }                                                                      \
  V8_INLINE int Decode##name##Impl(TraceLine* trace_msg, WasmOpcode opcode)

  DECODE(Nop) { return 1; }

#define BUILD_SIMPLE_OPCODE(op, _, sig) \
  DECODE(op) { return BuildSimpleOperator_##sig(kExpr##op); }
  FOREACH_SIMPLE_OPCODE(BUILD_SIMPLE_OPCODE)
#undef BUILD_SIMPLE_OPCODE

  DECODE(Block) {
    BlockTypeImmediate<validate> imm(this->enabled_, this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    ArgVector args = PopArgs(imm.sig);
    Control* block = PushControl(kControlBlock);
    SetBlockType(block, imm, args.begin());
    CALL_INTERFACE_IF_REACHABLE(Block, block);
    PushMergeValues(block, &block->start_merge);
    return 1 + imm.length;
  }

  DECODE(Rethrow) {
    CHECK_PROTOTYPE_OPCODE(eh);
    Value exception = Pop(0, kWasmExnRef);
    CALL_INTERFACE_IF_REACHABLE(Rethrow, exception);
    EndControl();
    return 1;
  }

  DECODE(Throw) {
    CHECK_PROTOTYPE_OPCODE(eh);
    ExceptionIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    ArgVector args = PopArgs(imm.exception->ToFunctionSig());
    CALL_INTERFACE_IF_REACHABLE(Throw, imm, VectorOf(args));
    EndControl();
    return 1 + imm.length;
  }

  DECODE(Try) {
    CHECK_PROTOTYPE_OPCODE(eh);
    BlockTypeImmediate<validate> imm(this->enabled_, this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    ArgVector args = PopArgs(imm.sig);
    Control* try_block = PushControl(kControlTry);
    SetBlockType(try_block, imm, args.begin());
    CALL_INTERFACE_IF_REACHABLE(Try, try_block);
    PushMergeValues(try_block, &try_block->start_merge);
    return 1 + imm.length;
  }

  DECODE(Catch) {
    CHECK_PROTOTYPE_OPCODE(eh);
    if (!VALIDATE(!control_.empty())) {
      this->DecodeError("catch does not match any try");
      return 0;
    }
    Control* c = &control_.back();
    if (!VALIDATE(c->is_try())) {
      this->DecodeError("catch does not match any try");
      return 0;
    }
    if (!VALIDATE(c->is_incomplete_try())) {
      this->DecodeError("catch already present for try");
      return 0;
    }
    c->kind = kControlTryCatch;
    FallThruTo(c);
    DCHECK_LE(stack_ + c->stack_depth, stack_end_);
    stack_end_ = stack_ + c->stack_depth;
    c->reachability = control_at(1)->innerReachability();
    current_code_reachable_ = this->ok() && c->reachable();
    Value* exception = Push(kWasmExnRef);
    CALL_INTERFACE_IF_PARENT_REACHABLE(Catch, c, exception);
    return 1;
  }

  DECODE(BrOnExn) {
    CHECK_PROTOTYPE_OPCODE(eh);
    BranchOnExceptionImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc() + 1, imm, control_.size())) return 0;
    Control* c = control_at(imm.depth.depth);
    Value exception = Pop(0, kWasmExnRef);
    const WasmExceptionSig* sig = imm.index.exception->sig;
    int value_count = static_cast<int>(sig->parameter_count());
    // TODO(wasm): This operand stack mutation is an ugly hack to make
    // both type checking here as well as environment merging in the
    // graph builder interface work out of the box. We should introduce
    // special handling for both and do minimal/no stack mutation here.
    EnsureStackSpace(value_count);
    for (int i = 0; i < value_count; ++i) Push(sig->GetParam(i));
    Vector<Value> values(stack_ + c->stack_depth, value_count);
    TypeCheckBranchResult check_result = TypeCheckBranch(c, true);
    if (this->failed()) return 0;
    if (V8_LIKELY(check_result == kReachableBranch)) {
      CALL_INTERFACE(BrOnException, exception, imm.index, imm.depth.depth,
                     values);
      c->br_merge()->reached = true;
    } else if (check_result == kInvalidStack) {
      return 0;
    }
    for (int i = value_count - 1; i >= 0; i--) Pop(i);
    Value* pexception = Push(kWasmExnRef);
    *pexception = exception;
    return 1 + imm.length;
  }

  DECODE(BrOnNull) {
    CHECK_PROTOTYPE_OPCODE(typed_funcref);
    BranchDepthImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm, control_.size())) return 0;
    Value ref_object = Pop(0);
    if (this->failed()) return 0;
    Control* c = control_at(imm.depth);
    TypeCheckBranchResult check_result = TypeCheckBranch(c, true);
    if (V8_LIKELY(check_result == kReachableBranch)) {
      switch (ref_object.type.kind()) {
        case ValueType::kBottom:
          // We are in unreachable code, just forward the bottom value.
        case ValueType::kRef: {
          Value* result = Push(ref_object.type);
          CALL_INTERFACE(PassThrough, ref_object, result);
          break;
        }
        case ValueType::kOptRef: {
          // We need to Push the result value after calling BrOnNull on
          // the interface. Therefore we must sync the ref_object and
          // result nodes afterwards (in PassThrough).
          CALL_INTERFACE(BrOnNull, ref_object, imm.depth);
          Value* result =
              Push(ValueType::Ref(ref_object.type.heap_type(), kNonNullable));
          CALL_INTERFACE(PassThrough, ref_object, result);
          c->br_merge()->reached = true;
          break;
        }
        default:
          this->DecodeError("invalid argument type to br_on_null");
          return 0;
      }
    } else if (check_result == kInvalidStack) {
      return 0;
    }
    return 1 + imm.length;
  }

  DECODE(Let) {
    CHECK_PROTOTYPE_OPCODE(typed_funcref);
    BlockTypeImmediate<validate> imm(this->enabled_, this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    uint32_t old_local_count = this->num_locals();
    // Temporarily add the let-defined values to the beginning of the function
    // locals.
    uint32_t locals_length;
    if (!this->DecodeLocals(this->pc() + 1 + imm.length, &locals_length, 0)) {
      return 0;
    }
    uint32_t num_added_locals = this->num_locals() - old_local_count;
    ArgVector let_local_values =
        PopArgs(static_cast<uint32_t>(imm.in_arity()),
                VectorOf(this->local_types_.data(), num_added_locals));
    ArgVector args = PopArgs(imm.sig);
    Control* let_block = PushControl(kControlLet, num_added_locals);
    SetBlockType(let_block, imm, args.begin());
    CALL_INTERFACE_IF_REACHABLE(Block, let_block);
    PushMergeValues(let_block, &let_block->start_merge);
    CALL_INTERFACE_IF_REACHABLE(AllocateLocals, VectorOf(let_local_values));
    return 1 + imm.length + locals_length;
  }

  DECODE(Loop) {
    BlockTypeImmediate<validate> imm(this->enabled_, this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    ArgVector args = PopArgs(imm.sig);
    Control* block = PushControl(kControlLoop);
    SetBlockType(&control_.back(), imm, args.begin());
    CALL_INTERFACE_IF_REACHABLE(Loop, block);
    PushMergeValues(block, &block->start_merge);
    return 1 + imm.length;
  }

  DECODE(If) {
    BlockTypeImmediate<validate> imm(this->enabled_, this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    Value cond = Pop(0, kWasmI32);
    ArgVector args = PopArgs(imm.sig);
    if (!VALIDATE(this->ok())) return 0;
    Control* if_block = PushControl(kControlIf);
    SetBlockType(if_block, imm, args.begin());
    CALL_INTERFACE_IF_REACHABLE(If, cond, if_block);
    PushMergeValues(if_block, &if_block->start_merge);
    return 1 + imm.length;
  }

  DECODE(Else) {
    if (!VALIDATE(!control_.empty())) {
      this->DecodeError("else does not match any if");
      return 0;
    }
    Control* c = &control_.back();
    if (!VALIDATE(c->is_if())) {
      this->DecodeError("else does not match an if");
      return 0;
    }
    if (!VALIDATE(c->is_onearmed_if())) {
      this->DecodeError("else already present for if");
      return 0;
    }
    if (!TypeCheckFallThru()) return 0;
    c->kind = kControlIfElse;
    CALL_INTERFACE_IF_PARENT_REACHABLE(Else, c);
    if (c->reachable()) c->end_merge.reached = true;
    PushMergeValues(c, &c->start_merge);
    c->reachability = control_at(1)->innerReachability();
    current_code_reachable_ = this->ok() && c->reachable();
    return 1;
  }

  DECODE(End) {
    if (!VALIDATE(!control_.empty())) {
      this->DecodeError("end does not match any if, try, or block");
      return 0;
    }
    Control* c = &control_.back();
    if (!VALIDATE(!c->is_incomplete_try())) {
      this->DecodeError("missing catch or catch-all in try");
      return 0;
    }
    if (c->is_onearmed_if()) {
      if (!VALIDATE(c->end_merge.arity == c->start_merge.arity)) {
        this->DecodeError(
            c->pc(), "start-arity and end-arity of one-armed if must match");
        return 0;
      }
      if (!TypeCheckOneArmedIf(c)) return 0;
    }
    if (c->is_let()) {
      this->local_types_.erase(this->local_types_.begin(),
                               this->local_types_.begin() + c->locals_count);
      this->num_locals_ -= c->locals_count;
      CALL_INTERFACE_IF_REACHABLE(DeallocateLocals, c->locals_count);
    }
    if (!TypeCheckFallThru()) return 0;

    if (control_.size() == 1) {
      // If at the last (implicit) control, check we are at end.
      if (!VALIDATE(this->pc_ + 1 == this->end_)) {
        this->DecodeError(this->pc_ + 1, "trailing code after function end");
        return 0;
      }
      // The result of the block is the return value.
      trace_msg->Append("\n" TRACE_INST_FORMAT, startrel(this->pc_),
                        "(implicit) return");
      DoReturn();
      control_.clear();
      return 1;
    }
    PopControl(c);
    return 1;
  }

  DECODE(Select) {
    Value cond = Pop(2, kWasmI32);
    Value fval = Pop(1);
    Value tval = Pop(0, fval.type);
    ValueType type = tval.type == kWasmBottom ? fval.type : tval.type;
    if (!VALIDATE(!type.is_reference_type())) {
      this->DecodeError(
          "select without type is only valid for value type inputs");
      return 0;
    }
    Value* result = Push(type);
    CALL_INTERFACE_IF_REACHABLE(Select, cond, fval, tval, result);
    return 1;
  }

  DECODE(SelectWithType) {
    CHECK_PROTOTYPE_OPCODE(reftypes);
    SelectTypeImmediate<validate> imm(this->enabled_, this, this->pc_ + 1);
    if (this->failed()) return 0;
    Value cond = Pop(2, kWasmI32);
    Value fval = Pop(1, imm.type);
    Value tval = Pop(0, imm.type);
    Value* result = Push(imm.type);
    CALL_INTERFACE_IF_REACHABLE(Select, cond, fval, tval, result);
    return 1 + imm.length;
  }

  DECODE(Br) {
    BranchDepthImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm, control_.size())) return 0;
    Control* c = control_at(imm.depth);
    TypeCheckBranchResult check_result = TypeCheckBranch(c, false);
    if (V8_LIKELY(check_result == kReachableBranch)) {
      if (imm.depth == control_.size() - 1) {
        DoReturn();
      } else {
        CALL_INTERFACE(Br, c);
        c->br_merge()->reached = true;
      }
    } else if (check_result == kInvalidStack) {
      return 0;
    }
    EndControl();
    return 1 + imm.length;
  }

  DECODE(BrIf) {
    BranchDepthImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm, control_.size())) return 0;
    Value cond = Pop(0, kWasmI32);
    if (this->failed()) return 0;
    Control* c = control_at(imm.depth);
    TypeCheckBranchResult check_result = TypeCheckBranch(c, true);
    if (V8_LIKELY(check_result == kReachableBranch)) {
      CALL_INTERFACE(BrIf, cond, imm.depth);
      c->br_merge()->reached = true;
    } else if (check_result == kInvalidStack) {
      return 0;
    }
    return 1 + imm.length;
  }

  DECODE(BrTable) {
    BranchTableImmediate<validate> imm(this, this->pc_ + 1);
    BranchTableIterator<validate> iterator(this, imm);
    Value key = Pop(0, kWasmI32);
    if (this->failed()) return 0;
    if (!this->Validate(this->pc_ + 1, imm, control_.size())) return 0;

    // Cache the branch targets during the iteration, so that we can set
    // all branch targets as reachable after the {CALL_INTERFACE} call.
    std::vector<bool> br_targets(control_.size());

    // The result types of the br_table instruction. We have to check the
    // stack against these types. Only needed during validation.
    std::vector<ValueType> result_types;

    while (iterator.has_next()) {
      const uint32_t index = iterator.cur_index();
      const byte* pos = iterator.pc();
      uint32_t target = iterator.next();
      if (!VALIDATE(ValidateBrTableTarget(target, pos, index))) return 0;
      // Avoid redundant branch target checks.
      if (br_targets[target]) continue;
      br_targets[target] = true;

      if (validate) {
        if (index == 0) {
          // With the first branch target, initialize the result types.
          result_types = InitializeBrTableResultTypes(target);
        } else if (!UpdateBrTableResultTypes(&result_types, target, pos,
                                             index)) {
          return 0;
        }
      }
    }

    if (!VALIDATE(TypeCheckBrTable(result_types))) return 0;

    DCHECK(this->ok());

    if (current_code_reachable_) {
      CALL_INTERFACE(BrTable, imm, key);

      for (int i = 0, e = control_depth(); i < e; ++i) {
        if (!br_targets[i]) continue;
        control_at(i)->br_merge()->reached = true;
      }
    }

    EndControl();
    return 1 + iterator.length();
  }

  DECODE(Return) {
    if (V8_LIKELY(current_code_reachable_)) {
      if (!VALIDATE(TypeCheckReturn())) return 0;
      DoReturn();
    } else {
      // We pop all return values from the stack to check their type.
      // Since we deal with unreachable code, we do not have to keep the
      // values.
      int num_returns = static_cast<int>(this->sig_->return_count());
      for (int i = num_returns - 1; i >= 0; --i) {
        Pop(i, this->sig_->GetReturn(i));
      }
    }

    EndControl();
    return 1;
  }

  DECODE(Unreachable) {
    CALL_INTERFACE_IF_REACHABLE(Unreachable);
    EndControl();
    return 1;
  }

  DECODE(I32Const) {
    ImmI32Immediate<validate> imm(this, this->pc_ + 1);
    Value* value = Push(kWasmI32);
    CALL_INTERFACE_IF_REACHABLE(I32Const, value, imm.value);
    return 1 + imm.length;
  }

  DECODE(I64Const) {
    ImmI64Immediate<validate> imm(this, this->pc_ + 1);
    Value* value = Push(kWasmI64);
    CALL_INTERFACE_IF_REACHABLE(I64Const, value, imm.value);
    return 1 + imm.length;
  }

  DECODE(F32Const) {
    ImmF32Immediate<validate> imm(this, this->pc_ + 1);
    Value* value = Push(kWasmF32);
    CALL_INTERFACE_IF_REACHABLE(F32Const, value, imm.value);
    return 1 + imm.length;
  }

  DECODE(F64Const) {
    ImmF64Immediate<validate> imm(this, this->pc_ + 1);
    Value* value = Push(kWasmF64);
    CALL_INTERFACE_IF_REACHABLE(F64Const, value, imm.value);
    return 1 + imm.length;
  }

  DECODE(RefNull) {
    CHECK_PROTOTYPE_OPCODE(reftypes);
    HeapTypeImmediate<validate> imm(this->enabled_, this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    ValueType type = ValueType::Ref(imm.type, kNullable);
    Value* value = Push(type);
    CALL_INTERFACE_IF_REACHABLE(RefNull, type, value);
    return 1 + imm.length;
  }

  DECODE(RefIsNull) {
    CHECK_PROTOTYPE_OPCODE(reftypes);
    Value value = Pop(0);
    Value* result = Push(kWasmI32);
    switch (value.type.kind()) {
      case ValueType::kOptRef:
        CALL_INTERFACE_IF_REACHABLE(UnOp, kExprRefIsNull, value, result);
        return 1;
      case ValueType::kBottom:
        // We are in unreachable code, the return value does not matter.
      case ValueType::kRef:
        // For non-nullable references, the result is always false.
        CALL_INTERFACE_IF_REACHABLE(I32Const, result, 0);
        return 1;
      default:
        if (validate) {
          this->DecodeError(
              "invalid argument type to ref.is_null. Expected reference type, "
              "got %s",
              value.type.name().c_str());
          return 0;
        }
        UNREACHABLE();
    }
  }

  DECODE(RefFunc) {
    CHECK_PROTOTYPE_OPCODE(reftypes);
    FunctionIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    HeapType heap_type(this->enabled_.has_typed_funcref()
                           ? this->module_->functions[imm.index].sig_index
                           : HeapType::kFunc);
    Value* value = Push(ValueType::Ref(heap_type, kNonNullable));
    CALL_INTERFACE_IF_REACHABLE(RefFunc, imm.index, value);
    return 1 + imm.length;
  }

  DECODE(RefAsNonNull) {
    CHECK_PROTOTYPE_OPCODE(typed_funcref);
    Value value = Pop(0);
    switch (value.type.kind()) {
      case ValueType::kBottom:
        // We are in unreachable code. Forward the bottom value.
      case ValueType::kRef: {
        Value* result = Push(value.type);
        CALL_INTERFACE_IF_REACHABLE(PassThrough, value, result);
        return 1;
      }
      case ValueType::kOptRef: {
        Value* result =
            Push(ValueType::Ref(value.type.heap_type(), kNonNullable));
        CALL_INTERFACE_IF_REACHABLE(RefAsNonNull, value, result);
        return 1;
      }
      default:
        if (validate) {
          this->DecodeError(
              "invalid agrument type to ref.as_non_null: Expected reference "
              "type, got %s",
              value.type.name().c_str());
        }
        return 0;
    }
  }

  DECODE(LocalGet) {
    LocalIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    Value* value = Push(this->local_type(imm.index));
    CALL_INTERFACE_IF_REACHABLE(LocalGet, value, imm);
    return 1 + imm.length;
  }

  DECODE(LocalSet) {
    LocalIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    Value value = Pop(0, this->local_type(imm.index));
    CALL_INTERFACE_IF_REACHABLE(LocalSet, value, imm);
    return 1 + imm.length;
  }

  DECODE(LocalTee) {
    LocalIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    Value value = Pop(0, this->local_type(imm.index));
    Value* result = Push(value.type);
    CALL_INTERFACE_IF_REACHABLE(LocalTee, value, result, imm);
    return 1 + imm.length;
  }

  DECODE(Drop) {
    Value value = Pop(0);
    CALL_INTERFACE_IF_REACHABLE(Drop, value);
    return 1;
  }

  DECODE(GlobalGet) {
    GlobalIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    Value* result = Push(imm.type);
    CALL_INTERFACE_IF_REACHABLE(GlobalGet, result, imm);
    return 1 + imm.length;
  }

  DECODE(GlobalSet) {
    GlobalIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    if (!VALIDATE(imm.global->mutability)) {
      this->DecodeError("immutable global #%u cannot be assigned", imm.index);
      return 0;
    }
    Value value = Pop(0, imm.type);
    CALL_INTERFACE_IF_REACHABLE(GlobalSet, value, imm);
    return 1 + imm.length;
  }

  DECODE(TableGet) {
    CHECK_PROTOTYPE_OPCODE(reftypes);
    TableIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    Value index = Pop(0, kWasmI32);
    Value* result = Push(this->module_->tables[imm.index].type);
    CALL_INTERFACE_IF_REACHABLE(TableGet, index, result, imm);
    return 1 + imm.length;
  }

  DECODE(TableSet) {
    CHECK_PROTOTYPE_OPCODE(reftypes);
    TableIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    Value value = Pop(1, this->module_->tables[imm.index].type);
    Value index = Pop(0, kWasmI32);
    CALL_INTERFACE_IF_REACHABLE(TableSet, index, value, imm);
    return 1 + imm.length;
  }

  DECODE(LoadMem) {
    // Hard-code the list of load types. The opcodes are highly unlikely to
    // ever change, and we have some checks here to guard against that.
    static_assert(sizeof(LoadType) == sizeof(uint8_t), "LoadType is compact");
    static constexpr uint8_t kMinOpcode = kExprI32LoadMem;
    static constexpr uint8_t kMaxOpcode = kExprI64LoadMem32U;
    static constexpr LoadType kLoadTypes[] = {
        LoadType::kI32Load,    LoadType::kI64Load,    LoadType::kF32Load,
        LoadType::kF64Load,    LoadType::kI32Load8S,  LoadType::kI32Load8U,
        LoadType::kI32Load16S, LoadType::kI32Load16U, LoadType::kI64Load8S,
        LoadType::kI64Load8U,  LoadType::kI64Load16S, LoadType::kI64Load16U,
        LoadType::kI64Load32S, LoadType::kI64Load32U};
    STATIC_ASSERT(arraysize(kLoadTypes) == kMaxOpcode - kMinOpcode + 1);
    DCHECK_LE(kMinOpcode, opcode);
    DCHECK_GE(kMaxOpcode, opcode);
    return DecodeLoadMem(kLoadTypes[opcode - kMinOpcode]);
  }

  DECODE(StoreMem) {
    // Hard-code the list of store types. The opcodes are highly unlikely to
    // ever change, and we have some checks here to guard against that.
    static_assert(sizeof(StoreType) == sizeof(uint8_t), "StoreType is compact");
    static constexpr uint8_t kMinOpcode = kExprI32StoreMem;
    static constexpr uint8_t kMaxOpcode = kExprI64StoreMem32;
    static constexpr StoreType kStoreTypes[] = {
        StoreType::kI32Store,  StoreType::kI64Store,   StoreType::kF32Store,
        StoreType::kF64Store,  StoreType::kI32Store8,  StoreType::kI32Store16,
        StoreType::kI64Store8, StoreType::kI64Store16, StoreType::kI64Store32};
    STATIC_ASSERT(arraysize(kStoreTypes) == kMaxOpcode - kMinOpcode + 1);
    DCHECK_LE(kMinOpcode, opcode);
    DCHECK_GE(kMaxOpcode, opcode);
    return DecodeStoreMem(kStoreTypes[opcode - kMinOpcode]);
  }

  DECODE(MemoryGrow) {
    if (!CheckHasMemory()) return 0;
    MemoryIndexImmediate<validate> imm(this, this->pc_ + 1);
    if (!VALIDATE(this->module_->origin == kWasmOrigin)) {
      this->DecodeError("grow_memory is not supported for asmjs modules");
      return 0;
    }
    Value value = Pop(0, kWasmI32);
    Value* result = Push(kWasmI32);
    CALL_INTERFACE_IF_REACHABLE(MemoryGrow, value, result);
    return 1 + imm.length;
  }

  DECODE(MemorySize) {
    if (!CheckHasMemory()) return 0;
    MemoryIndexImmediate<validate> imm(this, this->pc_ + 1);
    Value* result = Push(kWasmI32);
    CALL_INTERFACE_IF_REACHABLE(CurrentMemoryPages, result);
    return 1 + imm.length;
  }

  DECODE(CallFunction) {
    CallFunctionImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    ArgVector args = PopArgs(imm.sig);
    Value* returns = PushReturns(imm.sig);
    CALL_INTERFACE_IF_REACHABLE(CallDirect, imm, args.begin(), returns);
    return 1 + imm.length;
  }

  DECODE(CallIndirect) {
    CallIndirectImmediate<validate> imm(this->enabled_, this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    Value index = Pop(0, kWasmI32);
    ArgVector args = PopArgs(imm.sig);
    Value* returns = PushReturns(imm.sig);
    CALL_INTERFACE_IF_REACHABLE(CallIndirect, index, imm, args.begin(),
                                returns);
    return 1 + imm.length;
  }

  DECODE(ReturnCall) {
    CHECK_PROTOTYPE_OPCODE(return_call);
    CallFunctionImmediate<validate> imm(this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    if (!VALIDATE(this->CanReturnCall(imm.sig))) {
      this->DecodeError("%s: %s", WasmOpcodes::OpcodeName(kExprReturnCall),
                        "tail call return types mismatch");
      return 0;
    }
    ArgVector args = PopArgs(imm.sig);
    CALL_INTERFACE_IF_REACHABLE(ReturnCall, imm, args.begin());
    EndControl();
    return 1 + imm.length;
  }

  DECODE(ReturnCallIndirect) {
    CHECK_PROTOTYPE_OPCODE(return_call);
    CallIndirectImmediate<validate> imm(this->enabled_, this, this->pc_ + 1);
    if (!this->Validate(this->pc_ + 1, imm)) return 0;
    if (!VALIDATE(this->CanReturnCall(imm.sig))) {
      this->DecodeError("%s: %s",
                        WasmOpcodes::OpcodeName(kExprReturnCallIndirect),
                        "tail call return types mismatch");
      return 0;
    }
    Value index = Pop(0, kWasmI32);
    ArgVector args = PopArgs(imm.sig);
    CALL_INTERFACE_IF_REACHABLE(ReturnCallIndirect, index, imm, args.begin());
    EndControl();
    return 1 + imm.length;
  }

  DECODE(CallRef) {
    CHECK_PROTOTYPE_OPCODE(typed_funcref);
    Value func_ref = Pop(0);
    ValueType func_type = func_ref.type;
    if (func_type == kWasmBottom) {
      // We are in unreachable code, maintain the polymorphic stack.
      return 1;
    }
    if (!VALIDATE(func_type.is_object_reference_type() &&
                  func_type.has_index() &&
                  this->module_->has_signature(func_type.ref_index()))) {
      this->DecodeError(
          "call_ref: Expected function reference on top of stack, found %s of "
          "type %s instead",
          SafeOpcodeNameAt(func_ref.pc()), func_type.name().c_str());
      return 0;
    }
    const FunctionSig* sig = this->module_->signature(func_type.ref_index());
    ArgVector args = PopArgs(sig);
    Value* returns = PushReturns(sig);
    CALL_INTERFACE_IF_REACHABLE(CallRef, func_ref, sig, func_type.ref_index(),
                                args.begin(), returns);
    return 1;
  }

  DECODE(ReturnCallRef) {
    CHECK_PROTOTYPE_OPCODE(typed_funcref);
    CHECK_PROTOTYPE_OPCODE(return_call);
    Value func_ref = Pop(0);
    ValueType func_type = func_ref.type;
    if (func_type == kWasmBottom) {
      // We are in unreachable code, maintain the polymorphic stack.
      return 1;
    }
    if (!VALIDATE(func_type.is_object_reference_type() &&
                  func_type.has_index() &&
                  this->module_->has_signature(func_type.ref_index()))) {
      this->DecodeError(
          "return_call_ref: Expected function reference on top of stack, found "
          "%s of type %s instead",
          SafeOpcodeNameAt(func_ref.pc()), func_type.name().c_str());
      return 0;
    }
    const FunctionSig* sig = this->module_->signature(func_type.ref_index());
    ArgVector args = PopArgs(sig);
    CALL_INTERFACE_IF_REACHABLE(ReturnCallRef, func_ref, sig,
                                func_type.ref_index(), args.begin());
    EndControl();
    return 1;
  }

  DECODE(Numeric) {
    uint32_t opcode_length = 0;
    WasmOpcode full_opcode = this->template read_prefixed_opcode<validate>(
        this->pc_, &opcode_length, "numeric index");
    if (full_opcode == kExprTableGrow || full_opcode == kExprTableSize ||
        full_opcode == kExprTableFill) {
      CHECK_PROTOTYPE_OPCODE(reftypes);
    } else if (full_opcode >= kExprMemoryInit) {
      CHECK_PROTOTYPE_OPCODE(bulk_memory);
    }
    trace_msg->AppendOpcode(full_opcode);
    return DecodeNumericOpcode(full_opcode, opcode_length);
  }

  DECODE(Simd) {
    CHECK_PROTOTYPE_OPCODE(simd);
    uint32_t opcode_length = 0;
    WasmOpcode full_opcode = this->template read_prefixed_opcode<validate>(
        this->pc_, &opcode_length);
    if (!VALIDATE(this->ok())) return 0;
    trace_msg->AppendOpcode(full_opcode);
    return DecodeSimdOpcode(full_opcode, opcode_length);
  }

  DECODE(Atomic) {
    CHECK_PROTOTYPE_OPCODE(threads);
    uint32_t opcode_length = 0;
    WasmOpcode full_opcode = this->template read_prefixed_opcode<validate>(
        this->pc_, &opcode_length, "atomic index");
    trace_msg->AppendOpcode(full_opcode);
    return DecodeAtomicOpcode(full_opcode, opcode_length);
  }

  DECODE(GC) {
    CHECK_PROTOTYPE_OPCODE(gc);
    uint32_t opcode_length = 0;
    WasmOpcode full_opcode = this->template read_prefixed_opcode<validate>(
        this->pc_, &opcode_length, "gc index");
    trace_msg->AppendOpcode(full_opcode);
    return DecodeGCOpcode(full_opcode, opcode_length);
  }

#define SIMPLE_PROTOTYPE_CASE(name, opc, sig) \
  DECODE(name) { return BuildSimplePrototypeOperator(opcode); }
  FOREACH_SIMPLE_PROTOTYPE_OPCODE(SIMPLE_PROTOTYPE_CASE)
#undef SIMPLE_PROTOTYPE_CASE

  DECODE(UnknownOrAsmJs) {
    // Deal with special asmjs opcodes.
    if (!VALIDATE(is_asmjs_module(this->module_))) {
      this->DecodeError("Invalid opcode 0x%x", opcode);
      return 0;
    }
    const FunctionSig* sig = WasmOpcodes::AsmjsSignature(opcode);
    DCHECK_NOT_NULL(sig);
    return BuildSimpleOperator(opcode, sig);
  }

#undef DECODE

  using OpcodeHandler = int (*)(WasmFullDecoder*, WasmOpcode);

  // Ideally we would use template specialization for the different opcodes, but
  // GCC does not allow to specialize templates in class scope
  // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282), and specializing
  // outside the class is not allowed for non-specialized classes.
  // Hence just list all implementations explicitly here, which also gives more
  // freedom to use the same implementation for different opcodes.
#define DECODE_IMPL(opcode) DECODE_IMPL2(kExpr##opcode, opcode)
#define DECODE_IMPL2(opcode, name) \
  if (idx == opcode) return &WasmFullDecoder::Decode##name

  static constexpr OpcodeHandler GetOpcodeHandlerTableEntry(size_t idx) {
    DECODE_IMPL(Nop);
#define BUILD_SIMPLE_OPCODE(op, _, sig) DECODE_IMPL(op);
    FOREACH_SIMPLE_OPCODE(BUILD_SIMPLE_OPCODE)
#undef BUILD_SIMPLE_OPCODE
    DECODE_IMPL(Block);
    DECODE_IMPL(Rethrow);
    DECODE_IMPL(Throw);
    DECODE_IMPL(Try);
    DECODE_IMPL(Catch);
    DECODE_IMPL(BrOnExn);
    DECODE_IMPL(BrOnNull);
    DECODE_IMPL(Let);
    DECODE_IMPL(Loop);
    DECODE_IMPL(If);
    DECODE_IMPL(Else);
    DECODE_IMPL(End);
    DECODE_IMPL(Select);
    DECODE_IMPL(SelectWithType);
    DECODE_IMPL(Br);
    DECODE_IMPL(BrIf);
    DECODE_IMPL(BrTable);
    DECODE_IMPL(Return);
    DECODE_IMPL(Unreachable);
    DECODE_IMPL(I32Const);
    DECODE_IMPL(I64Const);
    DECODE_IMPL(F32Const);
    DECODE_IMPL(F64Const);
    DECODE_IMPL(RefNull);
    DECODE_IMPL(RefIsNull);
    DECODE_IMPL(RefFunc);
    DECODE_IMPL(RefAsNonNull);
    DECODE_IMPL(LocalGet);
    DECODE_IMPL(LocalSet);
    DECODE_IMPL(LocalTee);
    DECODE_IMPL(Drop);
    DECODE_IMPL(GlobalGet);
    DECODE_IMPL(GlobalSet);
    DECODE_IMPL(TableGet);
    DECODE_IMPL(TableSet);
#define DECODE_LOAD_MEM(op, ...) DECODE_IMPL2(kExpr##op, LoadMem);
    FOREACH_LOAD_MEM_OPCODE(DECODE_LOAD_MEM)
#undef DECODE_LOAD_MEM
#define DECODE_STORE_MEM(op, ...) DECODE_IMPL2(kExpr##op, StoreMem);
    FOREACH_STORE_MEM_OPCODE(DECODE_STORE_MEM)
#undef DECODE_LOAD_MEM
    DECODE_IMPL(MemoryGrow);
    DECODE_IMPL(MemorySize);
    DECODE_IMPL(CallFunction);
    DECODE_IMPL(CallIndirect);
    DECODE_IMPL(ReturnCall);
    DECODE_IMPL(ReturnCallIndirect);
    DECODE_IMPL(CallRef);
    DECODE_IMPL(ReturnCallRef);
    DECODE_IMPL2(kNumericPrefix, Numeric);
    DECODE_IMPL2(kSimdPrefix, Simd);
    DECODE_IMPL2(kAtomicPrefix, Atomic);
    DECODE_IMPL2(kGCPrefix, GC);
#define SIMPLE_PROTOTYPE_CASE(name, opc, sig) DECODE_IMPL(name);
    FOREACH_SIMPLE_PROTOTYPE_OPCODE(SIMPLE_PROTOTYPE_CASE)
#undef SIMPLE_PROTOTYPE_CASE
    return &WasmFullDecoder::DecodeUnknownOrAsmJs;
  }

#undef DECODE_IMPL
#undef DECODE_IMPL2

  OpcodeHandler GetOpcodeHandler(uint8_t opcode) {
#ifndef V8_OS_STARBOARD
    static constexpr std::array<OpcodeHandler, 256> kOpcodeHandlers =
        base::make_array<256>(GetOpcodeHandlerTableEntry);
#else
    DCHECK(false);
    static constexpr std::array<OpcodeHandler, 256> kOpcodeHandlers{};
#endif
    return kOpcodeHandlers[opcode];
  }

  void DecodeFunctionBody() {
    TRACE("wasm-decode %p...%p (module+%u, %d bytes)\n", this->start(),
          this->end(), this->pc_offset(),
          static_cast<int>(this->end() - this->start()));

    // Set up initial function block.
    {
      Control* c = PushControl(kControlBlock);
      InitMerge(&c->start_merge, 0, [](uint32_t) -> Value { UNREACHABLE(); });
      InitMerge(&c->end_merge,
                static_cast<uint32_t>(this->sig_->return_count()),
                [&](uint32_t i) {
                  return Value{this->pc_, this->sig_->GetReturn(i)};
                });
      CALL_INTERFACE(StartFunctionBody, c);
    }

    // Decode the function body.
    while (this->pc_ < this->end_) {
      // Most operations only grow the stack by at least one element (unary and
      // binary operations, local.get, constants, ...). Thus check that there is
      // enough space for those operations centrally, and avoid any bounds
      // checks in those operations.
      EnsureStackSpace(1);
      uint8_t first_byte = *this->pc_;
      WasmOpcode opcode = static_cast<WasmOpcode>(first_byte);
      CALL_INTERFACE_IF_REACHABLE(NextInstruction, opcode);
      OpcodeHandler handler = GetOpcodeHandler(first_byte);
      int len = (*handler)(this, opcode);
      this->pc_ += len;
    }

    if (!VALIDATE(this->pc_ == this->end_)) {
      this->DecodeError("Beyond end of code");
    }
  }

  void EndControl() {
    DCHECK(!control_.empty());
    Control* current = &control_.back();
    DCHECK_LE(stack_ + current->stack_depth, stack_end_);
    stack_end_ = stack_ + current->stack_depth;
    CALL_INTERFACE_IF_REACHABLE(EndControl, current);
    current->reachability = kUnreachable;
    current_code_reachable_ = false;
  }

  template <typename func>
  void InitMerge(Merge<Value>* merge, uint32_t arity, func get_val) {
    merge->arity = arity;
    if (arity == 1) {
      merge->vals.first = get_val(0);
    } else if (arity > 1) {
      merge->vals.array = this->zone()->template NewArray<Value>(arity);
      for (uint32_t i = 0; i < arity; i++) {
        merge->vals.array[i] = get_val(i);
      }
    }
  }

  void SetBlockType(Control* c, BlockTypeImmediate<validate>& imm,
                    Value* args) {
    const byte* pc = this->pc_;
    InitMerge(&c->end_merge, imm.out_arity(), [pc, &imm](uint32_t i) {
      return Value{pc, imm.out_type(i)};
    });
    InitMerge(&c->start_merge, imm.in_arity(),
              [args](uint32_t i) { return args[i]; });
  }

  // Pops arguments as required by signature.
  V8_INLINE ArgVector PopArgs(const FunctionSig* sig) {
    int count = sig ? static_cast<int>(sig->parameter_count()) : 0;
    ArgVector args(count);
    for (int i = count - 1; i >= 0; --i) {
      args[i] = Pop(i, sig->GetParam(i));
    }
    return args;
  }

  V8_INLINE ArgVector PopArgs(const StructType* type) {
    int count = static_cast<int>(type->field_count());
    ArgVector args(count);
    for (int i = count - 1; i >= 0; i--) {
      args[i] = Pop(i, type->field(i).Unpacked());
    }
    return args;
  }

  V8_INLINE ArgVector PopArgs(uint32_t base_index,
                              Vector<ValueType> arg_types) {
    ArgVector args(arg_types.size());
    for (int i = static_cast<int>(arg_types.size()) - 1; i >= 0; i--) {
      args[i] = Pop(base_index + i, arg_types[i]);
    }
    return args;
  }

  ValueType GetReturnType(const FunctionSig* sig) {
    DCHECK_GE(1, sig->return_count());
    return sig->return_count() == 0 ? kWasmStmt : sig->GetReturn();
  }

  Control* PushControl(ControlKind kind, uint32_t locals_count = 0) {
    Reachability reachability =
        control_.empty() ? kReachable : control_.back().innerReachability();
    control_.emplace_back(kind, locals_count, stack_size(), this->pc_,
                          reachability);
    current_code_reachable_ = this->ok() && reachability == kReachable;
    return &control_.back();
  }

  void PopControl(Control* c) {
    DCHECK_EQ(c, &control_.back());
    CALL_INTERFACE_IF_PARENT_REACHABLE(PopControl, c);

    // A loop just leaves the values on the stack.
    if (!c->is_loop()) PushMergeValues(c, &c->end_merge);

    bool parent_reached =
        c->reachable() || c->end_merge.reached || c->is_onearmed_if();
    control_.pop_back();
    // If the parent block was reachable before, but the popped control does not
    // return to here, this block becomes "spec only reachable".
    if (!parent_reached) SetSucceedingCodeDynamicallyUnreachable();
    current_code_reachable_ = control_.back().reachable();
  }

  int DecodeLoadMem(LoadType type, int prefix_len = 1) {
    if (!CheckHasMemory()) return 0;
    MemoryAccessImmediate<validate> imm(this, this->pc_ + prefix_len,
                                        type.size_log_2());
    ValueType index_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
    Value index = Pop(0, index_type);
    Value* result = Push(type.value_type());
    CALL_INTERFACE_IF_REACHABLE(LoadMem, type, imm, index, result);
    return prefix_len + imm.length;
  }

  int DecodeLoadTransformMem(LoadType type, LoadTransformationKind transform,
                             uint32_t opcode_length) {
    if (!CheckHasMemory()) return 0;
    // Load extends always load 64-bits.
    uint32_t max_alignment =
        transform == LoadTransformationKind::kExtend ? 3 : type.size_log_2();
    MemoryAccessImmediate<validate> imm(this, this->pc_ + opcode_length,
                                        max_alignment);
    ValueType index_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
    Value index = Pop(0, index_type);
    Value* result = Push(kWasmS128);
    CALL_INTERFACE_IF_REACHABLE(LoadTransform, type, transform, imm, index,
                                result);
    return opcode_length + imm.length;
  }

  int DecodeLoadLane(LoadType type, uint32_t opcode_length) {
    if (!CheckHasMemory()) return 0;
    MemoryAccessImmediate<validate> mem_imm(this, this->pc_ + opcode_length,
                                            type.size_log_2());
    SimdLaneImmediate<validate> lane_imm(
        this, this->pc_ + opcode_length + mem_imm.length);
    Value v128 = Pop(1, kWasmS128);
    Value index = Pop(0, kWasmI32);

    Value* result = Push(kWasmS128);
    CALL_INTERFACE_IF_REACHABLE(LoadLane, type, v128, index, mem_imm,
                                lane_imm.lane, result);
    return opcode_length + mem_imm.length + lane_imm.length;
  }

  int DecodeStoreLane(StoreType type, uint32_t opcode_length) {
    if (!CheckHasMemory()) return 0;
    MemoryAccessImmediate<validate> mem_imm(this, this->pc_ + opcode_length,
                                            type.size_log_2());
    SimdLaneImmediate<validate> lane_imm(
        this, this->pc_ + opcode_length + mem_imm.length);
    Value v128 = Pop(1, kWasmS128);
    Value index = Pop(0, kWasmI32);

    CALL_INTERFACE_IF_REACHABLE(StoreLane, type, mem_imm, index, v128,
                                lane_imm.lane);
    return opcode_length + mem_imm.length + lane_imm.length;
  }

  int DecodeStoreMem(StoreType store, int prefix_len = 1) {
    if (!CheckHasMemory()) return 0;
    MemoryAccessImmediate<validate> imm(this, this->pc_ + prefix_len,
                                        store.size_log_2());
    Value value = Pop(1, store.value_type());
    ValueType index_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
    Value index = Pop(0, index_type);
    CALL_INTERFACE_IF_REACHABLE(StoreMem, store, imm, index, value);
    return prefix_len + imm.length;
  }

  bool ValidateBrTableTarget(uint32_t target, const byte* pos, int index) {
    if (!VALIDATE(target < this->control_.size())) {
      this->DecodeError(pos, "improper branch in br_table target %u (depth %u)",
                        index, target);
      return false;
    }
    return true;
  }

  std::vector<ValueType> InitializeBrTableResultTypes(uint32_t target) {
    Merge<Value>* merge = control_at(target)->br_merge();
    int br_arity = merge->arity;
    std::vector<ValueType> result(br_arity);
    for (int i = 0; i < br_arity; ++i) {
      result[i] = (*merge)[i].type;
    }
    return result;
  }

  bool UpdateBrTableResultTypes(std::vector<ValueType>* result_types,
                                uint32_t target, const byte* pos, int index) {
    Merge<Value>* merge = control_at(target)->br_merge();
    int br_arity = merge->arity;
    // First we check if the arities match.
    if (!VALIDATE(br_arity == static_cast<int>(result_types->size()))) {
      this->DecodeError(pos,
                        "inconsistent arity in br_table target %u (previous "
                        "was %zu, this one is %u)",
                        index, result_types->size(), br_arity);
      return false;
    }

    for (int i = 0; i < br_arity; ++i) {
      if (this->enabled_.has_reftypes()) {
        // The expected type is the biggest common sub type of all targets.
        ValueType type = (*result_types)[i];
        (*result_types)[i] =
            CommonSubtype((*result_types)[i], (*merge)[i].type, this->module_);
        if (!VALIDATE((*result_types)[i] != kWasmBottom)) {
          this->DecodeError(pos,
                            "inconsistent type in br_table target %u (previous "
                            "was %s, this one is %s)",
                            index, type.name().c_str(),
                            (*merge)[i].type.name().c_str());
          return false;
        }
      } else {
        // All target must have the same signature.
        if (!VALIDATE((*result_types)[i] == (*merge)[i].type)) {
          this->DecodeError(pos,
                            "inconsistent type in br_table target %u (previous "
                            "was %s, this one is %s)",
                            index, (*result_types)[i].name().c_str(),
                            (*merge)[i].type.name().c_str());
          return false;
        }
      }
    }
    return true;
  }

  bool TypeCheckBrTable(const std::vector<ValueType>& result_types) {
    int br_arity = static_cast<int>(result_types.size());
    if (V8_LIKELY(!control_.back().unreachable())) {
      int available =
          static_cast<int>(stack_size()) - control_.back().stack_depth;
      // There have to be enough values on the stack.
      if (!VALIDATE(available >= br_arity)) {
        this->DecodeError(
            "expected %u elements on the stack for branch to @%d, found %u",
            br_arity, startrel(control_.back().pc()), available);
        return false;
      }
      Value* stack_values = stack_end_ - br_arity;
      // Type-check the topmost br_arity values on the stack.
      for (int i = 0; i < br_arity; ++i) {
        Value& val = stack_values[i];
        if (!VALIDATE(IsSubtypeOf(val.type, result_types[i], this->module_))) {
          this->DecodeError("type error in merge[%u] (expected %s, got %s)", i,
                            result_types[i].name().c_str(),
                            val.type.name().c_str());
          return false;
        }
      }
    } else {  // !control_.back().reachable()
      // Pop values from the stack, accoring to the expected signature.
      for (int i = 0; i < br_arity; ++i) Pop(i + 1, result_types[i]);
    }
    return this->ok();
  }

  uint32_t SimdConstOp(uint32_t opcode_length) {
    Simd128Immediate<validate> imm(this, this->pc_ + opcode_length);
    auto* result = Push(kWasmS128);
    CALL_INTERFACE_IF_REACHABLE(S128Const, imm, result);
    return opcode_length + kSimd128Size;
  }

  uint32_t SimdExtractLane(WasmOpcode opcode, ValueType type,
                           uint32_t opcode_length) {
    SimdLaneImmediate<validate> imm(this, this->pc_ + opcode_length);
    if (this->Validate(this->pc_ + opcode_length, opcode, imm)) {
      Value inputs[] = {Pop(0, kWasmS128)};
      Value* result = Push(type);
      CALL_INTERFACE_IF_REACHABLE(SimdLaneOp, opcode, imm, ArrayVector(inputs),
                                  result);
    }
    return opcode_length + imm.length;
  }

  uint32_t SimdReplaceLane(WasmOpcode opcode, ValueType type,
                           uint32_t opcode_length) {
    SimdLaneImmediate<validate> imm(this, this->pc_ + opcode_length);
    if (this->Validate(this->pc_ + opcode_length, opcode, imm)) {
      Value inputs[2] = {UnreachableValue(this->pc_),
                         UnreachableValue(this->pc_)};
      inputs[1] = Pop(1, type);
      inputs[0] = Pop(0, kWasmS128);
      Value* result = Push(kWasmS128);
      CALL_INTERFACE_IF_REACHABLE(SimdLaneOp, opcode, imm, ArrayVector(inputs),
                                  result);
    }
    return opcode_length + imm.length;
  }

  uint32_t Simd8x16ShuffleOp(uint32_t opcode_length) {
    Simd128Immediate<validate> imm(this, this->pc_ + opcode_length);
    if (this->Validate(this->pc_ + opcode_length, imm)) {
      Value input1 = Pop(1, kWasmS128);
      Value input0 = Pop(0, kWasmS128);
      Value* result = Push(kWasmS128);
      CALL_INTERFACE_IF_REACHABLE(Simd8x16ShuffleOp, imm, input0, input1,
                                  result);
    }
    return opcode_length + 16;
  }

  uint32_t DecodeSimdOpcode(WasmOpcode opcode, uint32_t opcode_length) {
    // opcode_length is the number of bytes that this SIMD-specific opcode takes
    // up in the LEB128 encoded form.
    switch (opcode) {
      case kExprF64x2ExtractLane:
        return SimdExtractLane(opcode, kWasmF64, opcode_length);
      case kExprF32x4ExtractLane:
        return SimdExtractLane(opcode, kWasmF32, opcode_length);
      case kExprI64x2ExtractLane:
        return SimdExtractLane(opcode, kWasmI64, opcode_length);
      case kExprI32x4ExtractLane:
      case kExprI16x8ExtractLaneS:
      case kExprI16x8ExtractLaneU:
      case kExprI8x16ExtractLaneS:
      case kExprI8x16ExtractLaneU:
        return SimdExtractLane(opcode, kWasmI32, opcode_length);
      case kExprF64x2ReplaceLane:
        return SimdReplaceLane(opcode, kWasmF64, opcode_length);
      case kExprF32x4ReplaceLane:
        return SimdReplaceLane(opcode, kWasmF32, opcode_length);
      case kExprI64x2ReplaceLane:
        return SimdReplaceLane(opcode, kWasmI64, opcode_length);
      case kExprI32x4ReplaceLane:
      case kExprI16x8ReplaceLane:
      case kExprI8x16ReplaceLane:
        return SimdReplaceLane(opcode, kWasmI32, opcode_length);
      case kExprI8x16Shuffle:
        return Simd8x16ShuffleOp(opcode_length);
      case kExprS128LoadMem:
        return DecodeLoadMem(LoadType::kS128Load, opcode_length);
      case kExprS128StoreMem:
        return DecodeStoreMem(StoreType::kS128Store, opcode_length);
      case kExprS128Load32Zero:
        return DecodeLoadTransformMem(LoadType::kI32Load,
                                      LoadTransformationKind::kZeroExtend,
                                      opcode_length);
      case kExprS128Load64Zero:
        return DecodeLoadTransformMem(LoadType::kI64Load,
                                      LoadTransformationKind::kZeroExtend,
                                      opcode_length);
      case kExprS128Load8Splat:
        return DecodeLoadTransformMem(LoadType::kI32Load8S,
                                      LoadTransformationKind::kSplat,
                                      opcode_length);
      case kExprS128Load16Splat:
        return DecodeLoadTransformMem(LoadType::kI32Load16S,
                                      LoadTransformationKind::kSplat,
                                      opcode_length);
      case kExprS128Load32Splat:
        return DecodeLoadTransformMem(
            LoadType::kI32Load, LoadTransformationKind::kSplat, opcode_length);
      case kExprS128Load64Splat:
        return DecodeLoadTransformMem(
            LoadType::kI64Load, LoadTransformationKind::kSplat, opcode_length);
      case kExprS128Load8x8S:
        return DecodeLoadTransformMem(LoadType::kI32Load8S,
                                      LoadTransformationKind::kExtend,
                                      opcode_length);
      case kExprS128Load8x8U:
        return DecodeLoadTransformMem(LoadType::kI32Load8U,
                                      LoadTransformationKind::kExtend,
                                      opcode_length);
      case kExprS128Load16x4S:
        return DecodeLoadTransformMem(LoadType::kI32Load16S,
                                      LoadTransformationKind::kExtend,
                                      opcode_length);
      case kExprS128Load16x4U:
        return DecodeLoadTransformMem(LoadType::kI32Load16U,
                                      LoadTransformationKind::kExtend,
                                      opcode_length);
      case kExprS128Load32x2S:
        return DecodeLoadTransformMem(LoadType::kI64Load32S,
                                      LoadTransformationKind::kExtend,
                                      opcode_length);
      case kExprS128Load32x2U:
        return DecodeLoadTransformMem(LoadType::kI64Load32U,
                                      LoadTransformationKind::kExtend,
                                      opcode_length);
      case kExprS128Load8Lane: {
        return DecodeLoadLane(LoadType::kI32Load8S, opcode_length);
      }
      case kExprS128Load16Lane: {
        return DecodeLoadLane(LoadType::kI32Load16S, opcode_length);
      }
      case kExprS128Load32Lane: {
        return DecodeLoadLane(LoadType::kI32Load, opcode_length);
      }
      case kExprS128Load64Lane: {
        return DecodeLoadLane(LoadType::kI64Load, opcode_length);
      }
      case kExprS128Store8Lane: {
        return DecodeStoreLane(StoreType::kI32Store8, opcode_length);
      }
      case kExprS128Store16Lane: {
        return DecodeStoreLane(StoreType::kI32Store16, opcode_length);
      }
      case kExprS128Store32Lane: {
        return DecodeStoreLane(StoreType::kI32Store, opcode_length);
      }
      case kExprS128Store64Lane: {
        return DecodeStoreLane(StoreType::kI64Store, opcode_length);
      }
      case kExprS128Const:
        return SimdConstOp(opcode_length);
      default: {
        if (!CheckSimdPostMvp(opcode)) {
          return 0;
        }
        const FunctionSig* sig = WasmOpcodes::Signature(opcode);
        if (!VALIDATE(sig != nullptr)) {
          this->DecodeError("invalid simd opcode");
          return 0;
        }
        ArgVector args = PopArgs(sig);
        Value* results =
            sig->return_count() == 0 ? nullptr : Push(GetReturnType(sig));
        CALL_INTERFACE_IF_REACHABLE(SimdOp, opcode, VectorOf(args), results);
        return opcode_length;
      }
    }
  }

  int DecodeGCOpcode(WasmOpcode opcode, uint32_t opcode_length) {
    switch (opcode) {
      case kExprStructNewWithRtt: {
        StructIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value rtt = Pop(imm.struct_type->field_count());
        if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
          this->DecodeError(
              "struct.new_with_rtt expected rtt, found %s of type %s",
              SafeOpcodeNameAt(rtt.pc()), rtt.type.name().c_str());
          return 0;
        }
        // TODO(7748): Drop this check if {imm} is dropped from the proposal
        // à la https://github.com/WebAssembly/function-references/pull/31.
        if (!VALIDATE(rtt.type.is_bottom() ||
                      rtt.type.heap_representation() == imm.index)) {
          this->DecodeError(
              "struct.new_with_rtt expected rtt for type %d, found rtt for "
              "type %s",
              imm.index, rtt.type.heap_type().name().c_str());
          return 0;
        }
        ArgVector args = PopArgs(imm.struct_type);
        Value* value = Push(ValueType::Ref(imm.index, kNonNullable));
        CALL_INTERFACE_IF_REACHABLE(StructNewWithRtt, imm, rtt, args.begin(),
                                    value);
        return opcode_length + imm.length;
      }
      case kExprStructNewDefault: {
        StructIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        if (validate) {
          for (uint32_t i = 0; i < imm.struct_type->field_count(); i++) {
            ValueType ftype = imm.struct_type->field(i);
            if (!VALIDATE(ftype.is_defaultable())) {
              this->DecodeError(
                  "struct.new_default_with_rtt: struct type %d has "
                  "non-defaultable type %s for field %d",
                  imm.index, ftype.name().c_str(), i);
              return 0;
            }
          }
        }
        Value rtt = Pop(0);
        if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
          this->DecodeError(
              "struct.new_default_with_rtt expected rtt, found %s of type %s",
              SafeOpcodeNameAt(rtt.pc()), rtt.type.name().c_str());
          return 0;
        }
        // TODO(7748): Drop this check if {imm} is dropped from the proposal
        // à la https://github.com/WebAssembly/function-references/pull/31.
        if (!VALIDATE(rtt.type.is_bottom() ||
                      rtt.type.heap_representation() == imm.index)) {
          this->DecodeError(
              "struct.new_default_with_rtt expected rtt for type %d, found rtt "
              "for type %s",
              imm.index, rtt.type.heap_type().name().c_str());
          return 0;
        }
        Value* value = Push(ValueType::Ref(imm.index, kNonNullable));
        CALL_INTERFACE_IF_REACHABLE(StructNewDefault, imm, rtt, value);
        return opcode_length + imm.length;
      }
      case kExprStructGet: {
        FieldIndexImmediate<validate> field(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, field)) return 0;
        ValueType field_type =
            field.struct_index.struct_type->field(field.index);
        if (!VALIDATE(!field_type.is_packed())) {
          this->DecodeError(
              "struct.get used with a field of packed type. Use struct.get_s "
              "or struct.get_u instead.");
          return 0;
        }
        Value struct_obj =
            Pop(0, ValueType::Ref(field.struct_index.index, kNullable));
        Value* value = Push(field_type);
        CALL_INTERFACE_IF_REACHABLE(StructGet, struct_obj, field, true, value);
        return opcode_length + field.length;
      }
      case kExprStructGetU:
      case kExprStructGetS: {
        FieldIndexImmediate<validate> field(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, field)) return 0;
        ValueType field_type =
            field.struct_index.struct_type->field(field.index);
        if (!VALIDATE(field_type.is_packed())) {
          this->DecodeError(
              "%s is only valid for packed struct fields. Use struct.get "
              "instead.",
              WasmOpcodes::OpcodeName(opcode));
          return 0;
        }
        Value struct_obj =
            Pop(0, ValueType::Ref(field.struct_index.index, kNullable));
        Value* value = Push(field_type.Unpacked());
        CALL_INTERFACE_IF_REACHABLE(StructGet, struct_obj, field,
                                    opcode == kExprStructGetS, value);
        return opcode_length + field.length;
      }
      case kExprStructSet: {
        FieldIndexImmediate<validate> field(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, field)) return 0;
        const StructType* struct_type = field.struct_index.struct_type;
        if (!VALIDATE(struct_type->mutability(field.index))) {
          this->DecodeError("setting immutable struct field");
          return 0;
        }
        Value field_value = Pop(1, struct_type->field(field.index).Unpacked());
        Value struct_obj =
            Pop(0, ValueType::Ref(field.struct_index.index, kNullable));
        CALL_INTERFACE_IF_REACHABLE(StructSet, struct_obj, field, field_value);
        return opcode_length + field.length;
      }
      case kExprArrayNewWithRtt: {
        ArrayIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value rtt = Pop(2);
        if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
          this->DecodeError(
              this->pc_ + opcode_length,
              "array.new_with_rtt expected rtt, found %s of type %s",
              SafeOpcodeNameAt(rtt.pc()), rtt.type.name().c_str());
          return 0;
        }
        // TODO(7748): Drop this check if {imm} is dropped from the proposal
        // à la https://github.com/WebAssembly/function-references/pull/31.
        if (!VALIDATE(rtt.type.is_bottom() ||
                      rtt.type.heap_representation() == imm.index)) {
          this->DecodeError(
              this->pc_ + opcode_length,
              "array.new_with_rtt expected rtt for type %d, found "
              "rtt for type %s",
              imm.index, rtt.type.heap_type().name().c_str());
          return 0;
        }
        Value length = Pop(1, kWasmI32);
        Value initial_value = Pop(0, imm.array_type->element_type().Unpacked());
        Value* value = Push(ValueType::Ref(imm.index, kNonNullable));
        CALL_INTERFACE_IF_REACHABLE(ArrayNewWithRtt, imm, length, initial_value,
                                    rtt, value);
        return opcode_length + imm.length;
      }
      case kExprArrayNewDefault: {
        ArrayIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        if (!VALIDATE(imm.array_type->element_type().is_defaultable())) {
          this->DecodeError(
              "array.new_default_with_rtt: array type %d has "
              "non-defaultable element type %s",
              imm.index, imm.array_type->element_type().name().c_str());
          return 0;
        }
        Value rtt = Pop(1);
        if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
          this->DecodeError(
              this->pc_ + opcode_length,
              "array.new_default_with_rtt expected rtt, found %s of type %s",
              SafeOpcodeNameAt(rtt.pc()), rtt.type.name().c_str());
          return 0;
        }
        // TODO(7748): Drop this check if {imm} is dropped from the proposal
        // à la https://github.com/WebAssembly/function-references/pull/31.
        if (!VALIDATE(rtt.type.is_bottom() ||
                      rtt.type.heap_representation() == imm.index)) {
          this->DecodeError(this->pc_ + opcode_length,
                            "array.new_default_with_rtt expected rtt for type "
                            "%d, found rtt for type %s",
                            imm.index, rtt.type.heap_type().name().c_str());
          return 0;
        }
        Value length = Pop(0, kWasmI32);
        Value* value = Push(ValueType::Ref(imm.index, kNonNullable));
        CALL_INTERFACE_IF_REACHABLE(ArrayNewDefault, imm, length, rtt, value);
        return opcode_length + imm.length;
      }
      case kExprArrayGetS:
      case kExprArrayGetU: {
        ArrayIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        if (!VALIDATE(imm.array_type->element_type().is_packed())) {
          this->DecodeError(
              "%s is only valid for packed arrays. Use array.get instead.",
              WasmOpcodes::OpcodeName(opcode));
          return 0;
        }
        Value index = Pop(1, kWasmI32);
        Value array_obj = Pop(0, ValueType::Ref(imm.index, kNullable));
        Value* value = Push(imm.array_type->element_type().Unpacked());
        CALL_INTERFACE_IF_REACHABLE(ArrayGet, array_obj, imm, index,
                                    opcode == kExprArrayGetS, value);
        return opcode_length + imm.length;
      }
      case kExprArrayGet: {
        ArrayIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        if (!VALIDATE(!imm.array_type->element_type().is_packed())) {
          this->DecodeError(
              "array.get used with a field of packed type. Use array.get_s or "
              "array.get_u instead.");
          return 0;
        }
        Value index = Pop(1, kWasmI32);
        Value array_obj = Pop(0, ValueType::Ref(imm.index, kNullable));
        Value* value = Push(imm.array_type->element_type());
        CALL_INTERFACE_IF_REACHABLE(ArrayGet, array_obj, imm, index, true,
                                    value);
        return opcode_length + imm.length;
      }
      case kExprArraySet: {
        ArrayIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        if (!VALIDATE(imm.array_type->mutability())) {
          this->DecodeError("setting element of immutable array");
          return 0;
        }
        Value value = Pop(2, imm.array_type->element_type().Unpacked());
        Value index = Pop(1, kWasmI32);
        Value array_obj = Pop(0, ValueType::Ref(imm.index, kNullable));
        CALL_INTERFACE_IF_REACHABLE(ArraySet, array_obj, imm, index, value);
        return opcode_length + imm.length;
      }
      case kExprArrayLen: {
        ArrayIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value array_obj = Pop(0, ValueType::Ref(imm.index, kNullable));
        Value* value = Push(kWasmI32);
        CALL_INTERFACE_IF_REACHABLE(ArrayLen, array_obj, value);
        return opcode_length + imm.length;
      }
      case kExprI31New: {
        Value input = Pop(0, kWasmI32);
        Value* value = Push(kWasmI31Ref);
        CALL_INTERFACE_IF_REACHABLE(I31New, input, value);
        return opcode_length;
      }
      case kExprI31GetS: {
        Value i31 = Pop(0, kWasmI31Ref);
        Value* value = Push(kWasmI32);
        CALL_INTERFACE_IF_REACHABLE(I31GetS, i31, value);
        return opcode_length;
      }
      case kExprI31GetU: {
        Value i31 = Pop(0, kWasmI31Ref);
        Value* value = Push(kWasmI32);
        CALL_INTERFACE_IF_REACHABLE(I31GetU, i31, value);
        return opcode_length;
      }
      case kExprRttCanon: {
        HeapTypeImmediate<validate> imm(this->enabled_, this,
                                        this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value* value = Push(ValueType::Rtt(imm.type, 1));
        CALL_INTERFACE_IF_REACHABLE(RttCanon, imm, value);
        return opcode_length + imm.length;
      }
      case kExprRttSub: {
        // TODO(7748): The proposal currently includes additional immediates
        // here: the subtyping depth <n> and the "parent type", see:
        // https://github.com/WebAssembly/gc/commit/20a80e34 .
        // If these immediates don't get dropped (in the spirit of
        // https://github.com/WebAssembly/function-references/pull/31 ),
        // implement them here.
        HeapTypeImmediate<validate> imm(this->enabled_, this,
                                        this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value parent = Pop(0);
        if (parent.type.is_bottom()) {
          Push(kWasmBottom);
        } else {
          // TODO(7748): Consider exposing "IsSubtypeOfHeap(HeapType t1, t2)" so
          // we can avoid creating (ref heaptype) wrappers here.
          if (!VALIDATE(parent.type.is_rtt() &&
                        IsSubtypeOf(ValueType::Ref(imm.type, kNonNullable),
                                    ValueType::Ref(parent.type.heap_type(),
                                                   kNonNullable),
                                    this->module_))) {
            this->DecodeError("rtt.sub requires a supertype rtt on stack");
            return 0;
          }
          Value* value =
              Push(ValueType::Rtt(imm.type, parent.type.depth() + 1));
          CALL_INTERFACE_IF_REACHABLE(RttSub, imm, parent, value);
        }
        return opcode_length + imm.length;
      }
      case kExprRefTest: {
        // "Tests whether {obj}'s runtime type is a runtime subtype of {rtt}."
        HeapTypeImmediate<validate> obj_type(this->enabled_, this,
                                             this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, obj_type)) return 0;
        int len = opcode_length + obj_type.length;
        HeapTypeImmediate<validate> rtt_type(this->enabled_, this,
                                             this->pc_ + len);
        if (!this->Validate(this->pc_ + len, rtt_type)) return 0;
        len += rtt_type.length;
        // The static type of {obj} must be a supertype of the {rtt}'s type.
        if (!VALIDATE(IsSubtypeOf(ValueType::Ref(rtt_type.type, kNonNullable),
                                  ValueType::Ref(obj_type.type, kNonNullable),
                                  this->module_))) {
          this->DecodeError(
              "ref.test: rtt type must be subtype of object type");
          return 0;
        }
        Value rtt = Pop(1);
        if (!VALIDATE(
                (rtt.type.is_rtt() && rtt.type.heap_type() == rtt_type.type) ||
                rtt.type == kWasmBottom)) {
          this->DecodeError("ref.test: expected rtt for type %s but got %s",
                            rtt_type.type.name().c_str(),
                            rtt.type.name().c_str());
          return 0;
        }
        Value obj = Pop(0, ValueType::Ref(obj_type.type, kNullable));
        Value* value = Push(kWasmI32);
        CALL_INTERFACE_IF_REACHABLE(RefTest, obj, rtt, value);
        return len;
      }
      case kExprRefCast: {
        HeapTypeImmediate<validate> obj_type(this->enabled_, this,
                                             this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, obj_type)) return 0;
        int len = opcode_length + obj_type.length;
        HeapTypeImmediate<validate> rtt_type(this->enabled_, this,
                                             this->pc_ + len);
        if (!this->Validate(this->pc_ + len, rtt_type)) return 0;
        len += rtt_type.length;
        if (!VALIDATE(IsSubtypeOf(ValueType::Ref(rtt_type.type, kNonNullable),
                                  ValueType::Ref(obj_type.type, kNonNullable),
                                  this->module_))) {
          this->DecodeError(
              "ref.cast: rtt type must be subtype of object type");
          return 0;
        }
        Value rtt = Pop(1);
        if (!VALIDATE(
                (rtt.type.is_rtt() && rtt.type.heap_type() == rtt_type.type) ||
                rtt.type == kWasmBottom)) {
          this->DecodeError("ref.cast: expected rtt for type %s but got %s",
                            rtt_type.type.name().c_str(),
                            rtt.type.name().c_str());
          return 0;
        }
        Value obj = Pop(0, ValueType::Ref(obj_type.type, kNullable));
        Value* value = Push(ValueType::Ref(rtt_type.type, kNonNullable));
        CALL_INTERFACE_IF_REACHABLE(RefCast, obj, rtt, value);
        return len;
      }
      case kExprBrOnCast: {
        BranchDepthImmediate<validate> branch_depth(this,
                                                    this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, branch_depth,
                            control_.size())) {
          return 0;
        }
        // TODO(7748): If the heap type immediates remain in the spec, read
        // them here.
        Value rtt = Pop(1);
        if (!VALIDATE(rtt.type.is_rtt() || rtt.type.is_bottom())) {
          this->DecodeError("br_on_cast[1]: expected rtt on stack");
          return 0;
        }
        Value obj = Pop(0);
        if (!VALIDATE(obj.type.is_object_reference_type() ||
                      rtt.type.is_bottom())) {
          this->DecodeError("br_on_cast[0]: expected reference on stack");
          return 0;
        }
        // The static type of {obj} must be a supertype of {rtt}'s type.
        if (!VALIDATE(
                rtt.type.is_bottom() || obj.type.is_bottom() ||
                IsSubtypeOf(ValueType::Ref(rtt.type.heap_type(), kNonNullable),
                            ValueType::Ref(obj.type.heap_type(), kNonNullable),
                            this->module_))) {
          this->DecodeError(
              "br_on_cast: rtt type must be a subtype of object type");
          return 0;
        }
        Control* c = control_at(branch_depth.depth);
        Value* result_on_branch =
            Push(rtt.type.is_bottom()
                     ? kWasmBottom
                     : ValueType::Ref(rtt.type.heap_type(), kNonNullable));
        TypeCheckBranchResult check_result = TypeCheckBranch(c, true);
        if (V8_LIKELY(check_result == kReachableBranch)) {
          CALL_INTERFACE(BrOnCast, obj, rtt, result_on_branch,
                         branch_depth.depth);
          c->br_merge()->reached = true;
        } else if (check_result == kInvalidStack) {
          return 0;
        }
        Pop(0);  // Drop {result_on_branch}, restore original value.
        Value* result_on_fallthrough = Push(obj.type);
        *result_on_fallthrough = obj;
        return opcode_length + branch_depth.length;
      }
      default:
        this->DecodeError("invalid gc opcode");
        return 0;
    }
  }

  uint32_t DecodeAtomicOpcode(WasmOpcode opcode, uint32_t opcode_length) {
    ValueType ret_type;
    const FunctionSig* sig = WasmOpcodes::Signature(opcode);
    if (!VALIDATE(sig != nullptr)) {
      this->DecodeError("invalid atomic opcode");
      return 0;
    }
    MachineType memtype;
    switch (opcode) {
#define CASE_ATOMIC_STORE_OP(Name, Type)          \
  case kExpr##Name: {                             \
    memtype = MachineType::Type();                \
    ret_type = kWasmStmt;                         \
    break; /* to generic mem access code below */ \
  }
      ATOMIC_STORE_OP_LIST(CASE_ATOMIC_STORE_OP)
#undef CASE_ATOMIC_OP
#define CASE_ATOMIC_OP(Name, Type)                \
  case kExpr##Name: {                             \
    memtype = MachineType::Type();                \
    ret_type = GetReturnType(sig);                \
    break; /* to generic mem access code below */ \
  }
      ATOMIC_OP_LIST(CASE_ATOMIC_OP)
#undef CASE_ATOMIC_OP
      case kExprAtomicFence: {
        byte zero =
            this->template read_u8<validate>(this->pc_ + opcode_length, "zero");
        if (!VALIDATE(zero == 0)) {
          this->DecodeError(this->pc_ + opcode_length,
                            "invalid atomic operand");
          return 0;
        }
        CALL_INTERFACE_IF_REACHABLE(AtomicFence);
        return 1 + opcode_length;
      }
      default:
        this->DecodeError("invalid atomic opcode");
        return 0;
    }
    if (!CheckHasMemory()) return 0;
    MemoryAccessImmediate<validate> imm(
        this, this->pc_ + opcode_length,
        ElementSizeLog2Of(memtype.representation()));
    // TODO(10949): Fix this for memory64 (index type should be kWasmI64
    // then).
    CHECK(!this->module_->is_memory64);
    ArgVector args = PopArgs(sig);
    Value* result = ret_type == kWasmStmt ? nullptr : Push(GetReturnType(sig));
    CALL_INTERFACE_IF_REACHABLE(AtomicOp, opcode, VectorOf(args), imm, result);
    return opcode_length + imm.length;
  }

  unsigned DecodeNumericOpcode(WasmOpcode opcode, uint32_t opcode_length) {
    const FunctionSig* sig = WasmOpcodes::Signature(opcode);
    if (!VALIDATE(sig != nullptr)) {
      this->DecodeError("invalid numeric opcode");
      return 0;
    }
    switch (opcode) {
      case kExprI32SConvertSatF32:
      case kExprI32UConvertSatF32:
      case kExprI32SConvertSatF64:
      case kExprI32UConvertSatF64:
      case kExprI64SConvertSatF32:
      case kExprI64UConvertSatF32:
      case kExprI64SConvertSatF64:
      case kExprI64UConvertSatF64: {
        BuildSimpleOperator(opcode, sig);
        return opcode_length;
      }
      case kExprMemoryInit: {
        MemoryInitImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value size = Pop(2, sig->GetParam(2));
        Value src = Pop(1, sig->GetParam(1));
        Value dst = Pop(0, sig->GetParam(0));
        CALL_INTERFACE_IF_REACHABLE(MemoryInit, imm, dst, src, size);
        return opcode_length + imm.length;
      }
      case kExprDataDrop: {
        DataDropImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        CALL_INTERFACE_IF_REACHABLE(DataDrop, imm);
        return opcode_length + imm.length;
      }
      case kExprMemoryCopy: {
        MemoryCopyImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value size = Pop(2, sig->GetParam(2));
        Value src = Pop(1, sig->GetParam(1));
        Value dst = Pop(0, sig->GetParam(0));
        CALL_INTERFACE_IF_REACHABLE(MemoryCopy, imm, dst, src, size);
        return opcode_length + imm.length;
      }
      case kExprMemoryFill: {
        MemoryIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value size = Pop(2, sig->GetParam(2));
        Value value = Pop(1, sig->GetParam(1));
        Value dst = Pop(0, sig->GetParam(0));
        CALL_INTERFACE_IF_REACHABLE(MemoryFill, imm, dst, value, size);
        return opcode_length + imm.length;
      }
      case kExprTableInit: {
        TableInitImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        ArgVector args = PopArgs(sig);
        CALL_INTERFACE_IF_REACHABLE(TableInit, imm, VectorOf(args));
        return opcode_length + imm.length;
      }
      case kExprElemDrop: {
        ElemDropImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        CALL_INTERFACE_IF_REACHABLE(ElemDrop, imm);
        return opcode_length + imm.length;
      }
      case kExprTableCopy: {
        TableCopyImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        ArgVector args = PopArgs(sig);
        CALL_INTERFACE_IF_REACHABLE(TableCopy, imm, VectorOf(args));
        return opcode_length + imm.length;
      }
      case kExprTableGrow: {
        TableIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value delta = Pop(1, sig->GetParam(1));
        Value value = Pop(0, this->module_->tables[imm.index].type);
        Value* result = Push(kWasmI32);
        CALL_INTERFACE_IF_REACHABLE(TableGrow, imm, value, delta, result);
        return opcode_length + imm.length;
      }
      case kExprTableSize: {
        TableIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value* result = Push(kWasmI32);
        CALL_INTERFACE_IF_REACHABLE(TableSize, imm, result);
        return opcode_length + imm.length;
      }
      case kExprTableFill: {
        TableIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
        if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
        Value count = Pop(2, sig->GetParam(2));
        Value value = Pop(1, this->module_->tables[imm.index].type);
        Value start = Pop(0, sig->GetParam(0));
        CALL_INTERFACE_IF_REACHABLE(TableFill, imm, start, value, count);
        return opcode_length + imm.length;
      }
      default:
        this->DecodeError("invalid numeric opcode");
        return 0;
    }
  }

  void DoReturn() {
    size_t return_count = this->sig_->return_count();
    if (return_count > 1) {
      this->detected_->Add(kFeature_mv);
    }
    DCHECK_GE(stack_size(), return_count);
    Vector<Value> return_values =
        Vector<Value>{stack_end_ - return_count, return_count};

    CALL_INTERFACE_IF_REACHABLE(DoReturn, return_values);
  }

  V8_INLINE void EnsureStackSpace(int slots_needed) {
    if (V8_LIKELY(stack_capacity_end_ - stack_end_ >= slots_needed)) return;
    GrowStackSpace(slots_needed);
  }

  V8_NOINLINE void GrowStackSpace(int slots_needed) {
    size_t new_stack_capacity =
        std::max(size_t{8},
                 base::bits::RoundUpToPowerOfTwo(stack_size() + slots_needed));
    Value* new_stack =
        this->zone()->template NewArray<Value>(new_stack_capacity);
    if (stack_) {
      std::copy(stack_, stack_end_, new_stack);
      this->zone()->DeleteArray(stack_, stack_capacity_end_ - stack_);
    }
    stack_end_ = new_stack + (stack_end_ - stack_);
    stack_ = new_stack;
    stack_capacity_end_ = new_stack + new_stack_capacity;
  }

  V8_INLINE Value* Push(ValueType type) {
    DCHECK_NE(kWasmStmt, type);
    // {EnsureStackSpace} should have been called before, either in the central
    // decoding loop, or individually if more than one element is pushed.
    DCHECK_GT(stack_capacity_end_, stack_end_);
    *stack_end_ = Value{this->pc_, type};
    ++stack_end_;
    return stack_end_ - 1;
  }

  void PushMergeValues(Control* c, Merge<Value>* merge) {
    DCHECK_EQ(c, &control_.back());
    DCHECK(merge == &c->start_merge || merge == &c->end_merge);
    DCHECK_LE(stack_ + c->stack_depth, stack_end_);
    stack_end_ = stack_ + c->stack_depth;
    if (merge->arity == 1) {
      // {EnsureStackSpace} should have been called before in the central
      // decoding loop.
      DCHECK_GT(stack_capacity_end_, stack_end_);
      *stack_end_++ = merge->vals.first;
    } else {
      EnsureStackSpace(merge->arity);
      for (uint32_t i = 0; i < merge->arity; i++) {
        *stack_end_++ = merge->vals.array[i];
      }
    }
    DCHECK_EQ(c->stack_depth + merge->arity, stack_size());
  }

  Value* PushReturns(const FunctionSig* sig) {
    size_t return_count = sig->return_count();
    EnsureStackSpace(static_cast<int>(return_count));
    for (size_t i = 0; i < return_count; ++i) {
      Push(sig->GetReturn(i));
    }
    return stack_end_ - return_count;
  }

  // We do not inline these functions because doing so causes a large binary
  // size increase. Not inlining them should not create a performance
  // degradation, because their invocations are guarded by V8_LIKELY.
  V8_NOINLINE void PopTypeError(int index, Value val, ValueType expected) {
    this->DecodeError(val.pc(), "%s[%d] expected type %s, found %s of type %s",
                      SafeOpcodeNameAt(this->pc_), index,
                      expected.name().c_str(), SafeOpcodeNameAt(val.pc()),
                      val.type.name().c_str());
  }

  V8_NOINLINE void NotEnoughArgumentsError(int index) {
    this->DecodeError(
        "not enough arguments on the stack for %s, expected %d more",
        SafeOpcodeNameAt(this->pc_), index + 1);
  }

  V8_INLINE Value Pop(int index, ValueType expected) {
    Value val = Pop(index);
    if (!VALIDATE(IsSubtypeOf(val.type, expected, this->module_) ||
                  val.type == kWasmBottom || expected == kWasmBottom)) {
      PopTypeError(index, val, expected);
    }
    return val;
  }

  V8_INLINE Value Pop(int index) {
    DCHECK(!control_.empty());
    uint32_t limit = control_.back().stack_depth;
    if (stack_size() <= limit) {
      // Popping past the current control start in reachable code.
      if (!VALIDATE(control_.back().unreachable())) {
        NotEnoughArgumentsError(index);
      }
      return UnreachableValue(this->pc_);
    }
    DCHECK_LT(stack_, stack_end_);
    stack_end_--;
    return *stack_end_;
  }

  // Pops values from the stack, as defined by {merge}. Thereby we type-check
  // unreachable merges. Afterwards the values are pushed again on the stack
  // according to the signature in {merge}. This is done so follow-up validation
  // is possible.
  bool TypeCheckUnreachableMerge(Merge<Value>& merge, bool conditional_branch) {
    int arity = merge.arity;
    // For conditional branches, stack value '0' is the condition of the branch,
    // and the result values start at index '1'.
    int index_offset = conditional_branch ? 1 : 0;
    for (int i = arity - 1; i >= 0; --i) Pop(index_offset + i, merge[i].type);
    // Push values of the correct type back on the stack.
    EnsureStackSpace(arity);
    for (int i = 0; i < arity; ++i) Push(merge[i].type);
    return this->ok();
  }

  int startrel(const byte* ptr) { return static_cast<int>(ptr - this->start_); }

  void FallThruTo(Control* c) {
    DCHECK_EQ(c, &control_.back());
    if (!TypeCheckFallThru()) return;
    if (!c->reachable()) return;

    if (!c->is_loop()) CALL_INTERFACE(FallThruTo, c);
    c->end_merge.reached = true;
  }

  bool TypeCheckMergeValues(Control* c, Merge<Value>* merge) {
    // This is a CHECK instead of a DCHECK because {validate} is a constexpr,
    // and a CHECK makes the whole function unreachable.
    static_assert(validate, "Call this function only within VALIDATE");
    DCHECK(merge == &c->start_merge || merge == &c->end_merge);
    DCHECK_GE(stack_size(), c->stack_depth + merge->arity);
    // The computation of {stack_values} is only valid if {merge->arity} is >0.
    DCHECK_LT(0, merge->arity);
    Value* stack_values = stack_end_ - merge->arity;
    // Typecheck the topmost {merge->arity} values on the stack.
    for (uint32_t i = 0; i < merge->arity; ++i) {
      Value& val = stack_values[i];
      Value& old = (*merge)[i];
      if (!VALIDATE(IsSubtypeOf(val.type, old.type, this->module_))) {
        this->DecodeError("type error in merge[%u] (expected %s, got %s)", i,
                          old.type.name().c_str(), val.type.name().c_str());
        return false;
      }
    }

    return true;
  }

  bool TypeCheckOneArmedIf(Control* c) {
    static_assert(validate, "Call this function only within VALIDATE");
    DCHECK(c->is_onearmed_if());
    DCHECK_EQ(c->start_merge.arity, c->end_merge.arity);
    for (uint32_t i = 0; i < c->start_merge.arity; ++i) {
      Value& start = c->start_merge[i];
      Value& end = c->end_merge[i];
      if (!VALIDATE(IsSubtypeOf(start.type, end.type, this->module_))) {
        this->DecodeError("type error in merge[%u] (expected %s, got %s)", i,
                          end.type.name().c_str(), start.type.name().c_str());
        return false;
      }
    }

    return true;
  }

  bool TypeCheckFallThru() {
    static_assert(validate, "Call this function only within VALIDATE");
    Control& c = control_.back();
    if (V8_LIKELY(c.reachable())) {
      uint32_t expected = c.end_merge.arity;
      DCHECK_GE(stack_size(), c.stack_depth);
      uint32_t actual = stack_size() - c.stack_depth;
      // Fallthrus must match the arity of the control exactly.
      if (!VALIDATE(actual == expected)) {
        this->DecodeError(
            "expected %u elements on the stack for fallthru to @%d, found %u",
            expected, startrel(c.pc()), actual);
        return false;
      }
      if (expected == 0) return true;  // Fast path.

      return TypeCheckMergeValues(&c, &c.end_merge);
    }

    // Type-check an unreachable fallthru. First we do an arity check, then a
    // type check. Note that type-checking may require an adjustment of the
    // stack, if some stack values are missing to match the block signature.
    Merge<Value>& merge = c.end_merge;
    int arity = static_cast<int>(merge.arity);
    int available = static_cast<int>(stack_size()) - c.stack_depth;
    // For fallthrus, not more than the needed values should be available.
    if (!VALIDATE(available <= arity)) {
      this->DecodeError(
          "expected %u elements on the stack for fallthru to @%d, found %u",
          arity, startrel(c.pc()), available);
      return false;
    }
    // Pop all values from the stack for type checking of existing stack
    // values.
    return TypeCheckUnreachableMerge(merge, false);
  }

  enum TypeCheckBranchResult {
    kReachableBranch,
    kUnreachableBranch,
    kInvalidStack,
  };

  TypeCheckBranchResult TypeCheckBranch(Control* c, bool conditional_branch) {
    if (V8_LIKELY(control_.back().reachable())) {
      // We only do type-checking here. This is only needed during validation.
      if (!validate) return kReachableBranch;

      // Branches must have at least the number of values expected; can have
      // more.
      uint32_t expected = c->br_merge()->arity;
      if (expected == 0) return kReachableBranch;  // Fast path.
      DCHECK_GE(stack_size(), control_.back().stack_depth);
      uint32_t actual =
          static_cast<uint32_t>(stack_size()) - control_.back().stack_depth;
      if (!VALIDATE(actual >= expected)) {
        this->DecodeError(
            "expected %u elements on the stack for br to @%d, found %u",
            expected, startrel(c->pc()), actual);
        return kInvalidStack;
      }
      return TypeCheckMergeValues(c, c->br_merge()) ? kReachableBranch
                                                    : kInvalidStack;
    }

    return TypeCheckUnreachableMerge(*c->br_merge(), conditional_branch)
               ? kUnreachableBranch
               : kInvalidStack;
  }

  bool TypeCheckReturn() {
    int num_returns = static_cast<int>(this->sig_->return_count());
    // No type checking is needed if there are no returns.
    if (num_returns == 0) return true;

    // Returns must have at least the number of values expected; can have more.
    int num_available =
        static_cast<int>(stack_size()) - control_.back().stack_depth;
    if (!VALIDATE(num_available >= num_returns)) {
      this->DecodeError(
          "expected %u elements on the stack for return, found %u", num_returns,
          num_available);
      return false;
    }

    // Typecheck the topmost {num_returns} values on the stack.
    // This line requires num_returns > 0.
    Value* stack_values = stack_end_ - num_returns;
    for (int i = 0; i < num_returns; ++i) {
      Value& val = stack_values[i];
      ValueType expected_type = this->sig_->GetReturn(i);
      if (!VALIDATE(IsSubtypeOf(val.type, expected_type, this->module_))) {
        this->DecodeError("type error in return[%u] (expected %s, got %s)", i,
                          expected_type.name().c_str(),
                          val.type.name().c_str());
        return false;
      }
    }
    return true;
  }

  void onFirstError() override {
    this->end_ = this->pc_;  // Terminate decoding loop.
    this->current_code_reachable_ = false;
    TRACE(" !%s\n", this->error_.message().c_str());
    CALL_INTERFACE(OnFirstError);
  }

  int BuildSimplePrototypeOperator(WasmOpcode opcode) {
    if (opcode == kExprRefEq) {
      CHECK_PROTOTYPE_OPCODE(gc);
    }
    const FunctionSig* sig = WasmOpcodes::Signature(opcode);
    return BuildSimpleOperator(opcode, sig);
  }

  int BuildSimpleOperator(WasmOpcode opcode, const FunctionSig* sig) {
    DCHECK_GE(1, sig->return_count());
    ValueType ret = sig->return_count() == 0 ? kWasmStmt : sig->GetReturn(0);
    if (sig->parameter_count() == 1) {
      return BuildSimpleOperator(opcode, ret, sig->GetParam(0));
    } else {
      DCHECK_EQ(2, sig->parameter_count());
      return BuildSimpleOperator(opcode, ret, sig->GetParam(0),
                                 sig->GetParam(1));
    }
  }

  int BuildSimpleOperator(WasmOpcode opcode, ValueType return_type,
                          ValueType arg_type) {
    Value val = Pop(0, arg_type);
    Value* ret = return_type == kWasmStmt ? nullptr : Push(return_type);
    CALL_INTERFACE_IF_REACHABLE(UnOp, opcode, val, ret);
    return 1;
  }

  int BuildSimpleOperator(WasmOpcode opcode, ValueType return_type,
                          ValueType lhs_type, ValueType rhs_type) {
    Value rval = Pop(1, rhs_type);
    Value lval = Pop(0, lhs_type);
    Value* ret = return_type == kWasmStmt ? nullptr : Push(return_type);
    CALL_INTERFACE_IF_REACHABLE(BinOp, opcode, lval, rval, ret);
    return 1;
  }

#define DEFINE_SIMPLE_SIG_OPERATOR(sig, ...)         \
  int BuildSimpleOperator_##sig(WasmOpcode opcode) { \
    return BuildSimpleOperator(opcode, __VA_ARGS__); \
  }
  FOREACH_SIGNATURE(DEFINE_SIMPLE_SIG_OPERATOR)
#undef DEFINE_SIMPLE_SIG_OPERATOR
};

#undef CALL_INTERFACE
#undef CALL_INTERFACE_IF_REACHABLE
#undef CALL_INTERFACE_IF_PARENT_REACHABLE

class EmptyInterface {
 public:
  static constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
  using Value = ValueBase<validate>;
  using Control = ControlBase<Value, validate>;
  using FullDecoder = WasmFullDecoder<validate, EmptyInterface>;

#define DEFINE_EMPTY_CALLBACK(name, ...) \
  void name(FullDecoder* decoder, ##__VA_ARGS__) {}
  INTERFACE_FUNCTIONS(DEFINE_EMPTY_CALLBACK)
#undef DEFINE_EMPTY_CALLBACK
};

#undef TRACE
#undef TRACE_INST_FORMAT
#undef VALIDATE
#undef CHECK_PROTOTYPE_OPCODE

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_FUNCTION_BODY_DECODER_IMPL_H_
