/*
 * 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 "wabt/binary-writer.h"

#include <cassert>
#include <cmath>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <set>
#include <string_view>
#include <vector>

#include "wabt/config.h"

#include "wabt/binary.h"
#include "wabt/cast.h"
#include "wabt/expr-visitor.h"
#include "wabt/ir.h"
#include "wabt/leb128.h"
#include "wabt/stream.h"

#define PRINT_HEADER_NO_INDEX -1
#define MAX_U32_LEB128_BYTES 5

namespace wabt {

void WriteStr(Stream* stream,
              std::string_view s,
              const char* desc,
              PrintChars print_chars) {
  WriteU32Leb128(stream, s.length(), "string length");
  stream->WriteData(s.data(), s.length(), desc, print_chars);
}

void WriteOpcode(Stream* stream, Opcode opcode) {
  if (opcode.HasPrefix()) {
    stream->WriteU8(opcode.GetPrefix(), "prefix");
    WriteU32Leb128(stream, opcode.GetCode(), opcode.GetName());
  } else {
    stream->WriteU8(opcode.GetCode(), opcode.GetName());
  }
}

void WriteType(Stream* stream, Type type, const char* desc) {
  WriteS32Leb128(stream, type, desc ? desc : type.GetName().c_str());
  if (type.IsReferenceWithIndex()) {
    WriteS32Leb128(stream, type.GetReferenceIndex(),
                   desc ? desc : type.GetName().c_str());
  }
}

void WriteLimits(Stream* stream, const Limits* limits) {
  uint32_t flags = limits->has_max ? WABT_BINARY_LIMITS_HAS_MAX_FLAG : 0;
  flags |= limits->is_shared ? WABT_BINARY_LIMITS_IS_SHARED_FLAG : 0;
  flags |= limits->is_64 ? WABT_BINARY_LIMITS_IS_64_FLAG : 0;
  WriteU32Leb128(stream, flags, "limits: flags");
  if (limits->is_64) {
    WriteU64Leb128(stream, limits->initial, "limits: initial");
    if (limits->has_max) {
      WriteU64Leb128(stream, limits->max, "limits: max");
    }
  } else {
    WriteU32Leb128(stream, limits->initial, "limits: initial");
    if (limits->has_max) {
      WriteU32Leb128(stream, limits->max, "limits: max");
    }
  }
}

void WriteDebugName(Stream* stream, std::string_view name, const char* desc) {
  std::string_view stripped_name = name;
  if (!stripped_name.empty()) {
    // Strip leading $ from name
    assert(stripped_name.front() == '$');
    stripped_name.remove_prefix(1);
  }
  WriteStr(stream, stripped_name, desc, PrintChars::Yes);
}

namespace {

/* TODO(binji): better leb size guess. Some sections we know will only be 1
 byte, but others we can be fairly certain will be larger. */
constexpr size_t LEB_SECTION_SIZE_GUESS = 1;

#define ALLOC_FAILURE \
  fprintf(stderr, "%s:%d: allocation failed\n", __FILE__, __LINE__)

struct RelocSection {
  RelocSection(const char* name, Index index)
      : name(name), section_index(index) {}

  const char* name;
  Index section_index;
  std::vector<Reloc> relocations;
};

class Symbol {
 public:
  struct Function {
    static const SymbolType type = SymbolType::Function;
    Index index;
  };
  struct Data {
    static const SymbolType type = SymbolType::Data;
    Index index;
    Offset offset;
    Address size;
  };
  struct Global {
    static const SymbolType type = SymbolType::Global;
    Index index;
  };
  struct Section {
    static const SymbolType type = SymbolType::Section;
    Index section;
  };
  struct Tag {
    static const SymbolType type = SymbolType::Tag;
    Index index;
  };
  struct Table {
    static const SymbolType type = SymbolType::Table;
    Index index;
  };

 private:
  SymbolType type_;
  std::string_view name_;
  uint8_t flags_;
  union {
    Function function_;
    Data data_;
    Global global_;
    Section section_;
    Tag tag_;
    Table table_;
  };

 public:
  Symbol(const std::string_view& name, uint8_t flags, const Function& f)
      : type_(Function::type), name_(name), flags_(flags), function_(f) {}
  Symbol(const std::string_view& name, uint8_t flags, const Data& d)
      : type_(Data::type), name_(name), flags_(flags), data_(d) {}
  Symbol(const std::string_view& name, uint8_t flags, const Global& g)
      : type_(Global::type), name_(name), flags_(flags), global_(g) {}
  Symbol(const std::string_view& name, uint8_t flags, const Section& s)
      : type_(Section::type), name_(name), flags_(flags), section_(s) {}
  Symbol(const std::string_view& name, uint8_t flags, const Tag& e)
      : type_(Tag::type), name_(name), flags_(flags), tag_(e) {}
  Symbol(const std::string_view& name, uint8_t flags, const Table& t)
      : type_(Table::type), name_(name), flags_(flags), table_(t) {}

  SymbolType type() const { return type_; }
  const std::string_view& name() const { return name_; }
  uint8_t flags() const { return flags_; }

  SymbolVisibility visibility() const {
    return static_cast<SymbolVisibility>(flags() & WABT_SYMBOL_MASK_VISIBILITY);
  }
  SymbolBinding binding() const {
    return static_cast<SymbolBinding>(flags() & WABT_SYMBOL_MASK_BINDING);
  }
  bool undefined() const { return flags() & WABT_SYMBOL_FLAG_UNDEFINED; }
  bool defined() const { return !undefined(); }
  bool exported() const { return flags() & WABT_SYMBOL_FLAG_EXPORTED; }
  bool explicit_name() const {
    return flags() & WABT_SYMBOL_FLAG_EXPLICIT_NAME;
  }
  bool no_strip() const { return flags() & WABT_SYMBOL_FLAG_NO_STRIP; }

  bool IsFunction() const { return type() == Function::type; }
  bool IsData() const { return type() == Data::type; }
  bool IsGlobal() const { return type() == Global::type; }
  bool IsSection() const { return type() == Section::type; }
  bool IsTag() const { return type() == Tag::type; }
  bool IsTable() const { return type() == Table::type; }

  const Function& AsFunction() const {
    assert(IsFunction());
    return function_;
  }
  const Data& AsData() const {
    assert(IsData());
    return data_;
  }
  const Global& AsGlobal() const {
    assert(IsGlobal());
    return global_;
  }
  const Section& AsSection() const {
    assert(IsSection());
    return section_;
  }
  const Tag& AsTag() const {
    assert(IsTag());
    return tag_;
  }
  const Table& AsTable() const {
    assert(IsTable());
    return table_;
  }
};

class SymbolTable {
  WABT_DISALLOW_COPY_AND_ASSIGN(SymbolTable);

  std::vector<Symbol> symbols_;

  std::vector<Index> functions_;
  std::vector<Index> tables_;
  std::vector<Index> globals_;

  std::set<std::string_view> seen_names_;

  Result EnsureUnique(const std::string_view& name) {
    if (seen_names_.count(name)) {
      fprintf(stderr,
              "error: duplicate symbol when writing relocatable "
              "binary: %s\n",
              &name[0]);
      return Result::Error;
    }
    seen_names_.insert(name);
    return Result::Ok;
  };

  template <typename T>
  Result AddSymbol(std::vector<Index>* map,
                   std::string_view name,
                   bool imported,
                   bool exported,
                   T&& sym) {
    uint8_t flags = 0;
    if (imported) {
      flags |= WABT_SYMBOL_FLAG_UNDEFINED;
      // Wabt currently has no way for a user to explicitly specify the name of
      // an import, so never set the EXPLICIT_NAME flag, and ignore any display
      // name fabricated by wabt.
      name = std::string_view();
    } else {
      if (name.empty()) {
        // Definitions without a name are local.
        flags |= uint8_t(SymbolBinding::Local);
        flags |= uint8_t(SymbolVisibility::Hidden);
      } else {
        // Otherwise, strip the dollar off the name; a definition $foo is
        // available for linking as "foo".
        assert(name[0] == '$');
        name.remove_prefix(1);
      }

      if (exported) {
        CHECK_RESULT(EnsureUnique(name));
        flags |= uint8_t(SymbolVisibility::Hidden);
        flags |= WABT_SYMBOL_FLAG_NO_STRIP;
      }
    }
    if (exported) {
      flags |= WABT_SYMBOL_FLAG_EXPORTED;
    }

    map->push_back(symbols_.size());
    symbols_.emplace_back(name, flags, sym);
    return Result::Ok;
  };

  Index SymbolIndex(const std::vector<Index>& table, Index index) const {
    // For well-formed modules, an index into (e.g.) functions_ will always be
    // within bounds; the out-of-bounds case here is just to allow --relocatable
    // to write known-invalid modules.
    return index < table.size() ? table[index] : kInvalidIndex;
  }

 public:
  SymbolTable() {}

  Result Populate(const Module* module) {
    std::set<Index> exported_funcs;
    std::set<Index> exported_globals;
    std::set<Index> exported_tags;
    std::set<Index> exported_tables;

    for (const Export* export_ : module->exports) {
      switch (export_->kind) {
        case ExternalKind::Func:
          exported_funcs.insert(module->GetFuncIndex(export_->var));
          break;
        case ExternalKind::Table:
          exported_tables.insert(module->GetTableIndex(export_->var));
          break;
        case ExternalKind::Memory:
          break;
        case ExternalKind::Global:
          exported_globals.insert(module->GetGlobalIndex(export_->var));
          break;
        case ExternalKind::Tag:
          exported_tags.insert(module->GetTagIndex(export_->var));
          break;
      }
    }

    // We currently only create symbol table entries for function, table, and
    // global symbols.
    for (size_t i = 0; i < module->funcs.size(); ++i) {
      const Func* func = module->funcs[i];
      bool imported = i < module->num_func_imports;
      bool exported = exported_funcs.count(i);
      CHECK_RESULT(AddSymbol(&functions_, func->name, imported, exported,
                             Symbol::Function{Index(i)}));
    }

    for (size_t i = 0; i < module->tables.size(); ++i) {
      const Table* table = module->tables[i];
      bool imported = i < module->num_table_imports;
      bool exported = exported_tables.count(i);
      CHECK_RESULT(AddSymbol(&tables_, table->name, imported, exported,
                             Symbol::Table{Index(i)}));
    }

    for (size_t i = 0; i < module->globals.size(); ++i) {
      const Global* global = module->globals[i];
      bool imported = i < module->num_global_imports;
      bool exported = exported_globals.count(i);
      CHECK_RESULT(AddSymbol(&globals_, global->name, imported, exported,
                             Symbol::Global{Index(i)}));
    }

    return Result::Ok;
  }

  const std::vector<Symbol>& symbols() const { return symbols_; }
  Index FunctionSymbolIndex(Index index) const {
    return SymbolIndex(functions_, index);
  }
  Index TableSymbolIndex(Index index) const {
    return SymbolIndex(tables_, index);
  }
  Index GlobalSymbolIndex(Index index) const {
    return SymbolIndex(globals_, index);
  }
};

struct CodeMetadata {
  Offset offset;
  std::vector<uint8_t> data;
  CodeMetadata(Offset offset, std::vector<uint8_t> data)
      : offset(offset), data(std::move(data)) {}
};
struct FuncCodeMetadata {
  Index func_idx;
  std::vector<CodeMetadata> entries;
  FuncCodeMetadata(Index func_idx) : func_idx(func_idx) {}
};
struct CodeMetadataSection {
  std::vector<FuncCodeMetadata> entries;
};
using CodeMetadataSections =
    std::unordered_map<std::string_view, CodeMetadataSection>;

class BinaryWriter {
  WABT_DISALLOW_COPY_AND_ASSIGN(BinaryWriter);

 public:
  BinaryWriter(Stream*,
               const WriteBinaryOptions& options,
               const Module* module);

  Result WriteModule();

 private:
  void WriteHeader(const char* name, int index);
  Offset WriteU32Leb128Space(Offset leb_size_guess, const char* desc);
  Offset WriteFixupU32Leb128Size(Offset offset,
                                 Offset leb_size_guess,
                                 const char* desc);
  void BeginKnownSection(BinarySection section_code);
  void BeginCustomSection(const char* name);
  void WriteSectionHeader(const char* desc, BinarySection section_code);
  void EndSection();
  void BeginSubsection(const char* name);
  void EndSubsection();
  Index GetLabelVarDepth(const Var* var);
  Index GetTagVarDepth(const Var* var);
  Index GetLocalIndex(const Func* func, const Var& var);
  Index GetSymbolIndex(RelocType reloc_type, Index index);
  void AddReloc(RelocType reloc_type, Index index);
  void WriteBlockDecl(const BlockDeclaration& decl);
  void WriteU32Leb128WithReloc(Index index,
                               const char* desc,
                               RelocType reloc_type);
  void WriteS32Leb128WithReloc(int32_t value,
                               const char* desc,
                               RelocType reloc_type);
  void WriteTableNumberWithReloc(Index table_number, const char* desc);
  template <typename T>
  void WriteLoadStoreExpr(const Func* func, const Expr* expr, const char* desc);
  template <typename T>
  void WriteSimdLoadStoreLaneExpr(const Func* func,
                                  const Expr* expr,
                                  const char* desc);
  void WriteExpr(const Func* func, const Expr* expr);
  void WriteExprList(const Func* func, const ExprList& exprs);
  void WriteInitExpr(const ExprList& expr);
  void WriteFuncLocals(const Func* func, const LocalTypes& local_types);
  void WriteFunc(const Func* func);
  void WriteTable(const Table* table);
  void WriteMemory(const Memory* memory);
  void WriteGlobalHeader(const Global* global);
  void WriteTagType(const Tag* tag);
  void WriteRelocSection(const RelocSection* reloc_section);
  void WriteLinkingSection();
  template <typename T>
  void WriteNames(const std::vector<T*>& elems, NameSectionSubsection type);
  void WriteCodeMetadataSections();

  Stream* stream_;
  const WriteBinaryOptions& options_;
  const Module* module_;

  SymbolTable symtab_;
  std::vector<RelocSection> reloc_sections_;
  RelocSection* current_reloc_section_ = nullptr;

  Index section_count_ = 0;
  size_t last_section_offset_ = 0;
  size_t last_section_leb_size_guess_ = 0;
  BinarySection last_section_type_ = BinarySection::Invalid;
  size_t last_section_payload_offset_ = 0;

  size_t last_subsection_offset_ = 0;
  size_t last_subsection_leb_size_guess_ = 0;
  size_t last_subsection_payload_offset_ = 0;

  // Information about the data count section, so it can be removed if it is
  // not needed, and relocs relative to the code section patched up.
  size_t code_start_ = 0;
  size_t data_count_start_ = 0;
  size_t data_count_end_ = 0;
  bool has_data_segment_instruction_ = false;

  CodeMetadataSections code_metadata_sections_;
  Offset cur_func_start_offset_;
  Index cur_func_index_;
};

static uint8_t log2_u32(uint32_t x) {
  uint8_t result = 0;
  while (x > 1) {
    x >>= 1;
    result++;
  }
  return result;
}

BinaryWriter::BinaryWriter(Stream* stream,
                           const WriteBinaryOptions& options,
                           const Module* module)
    : stream_(stream), options_(options), module_(module) {}

void BinaryWriter::WriteHeader(const char* name, int index) {
  if (stream_->has_log_stream()) {
    if (index == PRINT_HEADER_NO_INDEX) {
      stream_->log_stream().Writef("; %s\n", name);
    } else {
      stream_->log_stream().Writef("; %s %d\n", name, index);
    }
  }
}

/* returns offset of leb128 */
Offset BinaryWriter::WriteU32Leb128Space(Offset leb_size_guess,
                                         const char* desc) {
  assert(leb_size_guess <= MAX_U32_LEB128_BYTES);
  uint8_t data[MAX_U32_LEB128_BYTES] = {0};
  Offset result = stream_->offset();
  Offset bytes_to_write =
      options_.canonicalize_lebs ? leb_size_guess : MAX_U32_LEB128_BYTES;
  stream_->WriteData(data, bytes_to_write, desc);
  return result;
}

Offset BinaryWriter::WriteFixupU32Leb128Size(Offset offset,
                                             Offset leb_size_guess,
                                             const char* desc) {
  if (options_.canonicalize_lebs) {
    Offset size = stream_->offset() - offset - leb_size_guess;
    Offset leb_size = U32Leb128Length(size);
    Offset delta = leb_size - leb_size_guess;
    if (delta != 0) {
      Offset src_offset = offset + leb_size_guess;
      Offset dst_offset = offset + leb_size;
      stream_->MoveData(dst_offset, src_offset, size);
    }
    WriteU32Leb128At(stream_, offset, size, desc);
    stream_->AddOffset(delta);
    return delta;
  } else {
    Offset size = stream_->offset() - offset - MAX_U32_LEB128_BYTES;
    WriteFixedU32Leb128At(stream_, offset, size, desc);
    return 0;
  }
}

void BinaryWriter::WriteBlockDecl(const BlockDeclaration& decl) {
  if (decl.sig.GetNumParams() == 0 && decl.sig.GetNumResults() <= 1) {
    if (decl.sig.GetNumResults() == 0) {
      WriteType(stream_, Type::Void);
    } else if (decl.sig.GetNumResults() == 1) {
      WriteType(stream_, decl.sig.GetResultType(0));
    }
    return;
  }

  Index index = decl.has_func_type ? module_->GetFuncTypeIndex(decl.type_var)
                                   : module_->GetFuncTypeIndex(decl.sig);
  assert(index != kInvalidIndex);
  WriteS32Leb128WithReloc(index, "block type function index",
                          RelocType::TypeIndexLEB);
}

void BinaryWriter::WriteSectionHeader(const char* desc,
                                      BinarySection section_code) {
  assert(last_section_leb_size_guess_ == 0);
  WriteHeader(desc, PRINT_HEADER_NO_INDEX);
  stream_->WriteU8Enum(section_code, "section code");
  last_section_type_ = section_code;
  last_section_leb_size_guess_ = LEB_SECTION_SIZE_GUESS;
  last_section_offset_ =
      WriteU32Leb128Space(LEB_SECTION_SIZE_GUESS, "section size (guess)");
  last_section_payload_offset_ = stream_->offset();
}

void BinaryWriter::BeginKnownSection(BinarySection section_code) {
  char desc[100];
  wabt_snprintf(desc, sizeof(desc), "section \"%s\" (%u)",
                GetSectionName(section_code),
                static_cast<unsigned>(section_code));
  WriteSectionHeader(desc, section_code);
}

void BinaryWriter::BeginCustomSection(const char* name) {
  char desc[100];
  wabt_snprintf(desc, sizeof(desc), "section \"%s\"", name);
  WriteSectionHeader(desc, BinarySection::Custom);
  WriteStr(stream_, name, "custom section name", PrintChars::Yes);
}

void BinaryWriter::EndSection() {
  assert(last_section_leb_size_guess_ != 0);
  WriteFixupU32Leb128Size(last_section_offset_, last_section_leb_size_guess_,
                          "FIXUP section size");
  last_section_leb_size_guess_ = 0;
  section_count_++;
}

void BinaryWriter::BeginSubsection(const char* name) {
  assert(last_subsection_leb_size_guess_ == 0);
  last_subsection_leb_size_guess_ = LEB_SECTION_SIZE_GUESS;
  last_subsection_offset_ =
      WriteU32Leb128Space(LEB_SECTION_SIZE_GUESS, "subsection size (guess)");
  last_subsection_payload_offset_ = stream_->offset();
}

void BinaryWriter::EndSubsection() {
  assert(last_subsection_leb_size_guess_ != 0);
  WriteFixupU32Leb128Size(last_subsection_offset_,
                          last_subsection_leb_size_guess_,
                          "FIXUP subsection size");
  last_subsection_leb_size_guess_ = 0;
}

Index BinaryWriter::GetLabelVarDepth(const Var* var) {
  return var->index();
}

Index BinaryWriter::GetTagVarDepth(const Var* var) {
  return var->index();
}

Index BinaryWriter::GetSymbolIndex(RelocType reloc_type, Index index) {
  switch (reloc_type) {
    case RelocType::FuncIndexLEB:
      return symtab_.FunctionSymbolIndex(index);
    case RelocType::TableNumberLEB:
      return symtab_.TableSymbolIndex(index);
    case RelocType::GlobalIndexLEB:
      return symtab_.GlobalSymbolIndex(index);
    case RelocType::TypeIndexLEB:
      // Type indexes don't create entries in the symbol table; instead their
      // index is used directly.
      return index;
    default:
      fprintf(stderr, "warning: unsupported relocation type: %s\n",
              GetRelocTypeName(reloc_type));
      return kInvalidIndex;
  }
}

void BinaryWriter::AddReloc(RelocType reloc_type, Index index) {
  // Add a new reloc section if needed
  if (!current_reloc_section_ ||
      current_reloc_section_->section_index != section_count_) {
    reloc_sections_.emplace_back(GetSectionName(last_section_type_),
                                 section_count_);
    current_reloc_section_ = &reloc_sections_.back();
  }

  // Add a new relocation to the curent reloc section
  size_t offset = stream_->offset() - last_section_payload_offset_;
  Index symbol_index = GetSymbolIndex(reloc_type, index);
  if (symbol_index == kInvalidIndex) {
    // The file is invalid, for example a reference to function 42 where only 10
    // functions are defined.  The user must have already passed --no-check, so
    // no extra warning here is needed.
    return;
  }
  current_reloc_section_->relocations.emplace_back(reloc_type, offset,
                                                   symbol_index);
}

void BinaryWriter::WriteU32Leb128WithReloc(Index index,
                                           const char* desc,
                                           RelocType reloc_type) {
  if (options_.relocatable) {
    AddReloc(reloc_type, index);
    WriteFixedU32Leb128(stream_, index, desc);
  } else {
    WriteU32Leb128(stream_, index, desc);
  }
}

void BinaryWriter::WriteS32Leb128WithReloc(int32_t value,
                                           const char* desc,
                                           RelocType reloc_type) {
  if (options_.relocatable) {
    AddReloc(reloc_type, value);
    WriteFixedS32Leb128(stream_, value, desc);
  } else {
    WriteS32Leb128(stream_, value, desc);
  }
}

void BinaryWriter::WriteTableNumberWithReloc(Index value, const char* desc) {
  // Unless reference types are enabled, all references to tables refer to table
  // 0, so no relocs need be emitted when making relocatable binaries.
  if (options_.relocatable && options_.features.reference_types_enabled()) {
    AddReloc(RelocType::TableNumberLEB, value);
    WriteFixedS32Leb128(stream_, value, desc);
  } else {
    WriteS32Leb128(stream_, value, desc);
  }
}

Index BinaryWriter::GetLocalIndex(const Func* func, const Var& var) {
  // func can be nullptr when using local.get/local.set/local.tee in an
  // init_expr.
  if (func) {
    return func->GetLocalIndex(var);
  } else if (var.is_index()) {
    return var.index();
  } else {
    return kInvalidIndex;
  }
}

// TODO(binji): Rename this, it is used for more than loads/stores now.
template <typename T>
void BinaryWriter::WriteLoadStoreExpr(const Func* func,
                                      const Expr* expr,
                                      const char* desc) {
  auto* typed_expr = cast<T>(expr);
  WriteOpcode(stream_, typed_expr->opcode);
  Address align = typed_expr->opcode.GetAlignment(typed_expr->align);
  Index memidx = module_->GetMemoryIndex(typed_expr->memidx);
  if (memidx != 0) {
    stream_->WriteU8(log2_u32(align) | (1 << 6), "alignment");
    WriteU32Leb128(stream_, memidx, "memidx");
  } else {
    stream_->WriteU8(log2_u32(align), "alignment");
  }
  WriteU32Leb128(stream_, typed_expr->offset, desc);
}

template <typename T>
void BinaryWriter::WriteSimdLoadStoreLaneExpr(const Func* func,
                                              const Expr* expr,
                                              const char* desc) {
  WriteLoadStoreExpr<T>(func, expr, desc);
  auto* typed_expr = cast<T>(expr);
  stream_->WriteU8(static_cast<uint8_t>(typed_expr->val), "Simd Lane literal");
}

void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) {
  switch (expr->type()) {
    case ExprType::AtomicLoad:
      WriteLoadStoreExpr<AtomicLoadExpr>(func, expr, "memory offset");
      break;
    case ExprType::AtomicRmw:
      WriteLoadStoreExpr<AtomicRmwExpr>(func, expr, "memory offset");
      break;
    case ExprType::AtomicRmwCmpxchg:
      WriteLoadStoreExpr<AtomicRmwCmpxchgExpr>(func, expr, "memory offset");
      break;
    case ExprType::AtomicStore:
      WriteLoadStoreExpr<AtomicStoreExpr>(func, expr, "memory offset");
      break;
    case ExprType::AtomicWait:
      WriteLoadStoreExpr<AtomicWaitExpr>(func, expr, "memory offset");
      break;
    case ExprType::AtomicFence: {
      auto* fence_expr = cast<AtomicFenceExpr>(expr);
      WriteOpcode(stream_, Opcode::AtomicFence);
      WriteU32Leb128(stream_, fence_expr->consistency_model,
                     "consistency model");
      break;
    }
    case ExprType::AtomicNotify:
      WriteLoadStoreExpr<AtomicNotifyExpr>(func, expr, "memory offset");
      break;
    case ExprType::Binary:
      WriteOpcode(stream_, cast<BinaryExpr>(expr)->opcode);
      break;
    case ExprType::Block:
      WriteOpcode(stream_, Opcode::Block);
      WriteBlockDecl(cast<BlockExpr>(expr)->block.decl);
      WriteExprList(func, cast<BlockExpr>(expr)->block.exprs);
      WriteOpcode(stream_, Opcode::End);
      break;
    case ExprType::Br:
      WriteOpcode(stream_, Opcode::Br);
      WriteU32Leb128(stream_, GetLabelVarDepth(&cast<BrExpr>(expr)->var),
                     "break depth");
      break;
    case ExprType::BrIf:
      WriteOpcode(stream_, Opcode::BrIf);
      WriteU32Leb128(stream_, GetLabelVarDepth(&cast<BrIfExpr>(expr)->var),
                     "break depth");
      break;
    case ExprType::BrTable: {
      auto* br_table_expr = cast<BrTableExpr>(expr);
      WriteOpcode(stream_, Opcode::BrTable);
      WriteU32Leb128(stream_, br_table_expr->targets.size(), "num targets");
      Index depth;
      for (const Var& var : br_table_expr->targets) {
        depth = GetLabelVarDepth(&var);
        WriteU32Leb128(stream_, depth, "break depth");
      }
      depth = GetLabelVarDepth(&br_table_expr->default_target);
      WriteU32Leb128(stream_, depth, "break depth for default");
      break;
    }
    case ExprType::Call: {
      Index index = module_->GetFuncIndex(cast<CallExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::Call);
      WriteU32Leb128WithReloc(index, "function index", RelocType::FuncIndexLEB);
      break;
    }
    case ExprType::ReturnCall: {
      Index index = module_->GetFuncIndex(cast<ReturnCallExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::ReturnCall);
      WriteU32Leb128WithReloc(index, "function index", RelocType::FuncIndexLEB);
      break;
    }
    case ExprType::CallIndirect: {
      Index sig_index =
          module_->GetFuncTypeIndex(cast<CallIndirectExpr>(expr)->decl);
      Index table_index =
          module_->GetTableIndex(cast<CallIndirectExpr>(expr)->table);
      WriteOpcode(stream_, Opcode::CallIndirect);
      WriteU32Leb128WithReloc(sig_index, "signature index",
                              RelocType::TypeIndexLEB);
      WriteTableNumberWithReloc(table_index, "table index");
      break;
    }
    case ExprType::CallRef: {
      WriteOpcode(stream_, Opcode::CallRef);
      break;
    }
    case ExprType::ReturnCallIndirect: {
      Index sig_index =
          module_->GetFuncTypeIndex(cast<ReturnCallIndirectExpr>(expr)->decl);
      Index table_index =
          module_->GetTableIndex(cast<ReturnCallIndirectExpr>(expr)->table);
      WriteOpcode(stream_, Opcode::ReturnCallIndirect);
      WriteU32Leb128WithReloc(sig_index, "signature index",
                              RelocType::TypeIndexLEB);
      WriteTableNumberWithReloc(table_index, "table index");
      break;
    }
    case ExprType::Compare:
      WriteOpcode(stream_, cast<CompareExpr>(expr)->opcode);
      break;
    case ExprType::Const: {
      const Const& const_ = cast<ConstExpr>(expr)->const_;
      switch (const_.type()) {
        case Type::I32: {
          WriteOpcode(stream_, Opcode::I32Const);
          WriteS32Leb128(stream_, const_.u32(), "i32 literal");
          break;
        }
        case Type::I64:
          WriteOpcode(stream_, Opcode::I64Const);
          WriteS64Leb128(stream_, const_.u64(), "i64 literal");
          break;
        case Type::F32:
          WriteOpcode(stream_, Opcode::F32Const);
          stream_->WriteU32(const_.f32_bits(), "f32 literal");
          break;
        case Type::F64:
          WriteOpcode(stream_, Opcode::F64Const);
          stream_->WriteU64(const_.f64_bits(), "f64 literal");
          break;
        case Type::V128:
          WriteOpcode(stream_, Opcode::V128Const);
          stream_->WriteU128(const_.vec128(), "v128 literal");
          break;
        default:
          assert(0);
      }
      break;
    }
    case ExprType::Convert:
      WriteOpcode(stream_, cast<ConvertExpr>(expr)->opcode);
      break;
    case ExprType::Drop:
      WriteOpcode(stream_, Opcode::Drop);
      break;
    case ExprType::GlobalGet: {
      Index index = module_->GetGlobalIndex(cast<GlobalGetExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::GlobalGet);
      WriteU32Leb128WithReloc(index, "global index", RelocType::GlobalIndexLEB);
      break;
    }
    case ExprType::GlobalSet: {
      Index index = module_->GetGlobalIndex(cast<GlobalSetExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::GlobalSet);
      WriteU32Leb128WithReloc(index, "global index", RelocType::GlobalIndexLEB);
      break;
    }
    case ExprType::If: {
      auto* if_expr = cast<IfExpr>(expr);
      WriteOpcode(stream_, Opcode::If);
      WriteBlockDecl(if_expr->true_.decl);
      WriteExprList(func, if_expr->true_.exprs);
      if (!if_expr->false_.empty()) {
        WriteOpcode(stream_, Opcode::Else);
        WriteExprList(func, if_expr->false_);
      }
      WriteOpcode(stream_, Opcode::End);
      break;
    }
    case ExprType::Load:
      WriteLoadStoreExpr<LoadExpr>(func, expr, "load offset");
      break;
    case ExprType::LocalGet: {
      Index index = GetLocalIndex(func, cast<LocalGetExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::LocalGet);
      WriteU32Leb128(stream_, index, "local index");
      break;
    }
    case ExprType::LocalSet: {
      Index index = GetLocalIndex(func, cast<LocalSetExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::LocalSet);
      WriteU32Leb128(stream_, index, "local index");
      break;
    }
    case ExprType::LocalTee: {
      Index index = GetLocalIndex(func, cast<LocalTeeExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::LocalTee);
      WriteU32Leb128(stream_, index, "local index");
      break;
    }
    case ExprType::Loop:
      WriteOpcode(stream_, Opcode::Loop);
      WriteBlockDecl(cast<LoopExpr>(expr)->block.decl);
      WriteExprList(func, cast<LoopExpr>(expr)->block.exprs);
      WriteOpcode(stream_, Opcode::End);
      break;
    case ExprType::MemoryCopy: {
      Index srcmemidx =
          module_->GetMemoryIndex(cast<MemoryCopyExpr>(expr)->srcmemidx);
      Index destmemidx =
          module_->GetMemoryIndex(cast<MemoryCopyExpr>(expr)->destmemidx);
      WriteOpcode(stream_, Opcode::MemoryCopy);
      WriteU32Leb128(stream_, srcmemidx, "memory.copy srcmemidx");
      WriteU32Leb128(stream_, destmemidx, "memory.copy destmemidx");
      break;
    }
    case ExprType::DataDrop: {
      Index index = module_->GetDataSegmentIndex(cast<DataDropExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::DataDrop);
      WriteU32Leb128(stream_, index, "data.drop segment");
      has_data_segment_instruction_ = true;
      break;
    }
    case ExprType::MemoryFill: {
      Index memidx =
          module_->GetMemoryIndex(cast<MemoryFillExpr>(expr)->memidx);
      WriteOpcode(stream_, Opcode::MemoryFill);
      WriteU32Leb128(stream_, memidx, "memory.fill memidx");
      break;
    }
    case ExprType::MemoryGrow: {
      Index memidx =
          module_->GetMemoryIndex(cast<MemoryGrowExpr>(expr)->memidx);
      WriteOpcode(stream_, Opcode::MemoryGrow);
      WriteU32Leb128(stream_, memidx, "memory.grow memidx");
      break;
    }
    case ExprType::MemoryInit: {
      Index index =
          module_->GetDataSegmentIndex(cast<MemoryInitExpr>(expr)->var);
      Index memidx =
          module_->GetMemoryIndex(cast<MemoryInitExpr>(expr)->memidx);
      WriteOpcode(stream_, Opcode::MemoryInit);
      WriteU32Leb128(stream_, index, "memory.init segment");
      WriteU32Leb128(stream_, memidx, "memory.init memidx");
      has_data_segment_instruction_ = true;
      break;
    }
    case ExprType::MemorySize: {
      Index memidx =
          module_->GetMemoryIndex(cast<MemorySizeExpr>(expr)->memidx);
      WriteOpcode(stream_, Opcode::MemorySize);
      WriteU32Leb128(stream_, memidx, "memory.size memidx");
      break;
    }
    case ExprType::TableCopy: {
      auto* copy_expr = cast<TableCopyExpr>(expr);
      Index dst = module_->GetTableIndex(copy_expr->dst_table);
      Index src = module_->GetTableIndex(copy_expr->src_table);
      WriteOpcode(stream_, Opcode::TableCopy);
      WriteTableNumberWithReloc(dst, "table.copy dst_table");
      WriteTableNumberWithReloc(src, "table.copy src_table");
      break;
    }
    case ExprType::ElemDrop: {
      Index index = module_->GetElemSegmentIndex(cast<ElemDropExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::ElemDrop);
      WriteU32Leb128(stream_, index, "elem.drop segment");
      break;
    }
    case ExprType::TableInit: {
      auto* init_expr = cast<TableInitExpr>(expr);
      Index table_index = module_->GetTableIndex(init_expr->table_index);
      Index segment_index =
          module_->GetElemSegmentIndex(init_expr->segment_index);
      WriteOpcode(stream_, Opcode::TableInit);
      WriteU32Leb128(stream_, segment_index, "table.init segment");
      WriteTableNumberWithReloc(table_index, "table.init table");
      break;
    }
    case ExprType::TableGet: {
      Index index = module_->GetTableIndex(cast<TableGetExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableGet);
      WriteTableNumberWithReloc(index, "table.get table index");
      break;
    }
    case ExprType::TableSet: {
      Index index = module_->GetTableIndex(cast<TableSetExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableSet);
      WriteTableNumberWithReloc(index, "table.set table index");
      break;
    }
    case ExprType::TableGrow: {
      Index index = module_->GetTableIndex(cast<TableGrowExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableGrow);
      WriteTableNumberWithReloc(index, "table.grow table index");
      break;
    }
    case ExprType::TableSize: {
      Index index = module_->GetTableIndex(cast<TableSizeExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableSize);
      WriteTableNumberWithReloc(index, "table.size table index");
      break;
    }
    case ExprType::TableFill: {
      Index index = module_->GetTableIndex(cast<TableFillExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableFill);
      WriteTableNumberWithReloc(index, "table.fill table index");
      break;
    }
    case ExprType::RefFunc: {
      WriteOpcode(stream_, Opcode::RefFunc);
      Index index = module_->GetFuncIndex(cast<RefFuncExpr>(expr)->var);
      WriteU32Leb128WithReloc(index, "function index", RelocType::FuncIndexLEB);
      break;
    }
    case ExprType::RefNull: {
      WriteOpcode(stream_, Opcode::RefNull);
      WriteType(stream_, cast<RefNullExpr>(expr)->type, "ref.null type");
      break;
    }
    case ExprType::RefIsNull:
      WriteOpcode(stream_, Opcode::RefIsNull);
      break;
    case ExprType::Nop:
      WriteOpcode(stream_, Opcode::Nop);
      break;
    case ExprType::Rethrow:
      WriteOpcode(stream_, Opcode::Rethrow);
      WriteU32Leb128(stream_, GetLabelVarDepth(&cast<RethrowExpr>(expr)->var),
                     "rethrow depth");
      break;
    case ExprType::Return:
      WriteOpcode(stream_, Opcode::Return);
      break;
    case ExprType::Select: {
      auto* select_expr = cast<SelectExpr>(expr);
      if (select_expr->result_type.empty()) {
        WriteOpcode(stream_, Opcode::Select);
      } else {
        WriteOpcode(stream_, Opcode::SelectT);
        WriteU32Leb128(stream_, select_expr->result_type.size(),
                       "num result types");
        for (Type t : select_expr->result_type) {
          WriteType(stream_, t, "result type");
        }
      }
      break;
    }
    case ExprType::Store:
      WriteLoadStoreExpr<StoreExpr>(func, expr, "store offset");
      break;
    case ExprType::Throw:
      WriteOpcode(stream_, Opcode::Throw);
      WriteU32Leb128(stream_, GetTagVarDepth(&cast<ThrowExpr>(expr)->var),
                     "throw tag");
      break;
    case ExprType::Try: {
      auto* try_expr = cast<TryExpr>(expr);
      WriteOpcode(stream_, Opcode::Try);
      WriteBlockDecl(try_expr->block.decl);
      WriteExprList(func, try_expr->block.exprs);
      switch (try_expr->kind) {
        case TryKind::Catch:
          for (const Catch& catch_ : try_expr->catches) {
            if (catch_.IsCatchAll()) {
              WriteOpcode(stream_, Opcode::CatchAll);
            } else {
              WriteOpcode(stream_, Opcode::Catch);
              WriteU32Leb128(stream_, GetTagVarDepth(&catch_.var), "catch tag");
            }
            WriteExprList(func, catch_.exprs);
          }
          WriteOpcode(stream_, Opcode::End);
          break;
        case TryKind::Delegate:
          WriteOpcode(stream_, Opcode::Delegate);
          WriteU32Leb128(stream_, GetLabelVarDepth(&try_expr->delegate_target),
                         "delegate depth");
          break;
        case TryKind::Plain:
          WriteOpcode(stream_, Opcode::End);
          break;
      }
      break;
    }
    case ExprType::Unary:
      WriteOpcode(stream_, cast<UnaryExpr>(expr)->opcode);
      break;
    case ExprType::Ternary:
      WriteOpcode(stream_, cast<TernaryExpr>(expr)->opcode);
      break;
    case ExprType::SimdLaneOp: {
      const Opcode opcode = cast<SimdLaneOpExpr>(expr)->opcode;
      WriteOpcode(stream_, opcode);
      stream_->WriteU8(static_cast<uint8_t>(cast<SimdLaneOpExpr>(expr)->val),
                       "Simd Lane literal");
      break;
    }
    case ExprType::SimdLoadLane: {
      WriteSimdLoadStoreLaneExpr<SimdLoadLaneExpr>(func, expr, "load offset");
      break;
    }
    case ExprType::SimdStoreLane: {
      WriteSimdLoadStoreLaneExpr<SimdStoreLaneExpr>(func, expr, "store offset");
      break;
    }
    case ExprType::SimdShuffleOp: {
      const Opcode opcode = cast<SimdShuffleOpExpr>(expr)->opcode;
      WriteOpcode(stream_, opcode);
      stream_->WriteU128(cast<SimdShuffleOpExpr>(expr)->val,
                         "Simd Lane[16] literal");
      break;
    }
    case ExprType::LoadSplat:
      WriteLoadStoreExpr<LoadSplatExpr>(func, expr, "load offset");
      break;
    case ExprType::LoadZero:
      WriteLoadStoreExpr<LoadZeroExpr>(func, expr, "load offset");
      break;
    case ExprType::Unreachable:
      WriteOpcode(stream_, Opcode::Unreachable);
      break;
    case ExprType::CodeMetadata: {
      auto* meta_expr = cast<CodeMetadataExpr>(expr);
      auto& s = code_metadata_sections_[meta_expr->name];
      if (s.entries.empty() || s.entries.back().func_idx != cur_func_index_) {
        s.entries.emplace_back(cur_func_index_);
      }
      auto& a = s.entries.back();
      Offset code_offset = stream_->offset() - cur_func_start_offset_;
      a.entries.emplace_back(code_offset, meta_expr->data);
      break;
    }
  }
}

void BinaryWriter::WriteExprList(const Func* func, const ExprList& exprs) {
  for (const Expr& expr : exprs) {
    WriteExpr(func, &expr);
  }
}

void BinaryWriter::WriteInitExpr(const ExprList& expr) {
  WriteExprList(nullptr, expr);
  WriteOpcode(stream_, Opcode::End);
}

void BinaryWriter::WriteFuncLocals(const Func* func,
                                   const LocalTypes& local_types) {
  if (local_types.size() == 0) {
    WriteU32Leb128(stream_, 0, "local decl count");
    return;
  }

  Index local_decl_count = local_types.decls().size();
  WriteU32Leb128(stream_, local_decl_count, "local decl count");
  for (auto decl : local_types.decls()) {
    WriteU32Leb128(stream_, decl.second, "local type count");
    WriteType(stream_, decl.first);
  }
}

void BinaryWriter::WriteFunc(const Func* func) {
  WriteFuncLocals(func, func->local_types);
  WriteExprList(func, func->exprs);
  WriteOpcode(stream_, Opcode::End);
}

void BinaryWriter::WriteTable(const Table* table) {
  WriteType(stream_, table->elem_type);
  WriteLimits(stream_, &table->elem_limits);
}

void BinaryWriter::WriteMemory(const Memory* memory) {
  WriteLimits(stream_, &memory->page_limits);
}

void BinaryWriter::WriteGlobalHeader(const Global* global) {
  WriteType(stream_, global->type);
  stream_->WriteU8(global->mutable_, "global mutability");
}

void BinaryWriter::WriteTagType(const Tag* tag) {
  stream_->WriteU8(0, "tag attribute");
  WriteU32Leb128(stream_, module_->GetFuncTypeIndex(tag->decl),
                 "tag signature index");
}

void BinaryWriter::WriteRelocSection(const RelocSection* reloc_section) {
  char section_name[128];
  wabt_snprintf(section_name, sizeof(section_name), "%s.%s",
                WABT_BINARY_SECTION_RELOC, reloc_section->name);
  BeginCustomSection(section_name);
  WriteU32Leb128(stream_, reloc_section->section_index, "reloc section index");
  const std::vector<Reloc>& relocs = reloc_section->relocations;
  WriteU32Leb128(stream_, relocs.size(), "num relocs");

  for (const Reloc& reloc : relocs) {
    WriteU32Leb128(stream_, reloc.type, "reloc type");
    WriteU32Leb128(stream_, reloc.offset, "reloc offset");
    WriteU32Leb128(stream_, reloc.index, "reloc index");
    switch (reloc.type) {
      case RelocType::MemoryAddressLEB:
      case RelocType::MemoryAddressLEB64:
      case RelocType::MemoryAddressSLEB:
      case RelocType::MemoryAddressSLEB64:
      case RelocType::MemoryAddressRelSLEB:
      case RelocType::MemoryAddressRelSLEB64:
      case RelocType::MemoryAddressI32:
      case RelocType::MemoryAddressI64:
      case RelocType::FunctionOffsetI32:
      case RelocType::SectionOffsetI32:
      case RelocType::MemoryAddressTLSSLEB:
      case RelocType::MemoryAddressTLSI32:
        WriteU32Leb128(stream_, reloc.addend, "reloc addend");
        break;
      case RelocType::FuncIndexLEB:
      case RelocType::TableIndexSLEB:
      case RelocType::TableIndexSLEB64:
      case RelocType::TableIndexI32:
      case RelocType::TableIndexI64:
      case RelocType::TypeIndexLEB:
      case RelocType::GlobalIndexLEB:
      case RelocType::TagIndexLEB:
      case RelocType::TableIndexRelSLEB:
      case RelocType::TableNumberLEB:
        break;
      default:
        fprintf(stderr, "warning: unsupported relocation type: %s\n",
                GetRelocTypeName(reloc.type));
    }
  }

  EndSection();
}

void BinaryWriter::WriteLinkingSection() {
  BeginCustomSection(WABT_BINARY_SECTION_LINKING);
  WriteU32Leb128(stream_, 2, "metadata version");
  const std::vector<Symbol>& symbols = symtab_.symbols();
  if (symbols.size()) {
    stream_->WriteU8Enum(LinkingEntryType::SymbolTable, "symbol table");
    BeginSubsection("symbol table");
    WriteU32Leb128(stream_, symbols.size(), "num symbols");

    for (const Symbol& sym : symbols) {
      stream_->WriteU8Enum(sym.type(), "symbol type");
      WriteU32Leb128(stream_, sym.flags(), "symbol flags");
      switch (sym.type()) {
        case SymbolType::Function:
          WriteU32Leb128(stream_, sym.AsFunction().index, "function index");
          if (sym.defined() || sym.explicit_name()) {
            WriteStr(stream_, sym.name(), "function name", PrintChars::Yes);
          }
          break;
        case SymbolType::Data:
          WriteStr(stream_, sym.name(), "data name", PrintChars::Yes);
          if (sym.defined()) {
            WriteU32Leb128(stream_, sym.AsData().index, "data index");
            WriteU32Leb128(stream_, sym.AsData().offset, "data offset");
            WriteU32Leb128(stream_, sym.AsData().size, "data size");
          }
          break;
        case SymbolType::Global:
          WriteU32Leb128(stream_, sym.AsGlobal().index, "global index");
          if (sym.defined() || sym.explicit_name()) {
            WriteStr(stream_, sym.name(), "global name", PrintChars::Yes);
          }
          break;
        case SymbolType::Section:
          WriteU32Leb128(stream_, sym.AsSection().section, "section index");
          break;
        case SymbolType::Tag:
          WriteU32Leb128(stream_, sym.AsTag().index, "tag index");
          if (sym.defined() || sym.explicit_name()) {
            WriteStr(stream_, sym.name(), "tag name", PrintChars::Yes);
          }
          break;
        case SymbolType::Table:
          WriteU32Leb128(stream_, sym.AsTable().index, "table index");
          if (sym.defined() || sym.explicit_name()) {
            WriteStr(stream_, sym.name(), "table name", PrintChars::Yes);
          }
          break;
      }
    }
    EndSubsection();
  }
  EndSection();
}

template <typename T>
void BinaryWriter::WriteNames(const std::vector<T*>& elems,
                              NameSectionSubsection type) {
  size_t num_named_elems = 0;
  for (const T* elem : elems) {
    if (!elem->name.empty()) {
      num_named_elems++;
    }
  }

  if (!num_named_elems) {
    return;
  }

  WriteU32Leb128(stream_, type, "name subsection type");
  BeginSubsection("name subsection");

  char desc[100];
  WriteU32Leb128(stream_, num_named_elems, "num names");
  for (size_t i = 0; i < elems.size(); ++i) {
    const T* elem = elems[i];
    if (elem->name.empty()) {
      continue;
    }
    WriteU32Leb128(stream_, i, "elem index");
    wabt_snprintf(desc, sizeof(desc), "elem name %" PRIzd, i);
    WriteDebugName(stream_, elem->name, desc);
  }
  EndSubsection();
}

Result BinaryWriter::WriteModule() {
  stream_->WriteU32(WABT_BINARY_MAGIC, "WASM_BINARY_MAGIC");
  stream_->WriteU32(WABT_BINARY_VERSION, "WASM_BINARY_VERSION");

  if (options_.relocatable) {
    CHECK_RESULT(symtab_.Populate(module_));
  }

  if (module_->types.size()) {
    BeginKnownSection(BinarySection::Type);
    WriteU32Leb128(stream_, module_->types.size(), "num types");
    for (size_t i = 0; i < module_->types.size(); ++i) {
      const TypeEntry* type = module_->types[i];
      switch (type->kind()) {
        case TypeEntryKind::Func: {
          const FuncType* func_type = cast<FuncType>(type);
          const FuncSignature* sig = &func_type->sig;
          WriteHeader("func type", i);
          WriteType(stream_, Type::Func);

          Index num_params = sig->param_types.size();
          Index num_results = sig->result_types.size();
          WriteU32Leb128(stream_, num_params, "num params");
          for (size_t j = 0; j < num_params; ++j) {
            WriteType(stream_, sig->param_types[j]);
          }

          WriteU32Leb128(stream_, num_results, "num results");
          for (size_t j = 0; j < num_results; ++j) {
            WriteType(stream_, sig->result_types[j]);
          }
          break;
        }

        case TypeEntryKind::Struct: {
          const StructType* struct_type = cast<StructType>(type);
          WriteHeader("struct type", i);
          WriteType(stream_, Type::Struct);
          Index num_fields = struct_type->fields.size();
          WriteU32Leb128(stream_, num_fields, "num fields");
          for (size_t j = 0; j < num_fields; ++j) {
            const Field& field = struct_type->fields[j];
            WriteType(stream_, field.type);
            stream_->WriteU8(field.mutable_, "field mutability");
          }
          break;
        }

        case TypeEntryKind::Array: {
          const ArrayType* array_type = cast<ArrayType>(type);
          WriteHeader("array type", i);
          WriteType(stream_, Type::Array);
          WriteType(stream_, array_type->field.type);
          stream_->WriteU8(array_type->field.mutable_, "field mutability");
          break;
        }
      }
    }
    EndSection();
  }

  if (module_->imports.size()) {
    BeginKnownSection(BinarySection::Import);
    WriteU32Leb128(stream_, module_->imports.size(), "num imports");

    for (size_t i = 0; i < module_->imports.size(); ++i) {
      const Import* import = module_->imports[i];
      WriteHeader("import header", i);
      WriteStr(stream_, import->module_name, "import module name",
               PrintChars::Yes);
      WriteStr(stream_, import->field_name, "import field name",
               PrintChars::Yes);
      stream_->WriteU8Enum(import->kind(), "import kind");
      switch (import->kind()) {
        case ExternalKind::Func:
          WriteU32Leb128(
              stream_,
              module_->GetFuncTypeIndex(cast<FuncImport>(import)->func.decl),
              "import signature index");
          break;

        case ExternalKind::Table:
          WriteTable(&cast<TableImport>(import)->table);
          break;

        case ExternalKind::Memory:
          WriteMemory(&cast<MemoryImport>(import)->memory);
          break;

        case ExternalKind::Global:
          WriteGlobalHeader(&cast<GlobalImport>(import)->global);
          break;

        case ExternalKind::Tag:
          WriteTagType(&cast<TagImport>(import)->tag);
          break;
      }
    }
    EndSection();
  }

  assert(module_->funcs.size() >= module_->num_func_imports);
  Index num_funcs = module_->funcs.size() - module_->num_func_imports;
  if (num_funcs) {
    BeginKnownSection(BinarySection::Function);
    WriteU32Leb128(stream_, num_funcs, "num functions");

    for (size_t i = 0; i < num_funcs; ++i) {
      const Func* func = module_->funcs[i + module_->num_func_imports];
      char desc[100];
      wabt_snprintf(desc, sizeof(desc), "function %" PRIzd " signature index",
                    i);
      WriteU32Leb128(stream_, module_->GetFuncTypeIndex(func->decl), desc);
    }
    EndSection();
  }

  assert(module_->tables.size() >= module_->num_table_imports);
  Index num_tables = module_->tables.size() - module_->num_table_imports;
  if (num_tables) {
    BeginKnownSection(BinarySection::Table);
    WriteU32Leb128(stream_, num_tables, "num tables");
    for (size_t i = 0; i < num_tables; ++i) {
      const Table* table = module_->tables[i + module_->num_table_imports];
      WriteHeader("table", i);
      WriteTable(table);
    }
    EndSection();
  }

  assert(module_->memories.size() >= module_->num_memory_imports);
  Index num_memories = module_->memories.size() - module_->num_memory_imports;
  if (num_memories) {
    BeginKnownSection(BinarySection::Memory);
    WriteU32Leb128(stream_, num_memories, "num memories");
    for (size_t i = 0; i < num_memories; ++i) {
      const Memory* memory = module_->memories[i + module_->num_memory_imports];
      WriteHeader("memory", i);
      WriteMemory(memory);
    }
    EndSection();
  }

  assert(module_->tags.size() >= module_->num_tag_imports);
  Index num_tags = module_->tags.size() - module_->num_tag_imports;
  if (num_tags) {
    BeginKnownSection(BinarySection::Tag);
    WriteU32Leb128(stream_, num_tags, "tag count");
    for (size_t i = 0; i < num_tags; ++i) {
      WriteHeader("tag", i);
      const Tag* tag = module_->tags[i + module_->num_tag_imports];
      WriteTagType(tag);
    }
    EndSection();
  }

  assert(module_->globals.size() >= module_->num_global_imports);
  Index num_globals = module_->globals.size() - module_->num_global_imports;
  if (num_globals) {
    BeginKnownSection(BinarySection::Global);
    WriteU32Leb128(stream_, num_globals, "num globals");

    for (size_t i = 0; i < num_globals; ++i) {
      const Global* global = module_->globals[i + module_->num_global_imports];
      WriteGlobalHeader(global);
      WriteInitExpr(global->init_expr);
    }
    EndSection();
  }

  if (module_->exports.size()) {
    BeginKnownSection(BinarySection::Export);
    WriteU32Leb128(stream_, module_->exports.size(), "num exports");

    for (const Export* export_ : module_->exports) {
      WriteStr(stream_, export_->name, "export name", PrintChars::Yes);
      stream_->WriteU8Enum(export_->kind, "export kind");
      switch (export_->kind) {
        case ExternalKind::Func: {
          Index index = module_->GetFuncIndex(export_->var);
          WriteU32Leb128(stream_, index, "export func index");
          break;
        }
        case ExternalKind::Table: {
          Index index = module_->GetTableIndex(export_->var);
          WriteU32Leb128(stream_, index, "export table index");
          break;
        }
        case ExternalKind::Memory: {
          Index index = module_->GetMemoryIndex(export_->var);
          WriteU32Leb128(stream_, index, "export memory index");
          break;
        }
        case ExternalKind::Global: {
          Index index = module_->GetGlobalIndex(export_->var);
          WriteU32Leb128(stream_, index, "export global index");
          break;
        }
        case ExternalKind::Tag: {
          Index index = module_->GetTagIndex(export_->var);
          WriteU32Leb128(stream_, index, "export tag index");
          break;
        }
      }
    }
    EndSection();
  }

  if (module_->starts.size()) {
    Index start_func_index = module_->GetFuncIndex(*module_->starts[0]);
    if (start_func_index != kInvalidIndex) {
      BeginKnownSection(BinarySection::Start);
      WriteU32Leb128(stream_, start_func_index, "start func index");
      EndSection();
    }
  }

  if (module_->elem_segments.size()) {
    BeginKnownSection(BinarySection::Elem);
    WriteU32Leb128(stream_, module_->elem_segments.size(), "num elem segments");
    for (size_t i = 0; i < module_->elem_segments.size(); ++i) {
      ElemSegment* segment = module_->elem_segments[i];
      WriteHeader("elem segment header", i);
      // 1. flags
      uint8_t flags = segment->GetFlags(module_);
      stream_->WriteU8(flags, "segment flags");
      // 2. optional target table
      if (flags & SegExplicitIndex && segment->kind != SegmentKind::Declared) {
        WriteU32Leb128(stream_, module_->GetTableIndex(segment->table_var),
                       "table index");
      }
      // 3. optional target location within the table (active segments only)
      if (!(flags & SegPassive)) {
        WriteInitExpr(segment->offset);
      }
      // 4. type of item in the following list (omitted for "legacy" segments)
      if (flags & (SegPassive | SegExplicitIndex)) {
        if (flags & SegUseElemExprs) {
          WriteType(stream_, segment->elem_type, "elem expr list type");
        } else {
          stream_->WriteU8Enum(ExternalKind::Func, "elem list type");
        }
      }
      // 5. actual list of elements (with extern indexes or elem expr's)
      // preceeded by length
      WriteU32Leb128(stream_, segment->elem_exprs.size(), "num elems");
      if (flags & SegUseElemExprs) {
        for (const ExprList& elem_expr : segment->elem_exprs) {
          WriteInitExpr(elem_expr);
        }
      } else {
        for (const ExprList& elem_expr : segment->elem_exprs) {
          assert(elem_expr.size() == 1);
          const Expr* expr = &elem_expr.front();
          assert(expr->type() == ExprType::RefFunc);
          WriteU32Leb128(stream_,
                         module_->GetFuncIndex(cast<RefFuncExpr>(expr)->var),
                         "elem function index");
        }
      }
    }
    EndSection();
  }

  if (options_.features.bulk_memory_enabled() &&
      module_->data_segments.size()) {
    // Keep track of the data count section offset so it can be removed if
    // it isn't needed.
    data_count_start_ = stream_->offset();
    BeginKnownSection(BinarySection::DataCount);
    WriteU32Leb128(stream_, module_->data_segments.size(), "data count");
    EndSection();
    data_count_end_ = stream_->offset();
  }

  if (num_funcs) {
    code_start_ = stream_->offset();
    BeginKnownSection(BinarySection::Code);
    WriteU32Leb128(stream_, num_funcs, "num functions");

    for (size_t i = 0; i < num_funcs; ++i) {
      cur_func_index_ = i + module_->num_func_imports;
      WriteHeader("function body", i);
      const Func* func = module_->funcs[cur_func_index_];

      /* TODO(binji): better guess of the size of the function body section */
      const Offset leb_size_guess = 1;
      Offset body_size_offset =
          WriteU32Leb128Space(leb_size_guess, "func body size (guess)");
      cur_func_start_offset_ = stream_->offset();
      WriteFunc(func);
      auto func_start_offset = body_size_offset - last_section_payload_offset_;
      auto func_end_offset = stream_->offset() - last_section_payload_offset_;
      auto delta = WriteFixupU32Leb128Size(body_size_offset, leb_size_guess,
                                           "FIXUP func body size");
      if (current_reloc_section_ && delta != 0) {
        for (Reloc& reloc : current_reloc_section_->relocations) {
          if (reloc.offset >= func_start_offset &&
              reloc.offset <= func_end_offset) {
            reloc.offset += delta;
          }
        }
      }
    }
    EndSection();
  }

  // Remove the DataCount section if there are no instructions that require it.
  if (options_.features.bulk_memory_enabled() &&
      module_->data_segments.size() && !has_data_segment_instruction_) {
    Offset size = stream_->offset() - data_count_end_;
    if (size) {
      // If the DataCount section was followed by anything, assert that it's
      // only the Code section.  This limits the amount of fixing-up that we
      // need to do.
      assert(data_count_end_ == code_start_);
      assert(last_section_type_ == BinarySection::Code);
      stream_->MoveData(data_count_start_, data_count_end_, size);
      code_start_ = data_count_start_;
    }
    stream_->Truncate(data_count_start_ + size);

    --section_count_;

    // We just effectively decremented the code section's index; adjust anything
    // that might have captured it.
    for (RelocSection& section : reloc_sections_) {
      if (section.section_index == section_count_) {
        assert(last_section_type_ == BinarySection::Code);
        --section.section_index;
      }
    }
  }

  WriteCodeMetadataSections();

  if (module_->data_segments.size()) {
    BeginKnownSection(BinarySection::Data);
    WriteU32Leb128(stream_, module_->data_segments.size(), "num data segments");
    for (size_t i = 0; i < module_->data_segments.size(); ++i) {
      const DataSegment* segment = module_->data_segments[i];
      WriteHeader("data segment header", i);
      uint8_t flags = segment->GetFlags(module_);
      stream_->WriteU8(flags, "segment flags");
      if (!(flags & SegPassive)) {
        if (options_.features.multi_memory_enabled() &&
            (flags & SegExplicitIndex)) {
          WriteU32Leb128(stream_, module_->GetMemoryIndex(segment->memory_var),
                         "memidx");
        } else {
          assert(module_->GetMemoryIndex(segment->memory_var) == 0);
        }
        WriteInitExpr(segment->offset);
      }
      WriteU32Leb128(stream_, segment->data.size(), "data segment size");
      WriteHeader("data segment data", i);
      stream_->WriteData(segment->data, "data segment data");
    }
    EndSection();
  }

  if (options_.write_debug_names) {
    std::vector<std::string> index_to_name;

    char desc[100];
    BeginCustomSection(WABT_BINARY_SECTION_NAME);

    if (!module_->name.empty()) {
      WriteU32Leb128(stream_, NameSectionSubsection::Module,
                     "module name type");
      BeginSubsection("module name subsection");
      WriteDebugName(stream_, module_->name, "module name");
      EndSubsection();
    }

    WriteNames<Func>(module_->funcs, NameSectionSubsection::Function);

    WriteU32Leb128(stream_, 2, "local name type");

    BeginSubsection("local name subsection");
    WriteU32Leb128(stream_, module_->funcs.size(), "num functions");
    for (size_t i = 0; i < module_->funcs.size(); ++i) {
      const Func* func = module_->funcs[i];
      Index num_params_and_locals = func->GetNumParamsAndLocals();
      MakeTypeBindingReverseMapping(num_params_and_locals, func->bindings,
                                    &index_to_name);
      Index num_named = 0;
      for (auto s : index_to_name) {
        if (!s.empty()) {
          num_named++;
        }
      }

      WriteU32Leb128(stream_, i, "function index");
      WriteU32Leb128(stream_, num_named, "num locals");

      for (size_t j = 0; j < num_params_and_locals; ++j) {
        const std::string& name = index_to_name[j];
        if (!name.empty()) {
          wabt_snprintf(desc, sizeof(desc), "local name %" PRIzd, j);
          WriteU32Leb128(stream_, j, "local index");
          WriteDebugName(stream_, name, desc);
        }
      }
    }
    EndSubsection();

    WriteNames<TypeEntry>(module_->types, NameSectionSubsection::Type);
    WriteNames<Table>(module_->tables, NameSectionSubsection::Table);
    WriteNames<Memory>(module_->memories, NameSectionSubsection::Memory);
    WriteNames<Global>(module_->globals, NameSectionSubsection::Global);
    WriteNames<ElemSegment>(module_->elem_segments,
                            NameSectionSubsection::ElemSegment);
    WriteNames<DataSegment>(module_->data_segments,
                            NameSectionSubsection::DataSegment);
    WriteNames<Tag>(module_->tags, NameSectionSubsection::Tag);

    EndSection();
  }

  if (options_.relocatable) {
    WriteLinkingSection();
    for (RelocSection& section : reloc_sections_) {
      WriteRelocSection(&section);
    }
  }

  return stream_->result();
}

void BinaryWriter::WriteCodeMetadataSections() {
  if (code_metadata_sections_.empty())
    return;

  section_count_ -= 1;
  // We have to increment the code section's index; adjust anything
  // that might have captured it.
  for (RelocSection& section : reloc_sections_) {
    if (section.section_index == section_count_) {
      assert(last_section_type_ == BinarySection::Code);
      section.section_index += code_metadata_sections_.size();
    }
  }

  MemoryStream tmp_stream;
  Stream* main_stream = stream_;
  stream_ = &tmp_stream;
  for (auto& s : code_metadata_sections_) {
    std::string name = "metadata.code.";
    name.append(s.first);
    auto& section = s.second;
    BeginCustomSection(name.c_str());
    WriteU32Leb128(stream_, section.entries.size(), "function count");
    for (auto& f : section.entries) {
      WriteU32Leb128WithReloc(f.func_idx, "function index",
                              RelocType::FuncIndexLEB);
      WriteU32Leb128(stream_, f.entries.size(), "instances count");
      for (auto& a : f.entries) {
        WriteU32Leb128(stream_, a.offset, "code offset");
        WriteU32Leb128(stream_, a.data.size(), "data length");
        stream_->WriteData(a.data.data(), a.data.size(), "data",
                           PrintChars::Yes);
      }
    }
    EndSection();
  }
  stream_ = main_stream;
  auto buf = tmp_stream.ReleaseOutputBuffer();
  stream_->MoveData(code_start_ + buf->data.size(), code_start_,
                    stream_->offset() - code_start_);
  stream_->WriteDataAt(code_start_, buf->data.data(), buf->data.size());
  stream_->AddOffset(buf->data.size());
  code_start_ += buf->data.size();
  section_count_ += 1;
  last_section_type_ = BinarySection::Code;
}

}  // end anonymous namespace

Result WriteBinaryModule(Stream* stream,
                         const Module* module,
                         const WriteBinaryOptions& options) {
  BinaryWriter binary_writer(stream, options, module);
  return binary_writer.WriteModule();
}

}  // namespace wabt
