/*
 * Copyright 2016 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <algorithm>
#include <fstream>
#include <iomanip>

#include "ir/eh-utils.h"
#include "ir/module-utils.h"
#include "ir/names.h"
#include "ir/table-utils.h"
#include "ir/type-updating.h"
#include "pass.h"
#include "support/bits.h"
#include "support/debug.h"
#include "support/stdckdint.h"
#include "support/string.h"
#include "wasm-annotations.h"
#include "wasm-binary.h"
#include "wasm-debug.h"
#include "wasm-limits.h"
#include "wasm-stack.h"

#define DEBUG_TYPE "binary"

namespace wasm {

void WasmBinaryWriter::prepare() {
  // Collect function types and their frequencies. Collect information in each
  // function in parallel, then merge.
  indexedTypes = ModuleUtils::getOptimizedIndexedHeapTypes(*wasm);
  for (Index i = 0, size = indexedTypes.types.size(); i < size; ++i) {
    if (indexedTypes.types[i].isSignature()) {
      signatureIndexes.insert({indexedTypes.types[i].getSignature(), i});
    }
  }
  importInfo = std::make_unique<ImportInfo>(*wasm);
}

void WasmBinaryWriter::write() {
  writeHeader();

  writeDylinkSection();

  initializeDebugInfo();
  if (sourceMap) {
    writeSourceMapProlog();
  }

  writeTypes();
  writeImports();
  writeFunctionSignatures();
  writeTableDeclarations();
  writeMemories();
  writeTags();
  if (wasm->features.hasStrings()) {
    writeStrings();
  }
  writeGlobals();
  writeExports();
  writeStart();
  writeElementSegments();
  writeDataCount();
  writeFunctions();
  writeDataSegments();
  if (debugInfo || emitModuleName) {
    writeNames();
  }
  if (sourceMap && !sourceMapUrl.empty()) {
    writeSourceMapUrl();
  }
  if (symbolMap.size() > 0) {
    writeSymbolMap();
  }

  if (sourceMap) {
    writeSourceMapEpilog();
  }

#ifdef BUILD_LLVM_DWARF
  // Update DWARF user sections after writing the data they refer to
  // (function bodies), and before writing the user sections themselves.
  if (Debug::hasDWARFSections(*wasm)) {
    Debug::writeDWARFSections(*wasm, binaryLocations);
  }
#endif

  writeLateCustomSections();
  writeFeaturesSection();
}

void WasmBinaryWriter::writeHeader() {
  o << int32_t(BinaryConsts::Magic); // magic number \0asm
  o << int32_t(BinaryConsts::Version);
}

int32_t WasmBinaryWriter::writeU32LEBPlaceholder() {
  return o.writeU32LEBPlaceholder();
}

void WasmBinaryWriter::writeResizableLimits(
  Address initial, Address maximum, bool hasMaximum, bool shared, bool is64) {
  uint32_t flags = (hasMaximum ? (uint32_t)BinaryConsts::HasMaximum : 0U) |
                   (shared ? (uint32_t)BinaryConsts::IsShared : 0U) |
                   (is64 ? (uint32_t)BinaryConsts::Is64 : 0U);
  o << U32LEB(flags);
  if (is64) {
    o << U64LEB(initial);
    if (hasMaximum) {
      o << U64LEB(maximum);
    }
  } else {
    o << U32LEB(initial);
    if (hasMaximum) {
      o << U32LEB(maximum);
    }
  }
}

template<typename T> int32_t WasmBinaryWriter::startSection(T code) {
  o << uint8_t(code);
  if (sourceMap) {
    sourceMapLocationsSizeAtSectionStart = sourceMapLocations.size();
  }
  binaryLocationsSizeAtSectionStart = binaryLocations.expressions.size();
  return writeU32LEBPlaceholder(); // section size to be filled in later
}

void WasmBinaryWriter::finishSection(int32_t start) {
  auto adjustmentForLEBShrinking = o.emitRetroactiveSectionSizeLEB(start);
  if (adjustmentForLEBShrinking && sourceMap) {
    for (auto i = sourceMapLocationsSizeAtSectionStart;
         i < sourceMapLocations.size();
         ++i) {
      sourceMapLocations[i].first -= adjustmentForLEBShrinking;
    }
  }

  if (binaryLocationsSizeAtSectionStart != binaryLocations.expressions.size()) {
    // We added the binary locations, adjust them: they must be relative
    // to the code section.
    assert(binaryLocationsSizeAtSectionStart == 0);
    // The section type byte is right before the LEB for the size; we want
    // offsets that are relative to the body, which is after that section type
    // byte and the the size LEB.
    //
    // We can compute the size of the size field LEB by considering the original
    // size of the maximal LEB, and the adjustment due to shrinking.
    auto sizeFieldSize = MaxLEB32Bytes - adjustmentForLEBShrinking;
    auto body = start + sizeFieldSize;
    // Offsets are relative to the body of the code section: after the
    // section type byte and the size.
    // Everything was moved by the adjustment, track that. After this,
    // we are at the right absolute address.
    // We are relative to the section start.
    auto totalAdjustment = adjustmentForLEBShrinking + body;
    for (auto& [_, locations] : binaryLocations.expressions) {
      locations.start -= totalAdjustment;
      locations.end -= totalAdjustment;
    }
    for (auto& [_, locations] : binaryLocations.functions) {
      locations.start -= totalAdjustment;
      locations.declarations -= totalAdjustment;
      locations.end -= totalAdjustment;
    }
    for (auto& [_, locations] : binaryLocations.delimiters) {
      for (auto& item : locations) {
        item -= totalAdjustment;
      }
    }
  }
}

int32_t WasmBinaryWriter::startSubsection(
  BinaryConsts::CustomSections::Subsection code) {
  return startSection(code);
}

void WasmBinaryWriter::finishSubsection(int32_t start) { finishSection(start); }

void WasmBinaryWriter::writeStart() {
  if (!wasm->start.is()) {
    return;
  }
  auto start = startSection(BinaryConsts::Section::Start);
  o << U32LEB(getFunctionIndex(wasm->start.str));
  finishSection(start);
}

void WasmBinaryWriter::writeMemories() {
  if (importInfo->getNumDefinedMemories() == 0) {
    return;
  }
  auto start = startSection(BinaryConsts::Section::Memory);
  auto num = importInfo->getNumDefinedMemories();
  o << U32LEB(num);
  ModuleUtils::iterDefinedMemories(*wasm, [&](Memory* memory) {
    writeResizableLimits(memory->initial,
                         memory->max,
                         memory->hasMax(),
                         memory->shared,
                         memory->is64());
  });
  finishSection(start);
}

void WasmBinaryWriter::writeTypes() {
  if (indexedTypes.types.size() == 0) {
    return;
  }
  // Count the number of recursion groups, which is the number of elements in
  // the type section.
  size_t numGroups = 0;
  {
    std::optional<RecGroup> lastGroup;
    for (auto type : indexedTypes.types) {
      auto currGroup = type.getRecGroup();
      numGroups += lastGroup != currGroup;
      lastGroup = currGroup;
    }
  }

  // As a temporary measure, detect which types have subtypes and always use
  // `sub` or `sub final` for these types. The standard says that types without
  // `sub` or `sub final` are final, but we currently treat them as non-final.
  // To avoid unsafe ambiguity, only use the short form for types that it would
  // be safe to treat as final, i.e. types without subtypes.
  std::vector<bool> hasSubtypes(indexedTypes.types.size());
  for (auto type : indexedTypes.types) {
    if (auto super = type.getDeclaredSuperType()) {
      hasSubtypes[indexedTypes.indices[*super]] = true;
    }
  }

  auto start = startSection(BinaryConsts::Section::Type);
  o << U32LEB(numGroups);
  std::optional<RecGroup> lastGroup = std::nullopt;
  for (Index i = 0; i < indexedTypes.types.size(); ++i) {
    auto type = indexedTypes.types[i];
    // Check whether we need to start a new recursion group. Recursion groups of
    // size 1 are implicit, so only emit a group header for larger groups.
    auto currGroup = type.getRecGroup();
    if (lastGroup != currGroup && currGroup.size() > 1) {
      o << uint8_t(BinaryConsts::EncodedType::Rec) << U32LEB(currGroup.size());
    }
    lastGroup = currGroup;
    // Emit the type definition.
    auto super = type.getDeclaredSuperType();
    if (super || type.isOpen()) {
      if (type.isOpen()) {
        o << uint8_t(BinaryConsts::EncodedType::Sub);
      } else {
        o << uint8_t(BinaryConsts::EncodedType::SubFinal);
      }
      if (super) {
        o << U32LEB(1);
        writeHeapType(*super, Inexact);
      } else {
        o << U32LEB(0);
      }
    }
    if (type.isShared()) {
      o << uint8_t(BinaryConsts::EncodedType::Shared);
    }
    if (auto desc = type.getDescribedType()) {
      o << uint8_t(BinaryConsts::EncodedType::Describes);
      writeHeapType(*desc, Inexact);
    }
    if (auto desc = type.getDescriptorType()) {
      o << uint8_t(BinaryConsts::EncodedType::Descriptor);
      writeHeapType(*desc, Inexact);
    }
    switch (type.getKind()) {
      case HeapTypeKind::Func: {
        o << uint8_t(BinaryConsts::EncodedType::Func);
        auto sig = type.getSignature();
        for (auto& sigType : {sig.params, sig.results}) {
          o << U32LEB(sigType.size());
          for (const auto& type : sigType) {
            writeType(type);
          }
        }
        break;
      }
      case HeapTypeKind::Struct: {
        o << uint8_t(BinaryConsts::EncodedType::Struct);
        auto fields = type.getStruct().fields;
        o << U32LEB(fields.size());
        for (const auto& field : fields) {
          writeField(field);
        }
        break;
      }
      case HeapTypeKind::Array:
        o << uint8_t(BinaryConsts::EncodedType::Array);
        writeField(type.getArray().element);
        break;
      case HeapTypeKind::Cont:
        o << uint8_t(BinaryConsts::EncodedType::Cont);
        writeHeapType(type.getContinuation().type, Inexact);
        break;
      case HeapTypeKind::Basic:
        WASM_UNREACHABLE("unexpected kind");
    }
  }
  finishSection(start);
}

void WasmBinaryWriter::writeImports() {
  auto num = importInfo->getNumImports();
  if (num == 0) {
    return;
  }
  auto start = startSection(BinaryConsts::Section::Import);
  o << U32LEB(num);
  auto writeImportHeader = [&](Importable* import) {
    writeInlineString(import->module.str);
    writeInlineString(import->base.str);
  };
  ModuleUtils::iterImportedFunctions(*wasm, [&](Function* func) {
    writeImportHeader(func);
    uint32_t kind = ExternalKind::Function;
    if (func->type.isExact()) {
      kind |= BinaryConsts::ExactImport;
    }
    o << U32LEB(kind) << U32LEB(getTypeIndex(func->type.getHeapType()));
  });
  ModuleUtils::iterImportedGlobals(*wasm, [&](Global* global) {
    writeImportHeader(global);
    o << U32LEB(int32_t(ExternalKind::Global));
    writeType(global->type);
    o << U32LEB(global->mutable_);
  });
  ModuleUtils::iterImportedTags(*wasm, [&](Tag* tag) {
    writeImportHeader(tag);
    o << U32LEB(int32_t(ExternalKind::Tag));
    o << uint8_t(0); // Reserved 'attribute' field. Always 0.
    o << U32LEB(getTypeIndex(tag->type));
  });
  ModuleUtils::iterImportedMemories(*wasm, [&](Memory* memory) {
    writeImportHeader(memory);
    o << U32LEB(int32_t(ExternalKind::Memory));
    writeResizableLimits(memory->initial,
                         memory->max,
                         memory->hasMax(),
                         memory->shared,
                         memory->is64());
  });
  ModuleUtils::iterImportedTables(*wasm, [&](Table* table) {
    writeImportHeader(table);
    o << U32LEB(int32_t(ExternalKind::Table));
    writeType(table->type);
    writeResizableLimits(table->initial,
                         table->max,
                         table->hasMax(),
                         /*shared=*/false,
                         table->is64());
  });
  finishSection(start);
}

void WasmBinaryWriter::writeFunctionSignatures() {
  if (importInfo->getNumDefinedFunctions() == 0) {
    return;
  }
  auto start = startSection(BinaryConsts::Section::Function);
  o << U32LEB(importInfo->getNumDefinedFunctions());
  ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
    o << U32LEB(getTypeIndex(func->type.getHeapType()));
  });
  finishSection(start);
}

void WasmBinaryWriter::writeExpression(Expression* curr) {
  BinaryenIRToBinaryWriter(*this, o).visit(curr);
}

void WasmBinaryWriter::writeFunctions() {
  if (importInfo->getNumDefinedFunctions() == 0) {
    return;
  }

  std::optional<ModuleStackIR> moduleStackIR;
  if (options.generateStackIR) {
    moduleStackIR.emplace(*wasm, options);
  }

  auto sectionStart = startSection(BinaryConsts::Section::Code);
  o << U32LEB(importInfo->getNumDefinedFunctions());
  bool DWARF = Debug::hasDWARFSections(*getModule());
  ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
    assert(binaryLocationTrackedExpressionsForFunc.empty());
    // Do not smear any debug location from the previous function.
    writeNoDebugLocation();
    size_t sourceMapLocationsSizeAtFunctionStart = sourceMapLocations.size();
    size_t sizePos = writeU32LEBPlaceholder();
    size_t start = o.size();
    // Emit Stack IR if present.
    StackIR* stackIR = nullptr;
    if (moduleStackIR) {
      stackIR = moduleStackIR->getStackIROrNull(func);
    }
    if (stackIR) {
      StackIRToBinaryWriter writer(*this, o, func, *stackIR, sourceMap, DWARF);
      writer.write();
      if (debugInfo) {
        funcMappedLocals[func->name] = std::move(writer.getMappedLocals());
      }
    } else {
      BinaryenIRToBinaryWriter writer(*this, o, func, sourceMap, DWARF);
      writer.write();
      if (debugInfo) {
        funcMappedLocals[func->name] = std::move(writer.getMappedLocals());
      }
    }
    size_t size = o.size() - start;
    assert(size <= std::numeric_limits<uint32_t>::max());
    auto sizeFieldSize = o.writeAt(sizePos, U32LEB(size));
    // We can move things back if the actual LEB for the size doesn't use the
    // maximum 5 bytes. In that case we need to adjust offsets after we move
    // things backwards.
    auto adjustmentForLEBShrinking = MaxLEB32Bytes - sizeFieldSize;
    if (adjustmentForLEBShrinking) {
      // we can save some room, nice
      assert(sizeFieldSize < MaxLEB32Bytes);
      std::move(&o[start], &o[start] + size, &o[sizePos] + sizeFieldSize);
      o.resize(o.size() - adjustmentForLEBShrinking);
      if (sourceMap) {
        for (auto i = sourceMapLocationsSizeAtFunctionStart;
             i < sourceMapLocations.size();
             ++i) {
          sourceMapLocations[i].first -= adjustmentForLEBShrinking;
        }
      }
      for (auto* curr : binaryLocationTrackedExpressionsForFunc) {
        // We added the binary locations, adjust them: they must be relative
        // to the code section.
        auto& span = binaryLocations.expressions[curr];
        span.start -= adjustmentForLEBShrinking;
        span.end -= adjustmentForLEBShrinking;
        auto iter = binaryLocations.delimiters.find(curr);
        if (iter != binaryLocations.delimiters.end()) {
          for (auto& item : iter->second) {
            item -= adjustmentForLEBShrinking;
          }
        }
      }
    }
    if (!binaryLocationTrackedExpressionsForFunc.empty()) {
      binaryLocations.functions[func] = BinaryLocations::FunctionLocations{
        BinaryLocation(sizePos),
        BinaryLocation(start - adjustmentForLEBShrinking),
        BinaryLocation(o.size())};
    }
    tableOfContents.functionBodies.emplace_back(
      func->name, sizePos + sizeFieldSize, size);
    binaryLocationTrackedExpressionsForFunc.clear();

    if (func->getParams().size() > WebLimitations::MaxFunctionParams) {
      std::cerr << "Some VMs may not accept this binary because it has a large "
                << "number of parameters in function " << func->name << ".\n";
    }
    if (func->getNumLocals() > WebLimitations::MaxFunctionLocals) {
      std::cerr << "Some VMs may not accept this binary because it has a large "
                << "number of locals in function " << func->name << ".\n";
    }
  });
  finishSection(sectionStart);

  // Code annotations must come before the code section (see comment on
  // writeCodeAnnotations).
  if (auto annotations = writeCodeAnnotations()) {
    // We need to move the code section and put the annotations before it.
    auto& annotationsBuffer = *annotations;
    auto oldSize = o.size();
    auto annotationsSectionSize = annotationsBuffer.size();
    o.resize(oldSize + annotationsSectionSize);

    // |sectionStart| is the start of the contents of the section. Subtract 1 to
    // include the section code as well, so we move all of it.
    std::move_backward(&o[sectionStart - 1], &o[oldSize], o.end());
    std::copy(
      annotationsBuffer.begin(), annotationsBuffer.end(), &o[sectionStart - 1]);

    // Source map offsets are absolute (from the start of the binary) so we must
    // adjust them after moving the code section.
    if (sourceMap) {
      for (auto& location : sourceMapLocations) {
        location.first += annotationsSectionSize;
      }
    }
  }
}

void WasmBinaryWriter::writeStrings() {
  assert(wasm->features.hasStrings());

  // Scan the entire wasm to find the relevant strings.
  // To find all the string literals we must scan all the code.
  using StringSet = std::unordered_set<Name>;

  struct StringWalker : public PostWalker<StringWalker> {
    StringSet& strings;

    StringWalker(StringSet& strings) : strings(strings) {}

    void visitStringConst(StringConst* curr) { strings.insert(curr->string); }
  };

  ModuleUtils::ParallelFunctionAnalysis<StringSet> analysis(
    *wasm, [&](Function* func, StringSet& strings) {
      if (!func->imported()) {
        StringWalker(strings).walk(func->body);
      }
    });

  // Also walk the global module code (for simplicity, also add it to the
  // function map, using a "function" key of nullptr).
  auto& globalStrings = analysis.map[nullptr];
  StringWalker(globalStrings).walkModuleCode(wasm);

  // Generate the indexes from the combined set of necessary strings,
  // which we sort for determinism.
  StringSet allStrings;
  for (auto& [func, strings] : analysis.map) {
    for (auto& string : strings) {
      allStrings.insert(string);
    }
  }
  std::vector<Name> sorted;
  for (auto& string : allStrings) {
    sorted.push_back(string);
  }
  std::sort(sorted.begin(), sorted.end());
  for (Index i = 0; i < sorted.size(); i++) {
    stringIndexes[sorted[i]] = i;
  }

  auto num = sorted.size();
  if (num == 0) {
    return;
  }

  auto start = startSection(BinaryConsts::Section::Strings);

  // Placeholder for future use in the spec.
  o << U32LEB(0);

  // The number of strings and then their contents.
  o << U32LEB(num);
  for (auto& string : sorted) {
    // Re-encode from WTF-16 to WTF-8.
    std::stringstream wtf8;
    [[maybe_unused]] bool valid = String::convertWTF16ToWTF8(wtf8, string.str);
    assert(valid);
    // TODO: Use wtf8.view() once we have C++20.
    writeInlineString(wtf8.str());
  }

  finishSection(start);
}

void WasmBinaryWriter::writeGlobals() {
  if (importInfo->getNumDefinedGlobals() == 0) {
    return;
  }
  auto start = startSection(BinaryConsts::Section::Global);
  // Count and emit the total number of globals after tuple globals have been
  // expanded into their constituent parts.
  Index num = 0;
  ModuleUtils::iterDefinedGlobals(
    *wasm, [&num](Global* global) { num += global->type.size(); });
  o << U32LEB(num);
  ModuleUtils::iterDefinedGlobals(*wasm, [&](Global* global) {
    size_t i = 0;
    for (const auto& t : global->type) {
      writeType(t);
      o << U32LEB(global->mutable_);
      if (global->type.size() == 1) {
        writeExpression(global->init);
      } else if (auto* make = global->init->dynCast<TupleMake>()) {
        // Emit the proper lane for this global.
        writeExpression(make->operands[i]);
      } else {
        // For now tuple globals must contain tuple.make. We could perhaps
        // support more operations, like global.get, but the code would need to
        // look something like this:
        //
        //   auto parentIndex = getGlobalIndex(get->name);
        //   o << int8_t(BinaryConsts::GlobalGet) << U32LEB(parentIndex + i);
        //
        // That is, we must emit the instruction here, and not defer to
        // writeExpression, as writeExpression writes an entire expression at a
        // time (and not just one of the lanes). As emitting an instruction here
        // is less clean, and there is no important use case for global.get of
        // one tuple global to another, we disallow this.
        WASM_UNREACHABLE("unsupported tuple global operation");
      }
      o << int8_t(BinaryConsts::End);
      ++i;
    }
  });
  finishSection(start);
}

void WasmBinaryWriter::writeExports() {
  if (wasm->exports.size() == 0) {
    return;
  }
  auto start = startSection(BinaryConsts::Section::Export);
  o << U32LEB(wasm->exports.size());
  for (auto& curr : wasm->exports) {
    writeInlineString(curr->name.str);
    o << U32LEB(int32_t(curr->kind));
    switch (curr->kind) {
      case ExternalKind::Function:
        o << U32LEB(getFunctionIndex(*curr->getInternalName()));
        break;
      case ExternalKind::Table:
        o << U32LEB(getTableIndex(*curr->getInternalName()));
        break;
      case ExternalKind::Memory:
        o << U32LEB(getMemoryIndex(*curr->getInternalName()));
        break;
      case ExternalKind::Global:
        o << U32LEB(getGlobalIndex(*curr->getInternalName()));
        break;
      case ExternalKind::Tag:
        o << U32LEB(getTagIndex(*curr->getInternalName()));
        break;
      default:
        WASM_UNREACHABLE("unexpected extern kind");
    }
  }
  finishSection(start);
}

void WasmBinaryWriter::writeDataCount() {
  if (!wasm->features.hasBulkMemory() || !wasm->dataSegments.size()) {
    return;
  }
  auto start = startSection(BinaryConsts::Section::DataCount);
  o << U32LEB(wasm->dataSegments.size());
  finishSection(start);
}

void WasmBinaryWriter::writeDataSegments() {
  if (wasm->dataSegments.size() == 0) {
    return;
  }
  if (wasm->dataSegments.size() > WebLimitations::MaxDataSegments) {
    std::cerr << "Some VMs may not accept this binary because it has a large "
              << "number of data segments. Run the limit-segments pass to "
              << "merge segments.\n";
  }
  auto start = startSection(BinaryConsts::Section::Data);
  o << U32LEB(wasm->dataSegments.size());
  for (auto& segment : wasm->dataSegments) {
    uint32_t flags = 0;
    Index memoryIndex = 0;
    if (segment->isPassive) {
      flags |= BinaryConsts::IsPassive;
    } else {
      memoryIndex = getMemoryIndex(segment->memory);
      if (memoryIndex) {
        flags |= BinaryConsts::HasIndex;
      }
    }
    o << U32LEB(flags);
    if (!segment->isPassive) {
      if (memoryIndex) {
        o << U32LEB(memoryIndex);
      }
      writeExpression(segment->offset);
      o << int8_t(BinaryConsts::End);
    }
    writeInlineBuffer(segment->data.data(), segment->data.size());
  }
  finishSection(start);
}

uint32_t WasmBinaryWriter::getFunctionIndex(Name name) const {
  auto it = indexes.functionIndexes.find(name);
  assert(it != indexes.functionIndexes.end());
  return it->second;
}

uint32_t WasmBinaryWriter::getTableIndex(Name name) const {
  auto it = indexes.tableIndexes.find(name);
  assert(it != indexes.tableIndexes.end());
  return it->second;
}

uint32_t WasmBinaryWriter::getMemoryIndex(Name name) const {
  auto it = indexes.memoryIndexes.find(name);
  assert(it != indexes.memoryIndexes.end());
  return it->second;
}

uint32_t WasmBinaryWriter::getGlobalIndex(Name name) const {
  auto it = indexes.globalIndexes.find(name);
  assert(it != indexes.globalIndexes.end());
  return it->second;
}

uint32_t WasmBinaryWriter::getTagIndex(Name name) const {
  auto it = indexes.tagIndexes.find(name);
  assert(it != indexes.tagIndexes.end());
  return it->second;
}

uint32_t WasmBinaryWriter::getDataSegmentIndex(Name name) const {
  auto it = indexes.dataIndexes.find(name);
  assert(it != indexes.dataIndexes.end());
  return it->second;
}

uint32_t WasmBinaryWriter::getElementSegmentIndex(Name name) const {
  auto it = indexes.elemIndexes.find(name);
  assert(it != indexes.elemIndexes.end());
  return it->second;
}

uint32_t WasmBinaryWriter::getTypeIndex(HeapType type) const {
  auto it = indexedTypes.indices.find(type);
#ifndef NDEBUG
  if (it == indexedTypes.indices.end()) {
    std::cout << "Missing type: " << type << '\n';
    assert(0);
  }
#endif
  return it->second;
}

uint32_t WasmBinaryWriter::getSignatureIndex(Signature sig) const {
  auto it = signatureIndexes.find(sig);
#ifndef NDEBUG
  if (it == signatureIndexes.end()) {
    std::cout << "Missing signature: " << sig << '\n';
    assert(0);
  }
#endif
  return it->second;
}

uint32_t WasmBinaryWriter::getStringIndex(Name string) const {
  auto it = stringIndexes.find(string);
  assert(it != stringIndexes.end());
  return it->second;
}

void WasmBinaryWriter::writeTableDeclarations() {
  if (importInfo->getNumDefinedTables() == 0) {
    // std::cerr << std::endl << "(WasmBinaryWriter::writeTableDeclarations) No
    // defined tables found. skipping" << std::endl;
    return;
  }
  auto start = startSection(BinaryConsts::Section::Table);
  auto num = importInfo->getNumDefinedTables();
  o << U32LEB(num);
  ModuleUtils::iterDefinedTables(*wasm, [&](Table* table) {
    writeType(table->type);
    writeResizableLimits(table->initial,
                         table->max,
                         table->hasMax(),
                         /*shared=*/false,
                         table->is64());
  });
  finishSection(start);
}

void WasmBinaryWriter::writeElementSegments() {
  size_t elemCount = wasm->elementSegments.size();
  auto needingElemDecl = TableUtils::getFunctionsNeedingElemDeclare(*wasm);
  if (!needingElemDecl.empty()) {
    elemCount++;
  }
  if (elemCount == 0) {
    return;
  }

  auto start = startSection(BinaryConsts::Section::Element);
  o << U32LEB(elemCount);

  Type funcref = Type(HeapType::func, Nullable);
  for (auto& segment : wasm->elementSegments) {
    Index tableIdx = 0;

    bool isPassive = segment->table.isNull();
    // If the segment is MVP, we can use the shorter form.
    bool usesExpressions = TableUtils::usesExpressions(segment.get(), wasm);

    // The table index can and should be elided for active segments of table 0
    // when table 0 has type funcref. This was the only type of segment
    // supported by the MVP, which also did not support table indices in the
    // segment encoding.
    bool hasTableIndex = false;
    if (!isPassive) {
      tableIdx = getTableIndex(segment->table);
      hasTableIndex =
        tableIdx > 0 || wasm->getTable(segment->table)->type != funcref;
    }

    uint32_t flags = 0;
    if (usesExpressions) {
      flags |= BinaryConsts::UsesExpressions;
    }
    if (isPassive) {
      flags |= BinaryConsts::IsPassive;
    } else if (hasTableIndex) {
      flags |= BinaryConsts::HasIndex;
    }

    o << U32LEB(flags);
    if (!isPassive) {
      if (hasTableIndex) {
        o << U32LEB(tableIdx);
      }
      writeExpression(segment->offset);
      o << int8_t(BinaryConsts::End);
    }

    if (isPassive || hasTableIndex) {
      if (usesExpressions) {
        // elemType
        writeType(segment->type);
      } else {
        // MVP elemKind of funcref
        o << U32LEB(0);
      }
    }
    o << U32LEB(segment->data.size());
    if (usesExpressions) {
      for (auto* item : segment->data) {
        writeExpression(item);
        o << int8_t(BinaryConsts::End);
      }
    } else {
      for (auto& item : segment->data) {
        // We've ensured that all items are ref.func.
        auto& name = item->cast<RefFunc>()->func;
        o << U32LEB(getFunctionIndex(name));
      }
    }
  }

  if (!needingElemDecl.empty()) {
    o << U32LEB(BinaryConsts::IsPassive | BinaryConsts::IsDeclarative);
    o << U32LEB(0); // type (indicating funcref)
    o << U32LEB(needingElemDecl.size());
    for (auto name : needingElemDecl) {
      o << U32LEB(indexes.functionIndexes[name]);
    }
  }

  finishSection(start);
}

void WasmBinaryWriter::writeTags() {
  if (importInfo->getNumDefinedTags() == 0) {
    return;
  }
  auto start = startSection(BinaryConsts::Section::Tag);
  auto num = importInfo->getNumDefinedTags();
  o << U32LEB(num);
  ModuleUtils::iterDefinedTags(*wasm, [&](Tag* tag) {
    o << uint8_t(0); // Reserved 'attribute' field. Always 0.
    o << U32LEB(getTypeIndex(tag->type));
  });

  finishSection(start);
}

void WasmBinaryWriter::writeNames() {
  auto start = startSection(BinaryConsts::Section::Custom);
  writeInlineString(BinaryConsts::CustomSections::Name);

  // module name
  if (emitModuleName && wasm->name.is()) {
    auto substart =
      startSubsection(BinaryConsts::CustomSections::Subsection::NameModule);
    writeEscapedName(wasm->name.str);
    finishSubsection(substart);
  }

  if (!debugInfo) {
    // We were only writing the module name.
    finishSection(start);
    return;
  }

  // function names
  {
    std::vector<std::pair<Index, Function*>> functionsWithNames;
    Index checked = 0;
    auto check = [&](Function* curr) {
      if (curr->hasExplicitName) {
        functionsWithNames.push_back({checked, curr});
      }
      checked++;
    };
    ModuleUtils::iterImportedFunctions(*wasm, check);
    ModuleUtils::iterDefinedFunctions(*wasm, check);
    assert(checked == indexes.functionIndexes.size());
    if (functionsWithNames.size() > 0) {
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameFunction);
      o << U32LEB(functionsWithNames.size());
      for (auto& [index, global] : functionsWithNames) {
        o << U32LEB(index);
        writeEscapedName(global->name.str);
      }
      finishSubsection(substart);
    }
  }

  // local names
  {
    // Find all functions with at least one local name and only emit the
    // subsection if there is at least one.
    std::vector<std::pair<Index, Function*>> functionsWithLocalNames;
    Index checked = 0;
    auto check = [&](Function* curr) {
      auto numLocals = curr->getNumLocals();
      for (Index i = 0; i < numLocals; ++i) {
        if (curr->hasLocalName(i)) {
          functionsWithLocalNames.push_back({checked, curr});
          break;
        }
      }
      checked++;
    };
    ModuleUtils::iterImportedFunctions(*wasm, check);
    ModuleUtils::iterDefinedFunctions(*wasm, check);
    assert(checked == indexes.functionIndexes.size());
    if (functionsWithLocalNames.size() > 0) {
      // Otherwise emit those functions but only include locals with a name.
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameLocal);
      o << U32LEB(functionsWithLocalNames.size());
      [[maybe_unused]] Index emitted = 0;
      for (auto& [index, func] : functionsWithLocalNames) {
        // Pairs of (local index in IR, name).
        std::vector<std::pair<Index, Name>> localsWithNames;
        auto numLocals = func->getNumLocals();
        for (Index indexInFunc = 0; indexInFunc < numLocals; ++indexInFunc) {
          if (func->hasLocalName(indexInFunc)) {
            Index indexInBinary;
            auto iter = funcMappedLocals.find(func->name);
            if (iter != funcMappedLocals.end()) {
              // TODO: handle multivalue
              indexInBinary = iter->second[{indexInFunc, 0}];
            } else {
              // No data on funcMappedLocals. That is only possible if we are an
              // imported function, where there are no locals to map, and in
              // that case the index is unchanged anyhow: parameters always have
              // the same index, they are not mapped in any way.
              assert(func->imported());
              indexInBinary = indexInFunc;
            }
            localsWithNames.push_back(
              {indexInBinary, func->getLocalName(indexInFunc)});
          }
        }
        assert(localsWithNames.size());
        std::sort(localsWithNames.begin(), localsWithNames.end());
        o << U32LEB(index);
        o << U32LEB(localsWithNames.size());
        for (auto& [indexInBinary, name] : localsWithNames) {
          o << U32LEB(indexInBinary);
          writeEscapedName(name.str);
        }
        emitted++;
      }
      assert(emitted == functionsWithLocalNames.size());
      finishSubsection(substart);
    }
  }

  // type names
  {
    std::vector<HeapType> namedTypes;
    for (auto type : indexedTypes.types) {
      if (wasm->typeNames.count(type) && wasm->typeNames[type].name.is()) {
        namedTypes.push_back(type);
      }
    }
    if (!namedTypes.empty()) {
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameType);
      o << U32LEB(namedTypes.size());
      for (auto type : namedTypes) {
        o << U32LEB(indexedTypes.indices[type]);
        writeEscapedName(wasm->typeNames[type].name.str);
      }
      finishSubsection(substart);
    }
  }

  // table names
  {
    std::vector<std::pair<Index, Table*>> tablesWithNames;
    Index checked = 0;
    auto check = [&](Table* curr) {
      if (curr->hasExplicitName) {
        tablesWithNames.push_back({checked, curr});
      }
      checked++;
    };
    ModuleUtils::iterImportedTables(*wasm, check);
    ModuleUtils::iterDefinedTables(*wasm, check);
    assert(checked == indexes.tableIndexes.size());

    if (tablesWithNames.size() > 0) {
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameTable);
      o << U32LEB(tablesWithNames.size());

      for (auto& [index, table] : tablesWithNames) {
        o << U32LEB(index);
        writeEscapedName(table->name.str);
      }

      finishSubsection(substart);
    }
  }

  // memory names
  {
    std::vector<std::pair<Index, Memory*>> memoriesWithNames;
    Index checked = 0;
    auto check = [&](Memory* curr) {
      if (curr->hasExplicitName) {
        memoriesWithNames.push_back({checked, curr});
      }
      checked++;
    };
    ModuleUtils::iterImportedMemories(*wasm, check);
    ModuleUtils::iterDefinedMemories(*wasm, check);
    assert(checked == indexes.memoryIndexes.size());
    if (memoriesWithNames.size() > 0) {
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameMemory);
      o << U32LEB(memoriesWithNames.size());
      for (auto& [index, memory] : memoriesWithNames) {
        o << U32LEB(index);
        writeEscapedName(memory->name.str);
      }
      finishSubsection(substart);
    }
  }

  // global names
  {
    std::vector<std::pair<Index, Global*>> globalsWithNames;
    Index checked = 0;
    auto check = [&](Global* curr) {
      if (curr->hasExplicitName) {
        globalsWithNames.push_back({checked, curr});
      }
      checked++;
    };
    ModuleUtils::iterImportedGlobals(*wasm, check);
    ModuleUtils::iterDefinedGlobals(*wasm, check);
    assert(checked == indexes.globalIndexes.size());
    if (globalsWithNames.size() > 0) {
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameGlobal);
      o << U32LEB(globalsWithNames.size());
      for (auto& [index, global] : globalsWithNames) {
        o << U32LEB(index);
        writeEscapedName(global->name.str);
      }
      finishSubsection(substart);
    }
  }

  // elem segment names
  {
    std::vector<std::pair<Index, ElementSegment*>> elemsWithNames;
    Index checked = 0;
    for (auto& curr : wasm->elementSegments) {
      if (curr->hasExplicitName) {
        elemsWithNames.push_back({checked, curr.get()});
      }
      checked++;
    }
    assert(checked == indexes.elemIndexes.size());

    if (elemsWithNames.size() > 0) {
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameElem);
      o << U32LEB(elemsWithNames.size());

      for (auto& [index, elem] : elemsWithNames) {
        o << U32LEB(index);
        writeEscapedName(elem->name.str);
      }

      finishSubsection(substart);
    }
  }

  // data segment names
  {
    Index count = 0;
    for (auto& seg : wasm->dataSegments) {
      if (seg->hasExplicitName) {
        count++;
      }
    }

    if (count) {
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameData);
      o << U32LEB(count);
      for (Index i = 0; i < wasm->dataSegments.size(); i++) {
        auto& seg = wasm->dataSegments[i];
        if (seg->hasExplicitName) {
          o << U32LEB(i);
          writeEscapedName(seg->name.str);
        }
      }
      finishSubsection(substart);
    }
  }

  // TODO: label, type, and element names
  // see: https://github.com/WebAssembly/extended-name-section

  // GC field names
  if (wasm->features.hasGC()) {
    std::vector<HeapType> relevantTypes;
    for (auto& type : indexedTypes.types) {
      if (type.isStruct() && wasm->typeNames.count(type) &&
          !wasm->typeNames[type].fieldNames.empty()) {
        relevantTypes.push_back(type);
      }
    }
    if (!relevantTypes.empty()) {
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameField);
      o << U32LEB(relevantTypes.size());
      for (Index i = 0; i < relevantTypes.size(); i++) {
        auto type = relevantTypes[i];
        o << U32LEB(indexedTypes.indices[type]);
        std::unordered_map<Index, Name>& fieldNames =
          wasm->typeNames.at(type).fieldNames;
        o << U32LEB(fieldNames.size());
        for (auto& [index, name] : fieldNames) {
          o << U32LEB(index);
          writeEscapedName(name.str);
        }
      }
      finishSubsection(substart);
    }
  }

  // tag names
  if (!wasm->tags.empty()) {
    Index count = 0;
    for (auto& tag : wasm->tags) {
      if (tag->hasExplicitName) {
        count++;
      }
    }

    if (count) {
      auto substart =
        startSubsection(BinaryConsts::CustomSections::Subsection::NameTag);
      o << U32LEB(count);
      for (Index i = 0; i < wasm->tags.size(); i++) {
        auto& tag = wasm->tags[i];
        if (tag->hasExplicitName) {
          o << U32LEB(i);
          writeEscapedName(tag->name.str);
        }
      }
      finishSubsection(substart);
    }
  }

  finishSection(start);
}

void WasmBinaryWriter::writeSourceMapUrl() {
  auto start = startSection(BinaryConsts::Section::Custom);
  writeInlineString(BinaryConsts::CustomSections::SourceMapUrl);
  writeInlineString(sourceMapUrl.c_str());
  finishSection(start);
}

void WasmBinaryWriter::writeSymbolMap() {
  std::ofstream file(symbolMap);
  auto write = [&](Function* func) {
    file << getFunctionIndex(func->name) << ":" << func->name.str << std::endl;
  };
  ModuleUtils::iterImportedFunctions(*wasm, write);
  ModuleUtils::iterDefinedFunctions(*wasm, write);
  file.close();
}

void WasmBinaryWriter::initializeDebugInfo() {
  lastDebugLocation = {0, /* lineNumber = */ 1, 0, std::nullopt};
}

void WasmBinaryWriter::writeSourceMapProlog() {
  *sourceMap << "{\"version\":3,";

  for (const auto& section : wasm->customSections) {
    if (section.name == BinaryConsts::CustomSections::BuildId) {
      U32LEB ret;
      size_t pos = 0;
      ret.read([&]() { return section.data[pos++]; });

      if (section.data.size() != pos + ret.value) {
        std::cerr
          << "warning: build id section with an incorrect size detected!\n";
        break;
      }

      *sourceMap << "\"debugId\":\"";
      for (size_t i = pos; i < section.data.size(); i++) {
        *sourceMap << std::setfill('0') << std::setw(2) << std::hex
                   << static_cast<int>(static_cast<uint8_t>(section.data[i]));
      }
      *sourceMap << "\",";
      break;
    }
  }

  auto writeOptionalString = [&](const char* name, const std::string& str) {
    if (!str.empty()) {
      *sourceMap << "\"" << name << "\":\"" << str << "\",";
    }
  };

  writeOptionalString("file", wasm->debugInfoFile);
  writeOptionalString("sourceRoot", wasm->debugInfoSourceRoot);

  auto writeStringVector = [&](const char* name,
                               const std::vector<std::string>& vec) {
    *sourceMap << "\"" << name << "\":[";
    for (size_t i = 0; i < vec.size(); i++) {
      if (i > 0) {
        *sourceMap << ",";
      }
      *sourceMap << "\"" << vec[i] << "\"";
    }
    *sourceMap << "],";
  };

  writeStringVector("sources", wasm->debugInfoFileNames);

  if (!wasm->debugInfoSourcesContent.empty()) {
    writeStringVector("sourcesContent", wasm->debugInfoSourcesContent);
  }

  // TODO: This field is optional; maybe we should omit if it's empty.
  // TODO: Binaryen actually does not correctly preserve symbol names when it
  // rewrites the mappings. We should maybe just drop them, or else handle
  // them correctly.
  writeStringVector("names", wasm->debugInfoSymbolNames);

  *sourceMap << "\"mappings\":\"";
}

static void writeBase64VLQ(std::ostream& out, int32_t n) {
  uint32_t value = n >= 0 ? n << 1 : ((-n) << 1) | 1;
  while (1) {
    uint32_t digit = value & 0x1F;
    value >>= 5;
    if (!value) {
      // last VLQ digit -- base64 codes 'A'..'Z', 'a'..'f'
      out << char(digit < 26 ? 'A' + digit : 'a' + digit - 26);
      break;
    }
    // more VLG digit will follow -- add continuation bit (0x20),
    // base64 codes 'g'..'z', '0'..'9', '+', '/'
    out << char(digit < 20
                  ? 'g' + digit
                  : digit < 30 ? '0' + digit - 20 : digit == 30 ? '+' : '/');
  }
}

void WasmBinaryWriter::writeSourceMapEpilog() {
  // write source map entries
  size_t lastOffset = 0;
  BinaryLocation lastFileIndex = 0;
  BinaryLocation lastLineNumber = 1;
  BinaryLocation lastColumnNumber = 0;
  BinaryLocation lastSymbolNameIndex = 0;
  for (const auto& [offset, loc] : sourceMapLocations) {
    if (lastOffset > 0) {
      *sourceMap << ",";
    }
    writeBase64VLQ(*sourceMap, int32_t(offset - lastOffset));
    lastOffset = offset;
    if (loc) {
      writeBase64VLQ(*sourceMap, int32_t(loc->fileIndex - lastFileIndex));
      lastFileIndex = loc->fileIndex;

      writeBase64VLQ(*sourceMap, int32_t(loc->lineNumber - lastLineNumber));
      lastLineNumber = loc->lineNumber;

      writeBase64VLQ(*sourceMap, int32_t(loc->columnNumber - lastColumnNumber));
      lastColumnNumber = loc->columnNumber;

      if (loc->symbolNameIndex) {
        writeBase64VLQ(*sourceMap,
                       int32_t(*loc->symbolNameIndex - lastSymbolNameIndex));
        lastSymbolNameIndex = *loc->symbolNameIndex;
      }
    }
  }
  *sourceMap << "\"}";
}

void WasmBinaryWriter::writeLateCustomSections() {
  for (auto& section : wasm->customSections) {
    if (section.name != BinaryConsts::CustomSections::Dylink) {
      writeCustomSection(section);
    }
  }
}

void WasmBinaryWriter::writeCustomSection(const CustomSection& section) {
  auto start = startSection(BinaryConsts::Custom);
  writeInlineString(section.name.c_str());
  for (size_t i = 0; i < section.data.size(); i++) {
    o << uint8_t(section.data[i]);
  }
  finishSection(start);
}

void WasmBinaryWriter::writeFeaturesSection() {
  if (!wasm->hasFeaturesSection || wasm->features.isMVP()) {
    return;
  }

  // TODO(tlively): unify feature names with rest of toolchain and use
  // FeatureSet::toString()
  auto toString = [](FeatureSet::Feature f) {
    switch (f) {
      case FeatureSet::Atomics:
        return BinaryConsts::CustomSections::AtomicsFeature;
      case FeatureSet::MutableGlobals:
        return BinaryConsts::CustomSections::MutableGlobalsFeature;
      case FeatureSet::TruncSat:
        return BinaryConsts::CustomSections::TruncSatFeature;
      case FeatureSet::SIMD:
        return BinaryConsts::CustomSections::SIMD128Feature;
      case FeatureSet::BulkMemory:
        return BinaryConsts::CustomSections::BulkMemoryFeature;
      case FeatureSet::SignExt:
        return BinaryConsts::CustomSections::SignExtFeature;
      case FeatureSet::ExceptionHandling:
        return BinaryConsts::CustomSections::ExceptionHandlingFeature;
      case FeatureSet::TailCall:
        return BinaryConsts::CustomSections::TailCallFeature;
      case FeatureSet::ReferenceTypes:
        return BinaryConsts::CustomSections::ReferenceTypesFeature;
      case FeatureSet::Multivalue:
        return BinaryConsts::CustomSections::MultivalueFeature;
      case FeatureSet::GC:
        return BinaryConsts::CustomSections::GCFeature;
      case FeatureSet::Memory64:
        return BinaryConsts::CustomSections::Memory64Feature;
      case FeatureSet::RelaxedSIMD:
        return BinaryConsts::CustomSections::RelaxedSIMDFeature;
      case FeatureSet::ExtendedConst:
        return BinaryConsts::CustomSections::ExtendedConstFeature;
      case FeatureSet::Strings:
        return BinaryConsts::CustomSections::StringsFeature;
      case FeatureSet::MultiMemory:
        return BinaryConsts::CustomSections::MultiMemoryFeature;
      case FeatureSet::StackSwitching:
        return BinaryConsts::CustomSections::StackSwitchingFeature;
      case FeatureSet::SharedEverything:
        return BinaryConsts::CustomSections::SharedEverythingFeature;
      case FeatureSet::FP16:
        return BinaryConsts::CustomSections::FP16Feature;
      case FeatureSet::BulkMemoryOpt:
        return BinaryConsts::CustomSections::BulkMemoryOptFeature;
      case FeatureSet::CallIndirectOverlong:
        return BinaryConsts::CustomSections::CallIndirectOverlongFeature;
      case FeatureSet::CustomDescriptors:
        return BinaryConsts::CustomSections::CustomDescriptorsFeature;
      case FeatureSet::None:
      case FeatureSet::Default:
      case FeatureSet::All:
        break;
    }
    WASM_UNREACHABLE("unexpected feature flag");
  };

  std::vector<const char*> features;
  wasm->features.iterFeatures(
    [&](FeatureSet::Feature f) { features.push_back(toString(f)); });

  auto start = startSection(BinaryConsts::Custom);
  writeInlineString(BinaryConsts::CustomSections::TargetFeatures);
  o << U32LEB(features.size());
  for (auto& f : features) {
    o << uint8_t(BinaryConsts::FeatureUsed);
    writeInlineString(f);
  }
  finishSection(start);
}

void WasmBinaryWriter::writeLegacyDylinkSection() {
  if (!wasm->dylinkSection) {
    return;
  }

  auto start = startSection(BinaryConsts::Custom);
  writeInlineString(BinaryConsts::CustomSections::Dylink);
  o << U32LEB(wasm->dylinkSection->memorySize);
  o << U32LEB(wasm->dylinkSection->memoryAlignment);
  o << U32LEB(wasm->dylinkSection->tableSize);
  o << U32LEB(wasm->dylinkSection->tableAlignment);
  o << U32LEB(wasm->dylinkSection->neededDynlibs.size());
  for (auto& neededDynlib : wasm->dylinkSection->neededDynlibs) {
    writeInlineString(neededDynlib.str);
  }
  finishSection(start);
}

void WasmBinaryWriter::writeDylinkSection() {
  if (!wasm->dylinkSection) {
    return;
  }

  if (wasm->dylinkSection->isLegacy) {
    writeLegacyDylinkSection();
    return;
  }

  auto start = startSection(BinaryConsts::Custom);
  writeInlineString(BinaryConsts::CustomSections::Dylink0);

  auto substart =
    startSubsection(BinaryConsts::CustomSections::Subsection::DylinkMemInfo);
  o << U32LEB(wasm->dylinkSection->memorySize);
  o << U32LEB(wasm->dylinkSection->memoryAlignment);
  o << U32LEB(wasm->dylinkSection->tableSize);
  o << U32LEB(wasm->dylinkSection->tableAlignment);
  finishSubsection(substart);

  if (wasm->dylinkSection->neededDynlibs.size()) {
    substart =
      startSubsection(BinaryConsts::CustomSections::Subsection::DylinkNeeded);
    o << U32LEB(wasm->dylinkSection->neededDynlibs.size());
    for (auto& neededDynlib : wasm->dylinkSection->neededDynlibs) {
      writeInlineString(neededDynlib.str);
    }
    finishSubsection(substart);
  }

  writeData(wasm->dylinkSection->tail.data(), wasm->dylinkSection->tail.size());
  finishSection(start);
}

void WasmBinaryWriter::writeDebugLocation(const Function::DebugLocation& loc) {
  if (loc == lastDebugLocation) {
    return;
  }
  auto offset = o.size();
  sourceMapLocations.emplace_back(offset, &loc);
  lastDebugLocation = loc;
}

void WasmBinaryWriter::writeNoDebugLocation() {
  // Emit an indication that there is no debug location there (so that
  // we do not get "smeared" with debug info from anything before or
  // after us).
  //
  // We don't need to write repeated "no debug info" indications, as a
  // single one is enough to make it clear that the debug information
  // before us is valid no longer. We also don't need to write one if
  // there is nothing before us.
  if (!sourceMapLocations.empty() &&
      sourceMapLocations.back().second != nullptr) {
    sourceMapLocations.emplace_back(o.size(), nullptr);

    // Initialize the state of debug info to indicate there is no current
    // debug info relevant. This sets |lastDebugLocation| to a dummy value,
    // so that later places with debug info can see that they differ from
    // it (without this, if we had some debug info, then a nullptr for none,
    // and then the same debug info, we could get confused).
    initializeDebugInfo();
  }
}

void WasmBinaryWriter::writeSourceMapLocation(Expression* curr,
                                              Function* func) {
  assert(sourceMap);

  auto& debugLocations = func->debugLocations;
  auto iter = debugLocations.find(curr);
  if (iter != debugLocations.end() && iter->second) {
    // There is debug information here, write it out.
    writeDebugLocation(*(iter->second));
  } else {
    // This expression has no debug location.
    writeNoDebugLocation();
  }
}

void WasmBinaryWriter::trackExpressionStart(Expression* curr, Function* func) {
  // If this is an instruction in a function, and if the original wasm had
  // binary locations tracked, then track it in the output as well. We also
  // track locations of instructions that have code annotations, as their binary
  // location goes in the custom section.
  if (func && (!func->expressionLocations.empty() ||
               func->codeAnnotations.count(curr))) {
    binaryLocations.expressions[curr] =
      BinaryLocations::Span{BinaryLocation(o.size()), 0};
    binaryLocationTrackedExpressionsForFunc.push_back(curr);
  }
}

void WasmBinaryWriter::trackExpressionEnd(Expression* curr, Function* func) {
  // TODO: If we need to track the end of annotated code locations, we need to
  //       enable that here.
  if (func && !func->expressionLocations.empty()) {
    auto& span = binaryLocations.expressions.at(curr);
    span.end = o.size();
  }
}

void WasmBinaryWriter::trackExpressionDelimiter(Expression* curr,
                                                Function* func,
                                                size_t id) {
  // TODO: If we need to track the delimiters of annotated code locations, we
  //       need to enable that here.
  if (func && !func->expressionLocations.empty()) {
    binaryLocations.delimiters[curr][id] = o.size();
  }
}

std::optional<BufferWithRandomAccess> WasmBinaryWriter::writeCodeAnnotations() {
  std::optional<BufferWithRandomAccess> ret;

  auto append = [&](std::optional<BufferWithRandomAccess>&& temp) {
    if (temp) {
      if (!ret) {
        // This is the first section.
        ret = std::move(temp);
      } else {
        // This is a later section, append.
        ret->insert(ret->end(), temp->begin(), temp->end());
      }
    }
  };

  append(getBranchHintsBuffer());
  append(getInlineHintsBuffer());
  return ret;
}

template<typename HasFunc, typename EmitFunc>
std::optional<BufferWithRandomAccess> WasmBinaryWriter::writeExpressionHints(
  Name sectionName, HasFunc has, EmitFunc emit) {
  // Assemble the info: for each function, a vector of the hints.
  struct ExprHint {
    Expression* expr;
    // The offset we will write in the custom section.
    BinaryLocation offset;
    Function::CodeAnnotation* hint;
  };

  struct FuncHints {
    Name func;
    std::vector<ExprHint> exprHints;
  };

  std::vector<FuncHints> funcHintsVec;

  for (auto& func : wasm->functions) {
    // Collect the hints for this function.
    FuncHints funcHints;

    // We compute the location of the function declaration area (where the
    // locals are declared) the first time we need it.
    BinaryLocation funcDeclarationsOffset = 0;

    for (auto& [expr, annotation] : func->codeAnnotations) {
      if (has(annotation)) {
        auto exprIter = binaryLocations.expressions.find(expr);
        if (exprIter == binaryLocations.expressions.end()) {
          // No expression exists for this annotation - perhaps optimizations
          // removed it.
          continue;
        }
        auto exprOffset = exprIter->second.start;

        if (!funcDeclarationsOffset) {
          auto funcIter = binaryLocations.functions.find(func.get());
          assert(funcIter != binaryLocations.functions.end());
          funcDeclarationsOffset = funcIter->second.declarations;
        }

        // Compute the offset: it should be relative to the start of the
        // function locals (i.e. the function declarations).
        auto offset = exprOffset - funcDeclarationsOffset;

        funcHints.exprHints.push_back(ExprHint{expr, offset, &annotation});
      }
    }

    if (funcHints.exprHints.empty()) {
      continue;
    }

    // We found something. Finalize the data.
    funcHints.func = func->name;

    // Hints must be sorted by increasing binary offset.
    std::sort(
      funcHints.exprHints.begin(),
      funcHints.exprHints.end(),
      [](const ExprHint& a, const ExprHint& b) { return a.offset < b.offset; });

    funcHintsVec.emplace_back(std::move(funcHints));
  }

  if (funcHintsVec.empty()) {
    return {};
  }

  BufferWithRandomAccess buffer;

  // We found data: emit the section.
  buffer << uint8_t(BinaryConsts::Custom);
  auto lebPos = buffer.writeU32LEBPlaceholder();
  buffer.writeInlineString(sectionName.str);

  buffer << U32LEB(funcHintsVec.size());
  for (auto& funcHints : funcHintsVec) {
    buffer << U32LEB(getFunctionIndex(funcHints.func));

    buffer << U32LEB(funcHints.exprHints.size());
    for (auto& exprHint : funcHints.exprHints) {
      buffer << U32LEB(exprHint.offset);

      emit(*exprHint.hint, buffer);
    }
  }

  // Write the final size. We can ignore the return value, which is the number
  // of bytes we shrank (if the LEB was smaller than the maximum size), as no
  // value in this section cares.
  buffer.emitRetroactiveSectionSizeLEB(lebPos);

  return buffer;
}

std::optional<BufferWithRandomAccess> WasmBinaryWriter::getBranchHintsBuffer() {
  return writeExpressionHints(
    Annotations::BranchHint,
    [](const Function::CodeAnnotation& annotation) {
      return annotation.branchLikely;
    },
    [](const Function::CodeAnnotation& annotation,
       BufferWithRandomAccess& buffer) {
      // Hint size, always 1 for now.
      buffer << U32LEB(1);

      // We must only emit hints that are present.
      assert(annotation.branchLikely);

      // Hint contents: likely or not.
      buffer << U32LEB(int(*annotation.branchLikely));
    });
}

std::optional<BufferWithRandomAccess> WasmBinaryWriter::getInlineHintsBuffer() {
  return writeExpressionHints(
    Annotations::InlineHint,
    [](const Function::CodeAnnotation& annotation) {
      return annotation.inline_;
    },
    [](const Function::CodeAnnotation& annotation,
       BufferWithRandomAccess& buffer) {
      // Hint size, always 1 for now.
      buffer << U32LEB(1);

      // We must only emit hints that are present.
      assert(annotation.inline_);

      // Hint must fit in one byte.
      assert(*annotation.inline_ <= 127);

      // Hint contents: inline frequency count
      buffer << U32LEB(*annotation.inline_);
    });
}

void WasmBinaryWriter::writeData(const char* data, size_t size) {
  for (size_t i = 0; i < size; i++) {
    o << int8_t(data[i]);
  }
}

void WasmBinaryWriter::writeInlineString(std::string_view name) {
  o.writeInlineString(name);
}

static bool isHexDigit(char ch) {
  return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') ||
         (ch >= 'A' && ch <= 'F');
}

static int decodeHexNibble(char ch) {
  return ch <= '9' ? ch & 15 : (ch & 15) + 9;
}

void WasmBinaryWriter::writeEscapedName(std::string_view name) {
  if (name.find('\\') == std::string_view::npos) {
    writeInlineString(name);
    return;
  }
  // decode escaped by escapeName (see below) function names
  std::string unescaped;
  for (size_t i = 0; i < name.size();) {
    char ch = name[i++];
    // support only `\xx` escapes; ignore invalid or unsupported escapes
    if (ch != '\\' || i + 1 >= name.size() || !isHexDigit(name[i]) ||
        !isHexDigit(name[i + 1])) {
      unescaped.push_back(ch);
      continue;
    }
    unescaped.push_back(
      char((decodeHexNibble(name[i]) << 4) | decodeHexNibble(name[i + 1])));
    i += 2;
  }
  writeInlineString({unescaped.data(), unescaped.size()});
}

void WasmBinaryWriter::writeInlineBuffer(const char* data, size_t size) {
  o << U32LEB(size);
  writeData(data, size);
}

void WasmBinaryWriter::writeType(Type type) {
  if (type.isRef()) {
    // The only reference types allowed without GC are funcref, externref, and
    // exnref. We internally use more refined versions of those types, but we
    // cannot emit those without GC.
    if (!wasm->features.hasGC()) {
      auto ht = type.getHeapType();
      if (ht.isMaybeShared(HeapType::string)) {
        // Do not overgeneralize stringref to anyref. We have tests that when a
        // stringref is expected, we actually get a stringref. If we see a
        // string, the stringref feature must be enabled.
        type = Type(HeapTypes::string.getBasic(ht.getShared()), Nullable);
      } else {
        // Only the top type (func, extern, exn) is available, and only the
        // nullable version.
        type = Type(type.getHeapType().getTop(), Nullable);
      }
    }
    auto heapType = type.getHeapType();
    if (type.isNullable() && heapType.isBasic() && !heapType.isShared()) {
      switch (heapType.getBasic(Unshared)) {
        case HeapType::ext:
          o << S32LEB(BinaryConsts::EncodedType::externref);
          return;
        case HeapType::any:
          o << S32LEB(BinaryConsts::EncodedType::anyref);
          return;
        case HeapType::func:
          o << S32LEB(BinaryConsts::EncodedType::funcref);
          return;
        case HeapType::cont:
          o << S32LEB(BinaryConsts::EncodedType::contref);
          return;
        case HeapType::eq:
          o << S32LEB(BinaryConsts::EncodedType::eqref);
          return;
        case HeapType::i31:
          o << S32LEB(BinaryConsts::EncodedType::i31ref);
          return;
        case HeapType::struct_:
          o << S32LEB(BinaryConsts::EncodedType::structref);
          return;
        case HeapType::array:
          o << S32LEB(BinaryConsts::EncodedType::arrayref);
          return;
        case HeapType::exn:
          o << S32LEB(BinaryConsts::EncodedType::exnref);
          return;
        case HeapType::string:
          o << S32LEB(BinaryConsts::EncodedType::stringref);
          return;
        case HeapType::none:
          o << S32LEB(BinaryConsts::EncodedType::nullref);
          return;
        case HeapType::noext:
          o << S32LEB(BinaryConsts::EncodedType::nullexternref);
          return;
        case HeapType::nofunc:
          o << S32LEB(BinaryConsts::EncodedType::nullfuncref);
          return;
        case HeapType::noexn:
          o << S32LEB(BinaryConsts::EncodedType::nullexnref);
          return;
        case HeapType::nocont:
          o << S32LEB(BinaryConsts::EncodedType::nullcontref);
          return;
      }
    }
    if (type.isNullable()) {
      o << S32LEB(BinaryConsts::EncodedType::nullable);
    } else {
      o << S32LEB(BinaryConsts::EncodedType::nonnullable);
    }
    writeHeapType(type.getHeapType(), type.getExactness());
    return;
  }
  int ret = 0;
  TODO_SINGLE_COMPOUND(type);
  switch (type.getBasic()) {
    // None only used for block signatures. TODO: Separate out?
    case Type::none:
      ret = BinaryConsts::EncodedType::Empty;
      break;
    case Type::i32:
      ret = BinaryConsts::EncodedType::i32;
      break;
    case Type::i64:
      ret = BinaryConsts::EncodedType::i64;
      break;
    case Type::f32:
      ret = BinaryConsts::EncodedType::f32;
      break;
    case Type::f64:
      ret = BinaryConsts::EncodedType::f64;
      break;
    case Type::v128:
      ret = BinaryConsts::EncodedType::v128;
      break;
    default:
      WASM_UNREACHABLE("unexpected type");
  }
  o << S32LEB(ret);
}

void WasmBinaryWriter::writeHeapType(HeapType type, Exactness exactness) {
  // ref.null always has a bottom heap type in Binaryen IR, but those types are
  // only actually valid with GC. Otherwise, emit the corresponding valid top
  // types instead.
  if (!wasm->features.hasCustomDescriptors()) {
    exactness = Inexact;
  }
  if (!wasm->features.hasGC()) {
    type = type.getTop();
  }
  assert(!type.isBasic() || exactness == Inexact);
  if (exactness == Exact) {
    o << uint8_t(BinaryConsts::EncodedType::Exact);
  }
  if (!type.isBasic()) {
    o << S64LEB(getTypeIndex(type)); // TODO: Actually s33
    return;
  }

  int ret = 0;
  if (type.isShared()) {
    o << uint8_t(BinaryConsts::EncodedType::Shared);
  }
  switch (type.getBasic(Unshared)) {
    case HeapType::ext:
      ret = BinaryConsts::EncodedHeapType::ext;
      break;
    case HeapType::func:
      ret = BinaryConsts::EncodedHeapType::func;
      break;
    case HeapType::cont:
      ret = BinaryConsts::EncodedHeapType::cont;
      break;
    case HeapType::any:
      ret = BinaryConsts::EncodedHeapType::any;
      break;
    case HeapType::eq:
      ret = BinaryConsts::EncodedHeapType::eq;
      break;
    case HeapType::i31:
      ret = BinaryConsts::EncodedHeapType::i31;
      break;
    case HeapType::struct_:
      ret = BinaryConsts::EncodedHeapType::struct_;
      break;
    case HeapType::array:
      ret = BinaryConsts::EncodedHeapType::array;
      break;
    case HeapType::exn:
      ret = BinaryConsts::EncodedHeapType::exn;
      break;
    case HeapType::string:
      ret = BinaryConsts::EncodedHeapType::string;
      break;
    case HeapType::none:
      ret = BinaryConsts::EncodedHeapType::none;
      break;
    case HeapType::noext:
      ret = BinaryConsts::EncodedHeapType::noext;
      break;
    case HeapType::nofunc:
      ret = BinaryConsts::EncodedHeapType::nofunc;
      break;
    case HeapType::noexn:
      ret = BinaryConsts::EncodedHeapType::noexn;
      break;
    case HeapType::nocont:
      ret = BinaryConsts::EncodedHeapType::nocont;
      break;
  }
  o << S64LEB(ret); // TODO: Actually s33
}

void WasmBinaryWriter::writeIndexedHeapType(HeapType type) {
  o << U32LEB(getTypeIndex(type));
}

void WasmBinaryWriter::writeField(const Field& field) {
  if (field.type == Type::i32 && field.packedType != Field::not_packed) {
    if (field.packedType == Field::i8) {
      o << S32LEB(BinaryConsts::EncodedType::i8);
    } else if (field.packedType == Field::i16) {
      o << S32LEB(BinaryConsts::EncodedType::i16);
    } else {
      WASM_UNREACHABLE("invalid packed type");
    }
  } else {
    writeType(field.type);
  }
  o << U32LEB(field.mutable_);
}

void WasmBinaryWriter::writeMemoryOrder(MemoryOrder order, bool isRMW) {
  uint8_t code = 0;
  switch (order) {
    case MemoryOrder::Unordered:
      // Non-atomic get or set does not need a memory order.
      return;
    case MemoryOrder::SeqCst:
      code = BinaryConsts::OrderSeqCst;
      break;
    case MemoryOrder::AcqRel:
      code = BinaryConsts::OrderAcqRel;
      break;
  }
  if (isRMW) {
    o << uint8_t((code << 4) | code);
  } else {
    o << code;
  }
}

// reader

WasmBinaryReader::WasmBinaryReader(Module& wasm,
                                   FeatureSet features,
                                   const std::vector<char>& input,
                                   std::vector<char>& sourceMap)
  : wasm(wasm), allocator(wasm.allocator), input(input), builder(wasm),
    sourceMapReader(sourceMap) {
  wasm.features = features;
}

void WasmBinaryReader::preScan() {
  assert(pos == 0);
  getInt32(); // magic
  getInt32(); // version

  bool foundDWARF = false;

  while (more()) {
    uint8_t sectionCode = getInt8();
    uint32_t payloadLen = getU32LEB();
    if (uint64_t(pos) + uint64_t(payloadLen) > input.size()) {
      throwError("Section extends beyond end of input");
    }
    auto oldPos = pos;
    if (sectionCode == BinaryConsts::Section::Custom) {
      auto sectionName = getInlineString();

      if (sectionName == Annotations::BranchHint ||
          sectionName == Annotations::InlineHint) {
        // Code annotations require code locations.
        // TODO: We could note which functions require code locations, as an
        //       optimization.
        needCodeLocations = true;
      } else if (DWARF && Debug::isDWARFSection(sectionName)) {
        // DWARF sections contain code offsets.
        needCodeLocations = true;
        foundDWARF = true;
      } else if (debugInfo &&
                 sectionName == BinaryConsts::CustomSections::Name) {
        readNames(oldPos, payloadLen);
      } else if (sectionName == BinaryConsts::CustomSections::TargetFeatures) {
        readFeatures(oldPos, payloadLen);
      }
      // TODO: We could stop early in some cases, if we've seen enough (e.g.
      //       seeing Code implies no BranchHint will appear, due to ordering).
    }
    pos = oldPos + payloadLen;
  }

  if (DWARF && !foundDWARF) {
    // The user asked for DWARF, but no DWARF sections exist in practice, so
    // disable the support.
    DWARF = false;
  }

  // Reset.
  pos = 0;
}

void WasmBinaryReader::read() {
  preScan();
  readHeader();
  sourceMapReader.parse(wasm);

  // Read sections until the end
  while (more()) {
    uint8_t sectionCode = getInt8();
    uint32_t payloadLen = getU32LEB();
    if (uint64_t(pos) + uint64_t(payloadLen) > input.size()) {
      throwError("Section extends beyond end of input");
    }

    auto oldPos = pos;

    // Note the section in the list of seen sections, as almost no sections can
    // appear more than once, and verify those that shouldn't do not.
    if (sectionCode != BinaryConsts::Section::Custom &&
        !seenSections.insert(sectionCode).second) {
      throwError("section seen more than once: " + std::to_string(sectionCode));
    }

    switch (sectionCode) {
      case BinaryConsts::Section::Start:
        readStart();
        break;
      case BinaryConsts::Section::Memory:
        readMemories();
        break;
      case BinaryConsts::Section::Type:
        readTypes();
        break;
      case BinaryConsts::Section::Import:
        readImports();
        break;
      case BinaryConsts::Section::Function:
        readFunctionSignatures();
        break;
      case BinaryConsts::Section::Code:
        if (needCodeLocations) {
          codeSectionLocation = pos;
        }
        readFunctions();
        break;
      case BinaryConsts::Section::Export:
        readExports();
        break;
      case BinaryConsts::Section::Element:
        readElementSegments();
        break;
      case BinaryConsts::Section::Strings:
        readStrings();
        break;
      case BinaryConsts::Section::Global:
        readGlobals();
        break;
      case BinaryConsts::Section::Data:
        readDataSegments();
        break;
      case BinaryConsts::Section::DataCount:
        readDataSegmentCount();
        break;
      case BinaryConsts::Section::Table:
        readTableDeclarations();
        break;
      case BinaryConsts::Section::Tag:
        readTags();
        break;
      case BinaryConsts::Section::Custom: {
        readCustomSection(payloadLen);
        if (pos > oldPos + payloadLen) {
          throwError("bad user section size, started at " +
                     std::to_string(oldPos) + " plus payload " +
                     std::to_string(payloadLen) +
                     " not being equal to new position " + std::to_string(pos));
        }
        pos = oldPos + payloadLen;
        break;
      }
      default:
        throwError(std::string("unrecognized section ID: ") +
                   std::to_string(sectionCode));
    }

    // make sure we advanced exactly past this section
    if (pos != oldPos + payloadLen) {
      throwError("bad section size, started at " + std::to_string(oldPos) +
                 " plus payload " + std::to_string(payloadLen) +
                 " not being equal to new position " + std::to_string(pos));
    }
  }

  // Go back and parse things we deferred.
  if (branchHintsPos) {
    pos = branchHintsPos;
    readBranchHints(branchHintsLen);
  }
  if (inlineHintsPos) {
    pos = inlineHintsPos;
    readInlineHints(inlineHintsLen);
  }

  validateBinary();
}

void WasmBinaryReader::readCustomSection(size_t payloadLen) {
  auto oldPos = pos;
  Name sectionName = getInlineString();
  size_t read = pos - oldPos;
  if (read > payloadLen) {
    throwError("bad user section size");
  }
  payloadLen -= read;
  if (sectionName.equals(BinaryConsts::CustomSections::Name) ||
      sectionName.equals(BinaryConsts::CustomSections::TargetFeatures)) {
    // We already read the name and target features sections before anything
    // else.
    pos += payloadLen;
  } else if (sectionName.equals(BinaryConsts::CustomSections::Dylink)) {
    readDylink(payloadLen);
  } else if (sectionName.equals(BinaryConsts::CustomSections::Dylink0)) {
    readDylink0(payloadLen);
  } else if (sectionName == Annotations::BranchHint) {
    // Only note the position and length, we read this later.
    branchHintsPos = pos;
    branchHintsLen = payloadLen;
  } else if (sectionName == Annotations::InlineHint) {
    inlineHintsPos = pos;
    inlineHintsLen = payloadLen;
  } else {
    // an unfamiliar custom section
    if (sectionName.equals(BinaryConsts::CustomSections::Linking)) {
      std::cerr
        << "warning: linking section is present, so this is not a standard "
           "wasm file - binaryen cannot handle this properly!\n";
    }
    wasm.customSections.resize(wasm.customSections.size() + 1);
    auto& section = wasm.customSections.back();
    section.name = sectionName.str;
    auto data = getByteView(payloadLen);
    section.data = {data.begin(), data.end()};
  }
}

std::string_view WasmBinaryReader::getByteView(size_t size) {
  if (size > input.size() || pos > input.size() - size) {
    throwError("unexpected end of input");
  }
  pos += size;
  return {input.data() + (pos - size), size};
}

uint8_t WasmBinaryReader::getInt8() {
  if (!more()) {
    throwError("unexpected end of input");
  }
  return input[pos++];
}

uint16_t WasmBinaryReader::getInt16() {
  auto ret = uint16_t(getInt8());
  ret |= uint16_t(getInt8()) << 8;
  return ret;
}

uint32_t WasmBinaryReader::getInt32() {
  auto ret = uint32_t(getInt16());
  ret |= uint32_t(getInt16()) << 16;
  return ret;
}

uint64_t WasmBinaryReader::getInt64() {
  auto ret = uint64_t(getInt32());
  ret |= uint64_t(getInt32()) << 32;
  return ret;
}

uint8_t WasmBinaryReader::getLaneIndex(size_t lanes) {
  auto ret = getInt8();
  if (ret >= lanes) {
    throwError("Illegal lane index");
  }
  return ret;
}

Literal WasmBinaryReader::getFloat32Literal() {
  auto ret = Literal(getInt32());
  ret = ret.castToF32();
  return ret;
}

Literal WasmBinaryReader::getFloat64Literal() {
  auto ret = Literal(getInt64());
  ret = ret.castToF64();
  return ret;
}

Literal WasmBinaryReader::getVec128Literal() {
  std::array<uint8_t, 16> bytes;
  for (auto i = 0; i < 16; ++i) {
    bytes[i] = getInt8();
  }
  auto ret = Literal(bytes.data());
  return ret;
}

uint32_t WasmBinaryReader::getU32LEB() {
  U32LEB ret;
  ret.read([&]() { return getInt8(); });
  return ret.value;
}

uint64_t WasmBinaryReader::getU64LEB() {
  U64LEB ret;
  ret.read([&]() { return getInt8(); });
  return ret.value;
}

int32_t WasmBinaryReader::getS32LEB() {
  S32LEB ret;
  ret.read([&]() { return (int8_t)getInt8(); });
  return ret.value;
}

int64_t WasmBinaryReader::getS64LEB() {
  S64LEB ret;
  ret.read([&]() { return (int8_t)getInt8(); });
  return ret.value;
}

bool WasmBinaryReader::getBasicType(int32_t code, Type& out) {
  switch (code) {
    case BinaryConsts::EncodedType::i32:
      out = Type::i32;
      return true;
    case BinaryConsts::EncodedType::i64:
      out = Type::i64;
      return true;
    case BinaryConsts::EncodedType::f32:
      out = Type::f32;
      return true;
    case BinaryConsts::EncodedType::f64:
      out = Type::f64;
      return true;
    case BinaryConsts::EncodedType::v128:
      out = Type::v128;
      return true;
    case BinaryConsts::EncodedType::funcref:
      out = Type(HeapType::func, Nullable);
      return true;
    case BinaryConsts::EncodedType::contref:
      out = Type(HeapType::cont, Nullable);
      return true;
    case BinaryConsts::EncodedType::externref:
      out = Type(HeapType::ext, Nullable);
      return true;
    case BinaryConsts::EncodedType::anyref:
      out = Type(HeapType::any, Nullable);
      return true;
    case BinaryConsts::EncodedType::eqref:
      out = Type(HeapType::eq, Nullable);
      return true;
    case BinaryConsts::EncodedType::i31ref:
      out = Type(HeapType::i31, Nullable);
      return true;
    case BinaryConsts::EncodedType::structref:
      out = Type(HeapType::struct_, Nullable);
      return true;
    case BinaryConsts::EncodedType::arrayref:
      out = Type(HeapType::array, Nullable);
      return true;
    case BinaryConsts::EncodedType::exnref:
      out = Type(HeapType::exn, Nullable);
      return true;
    case BinaryConsts::EncodedType::stringref:
      out = Type(HeapType::string, Nullable);
      return true;
    case BinaryConsts::EncodedType::nullref:
      out = Type(HeapType::none, Nullable);
      return true;
    case BinaryConsts::EncodedType::nullexternref:
      out = Type(HeapType::noext, Nullable);
      return true;
    case BinaryConsts::EncodedType::nullfuncref:
      out = Type(HeapType::nofunc, Nullable);
      return true;
    case BinaryConsts::EncodedType::nullexnref:
      out = Type(HeapType::noexn, Nullable);
      return true;
    case BinaryConsts::EncodedType::nullcontref:
      out = Type(HeapType::nocont, Nullable);
      return true;
    default:
      return false;
  }
}

bool WasmBinaryReader::getBasicHeapType(int64_t code, HeapType& out) {
  switch (code) {
    case BinaryConsts::EncodedHeapType::func:
      out = HeapType::func;
      return true;
    case BinaryConsts::EncodedHeapType::cont:
      out = HeapType::cont;
      return true;
    case BinaryConsts::EncodedHeapType::ext:
      out = HeapType::ext;
      return true;
    case BinaryConsts::EncodedHeapType::any:
      out = HeapType::any;
      return true;
    case BinaryConsts::EncodedHeapType::eq:
      out = HeapType::eq;
      return true;
    case BinaryConsts::EncodedHeapType::i31:
      out = HeapType::i31;
      return true;
    case BinaryConsts::EncodedHeapType::struct_:
      out = HeapType::struct_;
      return true;
    case BinaryConsts::EncodedHeapType::array:
      out = HeapType::array;
      return true;
    case BinaryConsts::EncodedHeapType::exn:
      out = HeapType::exn;
      return true;
    case BinaryConsts::EncodedHeapType::string:
      out = HeapType::string;
      return true;
    case BinaryConsts::EncodedHeapType::none:
      out = HeapType::none;
      return true;
    case BinaryConsts::EncodedHeapType::noext:
      out = HeapType::noext;
      return true;
    case BinaryConsts::EncodedHeapType::nofunc:
      out = HeapType::nofunc;
      return true;
    case BinaryConsts::EncodedHeapType::noexn:
      out = HeapType::noexn;
      return true;
    case BinaryConsts::EncodedHeapType::nocont:
      out = HeapType::nocont;
      return true;
    default:
      return false;
  }
}

Signature WasmBinaryReader::getBlockType() {
  // Single value types are negative; signature indices are non-negative.
  auto code = getS32LEB();
  if (code >= 0) {
    return getSignatureByTypeIndex(code);
  }
  if (code == BinaryConsts::EncodedType::Empty) {
    return Signature();
  }
  return Signature(Type::none, getType(code));
}

Type WasmBinaryReader::getType(int code) {
  Type type;
  if (getBasicType(code, type)) {
    return type;
  }
  auto [heapType, exactness] = getHeapType();
  switch (code) {
    case BinaryConsts::EncodedType::nullable:
      return Type(heapType, Nullable, exactness);
    case BinaryConsts::EncodedType::nonnullable:
      return Type(heapType, NonNullable, exactness);
    default:
      throwError("invalid wasm type: " + std::to_string(code));
  }
  WASM_UNREACHABLE("unexpected type");
}

Type WasmBinaryReader::getType() { return getType(getS32LEB()); }

std::pair<HeapType, Exactness> WasmBinaryReader::getHeapType() {
  auto type = getS64LEB(); // TODO: Actually s33
  auto exactness = Inexact;
  if (type == BinaryConsts::EncodedType::ExactLEB) {
    exactness = Exact;
    type = getS64LEB(); // TODO: Actually s33
  }
  // Single heap types are negative; heap type indices are non-negative
  if (type >= 0) {
    if (size_t(type) >= types.size()) {
      throwError("invalid type index: " + std::to_string(type));
    }
    return {types[type], exactness};
  }
  if (exactness == Exact) {
    throwError("invalid type index: " + std::to_string(type));
  }
  auto share = Unshared;
  if (type == BinaryConsts::EncodedType::SharedLEB) {
    share = Shared;
    type = getS64LEB(); // TODO: Actually s33
  }
  HeapType ht;
  if (getBasicHeapType(type, ht)) {
    return {ht.getBasic(share), Inexact};
  }
  throwError("invalid wasm heap type: " + std::to_string(type));
}

HeapType WasmBinaryReader::getIndexedHeapType() {
  auto index = getU32LEB();
  if (index >= types.size()) {
    throwError("invalid heap type index: " + std::to_string(index));
  }
  return types[index];
}

Type WasmBinaryReader::getConcreteType() {
  auto type = getType();
  if (!type.isConcrete()) {
    throwError("non-concrete type when one expected");
  }
  return type;
}

Name WasmBinaryReader::getInlineString(bool requireValid) {
  auto len = getU32LEB();
  auto data = getByteView(len);
  if (requireValid && !String::isUTF8(data)) {
    throwError("invalid UTF-8 string");
  }
  return Name(data);
}

void WasmBinaryReader::verifyInt8(int8_t x) {
  int8_t y = getInt8();
  if (x != y) {
    throwError("surprising value");
  }
}

void WasmBinaryReader::verifyInt16(int16_t x) {
  int16_t y = getInt16();
  if (x != y) {
    throwError("surprising value");
  }
}

void WasmBinaryReader::verifyInt32(int32_t x) {
  int32_t y = getInt32();
  if (x != y) {
    throwError("surprising value");
  }
}

void WasmBinaryReader::verifyInt64(int64_t x) {
  int64_t y = getInt64();
  if (x != y) {
    throwError("surprising value");
  }
}

void WasmBinaryReader::readHeader() {
  verifyInt32(BinaryConsts::Magic);
  auto version = getInt32();
  if (version != BinaryConsts::Version) {
    if (version == 0x1000d) {
      throwError("this looks like a wasm component, which Binaryen does not "
                 "support yet (see "
                 "https://github.com/WebAssembly/binaryen/issues/6728)");
    }
    throwError("invalid version");
  }
}

void WasmBinaryReader::readStart() {
  startIndex = getU32LEB();
  wasm.start = getFunctionName(startIndex);
}

static Name makeName(std::string prefix, size_t counter) {
  return Name(prefix + std::to_string(counter));
}

// Look up a name from the names section or use a validated version of the
// provided name. Return the name and whether it is explicit in the input.
static std::pair<Name, bool>
getOrMakeName(const std::unordered_map<Index, Name>& nameMap,
              Index i,
              Name name,
              std::unordered_set<Name>& usedNames) {
  if (auto it = nameMap.find(i); it != nameMap.end()) {
    return {it->second, true};
  } else {
    auto valid = Names::getValidNameGivenExisting(name, usedNames);
    usedNames.insert(valid);
    return {valid, false};
  }
}

void WasmBinaryReader::readMemories() {
  auto num = getU32LEB();
  auto numImports = wasm.memories.size();
  for (auto& [index, name] : memoryNames) {
    if (index >= num + numImports) {
      std::cerr << "warning: memory index out of bounds in name section: "
                << name << " at index " << index << '\n';
    }
  }
  for (size_t i = 0; i < num; i++) {
    auto [name, isExplicit] = getOrMakeName(
      memoryNames, numImports + i, makeName("", i), usedMemoryNames);
    auto memory = Builder::makeMemory(name);
    memory->hasExplicitName = isExplicit;
    getResizableLimits(memory->initial,
                       memory->max,
                       memory->shared,
                       memory->addressType,
                       Memory::kUnlimitedSize);
    wasm.addMemory(std::move(memory));
  }
}

void WasmBinaryReader::readTypes() {
  TypeBuilder builder(getU32LEB(), wasm.features);

  auto readHeapType = [&]() -> std::pair<HeapType, Exactness> {
    int64_t htCode = getS64LEB(); // TODO: Actually s33
    auto exactness = Inexact;
    if (htCode == BinaryConsts::EncodedType::ExactLEB) {
      exactness = Exact;
      htCode = getS64LEB(); // TODO: Actually s33
    }
    if (htCode >= 0) {
      if (size_t(htCode) >= builder.size()) {
        throwError("invalid type index: " + std::to_string(htCode));
      }
      return {builder.getTempHeapType(size_t(htCode)), exactness};
    }
    if (exactness == Exact) {
      throwError("invalid type index: " + std::to_string(htCode));
    }
    auto share = Unshared;
    if (htCode == BinaryConsts::EncodedType::SharedLEB) {
      share = Shared;
      htCode = getS64LEB(); // TODO: Actually s33
    }
    HeapType ht;
    if (getBasicHeapType(htCode, ht)) {
      return {ht.getBasic(share), Inexact};
    }
    throwError("invalid wasm heap type: " + std::to_string(htCode));
  };
  auto makeType = [&](int32_t typeCode) {
    Type type;
    if (getBasicType(typeCode, type)) {
      return type;
    }

    switch (typeCode) {
      case BinaryConsts::EncodedType::nullable:
      case BinaryConsts::EncodedType::nonnullable: {
        auto nullability = typeCode == BinaryConsts::EncodedType::nullable
                             ? Nullable
                             : NonNullable;

        auto [ht, exactness] = readHeapType();
        if (ht.isBasic()) {
          return Type(ht, nullability, exactness);
        }

        return builder.getTempRefType(ht, nullability, exactness);
      }
      default:
        throwError("unexpected type index: " + std::to_string(typeCode));
    }
    WASM_UNREACHABLE("unexpected type");
  };
  auto readType = [&]() { return makeType(getS32LEB()); };

  auto readSignatureDef = [&]() {
    std::vector<Type> params;
    std::vector<Type> results;
    size_t numParams = getU32LEB();
    for (size_t j = 0; j < numParams; j++) {
      params.push_back(readType());
    }
    auto numResults = getU32LEB();
    for (size_t j = 0; j < numResults; j++) {
      results.push_back(readType());
    }
    return Signature(builder.getTempTupleType(params),
                     builder.getTempTupleType(results));
  };

  auto readContinuationDef = [&]() {
    auto [ht, exactness] = readHeapType();
    if (exactness != Inexact) {
      throw ParseException("invalid exact type in cont definition");
    }
    if (!ht.isSignature()) {
      throw ParseException("cont types must be built from function types");
    }
    return Continuation(ht);
  };

  auto readMutability = [&]() {
    switch (getU32LEB()) {
      case 0:
        return Immutable;
      case 1:
        return Mutable;
      default:
        throw ParseException("Expected 0 or 1 for mutability");
    }
  };

  auto readFieldDef = [&]() {
    // The value may be a general wasm type, or one of the types only possible
    // in a field.
    auto typeCode = getS32LEB();
    if (typeCode == BinaryConsts::EncodedType::i8) {
      auto mutable_ = readMutability();
      return Field(Field::i8, mutable_);
    }
    if (typeCode == BinaryConsts::EncodedType::i16) {
      auto mutable_ = readMutability();
      return Field(Field::i16, mutable_);
    }
    // It's a regular wasm value.
    auto type = makeType(typeCode);
    auto mutable_ = readMutability();
    return Field(type, mutable_);
  };

  auto readStructDef = [&]() {
    FieldList fields;
    size_t numFields = getU32LEB();
    for (size_t j = 0; j < numFields; j++) {
      fields.push_back(readFieldDef());
    }
    return Struct(std::move(fields));
  };

  for (size_t i = 0; i < builder.size(); i++) {
    auto form = getInt8();
    if (form == BinaryConsts::EncodedType::Rec) {
      uint32_t groupSize = getU32LEB();
      if (groupSize == 0u) {
        // TODO: Support groups of size zero by shrinking the builder.
        throwError("Recursion groups of size zero not supported");
      }
      // The group counts as one element in the type section, so we have to
      // allocate space for the extra types.
      builder.grow(groupSize - 1);
      builder.createRecGroup(i, groupSize);
      form = getInt8();
    }
    if (form == BinaryConsts::EncodedType::Sub ||
        form == BinaryConsts::EncodedType::SubFinal) {
      if (form == BinaryConsts::EncodedType::Sub) {
        builder[i].setOpen();
      }
      uint32_t supers = getU32LEB();
      if (supers > 0) {
        if (supers != 1) {
          throwError("Invalid type definition with " + std::to_string(supers) +
                     " supertypes");
        }
        auto superIdx = getU32LEB();
        if (superIdx >= builder.size()) {
          throwError("invalid supertype index: " + std::to_string(superIdx));
        }
        builder[i].subTypeOf(builder[superIdx]);
      }
      form = getInt8();
    }
    if (form == BinaryConsts::EncodedType::Shared) {
      builder[i].setShared();
      form = getInt8();
    }
    if (form == BinaryConsts::EncodedType::Describes) {
      auto descIdx = getU32LEB();
      if (descIdx >= builder.size()) {
        throwError("invalid described type index: " + std::to_string(descIdx));
      }
      builder[i].describes(builder[descIdx]);
      form = getInt8();
    }
    if (form == BinaryConsts::EncodedType::Descriptor) {
      auto descIdx = getU32LEB();
      if (descIdx >= builder.size()) {
        throwError("invalid descriptor type index: " + std::to_string(descIdx));
      }
      builder[i].descriptor(builder[descIdx]);
      form = getInt8();
    }
    if (form == BinaryConsts::EncodedType::Func) {
      builder[i] = readSignatureDef();
    } else if (form == BinaryConsts::EncodedType::Cont) {
      builder[i] = readContinuationDef();
    } else if (form == BinaryConsts::EncodedType::Struct) {
      builder[i] = readStructDef();
    } else if (form == BinaryConsts::EncodedType::Array) {
      builder[i] = Array(readFieldDef());
    } else {
      throwError("Bad type form " + std::to_string(form));
    }
  }

  auto result = builder.build();
  if (auto* err = result.getError()) {
    Fatal() << "invalid type: " << err->reason << " at index " << err->index;
  }
  types = std::move(*result);

  // Record the type indices.
  for (Index i = 0; i < types.size(); ++i) {
    wasm.typeIndices.insert({types[i], i});
  }

  // Assign names from the names section.
  for (auto& [index, name] : typeNames) {
    if (index >= types.size()) {
      std::cerr << "warning: type index out of bounds in name section: " << name
                << " at index " << index << '\n';
      continue;
    }
    wasm.typeNames[types[index]].name = name;
  }
  for (auto& [index, fields] : fieldNames) {
    if (index >= types.size()) {
      std::cerr
        << "warning: type index out of bounds in name section: fields at index "
        << index << '\n';
      continue;
    }
    if (!types[index].isStruct()) {
      std::cerr << "warning: field names applied to non-struct type at index "
                << index << '\n';
      continue;
    }
    auto& names = wasm.typeNames[types[index]].fieldNames;
    for (auto& [field, name] : fields) {
      if (field >= types[index].getStruct().fields.size()) {
        std::cerr << "warning: field index out of bounds in name section: "
                  << name << " at index " << field << " in type " << index
                  << '\n';
        continue;
      }
      names[field] = name;
    }
  }
}

Name WasmBinaryReader::getFunctionName(Index index) {
  if (index >= wasm.functions.size()) {
    throwError("invalid function index");
  }
  return wasm.functions[index]->name;
}

Name WasmBinaryReader::getTableName(Index index) {
  if (index >= wasm.tables.size()) {
    throwError("invalid table index");
  }
  return wasm.tables[index]->name;
}

Name WasmBinaryReader::getMemoryName(Index index) {
  if (index >= wasm.memories.size()) {
    throwError("invalid memory index");
  }
  return wasm.memories[index]->name;
}

Name WasmBinaryReader::getGlobalName(Index index) {
  if (index >= wasm.globals.size()) {
    throwError("invalid global index");
  }
  return wasm.globals[index]->name;
}

Table* WasmBinaryReader::getTable(Index index) {
  if (index < wasm.tables.size()) {
    return wasm.tables[index].get();
  }
  throwError("Table index out of range.");
}

Name WasmBinaryReader::getTagName(Index index) {
  if (index >= wasm.tags.size()) {
    throwError("invalid tag index");
  }
  return wasm.tags[index]->name;
}

Name WasmBinaryReader::getDataName(Index index) {
  if (index >= wasm.dataSegments.size()) {
    throwError("invalid data segment index");
  }
  return wasm.dataSegments[index]->name;
}

Name WasmBinaryReader::getElemName(Index index) {
  if (index >= wasm.elementSegments.size()) {
    throwError("invalid element segment index");
  }
  return wasm.elementSegments[index]->name;
}

Memory* WasmBinaryReader::getMemory(Index index) {
  if (index < wasm.memories.size()) {
    return wasm.memories[index].get();
  }
  throwError("Memory index out of range.");
}

void WasmBinaryReader::getResizableLimits(Address& initial,
                                          Address& max,
                                          bool& shared,
                                          Type& addressType,
                                          Address defaultIfNoMax) {
  auto flags = getU32LEB();
  bool hasMax = (flags & BinaryConsts::HasMaximum) != 0;
  bool isShared = (flags & BinaryConsts::IsShared) != 0;
  bool is64 = (flags & BinaryConsts::Is64) != 0;
  initial = is64 ? getU64LEB() : getU32LEB();
  if (isShared && !hasMax) {
    throwError("shared memory must have max size");
  }
  shared = isShared;
  addressType = is64 ? Type::i64 : Type::i32;
  if (hasMax) {
    max = is64 ? getU64LEB() : getU32LEB();
  } else {
    max = defaultIfNoMax;
  }
}

void WasmBinaryReader::readImports() {
  size_t num = getU32LEB();
  Builder builder(wasm);
  for (size_t i = 0; i < num; i++) {
    auto module = getInlineString();
    auto base = getInlineString();
    auto kind = getU32LEB();
    // We set a unique prefix for the name based on the kind. This ensures no
    // collisions between them, which can't occur here (due to the index i) but
    // could occur later due to the names section.
    switch (kind) {
      case ExternalKind::Function:
      case ExternalKind::Function | BinaryConsts::ExactImport: {
        auto [name, isExplicit] =
          getOrMakeName(functionNames,
                        wasm.functions.size(),
                        makeName("fimport$", wasm.functions.size()),
                        usedFunctionNames);
        auto index = getU32LEB();
        functionTypes.push_back(getTypeByIndex(index));
        auto type = getTypeByIndex(index);
        if (!type.isSignature()) {
          throwError(std::string("Imported function ") + module.toString() +
                     '.' + base.toString() +
                     "'s type must be a signature. Given: " + type.toString());
        }
        auto exact = (kind & BinaryConsts::ExactImport) ? Exact : Inexact;
        auto curr =
          builder.makeFunction(name, Type(type, NonNullable, exact), {});
        curr->hasExplicitName = isExplicit;
        curr->module = module;
        curr->base = base;
        setLocalNames(*curr, wasm.functions.size());
        wasm.addFunction(std::move(curr));
        break;
      }
      case ExternalKind::Table: {
        auto [name, isExplicit] =
          getOrMakeName(tableNames,
                        wasm.tables.size(),
                        makeName("timport$", wasm.tables.size()),
                        usedTableNames);
        auto table = builder.makeTable(name);
        table->hasExplicitName = isExplicit;
        table->module = module;
        table->base = base;
        table->type = getType();

        bool is_shared;
        getResizableLimits(table->initial,
                           table->max,
                           is_shared,
                           table->addressType,
                           Table::kUnlimitedSize);
        if (is_shared) {
          throwError("Tables may not be shared");
        }
        wasm.addTable(std::move(table));
        break;
      }
      case ExternalKind::Memory: {
        auto [name, isExplicit] =
          getOrMakeName(memoryNames,
                        wasm.memories.size(),
                        makeName("mimport$", wasm.memories.size()),
                        usedMemoryNames);
        auto memory = builder.makeMemory(name);
        memory->hasExplicitName = isExplicit;
        memory->module = module;
        memory->base = base;
        getResizableLimits(memory->initial,
                           memory->max,
                           memory->shared,
                           memory->addressType,
                           Memory::kUnlimitedSize);
        wasm.addMemory(std::move(memory));
        break;
      }
      case ExternalKind::Global: {
        auto [name, isExplicit] =
          getOrMakeName(globalNames,
                        wasm.globals.size(),
                        makeName("gimport$", wasm.globals.size()),
                        usedGlobalNames);
        auto type = getConcreteType();
        auto mutable_ = getU32LEB();
        if (mutable_ & ~1) {
          throwError("Global mutability must be 0 or 1");
        }
        auto curr =
          builder.makeGlobal(name,
                             type,
                             nullptr,
                             mutable_ ? Builder::Mutable : Builder::Immutable);
        curr->hasExplicitName = isExplicit;
        curr->module = module;
        curr->base = base;
        wasm.addGlobal(std::move(curr));
        break;
      }
      case ExternalKind::Tag: {
        auto [name, isExplicit] =
          getOrMakeName(tagNames,
                        wasm.tags.size(),
                        makeName("eimport$", wasm.tags.size()),
                        usedTagNames);
        getInt8(); // Reserved 'attribute' field
        auto index = getU32LEB();
        auto curr = builder.makeTag(name, getSignatureByTypeIndex(index));
        curr->hasExplicitName = isExplicit;
        curr->module = module;
        curr->base = base;
        wasm.addTag(std::move(curr));
        break;
      }
      default: {
        throwError("bad import kind");
      }
    }
  }
  numFuncImports = wasm.functions.size();
}

void WasmBinaryReader::setLocalNames(Function& func, Index i) {
  if (auto it = localNames.find(i); it != localNames.end()) {
    for (auto& [local, name] : it->second) {
      if (local >= func.getNumLocals()) {
        std::cerr << "warning: local index out of bounds in name section: "
                  << name << " at index " << local << " in function " << i
                  << '\n';
        continue;
      }
      func.setLocalName(local, name);
    }
  }
}

void WasmBinaryReader::readFunctionSignatures() {
  size_t num = getU32LEB();
  auto numImports = wasm.functions.size();
  for (auto& [index, name] : functionNames) {
    if (index >= num + numImports) {
      std::cerr << "warning: function index out of bounds in name section: "
                << name << " at index " << index << '\n';
    }
  }
  // Also check that the function indices in the local names subsection are
  // in-bounds, even though we don't use them here.
  for (auto& [index, locals] : localNames) {
    if (index >= num + numImports) {
      std::cerr << "warning: function index out of bounds in name section: "
                   "locals at index "
                << index << '\n';
    }
  }
  for (size_t i = 0; i < num; i++) {
    auto [name, isExplicit] = getOrMakeName(
      functionNames, numImports + i, makeName("", i), usedFunctionNames);
    auto index = getU32LEB();
    HeapType type = getTypeByIndex(index);
    functionTypes.push_back(type);
    // Check that the type is a signature.
    getSignatureByTypeIndex(index);
    auto func = Builder(wasm).makeFunction(
      name, Type(type, NonNullable, Exact), {}, nullptr);
    func->hasExplicitName = isExplicit;
    wasm.addFunction(std::move(func));
  }
}

HeapType WasmBinaryReader::getTypeByIndex(Index index) {
  if (index >= types.size()) {
    throwError("invalid type index " + std::to_string(index) + " / " +
               std::to_string(types.size()));
  }
  return types[index];
}

HeapType WasmBinaryReader::getTypeByFunctionIndex(Index index) {
  if (index >= functionTypes.size()) {
    throwError("invalid function index");
  }
  return functionTypes[index];
}

Signature WasmBinaryReader::getSignatureByTypeIndex(Index index) {
  auto heapType = getTypeByIndex(index);
  if (!heapType.isSignature()) {
    throwError("invalid signature type " + heapType.toString());
  }
  return heapType.getSignature();
}

Signature WasmBinaryReader::getSignatureByFunctionIndex(Index index) {
  auto heapType = getTypeByFunctionIndex(index);
  if (!heapType.isSignature()) {
    throwError("invalid signature type " + heapType.toString());
  }
  return heapType.getSignature();
}

void WasmBinaryReader::readFunctions() {
  numFuncBodies = getU32LEB();
  if (numFuncBodies + numFuncImports != wasm.functions.size()) {
    throwError("invalid function section size, must equal types");
  }
  if (needCodeLocations) {
    builder.setBinaryLocation(&pos, codeSectionLocation);
  }
  for (size_t i = 0; i < numFuncBodies; i++) {
    auto sizePos = pos;
    size_t size = getU32LEB();
    if (size == 0) {
      throwError("empty function size");
    }
    Index endOfFunction = pos + size;

    auto& func = wasm.functions[numFuncImports + i];
    currFunction = func.get();

    if (needCodeLocations) {
      func->funcLocation = BinaryLocations::FunctionLocations{
        BinaryLocation(sizePos - codeSectionLocation),
        BinaryLocation(pos - codeSectionLocation),
        BinaryLocation(pos - codeSectionLocation + size)};
    }

    func->prologLocation = sourceMapReader.readDebugLocationAt(pos);

    readVars();
    setLocalNames(*func, numFuncImports + i);
    {
      // Process the function body. Even if we are skipping function bodies we
      // need to not skip the start function. That contains important code for
      // wasm-emscripten-finalize in the form of pthread-related segment
      // initializations. As this is just one function, it doesn't add
      // significant time, so the optimization of skipping bodies is still very
      // useful.
      auto currFunctionIndex = wasm.functions.size();
      bool isStart = startIndex == currFunctionIndex;
      if (skipFunctionBodies && !isStart) {
        // When skipping the function body we need to put something valid in
        // their place so we validate. An unreachable is always acceptable
        // there.
        func->body = Builder(wasm).makeUnreachable();
        // Skip reading the contents.
        pos = endOfFunction;
      } else {
        auto start = builder.visitFunctionStart(func.get());
        if (auto* err = start.getErr()) {
          throwError(err->msg);
        }
        while (pos < endOfFunction) {
          auto inst = readInst();
          if (auto* err = inst.getErr()) {
            throwError(err->msg);
          }
        }
        if (pos != endOfFunction) {
          throwError("function overflowed its bounds");
        }
        if (!builder.empty()) {
          throwError("expected function end");
        }
      }
    }

    sourceMapReader.finishFunction();
    TypeUpdating::handleNonDefaultableLocals(func.get(), wasm);
    currFunction = nullptr;
  }
}

void WasmBinaryReader::readVars() {
  uint32_t totalVars = 0;
  size_t numLocalTypes = getU32LEB();
  // Use a SmallVector as in the common (MVP) case there are only 4 possible
  // types.
  SmallVector<std::pair<uint32_t, Type>, 4> decodedVars;
  decodedVars.reserve(numLocalTypes);
  for (size_t t = 0; t < numLocalTypes; t++) {
    auto num = getU32LEB();
    if (std::ckd_add(&totalVars, totalVars, num)) {
      throwError("unaddressable number of locals");
    }
    auto type = getConcreteType();
    decodedVars.emplace_back(num, type);
  }
  currFunction->vars.reserve(totalVars);
  for (auto [num, type] : decodedVars) {
    while (num > 0) {
      currFunction->vars.push_back(type);
      num--;
    }
  }
}

Result<> WasmBinaryReader::readInst() {
  if (auto loc = sourceMapReader.readDebugLocationAt(pos)) {
    builder.setDebugLocation(loc);
  }
  uint8_t code = getInt8();
  switch (code) {
    case BinaryConsts::Block:
      return builder.makeBlock(Name(), getBlockType());
    case BinaryConsts::If:
      return builder.makeIf(Name(), getBlockType());
    case BinaryConsts::Loop:
      return builder.makeLoop(Name(), getBlockType());
    case BinaryConsts::Br:
      return builder.makeBreak(getU32LEB(), false);
    case BinaryConsts::BrIf:
      return builder.makeBreak(getU32LEB(), true);
    case BinaryConsts::BrTable: {
      auto numTargets = getU32LEB();
      std::vector<Index> labels(numTargets);
      for (Index i = 0; i < numTargets; ++i) {
        labels[i] = getU32LEB();
      }
      return builder.makeSwitch(labels, getU32LEB());
    }
    case BinaryConsts::CallFunction:
    case BinaryConsts::RetCallFunction:
      return builder.makeCall(getFunctionName(getU32LEB()),
                              code == BinaryConsts::RetCallFunction);
    case BinaryConsts::CallIndirect:
    case BinaryConsts::RetCallIndirect: {
      auto type = getIndexedHeapType();
      auto table = getTableName(getU32LEB());
      return builder.makeCallIndirect(
        table, type, code == BinaryConsts::RetCallIndirect);
    }
    case BinaryConsts::LocalGet:
      return builder.makeLocalGet(getU32LEB());
    case BinaryConsts::LocalSet:
      return builder.makeLocalSet(getU32LEB());
    case BinaryConsts::LocalTee:
      return builder.makeLocalTee(getU32LEB());
    case BinaryConsts::GlobalGet:
      return builder.makeGlobalGet(getGlobalName(getU32LEB()));
    case BinaryConsts::GlobalSet:
      return builder.makeGlobalSet(getGlobalName(getU32LEB()));
    case BinaryConsts::Select:
      return builder.makeSelect(std::nullopt);
    case BinaryConsts::SelectWithType: {
      auto numTypes = getU32LEB();
      std::vector<Type> types;
      for (Index i = 0; i < numTypes; ++i) {
        auto t = getType();
        if (!t.isConcrete()) {
          return Err{"bad select type"};
        }
        types.push_back(t);
      }
      return builder.makeSelect(Type(types));
    }
    case BinaryConsts::Return:
      return builder.makeReturn();
    case BinaryConsts::Nop:
      return builder.makeNop();
    case BinaryConsts::Unreachable:
      return builder.makeUnreachable();
    case BinaryConsts::Drop:
      return builder.makeDrop();
    case BinaryConsts::End:
      return builder.visitEnd();
    case BinaryConsts::Else:
      return builder.visitElse();
    case BinaryConsts::Catch_Legacy:
      return builder.visitCatch(getTagName(getU32LEB()));
    case BinaryConsts::CatchAll_Legacy:
      return builder.visitCatchAll();
    case BinaryConsts::Delegate:
      return builder.visitDelegate(getU32LEB());
    case BinaryConsts::RefNull: {
      auto [heapType, exactness] = getHeapType();
      // Exactness is allowed but doesn't matter, since we always use the bottom
      // heap type.
      return builder.makeRefNull(heapType);
    }
    case BinaryConsts::RefIsNull:
      return builder.makeRefIsNull();
    case BinaryConsts::RefFunc:
      return builder.makeRefFunc(getFunctionName(getU32LEB()));
    case BinaryConsts::RefEq:
      return builder.makeRefEq();
    case BinaryConsts::RefAsNonNull:
      return builder.makeRefAs(RefAsNonNull);
    case BinaryConsts::BrOnNull:
      return builder.makeBrOn(getU32LEB(), BrOnNull);
    case BinaryConsts::BrOnNonNull:
      return builder.makeBrOn(getU32LEB(), BrOnNonNull);
    case BinaryConsts::TableGet:
      return builder.makeTableGet(getTableName(getU32LEB()));
    case BinaryConsts::TableSet:
      return builder.makeTableSet(getTableName(getU32LEB()));
    case BinaryConsts::Try:
      return builder.makeTry(Name(), getBlockType());
    case BinaryConsts::TryTable: {
      auto type = getBlockType();
      std::vector<Name> tags;
      std::vector<Index> labels;
      std::vector<bool> isRefs;
      auto numHandlers = getU32LEB();
      for (Index i = 0; i < numHandlers; ++i) {
        uint8_t code = getInt8();
        if (code == BinaryConsts::Catch || code == BinaryConsts::CatchRef) {
          tags.push_back(getTagName(getU32LEB()));
        } else {
          tags.push_back(Name());
        }
        labels.push_back(getU32LEB());
        isRefs.push_back(code == BinaryConsts::CatchRef ||
                         code == BinaryConsts::CatchAllRef);
      }
      return builder.makeTryTable(Name(), type, tags, labels, isRefs);
    }
    case BinaryConsts::Throw:
      return builder.makeThrow(getTagName(getU32LEB()));
    case BinaryConsts::Rethrow:
      return builder.makeRethrow(getU32LEB());
    case BinaryConsts::ThrowRef:
      return builder.makeThrowRef();
    case BinaryConsts::MemorySize:
      return builder.makeMemorySize(getMemoryName(getU32LEB()));
    case BinaryConsts::MemoryGrow:
      return builder.makeMemoryGrow(getMemoryName(getU32LEB()));
    case BinaryConsts::CallRef:
    case BinaryConsts::RetCallRef:
      return builder.makeCallRef(getIndexedHeapType(),
                                 code == BinaryConsts::RetCallRef);
    case BinaryConsts::ContNew:
      return builder.makeContNew(getIndexedHeapType());
    case BinaryConsts::ContBind: {
      auto before = getIndexedHeapType();
      auto after = getIndexedHeapType();
      return builder.makeContBind(before, after);
    }
    case BinaryConsts::Suspend:
      return builder.makeSuspend(getTagName(getU32LEB()));
    case BinaryConsts::Resume: {
      auto type = getIndexedHeapType();
      auto numHandlers = getU32LEB();
      std::vector<Name> tags;
      std::vector<std::optional<Index>> labels;
      tags.reserve(numHandlers);
      labels.reserve(numHandlers);
      for (Index i = 0; i < numHandlers; ++i) {
        uint8_t code = getInt8();
        if (code == BinaryConsts::OnLabel) {
          tags.push_back(getTagName(getU32LEB()));
          labels.push_back(std::optional<Index>{getU32LEB()});
        } else if (code == BinaryConsts::OnSwitch) {
          tags.push_back(getTagName(getU32LEB()));
          labels.push_back(std::nullopt);
        } else {
          return Err{"ON opcode expected"};
        }
      }
      return builder.makeResume(type, tags, labels);
    }
    case BinaryConsts::ResumeThrow: {
      auto type = getIndexedHeapType();
      auto tag = getTagName(getU32LEB());
      auto numHandlers = getU32LEB();
      std::vector<Name> tags;
      std::vector<std::optional<Index>> labels;
      tags.reserve(numHandlers);
      labels.reserve(numHandlers);
      for (Index i = 0; i < numHandlers; ++i) {
        uint8_t code = getInt8();
        if (code == BinaryConsts::OnLabel) {
          tags.push_back(getTagName(getU32LEB()));
          labels.push_back(std::optional<Index>{getU32LEB()});
        } else if (code == BinaryConsts::OnSwitch) {
          tags.push_back(getTagName(getU32LEB()));
          labels.push_back(std::nullopt);
        } else {
          return Err{"ON opcode expected"};
        }
      }
      return builder.makeResumeThrow(type, tag, tags, labels);
    }
    case BinaryConsts::Switch: {
      auto type = getIndexedHeapType();
      auto tag = getTagName(getU32LEB());
      return builder.makeStackSwitch(type, tag);
    }

#define BINARY_INT(code)                                                       \
  case BinaryConsts::I32##code:                                                \
    return builder.makeBinary(code##Int32);                                    \
  case BinaryConsts::I64##code:                                                \
    return builder.makeBinary(code##Int64);
#define BINARY_FLOAT(code)                                                     \
  case BinaryConsts::F32##code:                                                \
    return builder.makeBinary(code##Float32);                                  \
  case BinaryConsts::F64##code:                                                \
    return builder.makeBinary(code##Float64);
#define BINARY_NUM(code)                                                       \
  BINARY_INT(code)                                                             \
  BINARY_FLOAT(code)

      BINARY_NUM(Add);
      BINARY_NUM(Sub);
      BINARY_NUM(Mul);
      BINARY_INT(DivS);
      BINARY_INT(DivU);
      BINARY_INT(RemS);
      BINARY_INT(RemU);
      BINARY_INT(And);
      BINARY_INT(Or);
      BINARY_INT(Xor);
      BINARY_INT(Shl);
      BINARY_INT(ShrU);
      BINARY_INT(ShrS);
      BINARY_INT(RotL);
      BINARY_INT(RotR);
      BINARY_FLOAT(Div);
      BINARY_FLOAT(CopySign);
      BINARY_FLOAT(Min);
      BINARY_FLOAT(Max);
      BINARY_NUM(Eq);
      BINARY_NUM(Ne);
      BINARY_INT(LtS);
      BINARY_INT(LtU);
      BINARY_INT(LeS);
      BINARY_INT(LeU);
      BINARY_INT(GtS);
      BINARY_INT(GtU);
      BINARY_INT(GeS);
      BINARY_INT(GeU);
      BINARY_FLOAT(Lt);
      BINARY_FLOAT(Le);
      BINARY_FLOAT(Gt);
      BINARY_FLOAT(Ge);

#define UNARY_INT(code)                                                        \
  case BinaryConsts::I32##code:                                                \
    return builder.makeUnary(code##Int32);                                     \
  case BinaryConsts::I64##code:                                                \
    return builder.makeUnary(code##Int64);
#define UNARY_FLOAT(code)                                                      \
  case BinaryConsts::F32##code:                                                \
    return builder.makeUnary(code##Float32);                                   \
  case BinaryConsts::F64##code:                                                \
    return builder.makeUnary(code##Float64);

      UNARY_INT(Clz);
      UNARY_INT(Ctz);
      UNARY_INT(Popcnt);
      UNARY_INT(EqZ);
      UNARY_FLOAT(Neg);
      UNARY_FLOAT(Abs);
      UNARY_FLOAT(Ceil);
      UNARY_FLOAT(Floor);
      UNARY_FLOAT(Nearest);
      UNARY_FLOAT(Sqrt);

    case BinaryConsts::F32UConvertI32:
      return builder.makeUnary(ConvertUInt32ToFloat32);
    case BinaryConsts::F64UConvertI32:
      return builder.makeUnary(ConvertUInt32ToFloat64);
    case BinaryConsts::F32SConvertI32:
      return builder.makeUnary(ConvertSInt32ToFloat32);
    case BinaryConsts::F64SConvertI32:
      return builder.makeUnary(ConvertSInt32ToFloat64);
    case BinaryConsts::F32UConvertI64:
      return builder.makeUnary(ConvertUInt64ToFloat32);
    case BinaryConsts::F64UConvertI64:
      return builder.makeUnary(ConvertUInt64ToFloat64);
    case BinaryConsts::F32SConvertI64:
      return builder.makeUnary(ConvertSInt64ToFloat32);
    case BinaryConsts::F64SConvertI64:
      return builder.makeUnary(ConvertSInt64ToFloat64);
    case BinaryConsts::I64SExtendI32:
      return builder.makeUnary(ExtendSInt32);
    case BinaryConsts::I64UExtendI32:
      return builder.makeUnary(ExtendUInt32);
    case BinaryConsts::I32WrapI64:
      return builder.makeUnary(WrapInt64);
    case BinaryConsts::I32UTruncF32:
      return builder.makeUnary(TruncUFloat32ToInt32);
    case BinaryConsts::I32UTruncF64:
      return builder.makeUnary(TruncUFloat64ToInt32);
    case BinaryConsts::I32STruncF32:
      return builder.makeUnary(TruncSFloat32ToInt32);
    case BinaryConsts::I32STruncF64:
      return builder.makeUnary(TruncSFloat64ToInt32);
    case BinaryConsts::I64UTruncF32:
      return builder.makeUnary(TruncUFloat32ToInt64);
    case BinaryConsts::I64UTruncF64:
      return builder.makeUnary(TruncUFloat64ToInt64);
    case BinaryConsts::I64STruncF32:
      return builder.makeUnary(TruncSFloat32ToInt64);
    case BinaryConsts::I64STruncF64:
      return builder.makeUnary(TruncSFloat64ToInt64);
    case BinaryConsts::F32Trunc:
      return builder.makeUnary(TruncFloat32);
    case BinaryConsts::F64Trunc:
      return builder.makeUnary(TruncFloat64);
    case BinaryConsts::F32DemoteI64:
      return builder.makeUnary(DemoteFloat64);
    case BinaryConsts::F64PromoteF32:
      return builder.makeUnary(PromoteFloat32);
    case BinaryConsts::I32ReinterpretF32:
      return builder.makeUnary(ReinterpretFloat32);
    case BinaryConsts::I64ReinterpretF64:
      return builder.makeUnary(ReinterpretFloat64);
    case BinaryConsts::F32ReinterpretI32:
      return builder.makeUnary(ReinterpretInt32);
    case BinaryConsts::F64ReinterpretI64:
      return builder.makeUnary(ReinterpretInt64);
    case BinaryConsts::I32ExtendS8:
      return builder.makeUnary(ExtendS8Int32);
    case BinaryConsts::I32ExtendS16:
      return builder.makeUnary(ExtendS16Int32);
    case BinaryConsts::I64ExtendS8:
      return builder.makeUnary(ExtendS8Int64);
    case BinaryConsts::I64ExtendS16:
      return builder.makeUnary(ExtendS16Int64);
    case BinaryConsts::I64ExtendS32:
      return builder.makeUnary(ExtendS32Int64);
    case BinaryConsts::I32Const:
      return builder.makeConst(Literal(getS32LEB()));
    case BinaryConsts::I64Const:
      return builder.makeConst(Literal(getS64LEB()));
    case BinaryConsts::F32Const:
      return builder.makeConst(getFloat32Literal());
    case BinaryConsts::F64Const:
      return builder.makeConst(getFloat64Literal());
    case BinaryConsts::I32LoadMem8S: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(1, true, offset, align, Type::i32, mem);
    }
    case BinaryConsts::I32LoadMem8U: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(1, false, offset, align, Type::i32, mem);
    }
    case BinaryConsts::I32LoadMem16S: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(2, true, offset, align, Type::i32, mem);
    }
    case BinaryConsts::I32LoadMem16U: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(2, false, offset, align, Type::i32, mem);
    }
    case BinaryConsts::I32LoadMem: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(4, false, offset, align, Type::i32, mem);
    }
    case BinaryConsts::I64LoadMem8S: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(1, true, offset, align, Type::i64, mem);
    }
    case BinaryConsts::I64LoadMem8U: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(1, false, offset, align, Type::i64, mem);
    }
    case BinaryConsts::I64LoadMem16S: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(2, true, offset, align, Type::i64, mem);
    }
    case BinaryConsts::I64LoadMem16U: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(2, false, offset, align, Type::i64, mem);
    }
    case BinaryConsts::I64LoadMem32S: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(4, true, offset, align, Type::i64, mem);
    }
    case BinaryConsts::I64LoadMem32U: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(4, false, offset, align, Type::i64, mem);
    }
    case BinaryConsts::I64LoadMem: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(8, false, offset, align, Type::i64, mem);
    }
    case BinaryConsts::F32LoadMem: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(4, false, offset, align, Type::f32, mem);
    }
    case BinaryConsts::F64LoadMem: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeLoad(8, false, offset, align, Type::f64, mem);
    }
    case BinaryConsts::I32StoreMem8: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeStore(1, offset, align, Type::i32, mem);
    }
    case BinaryConsts::I32StoreMem16: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeStore(2, offset, align, Type::i32, mem);
    }
    case BinaryConsts::I32StoreMem: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeStore(4, offset, align, Type::i32, mem);
    }
    case BinaryConsts::I64StoreMem8: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeStore(1, offset, align, Type::i64, mem);
    }
    case BinaryConsts::I64StoreMem16: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeStore(2, offset, align, Type::i64, mem);
    }
    case BinaryConsts::I64StoreMem32: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeStore(4, offset, align, Type::i64, mem);
    }
    case BinaryConsts::I64StoreMem: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeStore(8, offset, align, Type::i64, mem);
    }
    case BinaryConsts::F32StoreMem: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeStore(4, offset, align, Type::f32, mem);
    }
    case BinaryConsts::F64StoreMem: {
      auto [mem, align, offset] = getMemarg();
      return builder.makeStore(8, offset, align, Type::f64, mem);
    }
    case BinaryConsts::AtomicPrefix: {
      auto op = getU32LEB();
      switch (op) {
        case BinaryConsts::I32AtomicLoad8U: {
          // TODO: pass align through for validation.
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicLoad(1, offset, Type::i32, mem);
        }
        case BinaryConsts::I32AtomicLoad16U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicLoad(2, offset, Type::i32, mem);
        }
        case BinaryConsts::I32AtomicLoad: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicLoad(4, offset, Type::i32, mem);
        }
        case BinaryConsts::I64AtomicLoad8U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicLoad(1, offset, Type::i64, mem);
        }
        case BinaryConsts::I64AtomicLoad16U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicLoad(2, offset, Type::i64, mem);
        }
        case BinaryConsts::I64AtomicLoad32U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicLoad(4, offset, Type::i64, mem);
        }
        case BinaryConsts::I64AtomicLoad: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicLoad(8, offset, Type::i64, mem);
        }
        case BinaryConsts::I32AtomicStore8: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicStore(1, offset, Type::i32, mem);
        }
        case BinaryConsts::I32AtomicStore16: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicStore(2, offset, Type::i32, mem);
        }
        case BinaryConsts::I32AtomicStore: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicStore(4, offset, Type::i32, mem);
        }
        case BinaryConsts::I64AtomicStore8: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicStore(1, offset, Type::i64, mem);
        }
        case BinaryConsts::I64AtomicStore16: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicStore(2, offset, Type::i64, mem);
        }
        case BinaryConsts::I64AtomicStore32: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicStore(4, offset, Type::i64, mem);
        }
        case BinaryConsts::I64AtomicStore: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicStore(8, offset, Type::i64, mem);
        }

#define RMW(op)                                                                \
  case BinaryConsts::I32AtomicRMW##op: {                                       \
    auto [mem, align, offset] = getMemarg();                                   \
    return builder.makeAtomicRMW(RMW##op, 4, offset, Type::i32, mem);          \
  }                                                                            \
  case BinaryConsts::I32AtomicRMW##op##8U: {                                   \
    auto [mem, align, offset] = getMemarg();                                   \
    return builder.makeAtomicRMW(RMW##op, 1, offset, Type::i32, mem);          \
  }                                                                            \
  case BinaryConsts::I32AtomicRMW##op##16U: {                                  \
    auto [mem, align, offset] = getMemarg();                                   \
    return builder.makeAtomicRMW(RMW##op, 2, offset, Type::i32, mem);          \
  }                                                                            \
  case BinaryConsts::I64AtomicRMW##op: {                                       \
    auto [mem, align, offset] = getMemarg();                                   \
    return builder.makeAtomicRMW(RMW##op, 8, offset, Type::i64, mem);          \
  }                                                                            \
  case BinaryConsts::I64AtomicRMW##op##8U: {                                   \
    auto [mem, align, offset] = getMemarg();                                   \
    return builder.makeAtomicRMW(RMW##op, 1, offset, Type::i64, mem);          \
  }                                                                            \
  case BinaryConsts::I64AtomicRMW##op##16U: {                                  \
    auto [mem, align, offset] = getMemarg();                                   \
    return builder.makeAtomicRMW(RMW##op, 2, offset, Type::i64, mem);          \
  }                                                                            \
  case BinaryConsts::I64AtomicRMW##op##32U: {                                  \
    auto [mem, align, offset] = getMemarg();                                   \
    return builder.makeAtomicRMW(RMW##op, 4, offset, Type::i64, mem);          \
  }

          RMW(Add);
          RMW(Sub);
          RMW(And);
          RMW(Or);
          RMW(Xor);
          RMW(Xchg);

        case BinaryConsts::I32AtomicCmpxchg: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicCmpxchg(4, offset, Type::i32, mem);
        }
        case BinaryConsts::I32AtomicCmpxchg8U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicCmpxchg(1, offset, Type::i32, mem);
        }
        case BinaryConsts::I32AtomicCmpxchg16U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicCmpxchg(2, offset, Type::i32, mem);
        }
        case BinaryConsts::I64AtomicCmpxchg: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicCmpxchg(8, offset, Type::i64, mem);
        }
        case BinaryConsts::I64AtomicCmpxchg8U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicCmpxchg(1, offset, Type::i64, mem);
        }
        case BinaryConsts::I64AtomicCmpxchg16U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicCmpxchg(2, offset, Type::i64, mem);
        }
        case BinaryConsts::I64AtomicCmpxchg32U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicCmpxchg(4, offset, Type::i64, mem);
        }
        case BinaryConsts::I32AtomicWait: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicWait(Type::i32, offset, mem);
        }
        case BinaryConsts::I64AtomicWait: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicWait(Type::i64, offset, mem);
        }
        case BinaryConsts::AtomicNotify: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeAtomicNotify(offset, mem);
        }
        case BinaryConsts::AtomicFence:
          if (getInt8() != 0) {
            return Err{"expected 0x00 byte immediate on atomic.fence"};
          }
          return builder.makeAtomicFence();
        case BinaryConsts::Pause:
          return builder.makePause();
        case BinaryConsts::StructAtomicGet:
        case BinaryConsts::StructAtomicGetS:
        case BinaryConsts::StructAtomicGetU: {
          auto order = getMemoryOrder();
          auto type = getIndexedHeapType();
          auto field = getU32LEB();
          bool signed_ = op == BinaryConsts::StructAtomicGetS;
          return builder.makeStructGet(type, field, signed_, order);
        }
        case BinaryConsts::StructAtomicSet: {
          auto order = getMemoryOrder();
          auto type = getIndexedHeapType();
          auto field = getU32LEB();
          return builder.makeStructSet(type, field, order);
        }

#define STRUCT_RMW(op)                                                         \
  case BinaryConsts::StructAtomicRMW##op: {                                    \
    auto order = getMemoryOrder(true);                                         \
    auto type = getIndexedHeapType();                                          \
    auto field = getU32LEB();                                                  \
    return builder.makeStructRMW(RMW##op, type, field, order);                 \
  }

          STRUCT_RMW(Add)
          STRUCT_RMW(Sub)
          STRUCT_RMW(And)
          STRUCT_RMW(Or)
          STRUCT_RMW(Xor)
          STRUCT_RMW(Xchg)

        case BinaryConsts::StructAtomicRMWCmpxchg: {
          auto order = getMemoryOrder(true);
          auto type = getIndexedHeapType();
          auto field = getU32LEB();
          return builder.makeStructCmpxchg(type, field, order);
        }
        case BinaryConsts::ArrayAtomicGet:
        case BinaryConsts::ArrayAtomicGetS:
        case BinaryConsts::ArrayAtomicGetU: {
          auto order = getMemoryOrder();
          auto type = getIndexedHeapType();
          bool signed_ = op == BinaryConsts::ArrayAtomicGetS;
          return builder.makeArrayGet(type, signed_, order);
        }
        case BinaryConsts::ArrayAtomicSet: {
          auto order = getMemoryOrder();
          auto type = getIndexedHeapType();
          return builder.makeArraySet(type, order);
        }

#define ARRAY_RMW(op)                                                          \
  case BinaryConsts::ArrayAtomicRMW##op: {                                     \
    auto order = getMemoryOrder(true);                                         \
    auto type = getIndexedHeapType();                                          \
    return builder.makeArrayRMW(RMW##op, type, order);                         \
  }

          ARRAY_RMW(Add)
          ARRAY_RMW(Sub)
          ARRAY_RMW(And)
          ARRAY_RMW(Or)
          ARRAY_RMW(Xor)
          ARRAY_RMW(Xchg)

        case BinaryConsts::ArrayAtomicRMWCmpxchg: {
          auto order = getMemoryOrder(true);
          auto type = getIndexedHeapType();
          return builder.makeArrayCmpxchg(type, order);
        }
      }
      return Err{"unknown atomic operation " + std::to_string(op)};
    }
    case BinaryConsts::MiscPrefix: {
      auto op = getU32LEB();
      switch (op) {
        case BinaryConsts::I32STruncSatF32:
          return builder.makeUnary(TruncSatSFloat32ToInt32);
        case BinaryConsts::I32UTruncSatF32:
          return builder.makeUnary(TruncSatUFloat32ToInt32);
        case BinaryConsts::I32STruncSatF64:
          return builder.makeUnary(TruncSatSFloat64ToInt32);
        case BinaryConsts::I32UTruncSatF64:
          return builder.makeUnary(TruncSatUFloat64ToInt32);
        case BinaryConsts::I64STruncSatF32:
          return builder.makeUnary(TruncSatSFloat32ToInt64);
        case BinaryConsts::I64UTruncSatF32:
          return builder.makeUnary(TruncSatUFloat32ToInt64);
        case BinaryConsts::I64STruncSatF64:
          return builder.makeUnary(TruncSatSFloat64ToInt64);
        case BinaryConsts::I64UTruncSatF64:
          return builder.makeUnary(TruncSatUFloat64ToInt64);
        case BinaryConsts::MemoryInit: {
          auto data = getDataName(getU32LEB());
          auto mem = getMemoryName(getU32LEB());
          return builder.makeMemoryInit(data, mem);
        }
        case BinaryConsts::DataDrop:
          return builder.makeDataDrop(getDataName(getU32LEB()));
        case BinaryConsts::MemoryCopy: {
          auto dest = getMemoryName(getU32LEB());
          auto src = getMemoryName(getU32LEB());
          return builder.makeMemoryCopy(dest, src);
        }
        case BinaryConsts::MemoryFill:
          return builder.makeMemoryFill(getMemoryName(getU32LEB()));
        case BinaryConsts::TableSize:
          return builder.makeTableSize(getTableName(getU32LEB()));
        case BinaryConsts::TableGrow:
          return builder.makeTableGrow(getTableName(getU32LEB()));
        case BinaryConsts::TableFill:
          return builder.makeTableFill(getTableName(getU32LEB()));
        case BinaryConsts::TableCopy: {
          auto dest = getTableName(getU32LEB());
          auto src = getTableName(getU32LEB());
          return builder.makeTableCopy(dest, src);
        }
        case BinaryConsts::TableInit: {
          auto elem = getElemName(getU32LEB());
          auto table = getTableName(getU32LEB());
          return builder.makeTableInit(elem, table);
        }
        case BinaryConsts::ElemDrop: {
          auto elem = getElemName(getU32LEB());
          return builder.makeElemDrop(elem);
        }
        case BinaryConsts::F32_F16LoadMem: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeLoad(2, false, offset, align, Type::f32, mem);
        }
        case BinaryConsts::F32_F16StoreMem: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeStore(2, offset, align, Type::f32, mem);
        }
      }
      return Err{"unknown misc operation: " + std::to_string(op)};
    }
    case BinaryConsts::SIMDPrefix: {
      auto op = getU32LEB();
      switch (op) {
        case BinaryConsts::I8x16Eq:
          return builder.makeBinary(EqVecI8x16);
        case BinaryConsts::I8x16Ne:
          return builder.makeBinary(NeVecI8x16);
        case BinaryConsts::I8x16LtS:
          return builder.makeBinary(LtSVecI8x16);
        case BinaryConsts::I8x16LtU:
          return builder.makeBinary(LtUVecI8x16);
        case BinaryConsts::I8x16GtS:
          return builder.makeBinary(GtSVecI8x16);
        case BinaryConsts::I8x16GtU:
          return builder.makeBinary(GtUVecI8x16);
        case BinaryConsts::I8x16LeS:
          return builder.makeBinary(LeSVecI8x16);
        case BinaryConsts::I8x16LeU:
          return builder.makeBinary(LeUVecI8x16);
        case BinaryConsts::I8x16GeS:
          return builder.makeBinary(GeSVecI8x16);
        case BinaryConsts::I8x16GeU:
          return builder.makeBinary(GeUVecI8x16);
        case BinaryConsts::I16x8Eq:
          return builder.makeBinary(EqVecI16x8);
        case BinaryConsts::I16x8Ne:
          return builder.makeBinary(NeVecI16x8);
        case BinaryConsts::I16x8LtS:
          return builder.makeBinary(LtSVecI16x8);
        case BinaryConsts::I16x8LtU:
          return builder.makeBinary(LtUVecI16x8);
        case BinaryConsts::I16x8GtS:
          return builder.makeBinary(GtSVecI16x8);
        case BinaryConsts::I16x8GtU:
          return builder.makeBinary(GtUVecI16x8);
        case BinaryConsts::I16x8LeS:
          return builder.makeBinary(LeSVecI16x8);
        case BinaryConsts::I16x8LeU:
          return builder.makeBinary(LeUVecI16x8);
        case BinaryConsts::I16x8GeS:
          return builder.makeBinary(GeSVecI16x8);
        case BinaryConsts::I16x8GeU:
          return builder.makeBinary(GeUVecI16x8);
        case BinaryConsts::I32x4Eq:
          return builder.makeBinary(EqVecI32x4);
        case BinaryConsts::I32x4Ne:
          return builder.makeBinary(NeVecI32x4);
        case BinaryConsts::I32x4LtS:
          return builder.makeBinary(LtSVecI32x4);
        case BinaryConsts::I32x4LtU:
          return builder.makeBinary(LtUVecI32x4);
        case BinaryConsts::I32x4GtS:
          return builder.makeBinary(GtSVecI32x4);
        case BinaryConsts::I32x4GtU:
          return builder.makeBinary(GtUVecI32x4);
        case BinaryConsts::I32x4LeS:
          return builder.makeBinary(LeSVecI32x4);
        case BinaryConsts::I32x4LeU:
          return builder.makeBinary(LeUVecI32x4);
        case BinaryConsts::I32x4GeS:
          return builder.makeBinary(GeSVecI32x4);
        case BinaryConsts::I32x4GeU:
          return builder.makeBinary(GeUVecI32x4);
        case BinaryConsts::I64x2Eq:
          return builder.makeBinary(EqVecI64x2);
        case BinaryConsts::I64x2Ne:
          return builder.makeBinary(NeVecI64x2);
        case BinaryConsts::I64x2LtS:
          return builder.makeBinary(LtSVecI64x2);
        case BinaryConsts::I64x2GtS:
          return builder.makeBinary(GtSVecI64x2);
        case BinaryConsts::I64x2LeS:
          return builder.makeBinary(LeSVecI64x2);
        case BinaryConsts::I64x2GeS:
          return builder.makeBinary(GeSVecI64x2);
        case BinaryConsts::F16x8Eq:
          return builder.makeBinary(EqVecF16x8);
        case BinaryConsts::F16x8Ne:
          return builder.makeBinary(NeVecF16x8);
        case BinaryConsts::F16x8Lt:
          return builder.makeBinary(LtVecF16x8);
        case BinaryConsts::F16x8Gt:
          return builder.makeBinary(GtVecF16x8);
        case BinaryConsts::F16x8Le:
          return builder.makeBinary(LeVecF16x8);
        case BinaryConsts::F16x8Ge:
          return builder.makeBinary(GeVecF16x8);
        case BinaryConsts::F32x4Eq:
          return builder.makeBinary(EqVecF32x4);
        case BinaryConsts::F32x4Ne:
          return builder.makeBinary(NeVecF32x4);
        case BinaryConsts::F32x4Lt:
          return builder.makeBinary(LtVecF32x4);
        case BinaryConsts::F32x4Gt:
          return builder.makeBinary(GtVecF32x4);
        case BinaryConsts::F32x4Le:
          return builder.makeBinary(LeVecF32x4);
        case BinaryConsts::F32x4Ge:
          return builder.makeBinary(GeVecF32x4);
        case BinaryConsts::F64x2Eq:
          return builder.makeBinary(EqVecF64x2);
        case BinaryConsts::F64x2Ne:
          return builder.makeBinary(NeVecF64x2);
        case BinaryConsts::F64x2Lt:
          return builder.makeBinary(LtVecF64x2);
        case BinaryConsts::F64x2Gt:
          return builder.makeBinary(GtVecF64x2);
        case BinaryConsts::F64x2Le:
          return builder.makeBinary(LeVecF64x2);
        case BinaryConsts::F64x2Ge:
          return builder.makeBinary(GeVecF64x2);
        case BinaryConsts::V128And:
          return builder.makeBinary(AndVec128);
        case BinaryConsts::V128Or:
          return builder.makeBinary(OrVec128);
        case BinaryConsts::V128Xor:
          return builder.makeBinary(XorVec128);
        case BinaryConsts::V128Andnot:
          return builder.makeBinary(AndNotVec128);
        case BinaryConsts::I8x16Add:
          return builder.makeBinary(AddVecI8x16);
        case BinaryConsts::I8x16AddSatS:
          return builder.makeBinary(AddSatSVecI8x16);
        case BinaryConsts::I8x16AddSatU:
          return builder.makeBinary(AddSatUVecI8x16);
        case BinaryConsts::I8x16Sub:
          return builder.makeBinary(SubVecI8x16);
        case BinaryConsts::I8x16SubSatS:
          return builder.makeBinary(SubSatSVecI8x16);
        case BinaryConsts::I8x16SubSatU:
          return builder.makeBinary(SubSatUVecI8x16);
        case BinaryConsts::I8x16MinS:
          return builder.makeBinary(MinSVecI8x16);
        case BinaryConsts::I8x16MinU:
          return builder.makeBinary(MinUVecI8x16);
        case BinaryConsts::I8x16MaxS:
          return builder.makeBinary(MaxSVecI8x16);
        case BinaryConsts::I8x16MaxU:
          return builder.makeBinary(MaxUVecI8x16);
        case BinaryConsts::I8x16AvgrU:
          return builder.makeBinary(AvgrUVecI8x16);
        case BinaryConsts::I16x8Add:
          return builder.makeBinary(AddVecI16x8);
        case BinaryConsts::I16x8AddSatS:
          return builder.makeBinary(AddSatSVecI16x8);
        case BinaryConsts::I16x8AddSatU:
          return builder.makeBinary(AddSatUVecI16x8);
        case BinaryConsts::I16x8Sub:
          return builder.makeBinary(SubVecI16x8);
        case BinaryConsts::I16x8SubSatS:
          return builder.makeBinary(SubSatSVecI16x8);
        case BinaryConsts::I16x8SubSatU:
          return builder.makeBinary(SubSatUVecI16x8);
        case BinaryConsts::I16x8Mul:
          return builder.makeBinary(MulVecI16x8);
        case BinaryConsts::I16x8MinS:
          return builder.makeBinary(MinSVecI16x8);
        case BinaryConsts::I16x8MinU:
          return builder.makeBinary(MinUVecI16x8);
        case BinaryConsts::I16x8MaxS:
          return builder.makeBinary(MaxSVecI16x8);
        case BinaryConsts::I16x8MaxU:
          return builder.makeBinary(MaxUVecI16x8);
        case BinaryConsts::I16x8AvgrU:
          return builder.makeBinary(AvgrUVecI16x8);
        case BinaryConsts::I16x8Q15MulrSatS:
          return builder.makeBinary(Q15MulrSatSVecI16x8);
        case BinaryConsts::I16x8ExtmulLowI8x16S:
          return builder.makeBinary(ExtMulLowSVecI16x8);
        case BinaryConsts::I16x8ExtmulHighI8x16S:
          return builder.makeBinary(ExtMulHighSVecI16x8);
        case BinaryConsts::I16x8ExtmulLowI8x16U:
          return builder.makeBinary(ExtMulLowUVecI16x8);
        case BinaryConsts::I16x8ExtmulHighI8x16U:
          return builder.makeBinary(ExtMulHighUVecI16x8);
        case BinaryConsts::I32x4Add:
          return builder.makeBinary(AddVecI32x4);
        case BinaryConsts::I32x4Sub:
          return builder.makeBinary(SubVecI32x4);
        case BinaryConsts::I32x4Mul:
          return builder.makeBinary(MulVecI32x4);
        case BinaryConsts::I32x4MinS:
          return builder.makeBinary(MinSVecI32x4);
        case BinaryConsts::I32x4MinU:
          return builder.makeBinary(MinUVecI32x4);
        case BinaryConsts::I32x4MaxS:
          return builder.makeBinary(MaxSVecI32x4);
        case BinaryConsts::I32x4MaxU:
          return builder.makeBinary(MaxUVecI32x4);
        case BinaryConsts::I32x4DotI16x8S:
          return builder.makeBinary(DotSVecI16x8ToVecI32x4);
        case BinaryConsts::I32x4ExtmulLowI16x8S:
          return builder.makeBinary(ExtMulLowSVecI32x4);
        case BinaryConsts::I32x4ExtmulHighI16x8S:
          return builder.makeBinary(ExtMulHighSVecI32x4);
        case BinaryConsts::I32x4ExtmulLowI16x8U:
          return builder.makeBinary(ExtMulLowUVecI32x4);
        case BinaryConsts::I32x4ExtmulHighI16x8U:
          return builder.makeBinary(ExtMulHighUVecI32x4);
        case BinaryConsts::I64x2Add:
          return builder.makeBinary(AddVecI64x2);
        case BinaryConsts::I64x2Sub:
          return builder.makeBinary(SubVecI64x2);
        case BinaryConsts::I64x2Mul:
          return builder.makeBinary(MulVecI64x2);
        case BinaryConsts::I64x2ExtmulLowI32x4S:
          return builder.makeBinary(ExtMulLowSVecI64x2);
        case BinaryConsts::I64x2ExtmulHighI32x4S:
          return builder.makeBinary(ExtMulHighSVecI64x2);
        case BinaryConsts::I64x2ExtmulLowI32x4U:
          return builder.makeBinary(ExtMulLowUVecI64x2);
        case BinaryConsts::I64x2ExtmulHighI32x4U:
          return builder.makeBinary(ExtMulHighUVecI64x2);
        case BinaryConsts::F16x8Add:
          return builder.makeBinary(AddVecF16x8);
        case BinaryConsts::F16x8Sub:
          return builder.makeBinary(SubVecF16x8);
        case BinaryConsts::F16x8Mul:
          return builder.makeBinary(MulVecF16x8);
        case BinaryConsts::F16x8Div:
          return builder.makeBinary(DivVecF16x8);
        case BinaryConsts::F16x8Min:
          return builder.makeBinary(MinVecF16x8);
        case BinaryConsts::F16x8Max:
          return builder.makeBinary(MaxVecF16x8);
        case BinaryConsts::F16x8Pmin:
          return builder.makeBinary(PMinVecF16x8);
        case BinaryConsts::F16x8Pmax:
          return builder.makeBinary(PMaxVecF16x8);
        case BinaryConsts::F32x4Add:
          return builder.makeBinary(AddVecF32x4);
        case BinaryConsts::F32x4Sub:
          return builder.makeBinary(SubVecF32x4);
        case BinaryConsts::F32x4Mul:
          return builder.makeBinary(MulVecF32x4);
        case BinaryConsts::F32x4Div:
          return builder.makeBinary(DivVecF32x4);
        case BinaryConsts::F32x4Min:
          return builder.makeBinary(MinVecF32x4);
        case BinaryConsts::F32x4Max:
          return builder.makeBinary(MaxVecF32x4);
        case BinaryConsts::F32x4Pmin:
          return builder.makeBinary(PMinVecF32x4);
        case BinaryConsts::F32x4Pmax:
          return builder.makeBinary(PMaxVecF32x4);
        case BinaryConsts::F64x2Add:
          return builder.makeBinary(AddVecF64x2);
        case BinaryConsts::F64x2Sub:
          return builder.makeBinary(SubVecF64x2);
        case BinaryConsts::F64x2Mul:
          return builder.makeBinary(MulVecF64x2);
        case BinaryConsts::F64x2Div:
          return builder.makeBinary(DivVecF64x2);
        case BinaryConsts::F64x2Min:
          return builder.makeBinary(MinVecF64x2);
        case BinaryConsts::F64x2Max:
          return builder.makeBinary(MaxVecF64x2);
        case BinaryConsts::F64x2Pmin:
          return builder.makeBinary(PMinVecF64x2);
        case BinaryConsts::F64x2Pmax:
          return builder.makeBinary(PMaxVecF64x2);
        case BinaryConsts::I8x16NarrowI16x8S:
          return builder.makeBinary(NarrowSVecI16x8ToVecI8x16);
        case BinaryConsts::I8x16NarrowI16x8U:
          return builder.makeBinary(NarrowUVecI16x8ToVecI8x16);
        case BinaryConsts::I16x8NarrowI32x4S:
          return builder.makeBinary(NarrowSVecI32x4ToVecI16x8);
        case BinaryConsts::I16x8NarrowI32x4U:
          return builder.makeBinary(NarrowUVecI32x4ToVecI16x8);
        case BinaryConsts::I8x16Swizzle:
          return builder.makeBinary(SwizzleVecI8x16);
        case BinaryConsts::I8x16RelaxedSwizzle:
          return builder.makeBinary(RelaxedSwizzleVecI8x16);
        case BinaryConsts::F32x4RelaxedMin:
          return builder.makeBinary(RelaxedMinVecF32x4);
        case BinaryConsts::F32x4RelaxedMax:
          return builder.makeBinary(RelaxedMaxVecF32x4);
        case BinaryConsts::F64x2RelaxedMin:
          return builder.makeBinary(RelaxedMinVecF64x2);
        case BinaryConsts::F64x2RelaxedMax:
          return builder.makeBinary(RelaxedMaxVecF64x2);
        case BinaryConsts::I16x8RelaxedQ15MulrS:
          return builder.makeBinary(RelaxedQ15MulrSVecI16x8);
        case BinaryConsts::I16x8DotI8x16I7x16S:
          return builder.makeBinary(DotI8x16I7x16SToVecI16x8);
        case BinaryConsts::I8x16Splat:
          return builder.makeUnary(SplatVecI8x16);
        case BinaryConsts::I16x8Splat:
          return builder.makeUnary(SplatVecI16x8);
        case BinaryConsts::I32x4Splat:
          return builder.makeUnary(SplatVecI32x4);
        case BinaryConsts::I64x2Splat:
          return builder.makeUnary(SplatVecI64x2);
        case BinaryConsts::F16x8Splat:
          return builder.makeUnary(SplatVecF16x8);
        case BinaryConsts::F32x4Splat:
          return builder.makeUnary(SplatVecF32x4);
        case BinaryConsts::F64x2Splat:
          return builder.makeUnary(SplatVecF64x2);
        case BinaryConsts::V128Not:
          return builder.makeUnary(NotVec128);
        case BinaryConsts::V128AnyTrue:
          return builder.makeUnary(AnyTrueVec128);
        case BinaryConsts::I8x16Popcnt:
          return builder.makeUnary(PopcntVecI8x16);
        case BinaryConsts::I8x16Abs:
          return builder.makeUnary(AbsVecI8x16);
        case BinaryConsts::I8x16Neg:
          return builder.makeUnary(NegVecI8x16);
        case BinaryConsts::I8x16AllTrue:
          return builder.makeUnary(AllTrueVecI8x16);
        case BinaryConsts::I8x16Bitmask:
          return builder.makeUnary(BitmaskVecI8x16);
        case BinaryConsts::I16x8Abs:
          return builder.makeUnary(AbsVecI16x8);
        case BinaryConsts::I16x8Neg:
          return builder.makeUnary(NegVecI16x8);
        case BinaryConsts::I16x8AllTrue:
          return builder.makeUnary(AllTrueVecI16x8);
        case BinaryConsts::I16x8Bitmask:
          return builder.makeUnary(BitmaskVecI16x8);
        case BinaryConsts::I32x4Abs:
          return builder.makeUnary(AbsVecI32x4);
        case BinaryConsts::I32x4Neg:
          return builder.makeUnary(NegVecI32x4);
        case BinaryConsts::I32x4AllTrue:
          return builder.makeUnary(AllTrueVecI32x4);
        case BinaryConsts::I32x4Bitmask:
          return builder.makeUnary(BitmaskVecI32x4);
        case BinaryConsts::I64x2Abs:
          return builder.makeUnary(AbsVecI64x2);
        case BinaryConsts::I64x2Neg:
          return builder.makeUnary(NegVecI64x2);
        case BinaryConsts::I64x2AllTrue:
          return builder.makeUnary(AllTrueVecI64x2);
        case BinaryConsts::I64x2Bitmask:
          return builder.makeUnary(BitmaskVecI64x2);
        case BinaryConsts::F16x8Abs:
          return builder.makeUnary(AbsVecF16x8);
        case BinaryConsts::F16x8Neg:
          return builder.makeUnary(NegVecF16x8);
        case BinaryConsts::F16x8Sqrt:
          return builder.makeUnary(SqrtVecF16x8);
        case BinaryConsts::F16x8Ceil:
          return builder.makeUnary(CeilVecF16x8);
        case BinaryConsts::F16x8Floor:
          return builder.makeUnary(FloorVecF16x8);
        case BinaryConsts::F16x8Trunc:
          return builder.makeUnary(TruncVecF16x8);
        case BinaryConsts::F16x8Nearest:
          return builder.makeUnary(NearestVecF16x8);
        case BinaryConsts::F32x4Abs:
          return builder.makeUnary(AbsVecF32x4);
        case BinaryConsts::F32x4Neg:
          return builder.makeUnary(NegVecF32x4);
        case BinaryConsts::F32x4Sqrt:
          return builder.makeUnary(SqrtVecF32x4);
        case BinaryConsts::F32x4Ceil:
          return builder.makeUnary(CeilVecF32x4);
        case BinaryConsts::F32x4Floor:
          return builder.makeUnary(FloorVecF32x4);
        case BinaryConsts::F32x4Trunc:
          return builder.makeUnary(TruncVecF32x4);
        case BinaryConsts::F32x4Nearest:
          return builder.makeUnary(NearestVecF32x4);
        case BinaryConsts::F64x2Abs:
          return builder.makeUnary(AbsVecF64x2);
        case BinaryConsts::F64x2Neg:
          return builder.makeUnary(NegVecF64x2);
        case BinaryConsts::F64x2Sqrt:
          return builder.makeUnary(SqrtVecF64x2);
        case BinaryConsts::F64x2Ceil:
          return builder.makeUnary(CeilVecF64x2);
        case BinaryConsts::F64x2Floor:
          return builder.makeUnary(FloorVecF64x2);
        case BinaryConsts::F64x2Trunc:
          return builder.makeUnary(TruncVecF64x2);
        case BinaryConsts::F64x2Nearest:
          return builder.makeUnary(NearestVecF64x2);
        case BinaryConsts::I16x8ExtaddPairwiseI8x16S:
          return builder.makeUnary(ExtAddPairwiseSVecI8x16ToI16x8);
        case BinaryConsts::I16x8ExtaddPairwiseI8x16U:
          return builder.makeUnary(ExtAddPairwiseUVecI8x16ToI16x8);
        case BinaryConsts::I32x4ExtaddPairwiseI16x8S:
          return builder.makeUnary(ExtAddPairwiseSVecI16x8ToI32x4);
        case BinaryConsts::I32x4ExtaddPairwiseI16x8U:
          return builder.makeUnary(ExtAddPairwiseUVecI16x8ToI32x4);
        case BinaryConsts::I32x4TruncSatF32x4S:
          return builder.makeUnary(TruncSatSVecF32x4ToVecI32x4);
        case BinaryConsts::I32x4TruncSatF32x4U:
          return builder.makeUnary(TruncSatUVecF32x4ToVecI32x4);
        case BinaryConsts::F32x4ConvertI32x4S:
          return builder.makeUnary(ConvertSVecI32x4ToVecF32x4);
        case BinaryConsts::F32x4ConvertI32x4U:
          return builder.makeUnary(ConvertUVecI32x4ToVecF32x4);
        case BinaryConsts::I16x8ExtendLowI8x16S:
          return builder.makeUnary(ExtendLowSVecI8x16ToVecI16x8);
        case BinaryConsts::I16x8ExtendHighI8x16S:
          return builder.makeUnary(ExtendHighSVecI8x16ToVecI16x8);
        case BinaryConsts::I16x8ExtendLowI8x16U:
          return builder.makeUnary(ExtendLowUVecI8x16ToVecI16x8);
        case BinaryConsts::I16x8ExtendHighI8x16U:
          return builder.makeUnary(ExtendHighUVecI8x16ToVecI16x8);
        case BinaryConsts::I32x4ExtendLowI16x8S:
          return builder.makeUnary(ExtendLowSVecI16x8ToVecI32x4);
        case BinaryConsts::I32x4ExtendHighI16x8S:
          return builder.makeUnary(ExtendHighSVecI16x8ToVecI32x4);
        case BinaryConsts::I32x4ExtendLowI16x8U:
          return builder.makeUnary(ExtendLowUVecI16x8ToVecI32x4);
        case BinaryConsts::I32x4ExtendHighI16x8U:
          return builder.makeUnary(ExtendHighUVecI16x8ToVecI32x4);
        case BinaryConsts::I64x2ExtendLowI32x4S:
          return builder.makeUnary(ExtendLowSVecI32x4ToVecI64x2);
        case BinaryConsts::I64x2ExtendHighI32x4S:
          return builder.makeUnary(ExtendHighSVecI32x4ToVecI64x2);
        case BinaryConsts::I64x2ExtendLowI32x4U:
          return builder.makeUnary(ExtendLowUVecI32x4ToVecI64x2);
        case BinaryConsts::I64x2ExtendHighI32x4U:
          return builder.makeUnary(ExtendHighUVecI32x4ToVecI64x2);
        case BinaryConsts::F64x2ConvertLowI32x4S:
          return builder.makeUnary(ConvertLowSVecI32x4ToVecF64x2);
        case BinaryConsts::F64x2ConvertLowI32x4U:
          return builder.makeUnary(ConvertLowUVecI32x4ToVecF64x2);
        case BinaryConsts::I32x4TruncSatF64x2SZero:
          return builder.makeUnary(TruncSatZeroSVecF64x2ToVecI32x4);
        case BinaryConsts::I32x4TruncSatF64x2UZero:
          return builder.makeUnary(TruncSatZeroUVecF64x2ToVecI32x4);
        case BinaryConsts::F32x4DemoteF64x2Zero:
          return builder.makeUnary(DemoteZeroVecF64x2ToVecF32x4);
        case BinaryConsts::F64x2PromoteLowF32x4:
          return builder.makeUnary(PromoteLowVecF32x4ToVecF64x2);
        case BinaryConsts::I32x4RelaxedTruncF32x4S:
          return builder.makeUnary(RelaxedTruncSVecF32x4ToVecI32x4);
        case BinaryConsts::I32x4RelaxedTruncF32x4U:
          return builder.makeUnary(RelaxedTruncUVecF32x4ToVecI32x4);
        case BinaryConsts::I32x4RelaxedTruncF64x2SZero:
          return builder.makeUnary(RelaxedTruncZeroSVecF64x2ToVecI32x4);
        case BinaryConsts::I32x4RelaxedTruncF64x2UZero:
          return builder.makeUnary(RelaxedTruncZeroUVecF64x2ToVecI32x4);
        case BinaryConsts::I16x8TruncSatF16x8S:
          return builder.makeUnary(TruncSatSVecF16x8ToVecI16x8);
        case BinaryConsts::I16x8TruncSatF16x8U:
          return builder.makeUnary(TruncSatUVecF16x8ToVecI16x8);
        case BinaryConsts::F16x8ConvertI16x8S:
          return builder.makeUnary(ConvertSVecI16x8ToVecF16x8);
        case BinaryConsts::F16x8ConvertI16x8U:
          return builder.makeUnary(ConvertUVecI16x8ToVecF16x8);
        case BinaryConsts::I8x16ExtractLaneS:
          return builder.makeSIMDExtract(ExtractLaneSVecI8x16,
                                         getLaneIndex(16));
        case BinaryConsts::I8x16ExtractLaneU:
          return builder.makeSIMDExtract(ExtractLaneUVecI8x16,
                                         getLaneIndex(16));
        case BinaryConsts::I16x8ExtractLaneS:
          return builder.makeSIMDExtract(ExtractLaneSVecI16x8, getLaneIndex(8));
        case BinaryConsts::I16x8ExtractLaneU:
          return builder.makeSIMDExtract(ExtractLaneUVecI16x8, getLaneIndex(8));
        case BinaryConsts::I32x4ExtractLane:
          return builder.makeSIMDExtract(ExtractLaneVecI32x4, getLaneIndex(4));
        case BinaryConsts::I64x2ExtractLane:
          return builder.makeSIMDExtract(ExtractLaneVecI64x2, getLaneIndex(2));
        case BinaryConsts::F16x8ExtractLane:
          return builder.makeSIMDExtract(ExtractLaneVecF16x8, getLaneIndex(8));
        case BinaryConsts::F32x4ExtractLane:
          return builder.makeSIMDExtract(ExtractLaneVecF32x4, getLaneIndex(4));
        case BinaryConsts::F64x2ExtractLane:
          return builder.makeSIMDExtract(ExtractLaneVecF64x2, getLaneIndex(2));
        case BinaryConsts::I8x16ReplaceLane:
          return builder.makeSIMDReplace(ReplaceLaneVecI8x16, getLaneIndex(16));
        case BinaryConsts::I16x8ReplaceLane:
          return builder.makeSIMDReplace(ReplaceLaneVecI16x8, getLaneIndex(8));
        case BinaryConsts::I32x4ReplaceLane:
          return builder.makeSIMDReplace(ReplaceLaneVecI32x4, getLaneIndex(4));
        case BinaryConsts::I64x2ReplaceLane:
          return builder.makeSIMDReplace(ReplaceLaneVecI64x2, getLaneIndex(2));
        case BinaryConsts::F16x8ReplaceLane:
          return builder.makeSIMDReplace(ReplaceLaneVecF16x8, getLaneIndex(8));
        case BinaryConsts::F32x4ReplaceLane:
          return builder.makeSIMDReplace(ReplaceLaneVecF32x4, getLaneIndex(4));
        case BinaryConsts::F64x2ReplaceLane:
          return builder.makeSIMDReplace(ReplaceLaneVecF64x2, getLaneIndex(2));
        case BinaryConsts::I8x16Shuffle: {
          std::array<uint8_t, 16> lanes;
          for (Index i = 0; i < 16; ++i) {
            lanes[i] = getLaneIndex(32);
          }
          return builder.makeSIMDShuffle(lanes);
        }
        case BinaryConsts::V128Bitselect:
          return builder.makeSIMDTernary(Bitselect);
        case BinaryConsts::I8x16Laneselect:
          return builder.makeSIMDTernary(LaneselectI8x16);
        case BinaryConsts::I16x8Laneselect:
          return builder.makeSIMDTernary(LaneselectI16x8);
        case BinaryConsts::I32x4Laneselect:
          return builder.makeSIMDTernary(LaneselectI32x4);
        case BinaryConsts::I64x2Laneselect:
          return builder.makeSIMDTernary(LaneselectI64x2);
        case BinaryConsts::F16x8RelaxedMadd:
          return builder.makeSIMDTernary(RelaxedMaddVecF16x8);
        case BinaryConsts::F16x8RelaxedNmadd:
          return builder.makeSIMDTernary(RelaxedNmaddVecF16x8);
        case BinaryConsts::F32x4RelaxedMadd:
          return builder.makeSIMDTernary(RelaxedMaddVecF32x4);
        case BinaryConsts::F32x4RelaxedNmadd:
          return builder.makeSIMDTernary(RelaxedNmaddVecF32x4);
        case BinaryConsts::F64x2RelaxedMadd:
          return builder.makeSIMDTernary(RelaxedMaddVecF64x2);
        case BinaryConsts::F64x2RelaxedNmadd:
          return builder.makeSIMDTernary(RelaxedNmaddVecF64x2);
        case BinaryConsts::I32x4DotI8x16I7x16AddS:
          return builder.makeSIMDTernary(DotI8x16I7x16AddSToVecI32x4);
        case BinaryConsts::I8x16Shl:
          return builder.makeSIMDShift(ShlVecI8x16);
        case BinaryConsts::I8x16ShrS:
          return builder.makeSIMDShift(ShrSVecI8x16);
        case BinaryConsts::I8x16ShrU:
          return builder.makeSIMDShift(ShrUVecI8x16);
        case BinaryConsts::I16x8Shl:
          return builder.makeSIMDShift(ShlVecI16x8);
        case BinaryConsts::I16x8ShrS:
          return builder.makeSIMDShift(ShrSVecI16x8);
        case BinaryConsts::I16x8ShrU:
          return builder.makeSIMDShift(ShrUVecI16x8);
        case BinaryConsts::I32x4Shl:
          return builder.makeSIMDShift(ShlVecI32x4);
        case BinaryConsts::I32x4ShrS:
          return builder.makeSIMDShift(ShrSVecI32x4);
        case BinaryConsts::I32x4ShrU:
          return builder.makeSIMDShift(ShrUVecI32x4);
        case BinaryConsts::I64x2Shl:
          return builder.makeSIMDShift(ShlVecI64x2);
        case BinaryConsts::I64x2ShrS:
          return builder.makeSIMDShift(ShrSVecI64x2);
        case BinaryConsts::I64x2ShrU:
          return builder.makeSIMDShift(ShrUVecI64x2);
        case BinaryConsts::V128Const:
          return builder.makeConst(getVec128Literal());
        case BinaryConsts::V128Store: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeStore(16, offset, align, Type::v128, mem);
        }
        case BinaryConsts::V128Load: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeLoad(16, false, offset, align, Type::v128, mem);
        }
        case BinaryConsts::V128Load8Splat: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load8SplatVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load16Splat: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load16SplatVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load32Splat: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load32SplatVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load64Splat: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load64SplatVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load8x8S: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load8x8SVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load8x8U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load8x8UVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load16x4S: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load16x4SVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load16x4U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load16x4UVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load32x2S: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load32x2SVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load32x2U: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load32x2UVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load32Zero: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load32ZeroVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load64Zero: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoad(Load64ZeroVec128, offset, align, mem);
        }
        case BinaryConsts::V128Load8Lane: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoadStoreLane(
            Load8LaneVec128, offset, align, getLaneIndex(16), mem);
        }
        case BinaryConsts::V128Load16Lane: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoadStoreLane(
            Load16LaneVec128, offset, align, getLaneIndex(8), mem);
        }
        case BinaryConsts::V128Load32Lane: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoadStoreLane(
            Load32LaneVec128, offset, align, getLaneIndex(4), mem);
        }
        case BinaryConsts::V128Load64Lane: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoadStoreLane(
            Load64LaneVec128, offset, align, getLaneIndex(2), mem);
        }
        case BinaryConsts::V128Store8Lane: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoadStoreLane(
            Store8LaneVec128, offset, align, getLaneIndex(16), mem);
        }
        case BinaryConsts::V128Store16Lane: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoadStoreLane(
            Store16LaneVec128, offset, align, getLaneIndex(8), mem);
        }
        case BinaryConsts::V128Store32Lane: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoadStoreLane(
            Store32LaneVec128, offset, align, getLaneIndex(4), mem);
        }
        case BinaryConsts::V128Store64Lane: {
          auto [mem, align, offset] = getMemarg();
          return builder.makeSIMDLoadStoreLane(
            Store64LaneVec128, offset, align, getLaneIndex(2), mem);
        }
      }
      return Err{"unknown SIMD operation " + std::to_string(op)};
    }
    case BinaryConsts::GCPrefix: {
      auto op = getU32LEB();
      switch (op) {
        case BinaryConsts::RefI31:
          return builder.makeRefI31(Unshared);
        case BinaryConsts::RefI31Shared:
          return builder.makeRefI31(Shared);
        case BinaryConsts::I31GetS:
          return builder.makeI31Get(true);
        case BinaryConsts::I31GetU:
          return builder.makeI31Get(false);
        case BinaryConsts::RefTest: {
          auto [heapType, exactness] = getHeapType();
          return builder.makeRefTest(Type(heapType, NonNullable, exactness));
        }
        case BinaryConsts::RefTestNull: {
          auto [heapType, exactness] = getHeapType();
          return builder.makeRefTest(Type(heapType, Nullable, exactness));
        }
        case BinaryConsts::RefCast: {
          auto [heapType, exactness] = getHeapType();
          return builder.makeRefCast(Type(heapType, NonNullable, exactness),
                                     false);
        }
        case BinaryConsts::RefCastNull: {
          auto [heapType, exactness] = getHeapType();
          return builder.makeRefCast(Type(heapType, Nullable, exactness),
                                     false);
        }
        case BinaryConsts::RefCastDesc: {
          auto [heapType, exactness] = getHeapType();
          return builder.makeRefCast(Type(heapType, NonNullable, exactness),
                                     true);
        }
        case BinaryConsts::RefCastDescNull: {
          auto [heapType, exactness] = getHeapType();
          return builder.makeRefCast(Type(heapType, Nullable, exactness), true);
        }
        case BinaryConsts::RefGetDesc: {
          auto type = getIndexedHeapType();
          return builder.makeRefGetDesc(type);
        }
        case BinaryConsts::BrOnCast:
        case BinaryConsts::BrOnCastFail:
        case BinaryConsts::BrOnCastDesc:
        case BinaryConsts::BrOnCastDescFail: {
          auto flags = getInt8();
          auto srcNull = (flags & BinaryConsts::BrOnCastFlag::InputNullable)
                           ? Nullable
                           : NonNullable;
          auto dstNull = (flags & BinaryConsts::BrOnCastFlag::OutputNullable)
                           ? Nullable
                           : NonNullable;
          auto label = getU32LEB();
          auto [srcType, srcExact] = getHeapType();
          auto [dstType, dstExact] = getHeapType();
          auto in = Type(srcType, srcNull, srcExact);
          auto cast = Type(dstType, dstNull, dstExact);
          auto kind = op == BinaryConsts::BrOnCast       ? BrOnCast
                      : op == BinaryConsts::BrOnCastFail ? BrOnCastFail
                      : op == BinaryConsts::BrOnCastDesc ? BrOnCastDesc
                                                         : BrOnCastDescFail;
          return builder.makeBrOn(label, kind, in, cast);
        }
        case BinaryConsts::StructNew:
          return builder.makeStructNew(getIndexedHeapType());
        case BinaryConsts::StructNewDefault:
          return builder.makeStructNewDefault(getIndexedHeapType());
        case BinaryConsts::StructGet:
        case BinaryConsts::StructGetS:
        case BinaryConsts::StructGetU: {
          auto type = getIndexedHeapType();
          auto field = getU32LEB();
          return builder.makeStructGet(type,
                                       field,
                                       op == BinaryConsts::StructGetS,
                                       MemoryOrder::Unordered);
        }
        case BinaryConsts::StructSet: {
          auto type = getIndexedHeapType();
          auto field = getU32LEB();
          return builder.makeStructSet(type, field, MemoryOrder::Unordered);
        }
        case BinaryConsts::ArrayNew:
          return builder.makeArrayNew(getIndexedHeapType());
        case BinaryConsts::ArrayNewDefault:
          return builder.makeArrayNewDefault(getIndexedHeapType());
        case BinaryConsts::ArrayNewFixed: {
          auto type = getIndexedHeapType();
          auto arity = getU32LEB();
          return builder.makeArrayNewFixed(type, arity);
        }
        case BinaryConsts::ArrayNewData: {
          auto type = getIndexedHeapType();
          auto data = getDataName(getU32LEB());
          return builder.makeArrayNewData(type, data);
        }
        case BinaryConsts::ArrayNewElem: {
          auto type = getIndexedHeapType();
          auto elem = getElemName(getU32LEB());
          return builder.makeArrayNewElem(type, elem);
        }
        case BinaryConsts::ArrayGet:
        case BinaryConsts::ArrayGetU:
          return builder.makeArrayGet(
            getIndexedHeapType(), false, MemoryOrder::Unordered);
        case BinaryConsts::ArrayGetS:
          return builder.makeArrayGet(
            getIndexedHeapType(), true, MemoryOrder::Unordered);
        case BinaryConsts::ArraySet:
          return builder.makeArraySet(getIndexedHeapType(),
                                      MemoryOrder::Unordered);
        case BinaryConsts::ArrayLen:
          return builder.makeArrayLen();
        case BinaryConsts::ArrayCopy: {
          auto dest = getIndexedHeapType();
          auto src = getIndexedHeapType();
          return builder.makeArrayCopy(dest, src);
        }
        case BinaryConsts::ArrayFill:
          return builder.makeArrayFill(getIndexedHeapType());
        case BinaryConsts::ArrayInitData: {
          auto type = getIndexedHeapType();
          auto data = getDataName(getU32LEB());
          return builder.makeArrayInitData(type, data);
        }
        case BinaryConsts::ArrayInitElem: {
          auto type = getIndexedHeapType();
          auto elem = getElemName(getU32LEB());
          return builder.makeArrayInitElem(type, elem);
        }
        case BinaryConsts::StringNewLossyUTF8Array:
          return builder.makeStringNew(StringNewLossyUTF8Array);
        case BinaryConsts::StringNewWTF16Array:
          return builder.makeStringNew(StringNewWTF16Array);
        case BinaryConsts::StringFromCodePoint:
          return builder.makeStringNew(StringNewFromCodePoint);
        case BinaryConsts::StringAsWTF16:
          // This turns into nothing because we do not represent stringviews in
          // the IR.
          return Ok{};
        case BinaryConsts::StringConst:
          return builder.makeStringConst(getIndexedString());
        case BinaryConsts::StringMeasureUTF8:
          return builder.makeStringMeasure(StringMeasureUTF8);
        case BinaryConsts::StringMeasureWTF16:
          return builder.makeStringMeasure(StringMeasureWTF16);
        case BinaryConsts::StringEncodeLossyUTF8Array:
          return builder.makeStringEncode(StringEncodeLossyUTF8Array);
        case BinaryConsts::StringEncodeWTF16Array:
          return builder.makeStringEncode(StringEncodeWTF16Array);
        case BinaryConsts::StringConcat:
          return builder.makeStringConcat();
        case BinaryConsts::StringEq:
          return builder.makeStringEq(StringEqEqual);
        case BinaryConsts::StringTest:
          return builder.makeStringTest();
        case BinaryConsts::StringCompare:
          return builder.makeStringEq(StringEqCompare);
        case BinaryConsts::StringViewWTF16GetCodePoint:
          return builder.makeStringWTF16Get();
        case BinaryConsts::StringViewWTF16Slice:
          return builder.makeStringSliceWTF();
        case BinaryConsts::AnyConvertExtern:
          return builder.makeRefAs(AnyConvertExtern);
        case BinaryConsts::ExternConvertAny:
          return builder.makeRefAs(ExternConvertAny);
      }
      return Err{"unknown GC operation " + std::to_string(op)};
    }
  }
  return Err{"unknown operation " + std::to_string(code)};
}

void WasmBinaryReader::readExports() {
  size_t num = getU32LEB();
  std::unordered_set<Name> names;
  for (size_t i = 0; i < num; i++) {
    Name name = getInlineString();
    if (!names.emplace(name).second) {
      throwError("duplicate export name");
    }
    auto kind = getU32LEB();
    std::optional<std::variant<Name, HeapType>> value;
    auto index = getU32LEB();
    switch (kind) {
      case ExternalKind::Function:
        value = getFunctionName(index);
        break;
      case ExternalKind::Table:
        value = getTableName(index);
        break;
      case ExternalKind::Memory:
        value = getMemoryName(index);
        break;
      case ExternalKind::Global:
        value = getGlobalName(index);
        break;
      case ExternalKind::Tag:
        value = getTagName(index);
        break;
      case ExternalKind::Invalid:
        break;
    }
    if (!value) {
      throwError("invalid export kind");
    }
    wasm.addExport(new Export(name, ExternalKind(kind), *value));
  }
}

Expression* WasmBinaryReader::readExpression() {
  assert(builder.empty());
  while (input[pos] != BinaryConsts::End) {
    auto inst = readInst();
    if (auto* err = inst.getErr()) {
      throwError(err->msg);
    }
  }
  ++pos;
  auto expr = builder.build();
  if (auto* err = expr.getErr()) {
    throwError(err->msg);
  }
  return *expr;
}

void WasmBinaryReader::readStrings() {
  auto reserved = getU32LEB();
  if (reserved != 0) {
    throwError("unexpected reserved value in strings");
  }
  size_t num = getU32LEB();
  for (size_t i = 0; i < num; i++) {
    auto string = getInlineString(false);
    // Re-encode from WTF-8 to WTF-16.
    std::stringstream wtf16;
    if (!String::convertWTF8ToWTF16(wtf16, string.str)) {
      throwError("invalid string constant");
    }
    // TODO: Use wtf16.view() once we have C++20.
    strings.push_back(wtf16.str());
  }
}

Name WasmBinaryReader::getIndexedString() {
  auto index = getU32LEB();
  if (index >= strings.size()) {
    throwError("bad string index");
  }
  return strings[index];
}

void WasmBinaryReader::readGlobals() {
  size_t num = getU32LEB();
  auto numImports = wasm.globals.size();
  for (auto& [index, name] : globalNames) {
    if (index >= num + numImports) {
      std::cerr << "warning: global index out of bounds in name section: "
                << name << " at index " << index << '\n';
    }
  }
  for (size_t i = 0; i < num; i++) {
    auto [name, isExplicit] = getOrMakeName(
      globalNames, numImports + i, makeName("global$", i), usedGlobalNames);
    auto type = getConcreteType();
    auto mutable_ = getU32LEB();
    if (mutable_ & ~1) {
      throwError("Global mutability must be 0 or 1");
    }
    auto* init = readExpression();
    auto global = Builder::makeGlobal(
      name, type, init, mutable_ ? Builder::Mutable : Builder::Immutable);
    global->hasExplicitName = isExplicit;
    wasm.addGlobal(std::move(global));
  }
}

void WasmBinaryReader::validateBinary() {
  if (hasDataCount && wasm.dataSegments.size() != dataCount) {
    throwError("Number of segments does not agree with DataCount section");
  }

  if (functionTypes.size() != numFuncImports + numFuncBodies) {
    throwError("function and code sections have inconsistent lengths");
  }
}

void WasmBinaryReader::createDataSegments(Index count) {
  std::unordered_set<Name> usedNames;
  for (auto& [index, name] : dataNames) {
    if (index >= count) {
      std::cerr << "warning: data index out of bounds in name section: " << name
                << " at index " << index << '\n';
    }
    usedNames.insert(name);
  }
  for (size_t i = 0; i < count; ++i) {
    auto [name, isExplicit] =
      getOrMakeName(dataNames, i, makeName("", i), usedNames);
    auto curr = Builder::makeDataSegment(name);
    curr->hasExplicitName = isExplicit;
    wasm.addDataSegment(std::move(curr));
  }
}

void WasmBinaryReader::readDataSegmentCount() {
  hasDataCount = true;
  dataCount = getU32LEB();
  // Eagerly create the data segments so they are available during parsing of
  // the code section.
  createDataSegments(dataCount);
}

void WasmBinaryReader::readDataSegments() {
  auto num = getU32LEB();
  if (hasDataCount) {
    if (num != dataCount) {
      throwError("data count and data sections disagree on size");
    }
  } else {
    // We haven't already created the data segments, so create them now.
    createDataSegments(num);
  }
  assert(wasm.dataSegments.size() == num);
  for (size_t i = 0; i < num; i++) {
    auto& curr = wasm.dataSegments[i];
    uint32_t flags = getU32LEB();
    if (flags > 2) {
      throwError("bad segment flags, must be 0, 1, or 2, not " +
                 std::to_string(flags));
    }
    curr->isPassive = flags & BinaryConsts::IsPassive;
    if (curr->isPassive) {
      curr->memory = Name();
      curr->offset = nullptr;
    } else {
      Index memIdx = 0;
      if (flags & BinaryConsts::HasIndex) {
        memIdx = getU32LEB();
      }
      curr->memory = getMemoryName(memIdx);
      curr->offset = readExpression();
    }
    auto size = getU32LEB();
    auto data = getByteView(size);
    curr->data = {data.begin(), data.end()};
  }
}

void WasmBinaryReader::readTableDeclarations() {
  auto num = getU32LEB();
  auto numImports = wasm.tables.size();
  for (auto& [index, name] : tableNames) {
    if (index >= num + numImports) {
      std::cerr << "warning: table index out of bounds in name section: "
                << name << " at index " << index << '\n';
    }
  }
  for (size_t i = 0; i < num; i++) {
    auto [name, isExplicit] = getOrMakeName(
      tableNames, numImports + i, makeName("", i), usedTableNames);
    auto elemType = getType();
    if (!elemType.isRef()) {
      throwError("Table type must be a reference type");
    }
    auto table = Builder::makeTable(name, elemType);
    table->hasExplicitName = isExplicit;
    bool is_shared;
    getResizableLimits(table->initial,
                       table->max,
                       is_shared,
                       table->addressType,
                       Table::kUnlimitedSize);
    if (is_shared) {
      throwError("Tables may not be shared");
    }
    wasm.addTable(std::move(table));
  }
}

void WasmBinaryReader::readElementSegments() {
  auto num = getU32LEB();
  if (num >= Table::kMaxSize) {
    throwError("Too many segments");
  }
  std::unordered_set<Name> usedNames;
  for (auto& [index, name] : elemNames) {
    if (index >= num) {
      std::cerr << "warning: elem index out of bounds in name section: " << name
                << " at index " << index << '\n';
    }
    usedNames.insert(name);
  }
  for (size_t i = 0; i < num; i++) {
    auto [name, isExplicit] =
      getOrMakeName(elemNames, i, makeName("", i), usedNames);
    auto flags = getU32LEB();
    bool isPassive = (flags & BinaryConsts::IsPassive) != 0;
    bool hasTableIdx = !isPassive && ((flags & BinaryConsts::HasIndex) != 0);
    bool isDeclarative =
      isPassive && ((flags & BinaryConsts::IsDeclarative) != 0);
    bool usesExpressions = (flags & BinaryConsts::UsesExpressions) != 0;

    if (isDeclarative) {
      // Declared segments are needed in wasm text and binary, but not in
      // Binaryen IR; skip over the segment
      [[maybe_unused]] auto type = getU32LEB();
      auto num = getU32LEB();
      for (Index i = 0; i < num; i++) {
        if (usesExpressions) {
          readExpression();
        } else {
          getU32LEB();
        }
      }
      continue;
    }

    auto segment = std::make_unique<ElementSegment>();
    segment->setName(name, isExplicit);

    if (!isPassive) {
      Index tableIdx = 0;
      if (hasTableIdx) {
        tableIdx = getU32LEB();
      }

      if (tableIdx >= wasm.tables.size()) {
        throwError("Table index out of range.");
      }
      auto* table = wasm.tables[tableIdx].get();
      segment->table = table->name;
      segment->offset = readExpression();
    }

    if (isPassive || hasTableIdx) {
      if (usesExpressions) {
        segment->type = getType();
      } else {
        auto elemKind = getU32LEB();
        if (elemKind != 0x0) {
          throwError("Invalid kind (!= funcref(0)) since !usesExpressions.");
        }
      }
    }

    auto& segmentData = segment->data;
    auto size = getU32LEB();
    if (usesExpressions) {
      for (Index j = 0; j < size; j++) {
        segmentData.push_back(readExpression());
      }
    } else {
      for (Index j = 0; j < size; j++) {
        Index index = getU32LEB();
        auto* refFunc = Builder(wasm).makeRefFunc(getFunctionName(index));
        segmentData.push_back(refFunc);
      }
    }
    wasm.addElementSegment(std::move(segment));
  }
}

void WasmBinaryReader::readTags() {
  size_t num = getU32LEB();
  auto numImports = wasm.tags.size();
  for (auto& [index, name] : tagNames) {
    if (index >= num + numImports) {
      std::cerr << "warning: tag index out of bounds in name section: " << name
                << " at index " << index << '\n';
    }
  }
  for (size_t i = 0; i < num; i++) {
    getInt8(); // Reserved 'attribute' field
    auto [name, isExplicit] = getOrMakeName(
      tagNames, numImports + i, makeName("tag$", i), usedTagNames);
    auto typeIndex = getU32LEB();
    auto tag = Builder::makeTag(name, getSignatureByTypeIndex(typeIndex));
    tag->hasExplicitName = isExplicit;
    wasm.addTag(std::move(tag));
  }
}

static bool isIdChar(char ch) {
  return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') ||
         (ch >= 'a' && ch <= 'z') || ch == '!' || ch == '#' || ch == '$' ||
         ch == '%' || ch == '&' || ch == '\'' || ch == '*' || ch == '+' ||
         ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == '<' ||
         ch == '=' || ch == '>' || ch == '?' || ch == '@' || ch == '^' ||
         ch == '_' || ch == '`' || ch == '|' || ch == '~';
}

static char formatNibble(int nibble) {
  return nibble < 10 ? '0' + nibble : 'a' - 10 + nibble;
}

Name WasmBinaryReader::escape(Name name) {
  bool allIdChars = true;
  for (char c : name.str) {
    if (!(allIdChars = isIdChar(c))) {
      break;
    }
  }
  if (allIdChars) {
    return name;
  }
  // encode name, if at least one non-idchar (per WebAssembly spec) was found
  std::string escaped;
  for (char c : name.str) {
    if (isIdChar(c)) {
      escaped.push_back(c);
      continue;
    }
    // replace non-idchar with `\xx` escape
    escaped.push_back('\\');
    escaped.push_back(formatNibble(c >> 4));
    escaped.push_back(formatNibble(c & 15));
  }
  return escaped;
}

namespace {

// Performs necessary processing of names from the name section before using
// them. Specifically it escapes and deduplicates them.
class NameProcessor {
public:
  // Returns a unique, escaped name. Notes that name for the items to follow to
  // keep them unique as well.
  Name process(Name name) {
    return deduplicate(WasmBinaryReader::escape(name));
  }

private:
  std::unordered_set<Name> usedNames;

  Name deduplicate(Name base) {
    auto name = Names::getValidNameGivenExisting(base, usedNames);
    usedNames.insert(name);
    return name;
  }
};

} // anonymous namespace

void WasmBinaryReader::readNames(size_t sectionPos, size_t payloadLen) {
  // Read the names.
  uint32_t lastType = 0;
  while (pos < sectionPos + payloadLen) {
    auto nameType = getU32LEB();
    if (lastType && nameType <= lastType) {
      std::cerr << "warning: out-of-order name subsection: " << nameType
                << std::endl;
    }
    lastType = nameType;
    auto subsectionSize = getU32LEB();
    auto subsectionPos = pos;
    using Subsection = BinaryConsts::CustomSections::Subsection;
    if (nameType == Subsection::NameModule) {
      wasm.name = getInlineString();
    } else if (nameType == Subsection::NameFunction) {
      auto num = getU32LEB();
      NameProcessor processor;
      for (size_t i = 0; i < num; i++) {
        auto index = getU32LEB();
        auto rawName = getInlineString();
        auto name = processor.process(rawName);
        functionNames[index] = name;
        usedFunctionNames.insert(name);
      }
    } else if (nameType == Subsection::NameLocal) {
      auto numFuncs = getU32LEB();
      for (size_t i = 0; i < numFuncs; i++) {
        auto funcIndex = getU32LEB();
        auto numLocals = getU32LEB();
        NameProcessor processor;
        for (size_t j = 0; j < numLocals; j++) {
          auto localIndex = getU32LEB();
          auto rawName = getInlineString();
          auto name = processor.process(rawName);
          localNames[funcIndex][localIndex] = name;
        }
      }
    } else if (nameType == Subsection::NameType) {
      auto num = getU32LEB();
      NameProcessor processor;
      for (size_t i = 0; i < num; i++) {
        auto index = getU32LEB();
        auto rawName = getInlineString();
        auto name = processor.process(rawName);
        typeNames[index] = name;
      }
    } else if (nameType == Subsection::NameTable) {
      auto num = getU32LEB();
      NameProcessor processor;
      for (size_t i = 0; i < num; i++) {
        auto index = getU32LEB();
        auto rawName = getInlineString();
        auto name = processor.process(rawName);
        tableNames[index] = name;
        usedTableNames.insert(name);
      }
    } else if (nameType == Subsection::NameElem) {
      auto num = getU32LEB();
      NameProcessor processor;
      for (size_t i = 0; i < num; i++) {
        auto index = getU32LEB();
        auto rawName = getInlineString();
        auto name = processor.process(rawName);
        elemNames[index] = name;
      }
    } else if (nameType == Subsection::NameMemory) {
      auto num = getU32LEB();
      NameProcessor processor;
      for (size_t i = 0; i < num; i++) {
        auto index = getU32LEB();
        auto rawName = getInlineString();
        auto name = processor.process(rawName);
        memoryNames[index] = name;
        usedMemoryNames.insert(name);
      }
    } else if (nameType == Subsection::NameData) {
      auto num = getU32LEB();
      NameProcessor processor;
      for (size_t i = 0; i < num; i++) {
        auto index = getU32LEB();
        auto rawName = getInlineString();
        auto name = processor.process(rawName);
        dataNames[index] = name;
      }
    } else if (nameType == Subsection::NameGlobal) {
      auto num = getU32LEB();
      NameProcessor processor;
      for (size_t i = 0; i < num; i++) {
        auto index = getU32LEB();
        auto rawName = getInlineString();
        auto name = processor.process(rawName);
        globalNames[index] = name;
        usedGlobalNames.insert(name);
      }
    } else if (nameType == Subsection::NameField) {
      auto numTypes = getU32LEB();
      for (size_t i = 0; i < numTypes; i++) {
        auto typeIndex = getU32LEB();
        auto numFields = getU32LEB();
        NameProcessor processor;
        for (size_t i = 0; i < numFields; i++) {
          auto fieldIndex = getU32LEB();
          auto rawName = getInlineString();
          auto name = processor.process(rawName);
          fieldNames[typeIndex][fieldIndex] = name;
        }
      }
    } else if (nameType == Subsection::NameTag) {
      auto num = getU32LEB();
      NameProcessor processor;
      for (size_t i = 0; i < num; i++) {
        auto index = getU32LEB();
        auto rawName = getInlineString();
        auto name = processor.process(rawName);
        tagNames[index] = name;
        usedTagNames.insert(name);
      }
    } else {
      std::cerr << "warning: unknown name subsection with id "
                << std::to_string(nameType) << " at " << pos << std::endl;
      pos = subsectionPos + subsectionSize;
    }
    if (pos != subsectionPos + subsectionSize) {
      throwError("bad names subsection position change");
    }
  }
  if (pos != sectionPos + payloadLen) {
    throwError("bad names section position change");
  }
}

void WasmBinaryReader::readFeatures(size_t sectionPos, size_t payloadLen) {
  wasm.hasFeaturesSection = true;

  size_t numFeatures = getU32LEB();
  for (size_t i = 0; i < numFeatures; ++i) {
    uint8_t prefix = getInt8();

    bool disallowed = prefix == BinaryConsts::FeatureDisallowed;
    bool used = prefix == BinaryConsts::FeatureUsed;

    if (!disallowed && !used) {
      throwError("Unrecognized feature policy prefix");
    }

    Name name = getInlineString();
    if (pos > sectionPos + payloadLen) {
      throwError("ill-formed string extends beyond section");
    }

    FeatureSet feature;
    if (name == BinaryConsts::CustomSections::AtomicsFeature) {
      feature = FeatureSet::Atomics;
    } else if (name == BinaryConsts::CustomSections::BulkMemoryFeature) {
      feature = FeatureSet::BulkMemory;
      if (used) {
        // For backward compatibility, enable this dependent feature.
        feature |= FeatureSet::BulkMemoryOpt;
      }
    } else if (name == BinaryConsts::CustomSections::BulkMemoryOptFeature) {
      feature = FeatureSet::BulkMemoryOpt;
    } else if (name ==
               BinaryConsts::CustomSections::CallIndirectOverlongFeature) {
      feature = FeatureSet::CallIndirectOverlong;
    } else if (name == BinaryConsts::CustomSections::ExceptionHandlingFeature) {
      feature = FeatureSet::ExceptionHandling;
    } else if (name == BinaryConsts::CustomSections::MutableGlobalsFeature) {
      feature = FeatureSet::MutableGlobals;
    } else if (name == BinaryConsts::CustomSections::TruncSatFeature) {
      feature = FeatureSet::TruncSat;
    } else if (name == BinaryConsts::CustomSections::SignExtFeature) {
      feature = FeatureSet::SignExt;
    } else if (name == BinaryConsts::CustomSections::SIMD128Feature) {
      feature = FeatureSet::SIMD;
    } else if (name == BinaryConsts::CustomSections::TailCallFeature) {
      feature = FeatureSet::TailCall;
    } else if (name == BinaryConsts::CustomSections::ReferenceTypesFeature) {
      feature = FeatureSet::ReferenceTypes;
    } else if (name == BinaryConsts::CustomSections::MultivalueFeature) {
      feature = FeatureSet::Multivalue;
    } else if (name == BinaryConsts::CustomSections::GCFeature) {
      feature = FeatureSet::GC;
    } else if (name == BinaryConsts::CustomSections::Memory64Feature) {
      feature = FeatureSet::Memory64;
    } else if (name == BinaryConsts::CustomSections::RelaxedSIMDFeature) {
      feature = FeatureSet::RelaxedSIMD;
    } else if (name == BinaryConsts::CustomSections::ExtendedConstFeature) {
      feature = FeatureSet::ExtendedConst;
    } else if (name == BinaryConsts::CustomSections::StringsFeature) {
      feature = FeatureSet::Strings;
    } else if (name == BinaryConsts::CustomSections::MultiMemoryFeature) {
      feature = FeatureSet::MultiMemory;
    } else if (name == BinaryConsts::CustomSections::StackSwitchingFeature) {
      feature = FeatureSet::StackSwitching;
    } else if (name == BinaryConsts::CustomSections::SharedEverythingFeature) {
      feature = FeatureSet::SharedEverything;
    } else if (name == BinaryConsts::CustomSections::FP16Feature) {
      feature = FeatureSet::FP16;
    } else if (name == BinaryConsts::CustomSections::CustomDescriptorsFeature) {
      feature = FeatureSet::CustomDescriptors;
    } else {
      // Silently ignore unknown features (this may be and old binaryen running
      // on a new wasm).
    }

    if (disallowed && wasm.features.has(feature)) {
      std::cerr
        << "warning: feature " << feature.toString()
        << " was enabled by the user, but disallowed in the features section.";
    }
    if (used) {
      featuresSectionFeatures.enable(feature);
    }
  }
  if (pos != sectionPos + payloadLen) {
    throwError("bad features section size");
  }

  wasm.features.enable(featuresSectionFeatures);
}

void WasmBinaryReader::readDylink(size_t payloadLen) {
  wasm.dylinkSection = std::make_unique<DylinkSection>();

  auto sectionPos = pos;

  wasm.dylinkSection->isLegacy = true;
  wasm.dylinkSection->memorySize = getU32LEB();
  wasm.dylinkSection->memoryAlignment = getU32LEB();
  wasm.dylinkSection->tableSize = getU32LEB();
  wasm.dylinkSection->tableAlignment = getU32LEB();

  size_t numNeededDynlibs = getU32LEB();
  for (size_t i = 0; i < numNeededDynlibs; ++i) {
    wasm.dylinkSection->neededDynlibs.push_back(getInlineString());
  }

  if (pos != sectionPos + payloadLen) {
    throwError("bad dylink section size");
  }
}

void WasmBinaryReader::readDylink0(size_t payloadLen) {
  auto sectionPos = pos;
  uint32_t lastType = 0;

  wasm.dylinkSection = std::make_unique<DylinkSection>();
  while (pos < sectionPos + payloadLen) {
    auto oldPos = pos;
    auto dylinkType = getU32LEB();
    if (lastType && dylinkType <= lastType) {
      std::cerr << "warning: out-of-order dylink.0 subsection: " << dylinkType
                << std::endl;
    }
    lastType = dylinkType;
    auto subsectionSize = getU32LEB();
    auto subsectionPos = pos;
    if (dylinkType == BinaryConsts::CustomSections::Subsection::DylinkMemInfo) {
      wasm.dylinkSection->memorySize = getU32LEB();
      wasm.dylinkSection->memoryAlignment = getU32LEB();
      wasm.dylinkSection->tableSize = getU32LEB();
      wasm.dylinkSection->tableAlignment = getU32LEB();
    } else if (dylinkType ==
               BinaryConsts::CustomSections::Subsection::DylinkNeeded) {
      size_t numNeededDynlibs = getU32LEB();
      for (size_t i = 0; i < numNeededDynlibs; ++i) {
        wasm.dylinkSection->neededDynlibs.push_back(getInlineString());
      }
    } else {
      // Unknown subsection.  Stop parsing now and store the rest of
      // the section verbatim.
      pos = oldPos;
      size_t remaining = (sectionPos + payloadLen) - pos;
      auto tail = getByteView(remaining);
      wasm.dylinkSection->tail = {tail.begin(), tail.end()};
      break;
    }
    if (pos != subsectionPos + subsectionSize) {
      throwError("bad dylink.0 subsection position change");
    }
  }
}

template<typename ReadFunc>
void WasmBinaryReader::readExpressionHints(Name sectionName,
                                           size_t payloadLen,
                                           ReadFunc read) {
  auto sectionPos = pos;

  auto numFuncs = getU32LEB();
  for (Index i = 0; i < numFuncs; i++) {
    auto funcIndex = getU32LEB();
    if (funcIndex >= wasm.functions.size()) {
      throwError("bad function in " + sectionName.toString());
    }

    auto& func = wasm.functions[funcIndex];

    // The encoded offsets we read below are relative to the start of the
    // function's locals (the declarations).
    auto funcLocalsOffset = func->funcLocation.declarations;

    // We have a map of expressions to their locations. Invert that to get the
    // map we will use below, from offsets to expressions.
    std::unordered_map<BinaryLocation, Expression*> locationsMap;

    for (auto& [expr, span] : func->expressionLocations) {
      locationsMap[span.start] = expr;
    }

    auto numHints = getU32LEB();
    for (Index hint = 0; hint < numHints; hint++) {
      // To get the absolute offset, add the function's offset.
      auto relativeOffset = getU32LEB();
      auto absoluteOffset = funcLocalsOffset + relativeOffset;

      auto iter = locationsMap.find(absoluteOffset);
      if (iter == locationsMap.end()) {
        throwError("bad offset in " + sectionName.toString());
      }
      auto* expr = iter->second;

      read(func->codeAnnotations[expr]);
    }
  }

  if (pos != sectionPos + payloadLen) {
    throwError("bad BranchHint section size");
  }
}

void WasmBinaryReader::readBranchHints(size_t payloadLen) {
  readExpressionHints(Annotations::BranchHint,
                      payloadLen,
                      [&](Function::CodeAnnotation& annotation) {
                        auto size = getU32LEB();
                        if (size != 1) {
                          throwError("bad BranchHint size");
                        }

                        auto likely = getU32LEB();
                        if (likely != 0 && likely != 1) {
                          throwError("bad BranchHint value");
                        }

                        annotation.branchLikely = likely;
                      });
}

void WasmBinaryReader::readInlineHints(size_t payloadLen) {
  readExpressionHints(Annotations::InlineHint,
                      payloadLen,
                      [&](Function::CodeAnnotation& annotation) {
                        auto size = getU32LEB();
                        if (size != 1) {
                          throwError("bad InlineHint size");
                        }

                        uint8_t inline_ = getInt8();
                        if (inline_ > 127) {
                          throwError("bad InlineHint value");
                        }

                        annotation.inline_ = inline_;
                      });
}

Index WasmBinaryReader::readMemoryAccess(Address& alignment, Address& offset) {
  auto rawAlignment = getU32LEB();
  bool hasMemIdx = false;
  Index memIdx = 0;
  // Check bit 6 in the alignment to know whether a memory index is present per:
  // https://github.com/WebAssembly/multi-memory/blob/main/proposals/multi-memory/Overview.md
  if (rawAlignment & (1 << (6))) {
    hasMemIdx = true;
    // Clear the bit before we parse alignment
    rawAlignment = rawAlignment & ~(1 << 6);
  }

  if (rawAlignment > 8) {
    throwError("Alignment must be of a reasonable size");
  }

  alignment = Bits::pow2(rawAlignment);
  if (hasMemIdx) {
    memIdx = getU32LEB();
  }
  if (memIdx >= wasm.memories.size()) {
    throwError("Memory index out of range while reading memory alignment.");
  }
  auto* memory = wasm.memories[memIdx].get();
  offset = memory->addressType == Type::i32 ? getU32LEB() : getU64LEB();

  return memIdx;
}

// TODO: make this the only version
std::tuple<Name, Address, Address> WasmBinaryReader::getMemarg() {
  Address alignment, offset;
  auto memIdx = readMemoryAccess(alignment, offset);
  return {getMemoryName(memIdx), alignment, offset};
}

MemoryOrder WasmBinaryReader::getMemoryOrder(bool isRMW) {
  auto code = getInt8();
  switch (code) {
    case BinaryConsts::OrderSeqCst:
      // Covers the RMW case as well because (0 << 4 ) | 0 == 0.
      return MemoryOrder::SeqCst;
    case BinaryConsts::OrderAcqRel:
      if (!isRMW) {
        return MemoryOrder::AcqRel;
      }
      throwError("RMW memory orders must match");
    case ((BinaryConsts::OrderAcqRel << 4) | BinaryConsts::OrderAcqRel):
      if (isRMW) {
        return MemoryOrder::AcqRel;
      }
      break;
  }
  throwError("Unrecognized memory order code " + std::to_string(code));
}

} // namespace wasm
