// Copyright 2015 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.

#include "src/wasm/module-decoder.h"

#include "src/base/functional.h"
#include "src/base/platform/platform.h"
#include "src/flags/flags.h"
#include "src/init/v8.h"
#include "src/logging/counters.h"
#include "src/logging/metrics.h"
#include "src/objects/objects-inl.h"
#include "src/utils/ostreams.h"
#include "src/wasm/decoder.h"
#include "src/wasm/function-body-decoder-impl.h"
#include "src/wasm/struct-types.h"
#include "src/wasm/wasm-constants.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-limits.h"

namespace v8 {
namespace internal {
namespace wasm {

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

namespace {

constexpr char kNameString[] = "name";
constexpr char kSourceMappingURLString[] = "sourceMappingURL";
constexpr char kCompilationHintsString[] = "compilationHints";
constexpr char kDebugInfoString[] = ".debug_info";
constexpr char kExternalDebugInfoString[] = "external_debug_info";

const char* ExternalKindName(ImportExportKindCode kind) {
  switch (kind) {
    case kExternalFunction:
      return "function";
    case kExternalTable:
      return "table";
    case kExternalMemory:
      return "memory";
    case kExternalGlobal:
      return "global";
    case kExternalException:
      return "exception";
  }
  return "unknown";
}

}  // namespace

const char* SectionName(SectionCode code) {
  switch (code) {
    case kUnknownSectionCode:
      return "Unknown";
    case kTypeSectionCode:
      return "Type";
    case kImportSectionCode:
      return "Import";
    case kFunctionSectionCode:
      return "Function";
    case kTableSectionCode:
      return "Table";
    case kMemorySectionCode:
      return "Memory";
    case kGlobalSectionCode:
      return "Global";
    case kExportSectionCode:
      return "Export";
    case kStartSectionCode:
      return "Start";
    case kCodeSectionCode:
      return "Code";
    case kElementSectionCode:
      return "Element";
    case kDataSectionCode:
      return "Data";
    case kExceptionSectionCode:
      return "Exception";
    case kDataCountSectionCode:
      return "DataCount";
    case kNameSectionCode:
      return kNameString;
    case kSourceMappingURLSectionCode:
      return kSourceMappingURLString;
    case kDebugInfoSectionCode:
      return kDebugInfoString;
    case kExternalDebugInfoSectionCode:
      return kExternalDebugInfoString;
    case kCompilationHintsSectionCode:
      return kCompilationHintsString;
    default:
      return "<unknown>";
  }
}

namespace {

bool validate_utf8(Decoder* decoder, WireBytesRef string) {
  return unibrow::Utf8::ValidateEncoding(
      decoder->start() + decoder->GetBufferRelativeOffset(string.offset()),
      string.length());
}

// Reads a length-prefixed string, checking that it is within bounds. Returns
// the offset of the string, and the length as an out parameter.
WireBytesRef consume_string(Decoder* decoder, bool validate_utf8,
                            const char* name) {
  uint32_t length = decoder->consume_u32v("string length");
  uint32_t offset = decoder->pc_offset();
  const byte* string_start = decoder->pc();
  // Consume bytes before validation to guarantee that the string is not oob.
  if (length > 0) {
    decoder->consume_bytes(length, name);
    if (decoder->ok() && validate_utf8 &&
        !unibrow::Utf8::ValidateEncoding(string_start, length)) {
      decoder->errorf(string_start, "%s: no valid UTF-8 string", name);
    }
  }
  return {offset, decoder->failed() ? 0 : length};
}

namespace {
SectionCode IdentifyUnknownSectionInternal(Decoder* decoder) {
  WireBytesRef string = consume_string(decoder, true, "section name");
  if (decoder->failed()) {
    return kUnknownSectionCode;
  }
  const byte* section_name_start =
      decoder->start() + decoder->GetBufferRelativeOffset(string.offset());

  TRACE("  +%d  section name        : \"%.*s\"\n",
        static_cast<int>(section_name_start - decoder->start()),
        string.length() < 20 ? string.length() : 20, section_name_start);

  using SpecialSectionPair = std::pair<Vector<const char>, SectionCode>;
  static constexpr SpecialSectionPair kSpecialSections[]{
      {StaticCharVector(kNameString), kNameSectionCode},
      {StaticCharVector(kSourceMappingURLString), kSourceMappingURLSectionCode},
      {StaticCharVector(kCompilationHintsString), kCompilationHintsSectionCode},
      {StaticCharVector(kDebugInfoString), kDebugInfoSectionCode},
      {StaticCharVector(kExternalDebugInfoString),
       kExternalDebugInfoSectionCode}};

  auto name_vec =
      Vector<const char>::cast(VectorOf(section_name_start, string.length()));
  for (auto& special_section : kSpecialSections) {
    if (name_vec == special_section.first) return special_section.second;
  }

  return kUnknownSectionCode;
}
}  // namespace

// An iterator over the sections in a wasm binary module.
// Automatically skips all unknown sections.
class WasmSectionIterator {
 public:
  explicit WasmSectionIterator(Decoder* decoder)
      : decoder_(decoder),
        section_code_(kUnknownSectionCode),
        section_start_(decoder->pc()),
        section_end_(decoder->pc()) {
    next();
  }

  inline bool more() const { return decoder_->ok() && decoder_->more(); }

  inline SectionCode section_code() const { return section_code_; }

  inline const byte* section_start() const { return section_start_; }

  inline uint32_t section_length() const {
    return static_cast<uint32_t>(section_end_ - section_start_);
  }

  inline Vector<const uint8_t> payload() const {
    return {payload_start_, payload_length()};
  }

  inline const byte* payload_start() const { return payload_start_; }

  inline uint32_t payload_length() const {
    return static_cast<uint32_t>(section_end_ - payload_start_);
  }

  inline const byte* section_end() const { return section_end_; }

  // Advances to the next section, checking that decoding the current section
  // stopped at {section_end_}.
  void advance(bool move_to_section_end = false) {
    if (move_to_section_end && decoder_->pc() < section_end_) {
      decoder_->consume_bytes(
          static_cast<uint32_t>(section_end_ - decoder_->pc()));
    }
    if (decoder_->pc() != section_end_) {
      const char* msg = decoder_->pc() < section_end_ ? "shorter" : "longer";
      decoder_->errorf(decoder_->pc(),
                       "section was %s than expected size "
                       "(%u bytes expected, %zu decoded)",
                       msg, section_length(),
                       static_cast<size_t>(decoder_->pc() - section_start_));
    }
    next();
  }

 private:
  Decoder* decoder_;
  SectionCode section_code_;
  const byte* section_start_;
  const byte* payload_start_;
  const byte* section_end_;

  // Reads the section code/name at the current position and sets up
  // the embedder fields.
  void next() {
    if (!decoder_->more()) {
      section_code_ = kUnknownSectionCode;
      return;
    }
    section_start_ = decoder_->pc();
    uint8_t section_code = decoder_->consume_u8("section code");
    // Read and check the section size.
    uint32_t section_length = decoder_->consume_u32v("section length");

    payload_start_ = decoder_->pc();
    if (decoder_->checkAvailable(section_length)) {
      // Get the limit of the section within the module.
      section_end_ = payload_start_ + section_length;
    } else {
      // The section would extend beyond the end of the module.
      section_end_ = payload_start_;
    }

    if (section_code == kUnknownSectionCode) {
      // Check for the known "name", "sourceMappingURL", or "compilationHints"
      // section.
      // To identify the unknown section we set the end of the decoder bytes to
      // the end of the custom section, so that we do not read the section name
      // beyond the end of the section.
      const byte* module_end = decoder_->end();
      decoder_->set_end(section_end_);
      section_code = IdentifyUnknownSectionInternal(decoder_);
      if (decoder_->ok()) decoder_->set_end(module_end);
      // As a side effect, the above function will forward the decoder to after
      // the identifier string.
      payload_start_ = decoder_->pc();
    } else if (!IsValidSectionCode(section_code)) {
      decoder_->errorf(decoder_->pc(), "unknown section code #0x%02x",
                       section_code);
      section_code = kUnknownSectionCode;
    }
    section_code_ = decoder_->failed() ? kUnknownSectionCode
                                       : static_cast<SectionCode>(section_code);

    if (section_code_ == kUnknownSectionCode && section_end_ > decoder_->pc()) {
      // skip to the end of the unknown section.
      uint32_t remaining = static_cast<uint32_t>(section_end_ - decoder_->pc());
      decoder_->consume_bytes(remaining, "section payload");
    }
  }
};

}  // namespace

// The main logic for decoding the bytes of a module.
class ModuleDecoderImpl : public Decoder {
 public:
  explicit ModuleDecoderImpl(const WasmFeatures& enabled, ModuleOrigin origin)
      : Decoder(nullptr, nullptr),
        enabled_features_(enabled),
        origin_(origin) {}

  ModuleDecoderImpl(const WasmFeatures& enabled, const byte* module_start,
                    const byte* module_end, ModuleOrigin origin)
      : Decoder(module_start, module_end),
        enabled_features_(enabled),
        module_start_(module_start),
        module_end_(module_end),
        origin_(origin) {
    if (end_ < start_) {
      error(start_, "end is less than start");
      end_ = start_;
    }
  }

  void onFirstError() override {
    pc_ = end_;  // On error, terminate section decoding loop.
  }

  void DumpModule(const Vector<const byte> module_bytes) {
#if !defined(STARBOARD)
    std::string path;
    if (FLAG_dump_wasm_module_path) {
      path = FLAG_dump_wasm_module_path;
      if (path.size() &&
          !base::OS::isDirectorySeparator(path[path.size() - 1])) {
        path += base::OS::DirectorySeparator();
      }
    }
    // File are named `HASH.{ok,failed}.wasm`.
    size_t hash = base::hash_range(module_bytes.begin(), module_bytes.end());
    EmbeddedVector<char, 32> buf;
    SNPrintF(buf, "%016zx.%s.wasm", hash, ok() ? "ok" : "failed");
    path += buf.begin();
    size_t rv = 0;
    if (FILE* file = base::OS::FOpen(path.c_str(), "wb")) {
      rv = fwrite(module_bytes.begin(), module_bytes.length(), 1, file);
      fclose(file);
    }
    if (rv != 1) {
      OFStream os(stderr);
      os << "Error while dumping wasm file to " << path << std::endl;
    }
#endif  // !defined(STARBOARD)
  }

  void StartDecoding(Counters* counters, AccountingAllocator* allocator) {
    CHECK_NULL(module_);
    SetCounters(counters);
    module_.reset(
        new WasmModule(std::make_unique<Zone>(allocator, "signatures")));
    module_->initial_pages = 0;
    module_->maximum_pages = 0;
    module_->mem_export = false;
    module_->origin = origin_;
  }

  void DecodeModuleHeader(Vector<const uint8_t> bytes, uint8_t offset) {
    if (failed()) return;
    Reset(bytes, offset);

    const byte* pos = pc_;
    uint32_t magic_word = consume_u32("wasm magic");
#define BYTES(x) (x & 0xFF), (x >> 8) & 0xFF, (x >> 16) & 0xFF, (x >> 24) & 0xFF
    if (magic_word != kWasmMagic) {
      errorf(pos,
             "expected magic word %02x %02x %02x %02x, "
             "found %02x %02x %02x %02x",
             BYTES(kWasmMagic), BYTES(magic_word));
    }

    pos = pc_;
    {
      uint32_t magic_version = consume_u32("wasm version");
      if (magic_version != kWasmVersion) {
        errorf(pos,
               "expected version %02x %02x %02x %02x, "
               "found %02x %02x %02x %02x",
               BYTES(kWasmVersion), BYTES(magic_version));
      }
    }
#undef BYTES
  }

  bool CheckSectionOrder(SectionCode section_code,
                         SectionCode prev_section_code,
                         SectionCode next_section_code) {
    if (next_ordered_section_ > next_section_code) {
      errorf(pc(), "The %s section must appear before the %s section",
             SectionName(section_code), SectionName(next_section_code));
      return false;
    }
    if (next_ordered_section_ <= prev_section_code) {
      next_ordered_section_ = prev_section_code + 1;
    }
    return true;
  }

  bool CheckUnorderedSection(SectionCode section_code) {
    if (has_seen_unordered_section(section_code)) {
      errorf(pc(), "Multiple %s sections not allowed",
             SectionName(section_code));
      return false;
    }
    set_seen_unordered_section(section_code);
    return true;
  }

  void DecodeSection(SectionCode section_code, Vector<const uint8_t> bytes,
                     uint32_t offset, bool verify_functions = true) {
    if (failed()) return;
    Reset(bytes, offset);
    TRACE("Section: %s\n", SectionName(section_code));
    TRACE("Decode Section %p - %p\n", bytes.begin(), bytes.end());

    // Check if the section is out-of-order.
    if (section_code < next_ordered_section_ &&
        section_code < kFirstUnorderedSection) {
      errorf(pc(), "unexpected section <%s>", SectionName(section_code));
      return;
    }

    switch (section_code) {
      case kUnknownSectionCode:
        break;
      case kDataCountSectionCode:
        if (!CheckUnorderedSection(section_code)) return;
        if (!CheckSectionOrder(section_code, kElementSectionCode,
                               kCodeSectionCode))
          return;
        break;
      case kExceptionSectionCode:
        if (!CheckUnorderedSection(section_code)) return;
        if (!CheckSectionOrder(section_code, kMemorySectionCode,
                               kGlobalSectionCode))
          return;
        break;
      case kNameSectionCode:
        // TODO(titzer): report out of place name section as a warning.
        // Be lenient with placement of name section. All except first
        // occurrence are ignored.
      case kSourceMappingURLSectionCode:
        // sourceMappingURL is a custom section and currently can occur anywhere
        // in the module. In case of multiple sourceMappingURL sections, all
        // except the first occurrence are ignored.
      case kDebugInfoSectionCode:
        // .debug_info is a custom section containing core DWARF information
        // if produced by compiler. Its presence likely means that Wasm was
        // built in a debug mode.
      case kExternalDebugInfoSectionCode:
        // external_debug_info is a custom section containing a reference to an
        // external symbol file.
      case kCompilationHintsSectionCode:
        // TODO(frgossen): report out of place compilation hints section as a
        // warning.
        // Be lenient with placement of compilation hints section. All except
        // first occurrence after function section and before code section are
        // ignored.
        break;
      default:
        next_ordered_section_ = section_code + 1;
        break;
    }

    switch (section_code) {
      case kUnknownSectionCode:
        break;
      case kTypeSectionCode:
        DecodeTypeSection();
        break;
      case kImportSectionCode:
        DecodeImportSection();
        break;
      case kFunctionSectionCode:
        DecodeFunctionSection();
        break;
      case kTableSectionCode:
        DecodeTableSection();
        break;
      case kMemorySectionCode:
        DecodeMemorySection();
        break;
      case kGlobalSectionCode:
        DecodeGlobalSection();
        break;
      case kExportSectionCode:
        DecodeExportSection();
        break;
      case kStartSectionCode:
        DecodeStartSection();
        break;
      case kCodeSectionCode:
        DecodeCodeSection(verify_functions);
        break;
      case kElementSectionCode:
        DecodeElementSection();
        break;
      case kDataSectionCode:
        DecodeDataSection();
        break;
      case kNameSectionCode:
        DecodeNameSection();
        break;
      case kSourceMappingURLSectionCode:
        DecodeSourceMappingURLSection();
        break;
      case kDebugInfoSectionCode:
        // If there is an explicit source map, prefer it over DWARF info.
        if (module_->debug_symbols.type == WasmDebugSymbols::Type::None) {
          module_->debug_symbols = {WasmDebugSymbols::Type::EmbeddedDWARF, {}};
        }
        consume_bytes(static_cast<uint32_t>(end_ - start_), ".debug_info");
        break;
      case kExternalDebugInfoSectionCode:
        DecodeExternalDebugInfoSection();
        break;
      case kCompilationHintsSectionCode:
        if (enabled_features_.has_compilation_hints()) {
          DecodeCompilationHintsSection();
        } else {
          // Ignore this section when feature was disabled. It is an optional
          // custom section anyways.
          consume_bytes(static_cast<uint32_t>(end_ - start_), nullptr);
        }
        break;
      case kDataCountSectionCode:
        if (enabled_features_.has_bulk_memory()) {
          DecodeDataCountSection();
        } else {
          errorf(pc(), "unexpected section <%s>", SectionName(section_code));
        }
        break;
      case kExceptionSectionCode:
        if (enabled_features_.has_eh()) {
          DecodeExceptionSection();
        } else {
          errorf(pc(), "unexpected section <%s>", SectionName(section_code));
        }
        break;
      default:
        errorf(pc(), "unexpected section <%s>", SectionName(section_code));
        return;
    }

    if (pc() != bytes.end()) {
      const char* msg = pc() < bytes.end() ? "shorter" : "longer";
      errorf(pc(),
             "section was %s than expected size "
             "(%zu bytes expected, %zu decoded)",
             msg, bytes.size(), static_cast<size_t>(pc() - bytes.begin()));
    }
  }

  void DecodeTypeSection() {
    uint32_t signatures_count = consume_count("types count", kV8MaxWasmTypes);
    module_->types.reserve(signatures_count);
    for (uint32_t i = 0; ok() && i < signatures_count; ++i) {
      TRACE("DecodeSignature[%d] module+%d\n", i,
            static_cast<int>(pc_ - start_));
      uint8_t kind = consume_u8("type kind");
      switch (kind) {
        case kWasmFunctionTypeCode: {
          const FunctionSig* s = consume_sig(module_->signature_zone.get());
          module_->add_signature(s);
          break;
        }
        case kWasmStructTypeCode: {
          if (!enabled_features_.has_gc()) {
            errorf(pc(),
                   "invalid struct type definition, enable with "
                   "--experimental-wasm-gc");
            break;
          }
          const StructType* s = consume_struct(module_->signature_zone.get());
          module_->add_struct_type(s);
          // TODO(7748): Should we canonicalize struct types, like
          // {signature_map} does for function signatures?
          break;
        }
        case kWasmArrayTypeCode: {
          if (!enabled_features_.has_gc()) {
            errorf(pc(),
                   "invalid array type definition, enable with "
                   "--experimental-wasm-gc");
            break;
          }
          const ArrayType* type = consume_array(module_->signature_zone.get());
          module_->add_array_type(type);
          break;
        }
        default:
          errorf(pc(), "unknown type form: %d", kind);
          break;
      }
    }
    module_->signature_map.Freeze();
  }

  void DecodeImportSection() {
    uint32_t import_table_count =
        consume_count("imports count", kV8MaxWasmImports);
    module_->import_table.reserve(import_table_count);
    for (uint32_t i = 0; ok() && i < import_table_count; ++i) {
      TRACE("DecodeImportTable[%d] module+%d\n", i,
            static_cast<int>(pc_ - start_));

      module_->import_table.push_back({
          {0, 0},             // module_name
          {0, 0},             // field_name
          kExternalFunction,  // kind
          0                   // index
      });
      WasmImport* import = &module_->import_table.back();
      const byte* pos = pc_;
      import->module_name = consume_string(this, true, "module name");
      import->field_name = consume_string(this, true, "field name");
      import->kind =
          static_cast<ImportExportKindCode>(consume_u8("import kind"));
      switch (import->kind) {
        case kExternalFunction: {
          // ===== Imported function ===========================================
          import->index = static_cast<uint32_t>(module_->functions.size());
          module_->num_imported_functions++;
          module_->functions.push_back({nullptr,        // sig
                                        import->index,  // func_index
                                        0,              // sig_index
                                        {0, 0},         // code
                                        true,           // imported
                                        false,          // exported
                                        false});        // declared
          WasmFunction* function = &module_->functions.back();
          function->sig_index =
              consume_sig_index(module_.get(), &function->sig);
          break;
        }
        case kExternalTable: {
          // ===== Imported table ==============================================
          if (!AddTable(module_.get())) break;
          import->index = static_cast<uint32_t>(module_->tables.size());
          module_->num_imported_tables++;
          module_->tables.emplace_back();
          WasmTable* table = &module_->tables.back();
          table->imported = true;
          const byte* type_position = pc();
          ValueType type = consume_reference_type();
          if (!WasmTable::IsValidTableType(type, module_.get())) {
            error(type_position,
                  "Currently, only nullable exnref, externref, and "
                  "function references are allowed as table types");
            break;
          }
          table->type = type;
          uint8_t flags = validate_table_flags("element count");
          consume_resizable_limits(
              "element count", "elements", std::numeric_limits<uint32_t>::max(),
              &table->initial_size, &table->has_maximum_size,
              std::numeric_limits<uint32_t>::max(), &table->maximum_size,
              flags);
          break;
        }
        case kExternalMemory: {
          // ===== Imported memory =============================================
          if (!AddMemory(module_.get())) break;
          uint8_t flags = validate_memory_flags(&module_->has_shared_memory,
                                                &module_->is_memory64);
          consume_resizable_limits("memory", "pages", max_mem_pages(),
                                   &module_->initial_pages,
                                   &module_->has_maximum_pages, max_mem_pages(),
                                   &module_->maximum_pages, flags);
          break;
        }
        case kExternalGlobal: {
          // ===== Imported global =============================================
          import->index = static_cast<uint32_t>(module_->globals.size());
          module_->globals.push_back(
              {kWasmStmt, false, WasmInitExpr(), {0}, true, false});
          WasmGlobal* global = &module_->globals.back();
          global->type = consume_value_type();
          global->mutability = consume_mutability();
          if (global->mutability) {
            module_->num_imported_mutable_globals++;
          }
          break;
        }
        case kExternalException: {
          // ===== Imported exception ==========================================
          if (!enabled_features_.has_eh()) {
            errorf(pos, "unknown import kind 0x%02x", import->kind);
            break;
          }
          import->index = static_cast<uint32_t>(module_->exceptions.size());
          const WasmExceptionSig* exception_sig = nullptr;
          consume_exception_attribute();  // Attribute ignored for now.
          consume_exception_sig_index(module_.get(), &exception_sig);
          module_->exceptions.emplace_back(exception_sig);
          break;
        }
        default:
          errorf(pos, "unknown import kind 0x%02x", import->kind);
          break;
      }
    }
  }

  void DecodeFunctionSection() {
    uint32_t functions_count =
        consume_count("functions count", kV8MaxWasmFunctions);
    auto counter =
        SELECT_WASM_COUNTER(GetCounters(), origin_, wasm_functions_per, module);
    counter->AddSample(static_cast<int>(functions_count));
    DCHECK_EQ(module_->functions.size(), module_->num_imported_functions);
    uint32_t total_function_count =
        module_->num_imported_functions + functions_count;
    module_->functions.reserve(total_function_count);
    module_->num_declared_functions = functions_count;
    for (uint32_t i = 0; i < functions_count; ++i) {
      uint32_t func_index = static_cast<uint32_t>(module_->functions.size());
      module_->functions.push_back({nullptr,     // sig
                                    func_index,  // func_index
                                    0,           // sig_index
                                    {0, 0},      // code
                                    false,       // imported
                                    false,       // exported
                                    false});     // declared
      WasmFunction* function = &module_->functions.back();
      function->sig_index = consume_sig_index(module_.get(), &function->sig);
      if (!ok()) return;
    }
    DCHECK_EQ(module_->functions.size(), total_function_count);
  }

  void DecodeTableSection() {
    // TODO(ahaas): Set the correct limit to {kV8MaxWasmTables} once the
    // implementation of ExternRef landed.
    uint32_t max_count =
        enabled_features_.has_reftypes() ? 100000 : kV8MaxWasmTables;
    uint32_t table_count = consume_count("table count", max_count);

    for (uint32_t i = 0; ok() && i < table_count; i++) {
      if (!AddTable(module_.get())) break;
      module_->tables.emplace_back();
      WasmTable* table = &module_->tables.back();
      const byte* type_position = pc();
      ValueType table_type = consume_reference_type();
      if (!WasmTable::IsValidTableType(table_type, module_.get())) {
        error(type_position,
              "Currently, only nullable exnref, externref, and "
              "function references are allowed as table types");
        continue;
      }
      table->type = table_type;
      uint8_t flags = validate_table_flags("table elements");
      consume_resizable_limits(
          "table elements", "elements", std::numeric_limits<uint32_t>::max(),
          &table->initial_size, &table->has_maximum_size,
          std::numeric_limits<uint32_t>::max(), &table->maximum_size, flags);
    }
  }

  void DecodeMemorySection() {
    uint32_t memory_count = consume_count("memory count", kV8MaxWasmMemories);

    for (uint32_t i = 0; ok() && i < memory_count; i++) {
      if (!AddMemory(module_.get())) break;
      uint8_t flags = validate_memory_flags(&module_->has_shared_memory,
                                            &module_->is_memory64);
      consume_resizable_limits("memory", "pages", max_mem_pages(),
                               &module_->initial_pages,
                               &module_->has_maximum_pages, max_mem_pages(),
                               &module_->maximum_pages, flags);
    }
  }

  void DecodeGlobalSection() {
    uint32_t globals_count = consume_count("globals count", kV8MaxWasmGlobals);
    uint32_t imported_globals = static_cast<uint32_t>(module_->globals.size());
    module_->globals.reserve(imported_globals + globals_count);
    for (uint32_t i = 0; ok() && i < globals_count; ++i) {
      TRACE("DecodeGlobal[%d] module+%d\n", i, static_cast<int>(pc_ - start_));
      // Add an uninitialized global and pass a pointer to it.
      module_->globals.push_back(
          {kWasmStmt, false, WasmInitExpr(), {0}, false, false});
      WasmGlobal* global = &module_->globals.back();
      global->type = consume_value_type();
      global->mutability = consume_mutability();
      global->init =
          consume_init_expr(module_.get(), global->type, imported_globals + i);
    }
    if (ok()) CalculateGlobalOffsets(module_.get());
  }

  void DecodeExportSection() {
    uint32_t export_table_count =
        consume_count("exports count", kV8MaxWasmExports);
    module_->export_table.reserve(export_table_count);
    for (uint32_t i = 0; ok() && i < export_table_count; ++i) {
      TRACE("DecodeExportTable[%d] module+%d\n", i,
            static_cast<int>(pc_ - start_));

      module_->export_table.push_back({
          {0, 0},             // name
          kExternalFunction,  // kind
          0                   // index
      });
      WasmExport* exp = &module_->export_table.back();

      exp->name = consume_string(this, true, "field name");

      const byte* pos = pc();
      exp->kind = static_cast<ImportExportKindCode>(consume_u8("export kind"));
      switch (exp->kind) {
        case kExternalFunction: {
          WasmFunction* func = nullptr;
          exp->index =
              consume_func_index(module_.get(), &func, "export function index");

          if (failed()) break;
          DCHECK_NOT_NULL(func);

          module_->num_exported_functions++;
          func->exported = true;
          // Exported functions are considered "declared".
          func->declared = true;
          break;
        }
        case kExternalTable: {
          WasmTable* table = nullptr;
          exp->index = consume_table_index(module_.get(), &table);
          if (table) table->exported = true;
          break;
        }
        case kExternalMemory: {
          uint32_t index = consume_u32v("memory index");
          // TODO(titzer): This should become more regular
          // once we support multiple memories.
          if (!module_->has_memory || index != 0) {
            error("invalid memory index != 0");
          }
          module_->mem_export = true;
          break;
        }
        case kExternalGlobal: {
          WasmGlobal* global = nullptr;
          exp->index = consume_global_index(module_.get(), &global);
          if (global) {
            global->exported = true;
          }
          break;
        }
        case kExternalException: {
          if (!enabled_features_.has_eh()) {
            errorf(pos, "invalid export kind 0x%02x", exp->kind);
            break;
          }
          WasmException* exception = nullptr;
          exp->index = consume_exception_index(module_.get(), &exception);
          break;
        }
        default:
          errorf(pos, "invalid export kind 0x%02x", exp->kind);
          break;
      }
    }
    // Check for duplicate exports (except for asm.js).
    if (ok() && origin_ == kWasmOrigin && module_->export_table.size() > 1) {
      std::vector<WasmExport> sorted_exports(module_->export_table);

      auto cmp_less = [this](const WasmExport& a, const WasmExport& b) {
        // Return true if a < b.
        if (a.name.length() != b.name.length()) {
          return a.name.length() < b.name.length();
        }
        const byte* left = start() + GetBufferRelativeOffset(a.name.offset());
        const byte* right = start() + GetBufferRelativeOffset(b.name.offset());
        return memcmp(left, right, a.name.length()) < 0;
      };
      std::stable_sort(sorted_exports.begin(), sorted_exports.end(), cmp_less);

      auto it = sorted_exports.begin();
      WasmExport* last = &*it++;
      for (auto end = sorted_exports.end(); it != end; last = &*it++) {
        DCHECK(!cmp_less(*it, *last));  // Vector must be sorted.
        if (!cmp_less(*last, *it)) {
          const byte* pc = start() + GetBufferRelativeOffset(it->name.offset());
          TruncatedUserString<> name(pc, it->name.length());
          errorf(pc, "Duplicate export name '%.*s' for %s %d and %s %d",
                 name.length(), name.start(), ExternalKindName(last->kind),
                 last->index, ExternalKindName(it->kind), it->index);
          break;
        }
      }
    }
  }

  void DecodeStartSection() {
    WasmFunction* func;
    const byte* pos = pc_;
    module_->start_function_index =
        consume_func_index(module_.get(), &func, "start function index");
    if (func &&
        (func->sig->parameter_count() > 0 || func->sig->return_count() > 0)) {
      error(pos, "invalid start function: non-zero parameter or return count");
    }
  }

  void DecodeElementSection() {
    uint32_t element_count =
        consume_count("element count", FLAG_wasm_max_table_size);

    for (uint32_t i = 0; ok() && i < element_count; ++i) {
      const byte* pos = pc();

      WasmElemSegment::Status status;
      bool functions_as_elements;
      uint32_t table_index;
      WasmInitExpr offset;
      ValueType type = kWasmBottom;
      consume_element_segment_header(&status, &functions_as_elements, &type,
                                     &table_index, &offset);
      if (failed()) return;
      DCHECK_NE(type, kWasmBottom);

      if (status == WasmElemSegment::kStatusActive) {
        if (table_index >= module_->tables.size()) {
          errorf(pos, "out of bounds table index %u", table_index);
          break;
        }
        if (!IsSubtypeOf(type, module_->tables[table_index].type,
                         this->module_.get())) {
          errorf(pos,
                 "Invalid element segment. Table %u is not a super-type of %s",
                 table_index, type.name().c_str());
          break;
        }
      }

      uint32_t num_elem =
          consume_count("number of elements", max_table_init_entries());
      if (status == WasmElemSegment::kStatusActive) {
        module_->elem_segments.emplace_back(table_index, std::move(offset));
      } else {
        module_->elem_segments.emplace_back(
            status == WasmElemSegment::kStatusDeclarative);
      }

      WasmElemSegment* init = &module_->elem_segments.back();
      init->type = type;
      for (uint32_t j = 0; j < num_elem; j++) {
        uint32_t index = functions_as_elements ? consume_element_expr()
                                               : consume_element_func_index();
        if (failed()) break;
        init->entries.push_back(index);
      }
    }
  }

  void DecodeCodeSection(bool verify_functions) {
    uint32_t pos = pc_offset();
    uint32_t functions_count = consume_u32v("functions count");
    CheckFunctionsCount(functions_count, pos);
    for (uint32_t i = 0; ok() && i < functions_count; ++i) {
      const byte* pos = pc();
      uint32_t size = consume_u32v("body size");
      if (size > kV8MaxWasmFunctionSize) {
        errorf(pos, "size %u > maximum function size %zu", size,
               kV8MaxWasmFunctionSize);
        return;
      }
      uint32_t offset = pc_offset();
      consume_bytes(size, "function body");
      if (failed()) break;
      DecodeFunctionBody(i, size, offset, verify_functions);
    }
    DCHECK_GE(pc_offset(), pos);
    set_code_section(pos, pc_offset() - pos);
  }

  bool CheckFunctionsCount(uint32_t functions_count, uint32_t offset) {
    if (functions_count != module_->num_declared_functions) {
      Reset(nullptr, nullptr, offset);
      errorf(nullptr, "function body count %u mismatch (%u expected)",
             functions_count, module_->num_declared_functions);
      return false;
    }
    return true;
  }

  void DecodeFunctionBody(uint32_t index, uint32_t length, uint32_t offset,
                          bool verify_functions) {
    WasmFunction* function =
        &module_->functions[index + module_->num_imported_functions];
    function->code = {offset, length};
    if (verify_functions) {
      ModuleWireBytes bytes(module_start_, module_end_);
      VerifyFunctionBody(module_->signature_zone->allocator(),
                         index + module_->num_imported_functions, bytes,
                         module_.get(), function);
    }
  }

  bool CheckDataSegmentsCount(uint32_t data_segments_count) {
    if (has_seen_unordered_section(kDataCountSectionCode) &&
        data_segments_count != module_->num_declared_data_segments) {
      errorf(pc(), "data segments count %u mismatch (%u expected)",
             data_segments_count, module_->num_declared_data_segments);
      return false;
    }
    return true;
  }

  void DecodeDataSection() {
    uint32_t data_segments_count =
        consume_count("data segments count", kV8MaxWasmDataSegments);
    if (!CheckDataSegmentsCount(data_segments_count)) return;

    module_->data_segments.reserve(data_segments_count);
    for (uint32_t i = 0; ok() && i < data_segments_count; ++i) {
      const byte* pos = pc();
      TRACE("DecodeDataSegment[%d] module+%d\n", i,
            static_cast<int>(pc_ - start_));

      bool is_active;
      uint32_t memory_index;
      WasmInitExpr dest_addr;
      consume_data_segment_header(&is_active, &memory_index, &dest_addr);
      if (failed()) break;

      if (is_active) {
        if (!module_->has_memory) {
          error("cannot load data without memory");
          break;
        }
        if (memory_index != 0) {
          errorf(pos, "illegal memory index %u != 0", memory_index);
          break;
        }
      }

      uint32_t source_length = consume_u32v("source size");
      uint32_t source_offset = pc_offset();

      if (is_active) {
        module_->data_segments.emplace_back(std::move(dest_addr));
      } else {
        module_->data_segments.emplace_back();
      }

      WasmDataSegment* segment = &module_->data_segments.back();

      consume_bytes(source_length, "segment data");
      if (failed()) break;

      segment->source = {source_offset, source_length};
    }
  }

  void DecodeNameSection() {
    // TODO(titzer): find a way to report name errors as warnings.
    // Ignore all but the first occurrence of name section.
    if (!has_seen_unordered_section(kNameSectionCode)) {
      set_seen_unordered_section(kNameSectionCode);
      // Use an inner decoder so that errors don't fail the outer decoder.
      Decoder inner(start_, pc_, end_, buffer_offset_);
      // Decode all name subsections.
      // Be lenient with their order.
      while (inner.ok() && inner.more()) {
        uint8_t name_type = inner.consume_u8("name type");
        if (name_type & 0x80) inner.error("name type if not varuint7");

        uint32_t name_payload_len = inner.consume_u32v("name payload length");
        if (!inner.checkAvailable(name_payload_len)) break;

        // Decode module name, ignore the rest.
        // Function and local names will be decoded when needed.
        if (name_type == NameSectionKindCode::kModule) {
          WireBytesRef name = consume_string(&inner, false, "module name");
          if (inner.ok() && validate_utf8(&inner, name)) {
            module_->name = name;
          }
        } else {
          inner.consume_bytes(name_payload_len, "name subsection payload");
        }
      }
    }
    // Skip the whole names section in the outer decoder.
    consume_bytes(static_cast<uint32_t>(end_ - start_), nullptr);
  }

  void DecodeSourceMappingURLSection() {
    Decoder inner(start_, pc_, end_, buffer_offset_);
    WireBytesRef url = wasm::consume_string(&inner, true, "module name");
    if (inner.ok() &&
        module_->debug_symbols.type != WasmDebugSymbols::Type::SourceMap) {
      module_->debug_symbols = {WasmDebugSymbols::Type::SourceMap, url};
    }
    set_seen_unordered_section(kSourceMappingURLSectionCode);
    consume_bytes(static_cast<uint32_t>(end_ - start_), nullptr);
  }

  void DecodeExternalDebugInfoSection() {
    Decoder inner(start_, pc_, end_, buffer_offset_);
    WireBytesRef url =
        wasm::consume_string(&inner, true, "external symbol file");
    // If there is an explicit source map, prefer it over DWARF info.
    if (inner.ok() &&
        module_->debug_symbols.type != WasmDebugSymbols::Type::SourceMap) {
      module_->debug_symbols = {WasmDebugSymbols::Type::ExternalDWARF, url};
      set_seen_unordered_section(kExternalDebugInfoSectionCode);
    }
    consume_bytes(static_cast<uint32_t>(end_ - start_), nullptr);
  }

  void DecodeCompilationHintsSection() {
    TRACE("DecodeCompilationHints module+%d\n", static_cast<int>(pc_ - start_));

    // TODO(frgossen): Find a way to report compilation hint errors as warnings.
    // All except first occurrence after function section and before code
    // section are ignored.
    const bool before_function_section =
        next_ordered_section_ <= kFunctionSectionCode;
    const bool after_code_section = next_ordered_section_ > kCodeSectionCode;
    if (before_function_section || after_code_section ||
        has_seen_unordered_section(kCompilationHintsSectionCode)) {
      return;
    }
    set_seen_unordered_section(kCompilationHintsSectionCode);

    // TODO(frgossen) Propagate errors to outer decoder in experimental phase.
    // We should use an inner decoder later and propagate its errors as
    // warnings.
    Decoder& decoder = *this;
    // Decoder decoder(start_, pc_, end_, buffer_offset_);

    // Ensure exactly one compilation hint per function.
    uint32_t hint_count = decoder.consume_u32v("compilation hint count");
    if (hint_count != module_->num_declared_functions) {
      decoder.errorf(decoder.pc(), "Expected %u compilation hints (%u found)",
                     module_->num_declared_functions, hint_count);
    }

    // Decode sequence of compilation hints.
    if (decoder.ok()) {
      module_->compilation_hints.reserve(hint_count);
    }
    for (uint32_t i = 0; decoder.ok() && i < hint_count; i++) {
      TRACE("DecodeCompilationHints[%d] module+%d\n", i,
            static_cast<int>(pc_ - start_));

      // Compilation hints are encoded in one byte each.
      // +-------+----------+---------------+----------+
      // | 2 bit | 2 bit    | 2 bit         | 2 bit    |
      // | ...   | Top tier | Baseline tier | Strategy |
      // +-------+----------+---------------+----------+
      uint8_t hint_byte = decoder.consume_u8("compilation hint");
      if (!decoder.ok()) break;

      // Decode compilation hint.
      WasmCompilationHint hint;
      hint.strategy =
          static_cast<WasmCompilationHintStrategy>(hint_byte & 0x03);
      hint.baseline_tier =
          static_cast<WasmCompilationHintTier>(hint_byte >> 2 & 0x3);
      hint.top_tier =
          static_cast<WasmCompilationHintTier>(hint_byte >> 4 & 0x3);

      // Ensure that the top tier never downgrades a compilation result.
      // If baseline and top tier are the same compilation will be invoked only
      // once.
      if (hint.top_tier < hint.baseline_tier &&
          hint.top_tier != WasmCompilationHintTier::kDefault) {
        decoder.errorf(decoder.pc(),
                       "Invalid compilation hint %#x (forbidden downgrade)",
                       hint_byte);
      }

      // Happily accept compilation hint.
      if (decoder.ok()) {
        module_->compilation_hints.push_back(std::move(hint));
      }
    }

    // If section was invalid reset compilation hints.
    if (decoder.failed()) {
      module_->compilation_hints.clear();
    }

    // @TODO(frgossen) Skip the whole compilation hints section in the outer
    // decoder if inner decoder was used.
    // consume_bytes(static_cast<uint32_t>(end_ - start_), nullptr);
  }

  void DecodeDataCountSection() {
    module_->num_declared_data_segments =
        consume_count("data segments count", kV8MaxWasmDataSegments);
  }

  void DecodeExceptionSection() {
    uint32_t exception_count =
        consume_count("exception count", kV8MaxWasmExceptions);
    for (uint32_t i = 0; ok() && i < exception_count; ++i) {
      TRACE("DecodeException[%d] module+%d\n", i,
            static_cast<int>(pc_ - start_));
      const WasmExceptionSig* exception_sig = nullptr;
      consume_exception_attribute();  // Attribute ignored for now.
      consume_exception_sig_index(module_.get(), &exception_sig);
      module_->exceptions.emplace_back(exception_sig);
    }
  }

  bool CheckMismatchedCounts() {
    // The declared vs. defined function count is normally checked when
    // decoding the code section, but we have to check it here too in case the
    // code section is absent.
    if (module_->num_declared_functions != 0) {
      DCHECK_LT(module_->num_imported_functions, module_->functions.size());
      // We know that the code section has been decoded if the first
      // non-imported function has its code set.
      if (!module_->functions[module_->num_imported_functions].code.is_set()) {
        errorf(pc(), "function count is %u, but code section is absent",
               module_->num_declared_functions);
        return false;
      }
    }
    // Perform a similar check for the DataCount and Data sections, where data
    // segments are declared but the Data section is absent.
    if (!CheckDataSegmentsCount(
            static_cast<uint32_t>(module_->data_segments.size()))) {
      return false;
    }
    return true;
  }

  ModuleResult FinishDecoding(bool verify_functions = true) {
    if (ok() && CheckMismatchedCounts()) {
      CalculateGlobalOffsets(module_.get());
    }

    ModuleResult result = toResult(std::move(module_));
    if (verify_functions && result.ok() && intermediate_error_.has_error()) {
      // Copy error message and location.
      return ModuleResult{std::move(intermediate_error_)};
    }
    return result;
  }

  void set_code_section(uint32_t offset, uint32_t size) {
    module_->code = {offset, size};
  }

  // Decodes an entire module.
  ModuleResult DecodeModule(Counters* counters, AccountingAllocator* allocator,
                            bool verify_functions = true) {
    StartDecoding(counters, allocator);
    uint32_t offset = 0;
    Vector<const byte> orig_bytes(start(), end() - start());
    DecodeModuleHeader(VectorOf(start(), end() - start()), offset);
    if (failed()) {
      return FinishDecoding(verify_functions);
    }
    // Size of the module header.
    offset += 8;
    Decoder decoder(start_ + offset, end_, offset);

    WasmSectionIterator section_iter(&decoder);

    while (ok() && section_iter.more()) {
      // Shift the offset by the section header length
      offset += section_iter.payload_start() - section_iter.section_start();
      if (section_iter.section_code() != SectionCode::kUnknownSectionCode) {
        DecodeSection(section_iter.section_code(), section_iter.payload(),
                      offset, verify_functions);
      }
      // Shift the offset by the remaining section payload
      offset += section_iter.payload_length();
      section_iter.advance(true);
    }

    if (FLAG_dump_wasm_module) DumpModule(orig_bytes);

    if (decoder.failed()) {
      return decoder.toResult<std::unique_ptr<WasmModule>>(nullptr);
    }

    return FinishDecoding(verify_functions);
  }

  // Decodes a single anonymous function starting at {start_}.
  FunctionResult DecodeSingleFunction(Zone* zone,
                                      const ModuleWireBytes& wire_bytes,
                                      const WasmModule* module,
                                      std::unique_ptr<WasmFunction> function) {
    pc_ = start_;
    expect_u8("type form", kWasmFunctionTypeCode);
    if (!ok()) return FunctionResult{std::move(intermediate_error_)};
    function->sig = consume_sig(zone);
    function->code = {off(pc_), static_cast<uint32_t>(end_ - pc_)};

    if (ok())
      VerifyFunctionBody(zone->allocator(), 0, wire_bytes, module,
                         function.get());

    if (intermediate_error_.has_error()) {
      return FunctionResult{std::move(intermediate_error_)};
    }

    return FunctionResult(std::move(function));
  }

  // Decodes a single function signature at {start}.
  const FunctionSig* DecodeFunctionSignature(Zone* zone, const byte* start) {
    pc_ = start;
    if (!expect_u8("type form", kWasmFunctionTypeCode)) return nullptr;
    const FunctionSig* result = consume_sig(zone);
    return ok() ? result : nullptr;
  }

  WasmInitExpr DecodeInitExprForTesting() {
    return consume_init_expr(nullptr, kWasmStmt, 0);
  }

  const std::shared_ptr<WasmModule>& shared_module() const { return module_; }

  Counters* GetCounters() const {
    DCHECK_NOT_NULL(counters_);
    return counters_;
  }

  void SetCounters(Counters* counters) {
    DCHECK_NULL(counters_);
    counters_ = counters;
  }

 private:
  const WasmFeatures enabled_features_;
  std::shared_ptr<WasmModule> module_;
  const byte* module_start_ = nullptr;
  const byte* module_end_ = nullptr;
  Counters* counters_ = nullptr;
  // The type section is the first section in a module.
  uint8_t next_ordered_section_ = kFirstSectionInModule;
  // We store next_ordered_section_ as uint8_t instead of SectionCode so that
  // we can increment it. This static_assert should make sure that SectionCode
  // does not get bigger than uint8_t accidentially.
  static_assert(sizeof(ModuleDecoderImpl::next_ordered_section_) ==
                    sizeof(SectionCode),
                "type mismatch");
  uint32_t seen_unordered_sections_ = 0;
  static_assert(kBitsPerByte *
                        sizeof(ModuleDecoderImpl::seen_unordered_sections_) >
                    kLastKnownModuleSection,
                "not enough bits");
  WasmError intermediate_error_;
  // Set of type offsets discovered in field types during type section decoding.
  // Since struct types may be recursive, this is used for checking and error
  // reporting once the whole type section is parsed.
  std::unordered_map<uint32_t, int> deferred_check_type_index_;
  ModuleOrigin origin_;

  ValueType TypeOf(const WasmInitExpr& expr) {
    switch (expr.kind()) {
      case WasmInitExpr::kNone:
        return kWasmStmt;
      case WasmInitExpr::kGlobalGet:
        return expr.immediate().index < module_->globals.size()
                   ? module_->globals[expr.immediate().index].type
                   : kWasmStmt;
      case WasmInitExpr::kI32Const:
        return kWasmI32;
      case WasmInitExpr::kI64Const:
        return kWasmI64;
      case WasmInitExpr::kF32Const:
        return kWasmF32;
      case WasmInitExpr::kF64Const:
        return kWasmF64;
      case WasmInitExpr::kS128Const:
        return kWasmS128;
      case WasmInitExpr::kRefFuncConst: {
        uint32_t heap_type =
            enabled_features_.has_typed_funcref()
                ? module_->functions[expr.immediate().index].sig_index
                : HeapType::kFunc;
        return ValueType::Ref(heap_type, kNonNullable);
      }
      case WasmInitExpr::kRefNullConst:
        return ValueType::Ref(expr.immediate().heap_type, kNullable);
      case WasmInitExpr::kRttCanon:
        // TODO(7748): If heaptype is "anyref" (not introduced yet),
        // then this should be uint8_t{0}.
        return ValueType::Rtt(expr.immediate().heap_type, uint8_t{1});
      case WasmInitExpr::kRttSub: {
        ValueType operand_type = TypeOf(*expr.operand());
        if (operand_type.is_rtt()) {
          return ValueType::Rtt(expr.immediate().heap_type,
                                operand_type.depth() + 1);
        } else {
          return kWasmStmt;
        }
      }
    }
  }

  bool has_seen_unordered_section(SectionCode section_code) {
    return seen_unordered_sections_ & (1 << section_code);
  }

  void set_seen_unordered_section(SectionCode section_code) {
    seen_unordered_sections_ |= 1 << section_code;
  }

  uint32_t off(const byte* ptr) {
    return static_cast<uint32_t>(ptr - start_) + buffer_offset_;
  }

  bool AddTable(WasmModule* module) {
    if (enabled_features_.has_reftypes()) return true;
    if (module->tables.size() > 0) {
      error("At most one table is supported");
      return false;
    } else {
      return true;
    }
  }

  bool AddMemory(WasmModule* module) {
    if (module->has_memory) {
      error("At most one memory is supported");
      return false;
    } else {
      module->has_memory = true;
      return true;
    }
  }

  // Calculate individual global offsets and total size of globals table.
  void CalculateGlobalOffsets(WasmModule* module) {
    uint32_t untagged_offset = 0;
    uint32_t tagged_offset = 0;
    uint32_t num_imported_mutable_globals = 0;
    for (WasmGlobal& global : module->globals) {
      if (global.mutability && global.imported) {
        global.index = num_imported_mutable_globals++;
      } else if (global.type.is_reference_type()) {
        global.offset = tagged_offset;
        // All entries in the tagged_globals_buffer have size 1.
        tagged_offset++;
      } else {
        int size = global.type.element_size_bytes();
        untagged_offset = (untagged_offset + size - 1) & ~(size - 1);  // align
        global.offset = untagged_offset;
        untagged_offset += size;
      }
    }
    module->untagged_globals_buffer_size = untagged_offset;
    module->tagged_globals_buffer_size = tagged_offset;
  }

  // Verifies the body (code) of a given function.
  void VerifyFunctionBody(AccountingAllocator* allocator, uint32_t func_num,
                          const ModuleWireBytes& wire_bytes,
                          const WasmModule* module, WasmFunction* function) {
    WasmFunctionName func_name(function,
                               wire_bytes.GetNameOrNull(function, module));
    if (FLAG_trace_wasm_decoder) {
      StdoutStream{} << "Verifying wasm function " << func_name << std::endl;
    }
    FunctionBody body = {
        function->sig, function->code.offset(),
        start_ + GetBufferRelativeOffset(function->code.offset()),
        start_ + GetBufferRelativeOffset(function->code.end_offset())};

    WasmFeatures unused_detected_features = WasmFeatures::None();
    DecodeResult result = VerifyWasmCode(allocator, enabled_features_, module,
                                         &unused_detected_features, body);

    // If the decode failed and this is the first error, set error code and
    // location.
    if (result.failed() && intermediate_error_.empty()) {
      // Wrap the error message from the function decoder.
      std::ostringstream error_msg;
      error_msg << "in function " << func_name << ": "
                << result.error().message();
      intermediate_error_ = WasmError{result.error().offset(), error_msg.str()};
    }
  }

  uint32_t consume_sig_index(WasmModule* module, const FunctionSig** sig) {
    const byte* pos = pc_;
    uint32_t sig_index = consume_u32v("signature index");
    if (!module->has_signature(sig_index)) {
      errorf(pos, "signature index %u out of bounds (%d signatures)", sig_index,
             static_cast<int>(module->types.size()));
      *sig = nullptr;
      return 0;
    }
    *sig = module->signature(sig_index);
    return sig_index;
  }

  uint32_t consume_exception_sig_index(WasmModule* module,
                                       const FunctionSig** sig) {
    const byte* pos = pc_;
    uint32_t sig_index = consume_sig_index(module, sig);
    if (*sig && (*sig)->return_count() != 0) {
      errorf(pos, "exception signature %u has non-void return", sig_index);
      *sig = nullptr;
      return 0;
    }
    return sig_index;
  }

  uint32_t consume_count(const char* name, size_t maximum) {
    const byte* p = pc_;
    uint32_t count = consume_u32v(name);
    if (count > maximum) {
      errorf(p, "%s of %u exceeds internal limit of %zu", name, count, maximum);
      return static_cast<uint32_t>(maximum);
    }
    return count;
  }

  uint32_t consume_func_index(WasmModule* module, WasmFunction** func,
                              const char* name) {
    return consume_index(name, &module->functions, func);
  }

  uint32_t consume_global_index(WasmModule* module, WasmGlobal** global) {
    return consume_index("global index", &module->globals, global);
  }

  uint32_t consume_table_index(WasmModule* module, WasmTable** table) {
    return consume_index("table index", &module->tables, table);
  }

  uint32_t consume_exception_index(WasmModule* module, WasmException** except) {
    return consume_index("exception index", &module->exceptions, except);
  }

  template <typename T>
  uint32_t consume_index(const char* name, std::vector<T>* vector, T** ptr) {
    const byte* pos = pc_;
    uint32_t index = consume_u32v(name);
    if (index >= vector->size()) {
      errorf(pos, "%s %u out of bounds (%d entr%s)", name, index,
             static_cast<int>(vector->size()),
             vector->size() == 1 ? "y" : "ies");
      *ptr = nullptr;
      return 0;
    }
    *ptr = &(*vector)[index];
    return index;
  }

  uint8_t validate_table_flags(const char* name) {
    uint8_t flags = consume_u8("table limits flags");
    STATIC_ASSERT(kNoMaximum < kWithMaximum);
    if (V8_UNLIKELY(flags > kWithMaximum)) {
      errorf(pc() - 1, "invalid %s limits flags", name);
    }
    return flags;
  }

  uint8_t validate_memory_flags(bool* has_shared_memory, bool* is_memory64) {
    uint8_t flags = consume_u8("memory limits flags");
    *has_shared_memory = false;
    switch (flags) {
      case kNoMaximum:
      case kWithMaximum:
        break;
      case kSharedNoMaximum:
      case kSharedWithMaximum:
        if (!enabled_features_.has_threads()) {
          errorf(pc() - 1,
                 "invalid memory limits flags 0x%x (enable via "
                 "--experimental-wasm-threads)",
                 flags);
        }
        *has_shared_memory = true;
        // V8 does not support shared memory without a maximum.
        if (flags == kSharedNoMaximum) {
          errorf(pc() - 1,
                 "memory limits flags must have maximum defined if shared is "
                 "true");
        }
        break;
      case kMemory64NoMaximum:
      case kMemory64WithMaximum:
        if (!enabled_features_.has_memory64()) {
          errorf(pc() - 1,
                 "invalid memory limits flags 0x%x (enable via "
                 "--experimental-wasm-memory64)",
                 flags);
        }
        *is_memory64 = true;
        break;
      default:
        errorf(pc() - 1, "invalid memory limits flags 0x%x", flags);
        break;
    }
    return flags;
  }

  void consume_resizable_limits(const char* name, const char* units,
                                uint32_t max_initial, uint32_t* initial,
                                bool* has_max, uint32_t max_maximum,
                                uint32_t* maximum, uint8_t flags) {
    const byte* pos = pc();
    // For memory64 we need to read the numbers as LEB-encoded 64-bit unsigned
    // integer. All V8 limits are still within uint32_t range though.
    const bool is_memory64 =
        flags == kMemory64NoMaximum || flags == kMemory64WithMaximum;
    uint64_t initial_64 = is_memory64 ? consume_u64v("initial size")
                                      : consume_u32v("initial size");
    if (initial_64 > max_initial) {
      errorf(pos,
             "initial %s size (%" PRIu64
             " %s) is larger than implementation limit (%u)",
             name, initial_64, units, max_initial);
    }
    *initial = static_cast<uint32_t>(initial_64);
    if (flags & 1) {
      *has_max = true;
      pos = pc();
      uint64_t maximum_64 = is_memory64 ? consume_u64v("maximum size")
                                        : consume_u32v("maximum size");
      if (maximum_64 > max_maximum) {
        errorf(pos,
               "maximum %s size (%" PRIu64
               " %s) is larger than implementation limit (%u)",
               name, maximum_64, units, max_maximum);
      }
      if (maximum_64 < *initial) {
        errorf(pos,
               "maximum %s size (%" PRIu64 " %s) is less than initial (%u %s)",
               name, maximum_64, units, *initial, units);
      }
      *maximum = static_cast<uint32_t>(maximum_64);
    } else {
      *has_max = false;
      *maximum = max_initial;
    }
  }

  bool expect_u8(const char* name, uint8_t expected) {
    const byte* pos = pc();
    uint8_t value = consume_u8(name);
    if (value != expected) {
      errorf(pos, "expected %s 0x%02x, got 0x%02x", name, expected, value);
      return false;
    }
    return true;
  }

  // TODO(manoskouk): This is copy-modified from function-body-decoder-impl.h.
  // We should find a way to share this code.
  V8_INLINE bool Validate(const byte* pc,
                          HeapTypeImmediate<kFullValidation>& imm) {
    if (V8_UNLIKELY(imm.type.is_bottom())) {
      error(pc, "invalid heap type");
      return false;
    }
    if (V8_UNLIKELY(!(imm.type.is_generic() ||
                      module_->has_type(imm.type.ref_index())))) {
      errorf(pc, "Type index %u is out of bounds", imm.type.ref_index());
      return false;
    }
    return true;
  }

  WasmInitExpr consume_init_expr(WasmModule* module, ValueType expected,
                                 size_t current_global_index) {
    constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
    WasmOpcode opcode = kExprNop;
    std::vector<WasmInitExpr> stack;
    while (pc() < end() && opcode != kExprEnd) {
      uint32_t len = 1;
      opcode = static_cast<WasmOpcode>(read_u8<validate>(pc(), "opcode"));
      switch (opcode) {
        case kExprGlobalGet: {
          GlobalIndexImmediate<validate> imm(this, pc() + 1);
          len = 1 + imm.length;
          // We use 'capacity' over 'size' because we might be
          // mid-DecodeGlobalSection().
          if (V8_UNLIKELY(imm.index >= module->globals.capacity())) {
            error(pc() + 1, "global index is out of bounds");
            return {};
          }
          if (V8_UNLIKELY(imm.index >= current_global_index)) {
            errorf(pc() + 1, "global #%u is not defined yet", imm.index);
            return {};
          }
          WasmGlobal* global = &module->globals[imm.index];
          if (V8_UNLIKELY(global->mutability)) {
            error(pc() + 1,
                  "mutable globals cannot be used in initializer "
                  "expressions");
            return {};
          }
          if (V8_UNLIKELY(!global->imported && !enabled_features_.has_gc())) {
            error(pc() + 1,
                  "non-imported globals cannot be used in initializer "
                  "expressions");
            return {};
          }
          stack.push_back(WasmInitExpr::GlobalGet(imm.index));
          break;
        }
        case kExprI32Const: {
          ImmI32Immediate<Decoder::kFullValidation> imm(this, pc() + 1);
          stack.emplace_back(imm.value);
          len = 1 + imm.length;
          break;
        }
        case kExprF32Const: {
          ImmF32Immediate<Decoder::kFullValidation> imm(this, pc() + 1);
          stack.emplace_back(imm.value);
          len = 1 + imm.length;
          break;
        }
        case kExprI64Const: {
          ImmI64Immediate<Decoder::kFullValidation> imm(this, pc() + 1);
          stack.emplace_back(imm.value);
          len = 1 + imm.length;
          break;
        }
        case kExprF64Const: {
          ImmF64Immediate<Decoder::kFullValidation> imm(this, pc() + 1);
          stack.emplace_back(imm.value);
          len = 1 + imm.length;
          break;
        }
        case kExprRefNull: {
          if (V8_UNLIKELY(!enabled_features_.has_reftypes() &&
                          !enabled_features_.has_eh())) {
            errorf(pc(),
                   "invalid opcode 0x%x in global initializer, enable with "
                   "--experimental-wasm-reftypes or --experimental-wasm-eh",
                   kExprRefNull);
            return {};
          }
          HeapTypeImmediate<Decoder::kFullValidation> imm(enabled_features_,
                                                          this, pc() + 1);
          len = 1 + imm.length;
          if (!Validate(pc() + 1, imm)) return {};
          stack.push_back(
              WasmInitExpr::RefNullConst(imm.type.representation()));
          break;
        }
        case kExprRefFunc: {
          if (V8_UNLIKELY(!enabled_features_.has_reftypes())) {
            errorf(pc(),
                   "invalid opcode 0x%x in global initializer, enable with "
                   "--experimental-wasm-reftypes",
                   kExprRefFunc);
            return {};
          }

          FunctionIndexImmediate<Decoder::kFullValidation> imm(this, pc() + 1);
          len = 1 + imm.length;
          if (V8_UNLIKELY(module->functions.size() <= imm.index)) {
            errorf(pc(), "invalid function index: %u", imm.index);
            return {};
          }
          stack.push_back(WasmInitExpr::RefFuncConst(imm.index));
          // Functions referenced in the globals section count as "declared".
          module->functions[imm.index].declared = true;
          break;
        }
        case kSimdPrefix: {
          // No need to check for Simd in enabled_features_ here; we either
          // failed to validate the global's type earlier, or will fail in
          // the type check or stack height check at the end.
          opcode = read_prefixed_opcode<validate>(pc(), &len);
          if (V8_UNLIKELY(opcode != kExprS128Const)) {
            errorf(pc(), "invalid SIMD opcode 0x%x in global initializer",
                   opcode);
            return {};
          }

          Simd128Immediate<validate> imm(this, pc() + len);
          len += kSimd128Size;
          stack.emplace_back(imm.value);
          break;
        }
        case kGCPrefix: {
          // No need to check for GC in enabled_features_ here; we either
          // failed to validate the global's type earlier, or will fail in
          // the type check or stack height check at the end.
          opcode = read_prefixed_opcode<validate>(pc(), &len);
          switch (opcode) {
            case kExprRttCanon: {
              HeapTypeImmediate<validate> imm(enabled_features_, this,
                                              pc() + 2);
              len += imm.length;
              if (!Validate(pc() + len, imm)) return {};
              stack.push_back(
                  WasmInitExpr::RttCanon(imm.type.representation()));
              break;
            }
            case kExprRttSub: {
              HeapTypeImmediate<validate> imm(enabled_features_, this,
                                              pc() + 2);
              len += imm.length;
              if (!Validate(pc() + len, imm)) return {};
              if (stack.empty()) {
                error(pc(), "calling rtt.sub without arguments");
                return {};
              }
              WasmInitExpr parent = std::move(stack.back());
              stack.pop_back();
              ValueType parent_type = TypeOf(parent);
              if (V8_UNLIKELY(
                      parent_type.kind() != ValueType::kRtt ||
                      !IsSubtypeOf(
                          ValueType::Ref(imm.type, kNonNullable),
                          ValueType::Ref(parent_type.heap_type(), kNonNullable),
                          module_.get()))) {
                error(pc(), "rtt.sub requires a supertype rtt on stack");
                return {};
              }
              stack.push_back(WasmInitExpr::RttSub(imm.type.representation(),
                                                   std::move(parent)));
              break;
            }
            default: {
              errorf(pc(), "invalid opcode 0x%x in global initializer", opcode);
              return {};
            }
          }
          break;  // case kGCPrefix
        }
        case kExprEnd:
          break;
        default: {
          errorf(pc(), "invalid opcode 0x%x in global initializer", opcode);
          return {};
        }
      }
      pc_ += len;
    }

    if (V8_UNLIKELY(pc() > end())) {
      error(end(), "Global initializer extending beyond code end");
      return {};
    }
    if (V8_UNLIKELY(opcode != kExprEnd)) {
      error(pc(), "Global initializer is missing 'end'");
      return {};
    }
    if (V8_UNLIKELY(stack.size() != 1)) {
      errorf(pc(),
             "Found 'end' in global initalizer, but %s expressions were "
             "found on the stack",
             stack.size() > 1 ? "more than one" : "no");
      return {};
    }

    WasmInitExpr expr = std::move(stack.back());
    if (expected != kWasmStmt && !IsSubtypeOf(TypeOf(expr), expected, module)) {
      errorf(pc(), "type error in init expression, expected %s, got %s",
             expected.name().c_str(), TypeOf(expr).name().c_str());
    }
    return expr;
  }

  // Read a mutability flag
  bool consume_mutability() {
    byte val = consume_u8("mutability");
    if (val > 1) error(pc_ - 1, "invalid mutability");
    return val != 0;
  }

  ValueType consume_value_type() {
    uint32_t type_length;
    ValueType result = value_type_reader::read_value_type<kFullValidation>(
        this, this->pc(), &type_length,
        origin_ == kWasmOrigin ? enabled_features_ : WasmFeatures::None());
    if (result == kWasmBottom) error(pc_, "invalid value type");
    // We use capacity() over size() so this function works
    // mid-DecodeTypeSection.
    if (result.has_index() && result.ref_index() >= module_->types.capacity()) {
      errorf(pc(), "Type index %u is out of bounds", result.ref_index());
    }
    consume_bytes(type_length, "value type");
    return result;
  }

  ValueType consume_storage_type() {
    uint8_t opcode = read_u8<kFullValidation>(this->pc());
    switch (opcode) {
      case kI8Code:
        consume_bytes(1, "i8");
        return kWasmI8;
      case kI16Code:
        consume_bytes(1, "i16");
        return kWasmI16;
      default:
        // It is not a packed type, so it has to be a value type.
        return consume_value_type();
    }
  }

  // Reads a reference type for tables and element segment headers.
  // Unless extensions are enabled, only funcref is allowed.
  // TODO(manoskouk): Replace this with consume_value_type (and checks against
  //                  the returned type at callsites as needed) once the
  //                  'reftypes' proposal is standardized.
  ValueType consume_reference_type() {
    if (!enabled_features_.has_reftypes()) {
      uint8_t ref_type = consume_u8("reference type");
      if (ref_type != kFuncRefCode) {
        error(pc_ - 1,
              "invalid table type. Consider using experimental flags.");
        return kWasmBottom;
      }
      return kWasmFuncRef;
    } else {
      const byte* position = pc();
      ValueType result = consume_value_type();
      if (!result.is_reference_type()) {
        error(position, "expected reference type");
      }
      return result;
    }
  }

  const FunctionSig* consume_sig(Zone* zone) {
    // Parse parameter types.
    uint32_t param_count =
        consume_count("param count", kV8MaxWasmFunctionParams);
    if (failed()) return nullptr;
    std::vector<ValueType> params;
    for (uint32_t i = 0; ok() && i < param_count; ++i) {
      params.push_back(consume_value_type());
    }
    std::vector<ValueType> returns;

    // Parse return types.
    const size_t max_return_count = enabled_features_.has_mv()
                                        ? kV8MaxWasmFunctionMultiReturns
                                        : kV8MaxWasmFunctionReturns;
    uint32_t return_count = consume_count("return count", max_return_count);
    if (failed()) return nullptr;
    for (uint32_t i = 0; ok() && i < return_count; ++i) {
      returns.push_back(consume_value_type());
    }
    if (failed()) return nullptr;

    // FunctionSig stores the return types first.
    ValueType* buffer = zone->NewArray<ValueType>(param_count + return_count);
    uint32_t b = 0;
    for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i];
    for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i];

    return zone->New<FunctionSig>(return_count, param_count, buffer);
  }

  const StructType* consume_struct(Zone* zone) {
    uint32_t field_count = consume_count("field count", kV8MaxWasmStructFields);
    if (failed()) return nullptr;
    ValueType* fields = zone->NewArray<ValueType>(field_count);
    bool* mutabilities = zone->NewArray<bool>(field_count);
    for (uint32_t i = 0; ok() && i < field_count; ++i) {
      ValueType field = consume_storage_type();
      fields[i] = field;
      bool mutability = consume_mutability();
      mutabilities[i] = mutability;
    }
    if (failed()) return nullptr;
    uint32_t* offsets = zone->NewArray<uint32_t>(field_count);
    return zone->New<StructType>(field_count, offsets, fields, mutabilities);
  }

  const ArrayType* consume_array(Zone* zone) {
    ValueType field = consume_storage_type();
    if (failed()) return nullptr;
    bool mutability = consume_mutability();
    if (!mutability) {
      error(this->pc() - 1, "immutable arrays are not supported yet");
    }
    return zone->New<ArrayType>(field, mutability);
  }

  // Consume the attribute field of an exception.
  uint32_t consume_exception_attribute() {
    const byte* pos = pc_;
    uint32_t attribute = consume_u32v("exception attribute");
    if (attribute != kExceptionAttribute) {
      errorf(pos, "exception attribute %u not supported", attribute);
      return 0;
    }
    return attribute;
  }

  void consume_element_segment_header(WasmElemSegment::Status* status,
                                      bool* functions_as_elements,
                                      ValueType* type, uint32_t* table_index,
                                      WasmInitExpr* offset) {
    const byte* pos = pc();
    uint32_t flag;
    if (enabled_features_.has_bulk_memory() ||
        enabled_features_.has_reftypes()) {
      flag = consume_u32v("flag");
    } else {
      uint32_t table_index = consume_u32v("table index");
      // The only valid flag value without bulk_memory or externref is '0'.
      if (table_index != 0) {
        error(
            "Element segments with table indices require "
            "--experimental-wasm-bulk-memory or --experimental-wasm-reftypes");
        return;
      }
      flag = 0;
    }

    // The mask for the bit in the flag which indicates if the segment is
    // active or not.
    constexpr uint8_t kIsPassiveMask = 0x01;
    // The mask for the bit in the flag which indicates if the segment has an
    // explicit table index field.
    constexpr uint8_t kHasTableIndexMask = 0x02;
    // The mask for the bit in the flag which indicates if the functions of this
    // segment are defined as function indices (=0) or elements(=1).
    constexpr uint8_t kFunctionsAsElementsMask = 0x04;
    constexpr uint8_t kFullMask =
        kIsPassiveMask | kHasTableIndexMask | kFunctionsAsElementsMask;

    bool is_passive = flag & kIsPassiveMask;
    if (!is_passive) {
      *status = WasmElemSegment::kStatusActive;
      if (module_->tables.size() == 0) {
        error(pc_, "Active element sections require a table");
      }
    } else if ((flag & kHasTableIndexMask)) {  // Special bit combination for
                                               // declarative segments.
      *status = WasmElemSegment::kStatusDeclarative;
    } else {
      *status = WasmElemSegment::kStatusPassive;
    }
    *functions_as_elements = flag & kFunctionsAsElementsMask;
    bool has_table_index = (flag & kHasTableIndexMask) &&
                           *status == WasmElemSegment::kStatusActive;

    if (*status == WasmElemSegment::kStatusDeclarative &&
        !enabled_features_.has_reftypes()) {
      error(
          "Declarative element segments require --experimental-wasm-reftypes");
      return;
    }
    if (*status == WasmElemSegment::kStatusPassive &&
        !enabled_features_.has_bulk_memory()) {
      error("Passive element segments require --experimental-wasm-bulk-memory");
      return;
    }
    if (*functions_as_elements && !enabled_features_.has_bulk_memory()) {
      error(
          "Illegal segment flag. Did you forget "
          "--experimental-wasm-bulk-memory?");
      return;
    }
    if (flag != 0 && !enabled_features_.has_bulk_memory() &&
        !enabled_features_.has_reftypes()) {
      error(
          "Invalid segment flag. Enable with --experimental-wasm-bulk-memory "
          "or --experimental-wasm-reftypes");
      return;
    }
    if ((flag & kFullMask) != flag) {
      errorf(pos, "illegal flag value %u. Must be between 0 and 7", flag);
    }

    if (has_table_index) {
      *table_index = consume_u32v("table index");
    } else {
      *table_index = 0;
    }

    if (*status == WasmElemSegment::kStatusActive) {
      *offset = consume_init_expr(module_.get(), kWasmI32,
                                  module_.get()->globals.size());
      if (offset->kind() == WasmInitExpr::kNone) {
        // Failed to parse offset initializer, return early.
        return;
      }
    }

    if (*status == WasmElemSegment::kStatusActive && !has_table_index) {
      // Active segments without table indices are a special case for backwards
      // compatibility. These cases have an implicit element kind or element
      // type, so we are done already with the segment header.
      *type = kWasmFuncRef;
      return;
    }

    if (*functions_as_elements) {
      *type = consume_reference_type();
    } else {
      // We have to check that there is an element kind of type Function. All
      // other element kinds are not valid yet.
      uint8_t val = consume_u8("element kind");
      ImportExportKindCode kind = static_cast<ImportExportKindCode>(val);
      if (kind != kExternalFunction) {
        errorf(pos, "illegal element kind %x. Must be 0x00", val);
        return;
      }
      *type = kWasmFuncRef;
    }
  }

  void consume_data_segment_header(bool* is_active, uint32_t* index,
                                   WasmInitExpr* offset) {
    const byte* pos = pc();
    uint32_t flag = consume_u32v("flag");

    // Some flag values are only valid for specific proposals.
    if (flag == SegmentFlags::kPassive) {
      if (!enabled_features_.has_bulk_memory()) {
        error(
            "Passive element segments require --experimental-wasm-bulk-memory");
        return;
      }
    } else if (flag == SegmentFlags::kActiveWithIndex) {
      if (!(enabled_features_.has_bulk_memory() ||
            enabled_features_.has_reftypes())) {
        error(
            "Element segments with table indices require "
            "--experimental-wasm-bulk-memory or --experimental-wasm-reftypes");
        return;
      }
    } else if (flag != SegmentFlags::kActiveNoIndex) {
      errorf(pos, "illegal flag value %u. Must be 0, 1, or 2", flag);
      return;
    }

    // We know now that the flag is valid. Time to read the rest.
    size_t num_globals = module_.get()->globals.size();
    if (flag == SegmentFlags::kActiveNoIndex) {
      *is_active = true;
      *index = 0;
      *offset = consume_init_expr(module_.get(), kWasmI32, num_globals);
      return;
    }
    if (flag == SegmentFlags::kPassive) {
      *is_active = false;
      return;
    }
    if (flag == SegmentFlags::kActiveWithIndex) {
      *is_active = true;
      *index = consume_u32v("memory index");
      *offset = consume_init_expr(module_.get(), kWasmI32, num_globals);
    }
  }

  uint32_t consume_element_func_index() {
    WasmFunction* func = nullptr;
    uint32_t index =
        consume_func_index(module_.get(), &func, "element function index");
    if (failed()) return index;
    func->declared = true;
    DCHECK_NE(func, nullptr);
    DCHECK_EQ(index, func->func_index);
    DCHECK_NE(index, WasmElemSegment::kNullIndex);
    return index;
  }

  uint32_t consume_element_expr() {
    uint32_t index = WasmElemSegment::kNullIndex;
    uint8_t opcode = consume_u8("element opcode");
    if (failed()) return index;
    switch (opcode) {
      case kExprRefNull: {
        HeapTypeImmediate<kFullValidation> imm(WasmFeatures::All(), this,
                                               this->pc());
        consume_bytes(imm.length, "ref.null immediate");
        index = WasmElemSegment::kNullIndex;
        break;
      }
      case kExprRefFunc:
        index = consume_element_func_index();
        if (failed()) return index;
        break;
      default:
        error("invalid opcode in element");
        break;
    }
    expect_u8("end opcode", kExprEnd);
    return index;
  }
};

ModuleResult DecodeWasmModule(
    const WasmFeatures& enabled, const byte* module_start,
    const byte* module_end, bool verify_functions, ModuleOrigin origin,
    Counters* counters, std::shared_ptr<metrics::Recorder> metrics_recorder,
    v8::metrics::Recorder::ContextId context_id, DecodingMethod decoding_method,
    AccountingAllocator* allocator) {
  size_t size = module_end - module_start;
  CHECK_LE(module_start, module_end);
  size_t max_size = max_module_size();
  if (size > max_size) {
    return ModuleResult{
        WasmError{0, "size > maximum module size (%zu): %zu", max_size, size}};
  }
  // TODO(bradnelson): Improve histogram handling of size_t.
  auto size_counter =
      SELECT_WASM_COUNTER(counters, origin, wasm, module_size_bytes);
  size_counter->AddSample(static_cast<int>(size));
  // Signatures are stored in zone memory, which have the same lifetime
  // as the {module}.
  ModuleDecoderImpl decoder(enabled, module_start, module_end, origin);
  v8::metrics::WasmModuleDecoded metrics_event;
  base::ElapsedTimer timer;
  timer.Start();
  ModuleResult result =
      decoder.DecodeModule(counters, allocator, verify_functions);

  // Record event metrics.
  metrics_event.wall_clock_duration_in_us = timer.Elapsed().InMicroseconds();
  timer.Stop();
  metrics_event.success = decoder.ok() && result.ok();
  metrics_event.async = decoding_method == DecodingMethod::kAsync ||
                        decoding_method == DecodingMethod::kAsyncStream;
  metrics_event.streamed = decoding_method == DecodingMethod::kSyncStream ||
                           decoding_method == DecodingMethod::kAsyncStream;
  if (result.ok()) {
    metrics_event.function_count = result.value()->num_declared_functions;
  } else if (auto&& module = decoder.shared_module()) {
    metrics_event.function_count = module->num_declared_functions;
  }
  metrics_event.module_size_in_bytes = size;
  metrics_recorder->DelayMainThreadEvent(metrics_event, context_id);

  return result;
}

ModuleDecoder::ModuleDecoder(const WasmFeatures& enabled)
    : enabled_features_(enabled) {}

ModuleDecoder::~ModuleDecoder() = default;

const std::shared_ptr<WasmModule>& ModuleDecoder::shared_module() const {
  return impl_->shared_module();
}

void ModuleDecoder::StartDecoding(
    Counters* counters, std::shared_ptr<metrics::Recorder> metrics_recorder,
    v8::metrics::Recorder::ContextId context_id, AccountingAllocator* allocator,
    ModuleOrigin origin) {
  DCHECK_NULL(impl_);
  impl_.reset(new ModuleDecoderImpl(enabled_features_, origin));
  impl_->StartDecoding(counters, allocator);
}

void ModuleDecoder::DecodeModuleHeader(Vector<const uint8_t> bytes,
                                       uint32_t offset) {
  impl_->DecodeModuleHeader(bytes, offset);
}

void ModuleDecoder::DecodeSection(SectionCode section_code,
                                  Vector<const uint8_t> bytes, uint32_t offset,
                                  bool verify_functions) {
  impl_->DecodeSection(section_code, bytes, offset, verify_functions);
}

void ModuleDecoder::DecodeFunctionBody(uint32_t index, uint32_t length,
                                       uint32_t offset, bool verify_functions) {
  impl_->DecodeFunctionBody(index, length, offset, verify_functions);
}

bool ModuleDecoder::CheckFunctionsCount(uint32_t functions_count,
                                        uint32_t offset) {
  return impl_->CheckFunctionsCount(functions_count, offset);
}

ModuleResult ModuleDecoder::FinishDecoding(bool verify_functions) {
  return impl_->FinishDecoding(verify_functions);
}

void ModuleDecoder::set_code_section(uint32_t offset, uint32_t size) {
  return impl_->set_code_section(offset, size);
}

size_t ModuleDecoder::IdentifyUnknownSection(ModuleDecoder* decoder,
                                             Vector<const uint8_t> bytes,
                                             uint32_t offset,
                                             SectionCode* result) {
  if (!decoder->ok()) return 0;
  decoder->impl_->Reset(bytes, offset);
  *result = IdentifyUnknownSectionInternal(decoder->impl_.get());
  return decoder->impl_->pc() - bytes.begin();
}

bool ModuleDecoder::ok() { return impl_->ok(); }

const FunctionSig* DecodeWasmSignatureForTesting(const WasmFeatures& enabled,
                                                 Zone* zone, const byte* start,
                                                 const byte* end) {
  ModuleDecoderImpl decoder(enabled, start, end, kWasmOrigin);
  return decoder.DecodeFunctionSignature(zone, start);
}

WasmInitExpr DecodeWasmInitExprForTesting(const WasmFeatures& enabled,
                                          const byte* start, const byte* end) {
  AccountingAllocator allocator;
  ModuleDecoderImpl decoder(enabled, start, end, kWasmOrigin);
  return decoder.DecodeInitExprForTesting();
}

FunctionResult DecodeWasmFunctionForTesting(
    const WasmFeatures& enabled, Zone* zone, const ModuleWireBytes& wire_bytes,
    const WasmModule* module, const byte* function_start,
    const byte* function_end, Counters* counters) {
  size_t size = function_end - function_start;
  CHECK_LE(function_start, function_end);
  auto size_histogram =
      SELECT_WASM_COUNTER(counters, module->origin, wasm, function_size_bytes);
  // TODO(bradnelson): Improve histogram handling of ptrdiff_t.
  size_histogram->AddSample(static_cast<int>(size));
  if (size > kV8MaxWasmFunctionSize) {
    return FunctionResult{WasmError{0,
                                    "size > maximum function size (%zu): %zu",
                                    kV8MaxWasmFunctionSize, size}};
  }
  ModuleDecoderImpl decoder(enabled, function_start, function_end, kWasmOrigin);
  decoder.SetCounters(counters);
  return decoder.DecodeSingleFunction(zone, wire_bytes, module,
                                      std::make_unique<WasmFunction>());
}

AsmJsOffsetsResult DecodeAsmJsOffsets(Vector<const uint8_t> encoded_offsets) {
  std::vector<AsmJsOffsetFunctionEntries> functions;

  Decoder decoder(encoded_offsets);
  uint32_t functions_count = decoder.consume_u32v("functions count");
  // Consistency check.
  DCHECK_GE(encoded_offsets.size(), functions_count);
  functions.reserve(functions_count);

  for (uint32_t i = 0; i < functions_count; ++i) {
    uint32_t size = decoder.consume_u32v("table size");
    if (size == 0) {
      functions.emplace_back();
      continue;
    }
    DCHECK(decoder.checkAvailable(size));
    const byte* table_end = decoder.pc() + size;
    uint32_t locals_size = decoder.consume_u32v("locals size");
    int function_start_position = decoder.consume_u32v("function start pos");
    int function_end_position = function_start_position;
    int last_byte_offset = locals_size;
    int last_asm_position = function_start_position;
    std::vector<AsmJsOffsetEntry> func_asm_offsets;
    func_asm_offsets.reserve(size / 4);  // conservative estimation
    // Add an entry for the stack check, associated with position 0.
    func_asm_offsets.push_back(
        {0, function_start_position, function_start_position});
    while (decoder.pc() < table_end) {
      DCHECK(decoder.ok());
      last_byte_offset += decoder.consume_u32v("byte offset delta");
      int call_position =
          last_asm_position + decoder.consume_i32v("call position delta");
      int to_number_position =
          call_position + decoder.consume_i32v("to_number position delta");
      last_asm_position = to_number_position;
      if (decoder.pc() == table_end) {
        // The last entry is the function end marker.
        DCHECK_EQ(call_position, to_number_position);
        function_end_position = call_position;
      } else {
        func_asm_offsets.push_back(
            {last_byte_offset, call_position, to_number_position});
      }
    }
    DCHECK_EQ(decoder.pc(), table_end);
    functions.emplace_back(AsmJsOffsetFunctionEntries{
        function_start_position, function_end_position,
        std::move(func_asm_offsets)});
  }
  DCHECK(decoder.ok());
  DCHECK(!decoder.more());

  return decoder.toResult(AsmJsOffsets{std::move(functions)});
}

std::vector<CustomSectionOffset> DecodeCustomSections(const byte* start,
                                                      const byte* end) {
  Decoder decoder(start, end);
  decoder.consume_bytes(4, "wasm magic");
  decoder.consume_bytes(4, "wasm version");

  std::vector<CustomSectionOffset> result;

  while (decoder.more()) {
    byte section_code = decoder.consume_u8("section code");
    uint32_t section_length = decoder.consume_u32v("section length");
    uint32_t section_start = decoder.pc_offset();
    if (section_code != 0) {
      // Skip known sections.
      decoder.consume_bytes(section_length, "section bytes");
      continue;
    }
    uint32_t name_length = decoder.consume_u32v("name length");
    uint32_t name_offset = decoder.pc_offset();
    decoder.consume_bytes(name_length, "section name");
    uint32_t payload_offset = decoder.pc_offset();
    if (section_length < (payload_offset - section_start)) {
      decoder.error("invalid section length");
      break;
    }
    uint32_t payload_length = section_length - (payload_offset - section_start);
    decoder.consume_bytes(payload_length);
    if (decoder.failed()) break;
    result.push_back({{section_start, section_length},
                      {name_offset, name_length},
                      {payload_offset, payload_length}});
  }

  return result;
}

namespace {

bool FindNameSection(Decoder* decoder) {
  static constexpr int kModuleHeaderSize = 8;
  decoder->consume_bytes(kModuleHeaderSize, "module header");

  WasmSectionIterator section_iter(decoder);

  while (decoder->ok() && section_iter.more() &&
         section_iter.section_code() != kNameSectionCode) {
    section_iter.advance(true);
  }
  if (!section_iter.more()) return false;

  // Reset the decoder to not read beyond the name section end.
  decoder->Reset(section_iter.payload(), decoder->pc_offset());
  return true;
}

}  // namespace

void DecodeFunctionNames(const byte* module_start, const byte* module_end,
                         std::unordered_map<uint32_t, WireBytesRef>* names,
                         const Vector<const WasmExport> export_table) {
  DCHECK_NOT_NULL(names);
  DCHECK(names->empty());

  Decoder decoder(module_start, module_end);
  if (FindNameSection(&decoder)) {
    while (decoder.ok() && decoder.more()) {
      uint8_t name_type = decoder.consume_u8("name type");
      if (name_type & 0x80) break;  // no varuint7

      uint32_t name_payload_len = decoder.consume_u32v("name payload length");
      if (!decoder.checkAvailable(name_payload_len)) break;

      if (name_type != NameSectionKindCode::kFunction) {
        decoder.consume_bytes(name_payload_len, "name subsection payload");
        continue;
      }
      uint32_t functions_count = decoder.consume_u32v("functions count");

      for (; decoder.ok() && functions_count > 0; --functions_count) {
        uint32_t function_index = decoder.consume_u32v("function index");
        WireBytesRef name = consume_string(&decoder, false, "function name");

        // Be lenient with errors in the name section: Ignore non-UTF8 names.
        // You can even assign to the same function multiple times (last valid
        // one wins).
        if (decoder.ok() && validate_utf8(&decoder, name)) {
          names->insert(std::make_pair(function_index, name));
        }
      }
    }
  }

  // Extract from export table.
  for (const WasmExport& exp : export_table) {
    if (exp.kind == kExternalFunction && names->count(exp.index) == 0) {
      names->insert(std::make_pair(exp.index, exp.name));
    }
  }
}

void GenerateNamesFromImportsAndExports(
    ImportExportKindCode kind, const Vector<const WasmImport> import_table,
    const Vector<const WasmExport> export_table,
    std::unordered_map<uint32_t, std::pair<WireBytesRef, WireBytesRef>>*
        names) {
  DCHECK_NOT_NULL(names);
  DCHECK(names->empty());
  DCHECK(kind == kExternalGlobal || kind == kExternalMemory ||
         kind == kExternalTable);

  // Extract from import table.
  for (const WasmImport& imp : import_table) {
    if (imp.kind != kind) continue;
    if (!imp.module_name.is_set() || !imp.field_name.is_set()) continue;
    if (names->count(imp.index) == 0) {
      names->insert(std::make_pair(
          imp.index, std::make_pair(imp.module_name, imp.field_name)));
    }
  }

  // Extract from export table.
  for (const WasmExport& exp : export_table) {
    if (exp.kind != kind) continue;
    if (!exp.name.is_set()) continue;
    if (names->count(exp.index) == 0) {
      names->insert(
          std::make_pair(exp.index, std::make_pair(WireBytesRef(), exp.name)));
    }
  }
}

LocalNames DecodeLocalNames(Vector<const uint8_t> module_bytes) {
  Decoder decoder(module_bytes);
  if (!FindNameSection(&decoder)) return LocalNames{{}};

  std::vector<LocalNamesPerFunction> functions;
  while (decoder.ok() && decoder.more()) {
    uint8_t name_type = decoder.consume_u8("name type");
    if (name_type & 0x80) break;  // no varuint7

    uint32_t name_payload_len = decoder.consume_u32v("name payload length");
    if (!decoder.checkAvailable(name_payload_len)) break;

    if (name_type != NameSectionKindCode::kLocal) {
      decoder.consume_bytes(name_payload_len, "name subsection payload");
      continue;
    }

    uint32_t local_names_count = decoder.consume_u32v("local names count");
    for (uint32_t i = 0; i < local_names_count; ++i) {
      uint32_t func_index = decoder.consume_u32v("function index");
      if (func_index > kMaxInt) continue;
      std::vector<LocalName> names;
      uint32_t num_names = decoder.consume_u32v("namings count");
      for (uint32_t k = 0; k < num_names; ++k) {
        uint32_t local_index = decoder.consume_u32v("local index");
        WireBytesRef name = consume_string(&decoder, false, "local name");
        if (!decoder.ok()) break;
        if (local_index > kMaxInt) continue;
        // Ignore non-utf8 names.
        if (!validate_utf8(&decoder, name)) continue;
        names.emplace_back(static_cast<int>(local_index), name);
      }
      // Use stable sort to get deterministic names (the first one declared)
      // even in the presence of duplicates.
      std::stable_sort(names.begin(), names.end(), LocalName::IndexLess{});
      functions.emplace_back(static_cast<int>(func_index), std::move(names));
    }
  }
  std::stable_sort(functions.begin(), functions.end(),
                   LocalNamesPerFunction::FunctionIndexLess{});
  return LocalNames{std::move(functions)};
}

#undef TRACE

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