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

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

#include "config.h"

#include "src/binary.h"
#include "src/cast.h"
#include "src/ir.h"
#include "src/leb128.h"
#include "src/stream.h"
#include "src/string-view.h"

#define PRINT_HEADER_NO_INDEX -1
#define MAX_U32_LEB128_BYTES 5

namespace wabt {

void WriteStr(Stream* stream,
              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());
}

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;
  WriteU32Leb128(stream, flags, "limits: flags");
  WriteU32Leb128(stream, limits->initial, "limits: initial");
  if (limits->has_max) {
    WriteU32Leb128(stream, limits->max, "limits: max");
  }
}

void WriteDebugName(Stream* stream, string_view name, const char* desc) {
  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. */
static const 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;
};

struct Symbol {
  Index symbol_index;
  SymbolType type;
  Index element_index;
};

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 GetEventVarDepth(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);
  template <typename T>
  void WriteLoadStoreExpr(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 WriteEventType(const Event* event);
  void WriteRelocSection(const RelocSection* reloc_section);
  void WriteLinkingSection();

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

  std::unordered_map<std::string, Index> symtab_;
  std::vector<Symbol> symbols_;
  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.
  size_t data_count_start_ = 0;
  size_t data_count_end_ = 0;
  bool has_data_segment_instruction_ = false;
};

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);
  WriteS32Leb128(stream_, index, "block type function index");
}

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);
  Offset delta = WriteFixupU32Leb128Size(
      last_section_offset_, last_section_leb_size_guess_, "FIXUP section size");
  if (current_reloc_section_ && delta != 0) {
    for (Reloc& reloc : current_reloc_section_->relocations) {
      reloc.offset += delta;
    }
  }
  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::GetEventVarDepth(const Var* var) {
  return var->index();
}

Index BinaryWriter::GetSymbolIndex(RelocType reloc_type, Index index) {
  std::string name;
  SymbolType type = SymbolType::Function;
  switch (reloc_type) {
    case RelocType::FuncIndexLEB:
      name = module_->funcs[index]->name;
      break;
    case RelocType::GlobalIndexLEB:
      type = SymbolType::Global;
      name = module_->globals[index]->name;
      break;
    default:
      // TODO: Add support for TypeIndexLEB.
      fprintf(stderr, "warning: unsupported relocation type: %s\n",
              GetRelocTypeName(reloc_type));
      return kInvalidIndex;
  }
  auto iter = symtab_.find(name);
  if (iter != symtab_.end()) {
    return iter->second;
  }

  Index sym_index = Index(symbols_.size());
  symtab_[name] = sym_index;
  symbols_.push_back(Symbol{sym_index, type, index});
  return sym_index;
}

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);
  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);
  }
}

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);
  stream_->WriteU8(log2_u32(align), "alignment");
  WriteU32Leb128(stream_, typed_expr->offset, desc);
}

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::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::BrOnExn: {
      auto* br_on_exn_expr = cast<BrOnExnExpr>(expr);
      WriteOpcode(stream_, Opcode::BrOnExn);
      WriteU32Leb128(stream_, GetLabelVarDepth(&br_on_exn_expr->label_var),
                     "break depth");
      WriteU32Leb128(stream_, module_->GetEventIndex(br_on_exn_expr->event_var),
                     "event index");
      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);
      WriteU32Leb128(stream_, table_index, "table index");
      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);
      WriteU32Leb128(stream_, 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:
      WriteOpcode(stream_, Opcode::MemoryCopy);
      WriteU32Leb128(stream_, 0, "memory.copy reserved");
      WriteU32Leb128(stream_, 0, "memory.copy reserved");
      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:
      WriteOpcode(stream_, Opcode::MemoryFill);
      WriteU32Leb128(stream_, 0, "memory.fill reserved");
      break;
    case ExprType::MemoryGrow:
      WriteOpcode(stream_, Opcode::MemoryGrow);
      WriteU32Leb128(stream_, 0, "memory.grow reserved");
      break;
    case ExprType::MemoryInit: {
      Index index =
          module_->GetDataSegmentIndex(cast<MemoryInitExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::MemoryInit);
      WriteU32Leb128(stream_, index, "memory.init segment");
      WriteU32Leb128(stream_, 0, "memory.init reserved");
      has_data_segment_instruction_ = true;
      break;
    }
    case ExprType::MemorySize:
      WriteOpcode(stream_, Opcode::MemorySize);
      WriteU32Leb128(stream_, 0, "memory.size reserved");
      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);
      WriteU32Leb128(stream_, dst, "table.copy dst_table");
      WriteU32Leb128(stream_, 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");
      WriteU32Leb128(stream_, table_index, "table.init table");
      break;
    }
    case ExprType::TableGet: {
      Index index =
          module_->GetTableIndex(cast<TableGetExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableGet);
      WriteU32Leb128(stream_, index, "table.get table index");
      break;
    }
    case ExprType::TableSet: {
      Index index =
          module_->GetTableIndex(cast<TableSetExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableSet);
      WriteU32Leb128(stream_, index, "table.set table index");
      break;
    }
    case ExprType::TableGrow: {
      Index index =
          module_->GetTableIndex(cast<TableGrowExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableGrow);
      WriteU32Leb128(stream_, index, "table.grow table index");
      break;
    }
    case ExprType::TableSize: {
      Index index =
          module_->GetTableIndex(cast<TableSizeExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableSize);
      WriteU32Leb128(stream_, index, "table.size table index");
      break;
    }
    case ExprType::TableFill: {
      Index index =
          module_->GetTableIndex(cast<TableFillExpr>(expr)->var);
      WriteOpcode(stream_, Opcode::TableFill);
      WriteU32Leb128(stream_, 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);
      break;
    }
    case ExprType::RefIsNull: {
      WriteOpcode(stream_, Opcode::RefIsNull);
      break;
    }
    case ExprType::Nop:
      WriteOpcode(stream_, Opcode::Nop);
      break;
    case ExprType::Rethrow:
      WriteOpcode(stream_, Opcode::Rethrow);
      break;
    case ExprType::Return:
      WriteOpcode(stream_, Opcode::Return);
      break;
    case ExprType::Select: {
      auto* select_expr = cast<SelectExpr>(expr);
      if (select_expr->result_type.size() == 1 &&
          select_expr->result_type[0] == Type::Any) {
        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_, GetEventVarDepth(&cast<ThrowExpr>(expr)->var),
                     "throw event");
      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);
      WriteOpcode(stream_, Opcode::Catch);
      WriteExprList(func, try_expr->catch_);
      WriteOpcode(stream_, Opcode::End);
      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::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::Unreachable:
      WriteOpcode(stream_, Opcode::Unreachable);
      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::WriteEventType(const Event* event) {
  WriteU32Leb128(stream_, 0, "event attribute");
  WriteU32Leb128(stream_, module_->GetFuncTypeIndex(event->decl),
                 "event 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::MemoryAddressSLEB:
      case RelocType::MemoryAddressRelSLEB:
      case RelocType::MemoryAddressI32:
      case RelocType::FunctionOffsetI32:
      case RelocType::SectionOffsetI32:
        WriteU32Leb128(stream_, reloc.addend, "reloc addend");
        break;
      default:
        break;
    }
  }

  EndSection();
}

void BinaryWriter::WriteLinkingSection() {
  BeginCustomSection(WABT_BINARY_SECTION_LINKING);
  WriteU32Leb128(stream_, 2, "metadata version");
  if (symbols_.size()) {
    stream_->WriteU8Enum(LinkingEntryType::SymbolTable, "symbol table");
    BeginSubsection("symbol table");
    WriteU32Leb128(stream_, symbols_.size(), "num symbols");

    for (const Symbol& sym : symbols_) {
      bool is_defined = true;
      if (sym.type == SymbolType::Function) {
        if (sym.element_index < module_->num_func_imports) {
          is_defined = false;
        }
      }
      if (sym.type == SymbolType::Global) {
        if (sym.element_index < module_->num_global_imports) {
          is_defined = false;
        }
      }
      stream_->WriteU8Enum(sym.type, "symbol type");
      WriteU32Leb128(stream_, is_defined ? 0 : WABT_SYMBOL_FLAG_UNDEFINED,
                     "symbol flags");
      WriteU32Leb128(stream_, sym.element_index, "element index");
      if (is_defined) {
        if (sym.type == SymbolType::Function) {
          WriteStr(stream_, module_->funcs[sym.element_index]->name,
                   "function name", PrintChars::Yes);
        } else if (sym.type == SymbolType::Global) {
          WriteStr(stream_, module_->globals[sym.element_index]->name,
                   "global name", PrintChars::Yes);
        }
      }
    }
    EndSubsection();
  }
  EndSection();
}

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

  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("type", i);  // TODO: switch to "func type"?
          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::Event:
          WriteEventType(&cast<EventImport>(import)->event);
          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_->events.size() >= module_->num_event_imports);
  Index num_events = module_->events.size() - module_->num_event_imports;
  if (num_events) {
    BeginKnownSection(BinarySection::Event);
    WriteU32Leb128(stream_, num_events, "event count");
    for (size_t i = 0; i < num_events; ++i) {
      WriteHeader("event", i);
      const Event* event = module_->events[i + module_->num_event_imports];
      WriteEventType(event);
    }
    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::Event: {
          Index index = module_->GetEventIndex(export_->var);
          WriteU32Leb128(stream_, index, "export event 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 ElemExpr& elem_expr : segment->elem_exprs) {
          switch (elem_expr.kind) {
            case ElemExprKind::RefNull:
              WriteOpcode(stream_, Opcode::RefNull);
              break;

            case ElemExprKind::RefFunc:
              WriteOpcode(stream_, Opcode::RefFunc);
              WriteU32Leb128WithReloc(module_->GetFuncIndex(elem_expr.var),
                                      "elem expr function index",
                                      RelocType::FuncIndexLEB);
              break;
          }
          WriteOpcode(stream_, Opcode::End);
        }
      } else {
        for (const ElemExpr& elem_expr : segment->elem_exprs) {
          assert(elem_expr.kind == ElemExprKind::RefFunc);
          WriteU32Leb128WithReloc(module_->GetFuncIndex(elem_expr.var),
                                  "elem function index",
                                  RelocType::FuncIndexLEB);
        }
      }
    }
    EndSection();
  }

  if (options_.features.bulk_memory_enabled()) {
    // 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) {
    BeginKnownSection(BinarySection::Code);
    WriteU32Leb128(stream_, num_funcs, "num functions");

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

      /* 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)");
      WriteFunc(func);
      WriteFixupU32Leb128Size(body_size_offset, leb_size_guess,
                              "FIXUP func body size");
    }
    EndSection();
  }

  // Remove the DataCount section if there are no instructions that require it.
  if (options_.features.bulk_memory_enabled() &&
      !has_data_segment_instruction_) {
    Offset size = stream_->offset() - data_count_end_;
    if (data_count_start_ != data_count_end_) {
      stream_->MoveData(data_count_start_, data_count_end_, size);
    }
    stream_->Truncate(data_count_start_ + size);
  }

  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)) {
        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);

    size_t named_functions = 0;
    for (const Func* func : module_->funcs) {
      if (!func->name.empty()) {
        named_functions++;
      }
    }

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

    if (named_functions > 0) {
      WriteU32Leb128(stream_, 1, "function name type");
      BeginSubsection("function name subsection");

      WriteU32Leb128(stream_, named_functions, "num functions");
      for (size_t i = 0; i < module_->funcs.size(); ++i) {
        const Func* func = module_->funcs[i];
        if (func->name.empty()) {
          continue;
        }
        WriteU32Leb128(stream_, i, "function index");
        wabt_snprintf(desc, sizeof(desc), "func name %" PRIzd, i);
        WriteDebugName(stream_, func->name, desc);
      }
      EndSubsection();
    }

    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();

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

      MakeTypeBindingReverseMapping(num_params_and_locals, func->bindings,
                                    &index_to_name);
      for (size_t j = 0; j < num_params_and_locals; ++j) {
        const std::string& name = index_to_name[j];
        wabt_snprintf(desc, sizeof(desc), "local name %" PRIzd, j);
        WriteU32Leb128(stream_, j, "local index");
        WriteDebugName(stream_, name, desc);
      }
    }
    EndSubsection();
    EndSection();
  }

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

  return stream_->result();
}

}  // 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
