/*
 * 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-reader-ir.h"

#include <cassert>
#include <cinttypes>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <vector>

#include "wabt/binary-reader-nop.h"
#include "wabt/cast.h"
#include "wabt/common.h"
#include "wabt/ir.h"

namespace wabt {

namespace {

struct LabelNode {
  LabelNode(LabelType, ExprList* exprs, Expr* context = nullptr);

  LabelType label_type;
  ExprList* exprs;
  Expr* context;
};

LabelNode::LabelNode(LabelType label_type, ExprList* exprs, Expr* context)
    : label_type(label_type), exprs(exprs), context(context) {}

class CodeMetadataExprQueue {
 private:
  struct Entry {
    Func* func;
    std::deque<std::unique_ptr<CodeMetadataExpr>> func_queue;
    Entry(Func* f) : func(f) {}
  };
  std::deque<Entry> entries;

 public:
  CodeMetadataExprQueue() {}
  void push_func(Func* f) { entries.emplace_back(f); }
  void push_metadata(std::unique_ptr<CodeMetadataExpr> meta) {
    assert(!entries.empty());
    entries.back().func_queue.push_back(std::move(meta));
  }

  std::unique_ptr<CodeMetadataExpr> pop_match(Func* f, Offset offset) {
    std::unique_ptr<CodeMetadataExpr> ret;
    if (entries.empty()) {
      return ret;
    }

    auto& current_entry = entries.front();

    if (current_entry.func != f)
      return ret;
    if (current_entry.func_queue.empty()) {
      entries.pop_front();
      return ret;
    }

    auto& current_metadata = current_entry.func_queue.front();
    if (current_metadata->loc.offset + current_entry.func->loc.offset !=
        offset) {
      return ret;
    }

    current_metadata->loc = Location(offset);
    ret = std::move(current_metadata);
    current_entry.func_queue.pop_front();

    return ret;
  }
};

class BinaryReaderIR : public BinaryReaderNop {
  static constexpr size_t kMaxNestingDepth = 16384;  // max depth of label stack
  static constexpr size_t kMaxFunctionLocals = 50000;  // matches V8
  static constexpr size_t kMaxFunctionParams = 1000;   // matches V8
  static constexpr size_t kMaxFunctionResults = 1000;  // matches V8

 public:
  BinaryReaderIR(Module* out_module, const char* filename, Errors* errors);

  bool OnError(const Error&) override;

  Result OnTypeCount(Index count) override;
  Result OnFuncType(Index index,
                    Index param_count,
                    Type* param_types,
                    Index result_count,
                    Type* result_types) override;
  Result OnStructType(Index index, Index field_count, TypeMut* fields) override;
  Result OnArrayType(Index index, TypeMut field) override;

  Result OnImportCount(Index count) override;
  Result OnImportFunc(Index import_index,
                      std::string_view module_name,
                      std::string_view field_name,
                      Index func_index,
                      Index sig_index) override;
  Result OnImportTable(Index import_index,
                       std::string_view module_name,
                       std::string_view field_name,
                       Index table_index,
                       Type elem_type,
                       const Limits* elem_limits) override;
  Result OnImportMemory(Index import_index,
                        std::string_view module_name,
                        std::string_view field_name,
                        Index memory_index,
                        const Limits* page_limits,
                        uint32_t page_size) override;
  Result OnImportGlobal(Index import_index,
                        std::string_view module_name,
                        std::string_view field_name,
                        Index global_index,
                        Type type,
                        bool mutable_) override;
  Result OnImportTag(Index import_index,
                     std::string_view module_name,
                     std::string_view field_name,
                     Index tag_index,
                     Index sig_index) override;

  Result OnFunctionCount(Index count) override;
  Result OnFunction(Index index, Index sig_index) override;

  Result OnTableCount(Index count) override;
  Result OnTable(Index index,
                 Type elem_type,
                 const Limits* elem_limits) override;

  Result OnMemoryCount(Index count) override;
  Result OnMemory(Index index,
                  const Limits* limits,
                  uint32_t page_size) override;

  Result OnGlobalCount(Index count) override;
  Result BeginGlobal(Index index, Type type, bool mutable_) override;
  Result BeginGlobalInitExpr(Index index) override;
  Result EndGlobalInitExpr(Index index) override;

  Result OnExportCount(Index count) override;
  Result OnExport(Index index,
                  ExternalKind kind,
                  Index item_index,
                  std::string_view name) override;

  Result OnStartFunction(Index func_index) override;

  Result OnFunctionBodyCount(Index count) override;
  Result BeginFunctionBody(Index index, Offset size) override;
  Result OnLocalDecl(Index decl_index, Index count, Type type) override;

  Result OnOpcode(Opcode opcode) override;
  Result OnAtomicLoadExpr(Opcode opcode,
                          Index memidx,
                          Address alignment_log2,
                          Address offset) override;
  Result OnAtomicStoreExpr(Opcode opcode,
                           Index memidx,
                           Address alignment_log2,
                           Address offset) override;
  Result OnAtomicRmwExpr(Opcode opcode,
                         Index memidx,
                         Address alignment_log2,
                         Address offset) override;
  Result OnAtomicRmwCmpxchgExpr(Opcode opcode,
                                Index memidx,
                                Address alignment_log2,
                                Address offset) override;
  Result OnAtomicWaitExpr(Opcode opcode,
                          Index memidx,
                          Address alignment_log2,
                          Address offset) override;
  Result OnAtomicFenceExpr(uint32_t consistency_model) override;
  Result OnAtomicNotifyExpr(Opcode opcode,
                            Index memidx,
                            Address alignment_log2,
                            Address offset) override;
  Result OnBinaryExpr(Opcode opcode) override;
  Result OnBlockExpr(Type sig_type) override;
  Result OnBrExpr(Index depth) override;
  Result OnBrIfExpr(Index depth) override;
  Result OnBrTableExpr(Index num_targets,
                       Index* target_depths,
                       Index default_target_depth) override;
  Result OnCallExpr(Index func_index) override;
  Result OnCatchExpr(Index tag_index) override;
  Result OnCatchAllExpr() override;
  Result OnCallIndirectExpr(Index sig_index, Index table_index) override;
  Result OnCallRefExpr() override;
  Result OnReturnCallExpr(Index func_index) override;
  Result OnReturnCallIndirectExpr(Index sig_index, Index table_index) override;
  Result OnCompareExpr(Opcode opcode) override;
  Result OnConvertExpr(Opcode opcode) override;
  Result OnDelegateExpr(Index depth) override;
  Result OnDropExpr() override;
  Result OnElseExpr() override;
  Result OnEndExpr() override;
  Result OnF32ConstExpr(uint32_t value_bits) override;
  Result OnF64ConstExpr(uint64_t value_bits) override;
  Result OnV128ConstExpr(v128 value_bits) override;
  Result OnGlobalGetExpr(Index global_index) override;
  Result OnGlobalSetExpr(Index global_index) override;
  Result OnI32ConstExpr(uint32_t value) override;
  Result OnI64ConstExpr(uint64_t value) override;
  Result OnIfExpr(Type sig_type) override;
  Result OnLoadExpr(Opcode opcode,
                    Index memidx,
                    Address alignment_log2,
                    Address offset) override;
  Result OnLocalGetExpr(Index local_index) override;
  Result OnLocalSetExpr(Index local_index) override;
  Result OnLocalTeeExpr(Index local_index) override;
  Result OnLoopExpr(Type sig_type) override;
  Result OnMemoryCopyExpr(Index destmemidx, Index srcmemidx) override;
  Result OnDataDropExpr(Index segment_index) override;
  Result OnMemoryFillExpr(Index memidx) override;
  Result OnMemoryGrowExpr(Index memidx) override;
  Result OnMemoryInitExpr(Index segment_index, Index memidx) override;
  Result OnMemorySizeExpr(Index memidx) override;
  Result OnTableCopyExpr(Index dst_index, Index src_index) override;
  Result OnElemDropExpr(Index segment_index) override;
  Result OnTableInitExpr(Index segment_index, Index table_index) override;
  Result OnTableGetExpr(Index table_index) override;
  Result OnTableSetExpr(Index table_index) override;
  Result OnTableGrowExpr(Index table_index) override;
  Result OnTableSizeExpr(Index table_index) override;
  Result OnTableFillExpr(Index table_index) override;
  Result OnRefFuncExpr(Index func_index) override;
  Result OnRefNullExpr(Type type) override;
  Result OnRefIsNullExpr() override;
  Result OnNopExpr() override;
  Result OnRethrowExpr(Index depth) override;
  Result OnReturnExpr() override;
  Result OnSelectExpr(Index result_count, Type* result_types) override;
  Result OnStoreExpr(Opcode opcode,
                     Index memidx,
                     Address alignment_log2,
                     Address offset) override;
  Result OnThrowExpr(Index tag_index) override;
  Result OnThrowRefExpr() override;
  Result OnTryExpr(Type sig_type) override;
  Result OnTryTableExpr(Type sig_type,
                        const CatchClauseVector& catches) override;
  Result OnUnaryExpr(Opcode opcode) override;
  Result OnTernaryExpr(Opcode opcode) override;
  Result OnUnreachableExpr() override;
  Result EndFunctionBody(Index index) override;
  Result OnSimdLaneOpExpr(Opcode opcode, uint64_t value) override;
  Result OnSimdLoadLaneExpr(Opcode opcode,
                            Index memidx,
                            Address alignment_log2,
                            Address offset,
                            uint64_t value) override;
  Result OnSimdStoreLaneExpr(Opcode opcode,
                             Index memidx,
                             Address alignment_log2,
                             Address offset,
                             uint64_t value) override;
  Result OnSimdShuffleOpExpr(Opcode opcode, v128 value) override;
  Result OnLoadSplatExpr(Opcode opcode,
                         Index memidx,
                         Address alignment_log2,
                         Address offset) override;
  Result OnLoadZeroExpr(Opcode opcode,
                        Index memidx,
                        Address alignment_log2,
                        Address offset) override;

  Result OnElemSegmentCount(Index count) override;
  Result BeginElemSegment(Index index,
                          Index table_index,
                          uint8_t flags) override;
  Result BeginElemSegmentInitExpr(Index index) override;
  Result EndElemSegmentInitExpr(Index index) override;
  Result OnElemSegmentElemType(Index index, Type elem_type) override;
  Result OnElemSegmentElemExprCount(Index index, Index count) override;
  Result BeginElemExpr(Index elem_index, Index expr_index) override;
  Result EndElemExpr(Index elem_index, Index expr_index) override;

  Result OnDataSegmentCount(Index count) override;
  Result BeginDataSegment(Index index,
                          Index memory_index,
                          uint8_t flags) override;
  Result BeginDataSegmentInitExpr(Index index) override;
  Result EndDataSegmentInitExpr(Index index) override;
  Result OnDataSegmentData(Index index,
                           const void* data,
                           Address size) override;

  Result OnModuleName(std::string_view module_name) override;
  Result OnFunctionNamesCount(Index num_functions) override;
  Result OnFunctionName(Index function_index,
                        std::string_view function_name) override;
  Result OnLocalNameLocalCount(Index function_index, Index num_locals) override;
  Result OnLocalName(Index function_index,
                     Index local_index,
                     std::string_view local_name) override;
  Result OnNameEntry(NameSectionSubsection type,
                     Index index,
                     std::string_view name) override;

  Result OnGenericCustomSection(std::string_view name,
                                const void* data,
                                Offset size) override;

  Result BeginTagSection(Offset size) override { return Result::Ok; }
  Result OnTagCount(Index count) override { return Result::Ok; }
  Result OnTagType(Index index, Index sig_index) override;
  Result EndTagSection() override { return Result::Ok; }

  Result OnDataSymbol(Index index,
                      uint32_t flags,
                      std::string_view name,
                      Index segment,
                      uint32_t offset,
                      uint32_t size) override;
  Result OnFunctionSymbol(Index index,
                          uint32_t flags,
                          std::string_view name,
                          Index func_index) override;
  Result OnGlobalSymbol(Index index,
                        uint32_t flags,
                        std::string_view name,
                        Index global_index) override;
  Result OnSectionSymbol(Index index,
                         uint32_t flags,
                         Index section_index) override;
  /* Code Metadata sections */
  Result BeginCodeMetadataSection(std::string_view name, Offset size) override;
  Result OnCodeMetadataFuncCount(Index count) override;
  Result OnCodeMetadataCount(Index function_index, Index count) override;
  Result OnCodeMetadata(Offset offset, const void* data, Address size) override;

  Result OnTagSymbol(Index index,
                     uint32_t flags,
                     std::string_view name,
                     Index tag_index) override;
  Result OnTableSymbol(Index index,
                       uint32_t flags,
                       std::string_view name,
                       Index table_index) override;

 private:
  Location GetLocation() const;
  void PrintError(const char* format, ...);
  Result PushLabel(LabelType label_type,
                   ExprList* first,
                   Expr* context = nullptr);
  Result BeginInitExpr(ExprList* init_expr);
  Result EndInitExpr();
  Result PopLabel();
  Result GetLabelAt(LabelNode** label, Index depth);
  Result TopLabel(LabelNode** label);
  Result TopLabelExpr(LabelNode** label, Expr** expr);
  Result AppendExpr(std::unique_ptr<Expr> expr);
  Result AppendCatch(Catch&& catch_);
  void SetFuncDeclaration(FuncDeclaration* decl, Var var);
  void SetBlockDeclaration(BlockDeclaration* decl, Type sig_type);
  Result SetMemoryName(Index index, std::string_view name);
  Result SetTableName(Index index, std::string_view name);
  Result SetFunctionName(Index index, std::string_view name);
  Result SetTypeName(Index index, std::string_view name);
  Result SetGlobalName(Index index, std::string_view name);
  Result SetDataSegmentName(Index index, std::string_view name);
  Result SetElemSegmentName(Index index, std::string_view name);
  Result SetTagName(Index index, std::string_view name);

  std::string GetUniqueName(BindingHash* bindings,
                            const std::string& original_name);

  Errors* errors_ = nullptr;
  Module* module_ = nullptr;

  Func* current_func_ = nullptr;
  std::vector<LabelNode> label_stack_;
  const char* filename_;

  CodeMetadataExprQueue code_metadata_queue_;
  std::string_view current_metadata_name_;
};

BinaryReaderIR::BinaryReaderIR(Module* out_module,
                               const char* filename,
                               Errors* errors)
    : errors_(errors), module_(out_module), filename_(filename) {}

Location BinaryReaderIR::GetLocation() const {
  Location loc;
  loc.filename = filename_;
  loc.offset = state->offset;
  return loc;
}

void WABT_PRINTF_FORMAT(2, 3) BinaryReaderIR::PrintError(const char* format,
                                                         ...) {
  WABT_SNPRINTF_ALLOCA(buffer, length, format);
  errors_->emplace_back(ErrorLevel::Error, Location(kInvalidOffset), buffer);
}

Result BinaryReaderIR::PushLabel(LabelType label_type,
                                 ExprList* first,
                                 Expr* context) {
  if (label_stack_.size() >= kMaxNestingDepth) {
    PrintError("label stack exceeds max nesting depth");
    return Result::Error;
  }
  label_stack_.emplace_back(label_type, first, context);
  return Result::Ok;
}

Result BinaryReaderIR::PopLabel() {
  if (label_stack_.size() == 0) {
    PrintError("popping empty label stack");
    return Result::Error;
  }

  label_stack_.pop_back();
  return Result::Ok;
}

Result BinaryReaderIR::GetLabelAt(LabelNode** label, Index depth) {
  if (depth >= label_stack_.size()) {
    PrintError("accessing stack depth: %" PRIindex " >= max: %" PRIzd, depth,
               label_stack_.size());
    return Result::Error;
  }

  *label = &label_stack_[label_stack_.size() - depth - 1];
  return Result::Ok;
}

Result BinaryReaderIR::TopLabel(LabelNode** label) {
  return GetLabelAt(label, 0);
}

Result BinaryReaderIR::TopLabelExpr(LabelNode** label, Expr** expr) {
  CHECK_RESULT(TopLabel(label));
  LabelNode* parent_label;
  CHECK_RESULT(GetLabelAt(&parent_label, 1));
  if (parent_label->exprs->empty()) {
    PrintError("TopLabelExpr: parent label has empty expr list");
    return Result::Error;
  }
  *expr = &parent_label->exprs->back();
  return Result::Ok;
}

Result BinaryReaderIR::AppendExpr(std::unique_ptr<Expr> expr) {
  expr->loc = GetLocation();
  LabelNode* label;
  CHECK_RESULT(TopLabel(&label));
  label->exprs->push_back(std::move(expr));
  return Result::Ok;
}

void BinaryReaderIR::SetFuncDeclaration(FuncDeclaration* decl, Var var) {
  decl->has_func_type = true;
  decl->type_var = var;
  if (auto* func_type = module_->GetFuncType(var)) {
    decl->sig = func_type->sig;
  }
}

void BinaryReaderIR::SetBlockDeclaration(BlockDeclaration* decl,
                                         Type sig_type) {
  if (sig_type.IsIndex()) {
    Index type_index = sig_type.GetIndex();
    SetFuncDeclaration(decl, Var(type_index, GetLocation()));
  } else {
    decl->has_func_type = false;
    decl->sig.param_types.clear();
    decl->sig.result_types = sig_type.GetInlineVector();
  }
}

std::string BinaryReaderIR::GetUniqueName(BindingHash* bindings,
                                          const std::string& orig_name) {
  int counter = 1;
  std::string unique_name = orig_name;
  while (bindings->count(unique_name) != 0) {
    unique_name = orig_name + "." + std::to_string(counter++);
  }
  return unique_name;
}

bool BinaryReaderIR::OnError(const Error& error) {
  errors_->push_back(error);
  return true;
}

Result BinaryReaderIR::OnTypeCount(Index count) {
  WABT_TRY
  module_->types.reserve(count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::OnFuncType(Index index,
                                  Index param_count,
                                  Type* param_types,
                                  Index result_count,
                                  Type* result_types) {
  if (param_count > kMaxFunctionParams) {
    PrintError("FuncType param count exceeds maximum value");
    return Result::Error;
  }

  if (result_count > kMaxFunctionResults) {
    PrintError("FuncType result count exceeds maximum value");
    return Result::Error;
  }

  auto field = std::make_unique<TypeModuleField>(GetLocation());
  auto func_type = std::make_unique<FuncType>();
  func_type->sig.param_types.assign(param_types, param_types + param_count);
  func_type->sig.result_types.assign(result_types, result_types + result_count);

  module_->features_used.simd |=
      std::any_of(func_type->sig.param_types.begin(),
                  func_type->sig.param_types.end(),
                  [](auto x) { return x == Type::V128; }) ||
      std::any_of(func_type->sig.result_types.begin(),
                  func_type->sig.result_types.end(),
                  [](auto x) { return x == Type::V128; });
  module_->features_used.exceptions |=
      std::any_of(func_type->sig.param_types.begin(),
                  func_type->sig.param_types.end(),
                  [](auto x) { return x == Type::ExnRef; }) ||
      std::any_of(func_type->sig.result_types.begin(),
                  func_type->sig.result_types.end(),
                  [](auto x) { return x == Type::ExnRef; });

  field->type = std::move(func_type);
  module_->AppendField(std::move(field));
  return Result::Ok;
}

Result BinaryReaderIR::OnStructType(Index index,
                                    Index field_count,
                                    TypeMut* fields) {
  auto field = std::make_unique<TypeModuleField>(GetLocation());
  auto struct_type = std::make_unique<StructType>();
  struct_type->fields.resize(field_count);
  for (Index i = 0; i < field_count; ++i) {
    struct_type->fields[i].type = fields[i].type;
    struct_type->fields[i].mutable_ = fields[i].mutable_;
    module_->features_used.simd |= (fields[i].type == Type::V128);
    module_->features_used.exceptions |= (fields[i].type == Type::ExnRef);
  }
  field->type = std::move(struct_type);
  module_->AppendField(std::move(field));
  return Result::Ok;
}

Result BinaryReaderIR::OnArrayType(Index index, TypeMut type_mut) {
  auto field = std::make_unique<TypeModuleField>(GetLocation());
  auto array_type = std::make_unique<ArrayType>();
  array_type->field.type = type_mut.type;
  array_type->field.mutable_ = type_mut.mutable_;
  module_->features_used.simd |= (type_mut.type == Type::V128);
  module_->features_used.exceptions |= (type_mut.type == Type::ExnRef);
  field->type = std::move(array_type);
  module_->AppendField(std::move(field));
  return Result::Ok;
}

Result BinaryReaderIR::OnImportCount(Index count) {
  WABT_TRY
  module_->imports.reserve(count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::OnImportFunc(Index import_index,
                                    std::string_view module_name,
                                    std::string_view field_name,
                                    Index func_index,
                                    Index sig_index) {
  auto import = std::make_unique<FuncImport>();
  import->module_name = module_name;
  import->field_name = field_name;
  SetFuncDeclaration(&import->func.decl, Var(sig_index, GetLocation()));
  module_->AppendField(
      std::make_unique<ImportModuleField>(std::move(import), GetLocation()));
  return Result::Ok;
}

Result BinaryReaderIR::OnImportTable(Index import_index,
                                     std::string_view module_name,
                                     std::string_view field_name,
                                     Index table_index,
                                     Type elem_type,
                                     const Limits* elem_limits) {
  auto import = std::make_unique<TableImport>();
  import->module_name = module_name;
  import->field_name = field_name;
  import->table.elem_limits = *elem_limits;
  import->table.elem_type = elem_type;
  module_->AppendField(
      std::make_unique<ImportModuleField>(std::move(import), GetLocation()));
  return Result::Ok;
}

Result BinaryReaderIR::OnImportMemory(Index import_index,
                                      std::string_view module_name,
                                      std::string_view field_name,
                                      Index memory_index,
                                      const Limits* page_limits,
                                      uint32_t page_size) {
  auto import = std::make_unique<MemoryImport>();
  import->module_name = module_name;
  import->field_name = field_name;
  import->memory.page_limits = *page_limits;
  import->memory.page_size = page_size;
  if (import->memory.page_limits.is_shared) {
    module_->features_used.threads = true;
  }
  module_->AppendField(
      std::make_unique<ImportModuleField>(std::move(import), GetLocation()));
  return Result::Ok;
}

Result BinaryReaderIR::OnImportGlobal(Index import_index,
                                      std::string_view module_name,
                                      std::string_view field_name,
                                      Index global_index,
                                      Type type,
                                      bool mutable_) {
  auto import = std::make_unique<GlobalImport>();
  import->module_name = module_name;
  import->field_name = field_name;
  import->global.type = type;
  import->global.mutable_ = mutable_;
  module_->AppendField(
      std::make_unique<ImportModuleField>(std::move(import), GetLocation()));
  module_->features_used.simd |= (type == Type::V128);
  module_->features_used.exceptions |= (type == Type::ExnRef);
  return Result::Ok;
}

Result BinaryReaderIR::OnImportTag(Index import_index,
                                   std::string_view module_name,
                                   std::string_view field_name,
                                   Index tag_index,
                                   Index sig_index) {
  auto import = std::make_unique<TagImport>();
  import->module_name = module_name;
  import->field_name = field_name;
  SetFuncDeclaration(&import->tag.decl, Var(sig_index, GetLocation()));
  module_->AppendField(
      std::make_unique<ImportModuleField>(std::move(import), GetLocation()));
  module_->features_used.exceptions = true;
  return Result::Ok;
}

Result BinaryReaderIR::OnFunctionCount(Index count) {
  WABT_TRY
  module_->funcs.reserve(module_->num_func_imports + count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::OnFunction(Index index, Index sig_index) {
  auto field = std::make_unique<FuncModuleField>(GetLocation());
  Func& func = field->func;
  SetFuncDeclaration(&func.decl, Var(sig_index, GetLocation()));
  module_->AppendField(std::move(field));
  return Result::Ok;
}

Result BinaryReaderIR::OnTableCount(Index count) {
  WABT_TRY
  module_->tables.reserve(module_->num_table_imports + count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::OnTable(Index index,
                               Type elem_type,
                               const Limits* elem_limits) {
  auto field = std::make_unique<TableModuleField>(GetLocation());
  Table& table = field->table;
  table.elem_limits = *elem_limits;
  table.elem_type = elem_type;
  module_->features_used.exceptions |= (elem_type == Type::ExnRef);
  module_->AppendField(std::move(field));
  return Result::Ok;
}

Result BinaryReaderIR::OnMemoryCount(Index count) {
  WABT_TRY
  module_->memories.reserve(module_->num_memory_imports + count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::OnMemory(Index index,
                                const Limits* page_limits,
                                uint32_t page_size) {
  auto field = std::make_unique<MemoryModuleField>(GetLocation());
  Memory& memory = field->memory;
  memory.page_limits = *page_limits;
  memory.page_size = page_size;
  if (memory.page_limits.is_shared) {
    module_->features_used.threads = true;
  }
  module_->AppendField(std::move(field));
  return Result::Ok;
}

Result BinaryReaderIR::OnGlobalCount(Index count) {
  WABT_TRY
  module_->globals.reserve(module_->num_global_imports + count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::BeginGlobal(Index index, Type type, bool mutable_) {
  auto field = std::make_unique<GlobalModuleField>(GetLocation());
  Global& global = field->global;
  global.type = type;
  global.mutable_ = mutable_;
  module_->AppendField(std::move(field));
  module_->features_used.simd |= (type == Type::V128);
  module_->features_used.exceptions |= (type == Type::ExnRef);
  return Result::Ok;
}

Result BinaryReaderIR::BeginGlobalInitExpr(Index index) {
  assert(index == module_->globals.size() - 1);
  Global* global = module_->globals[index];
  return BeginInitExpr(&global->init_expr);
}

Result BinaryReaderIR::EndGlobalInitExpr(Index index) {
  return EndInitExpr();
}

Result BinaryReaderIR::OnExportCount(Index count) {
  WABT_TRY
  module_->exports.reserve(count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::OnExport(Index index,
                                ExternalKind kind,
                                Index item_index,
                                std::string_view name) {
  auto field = std::make_unique<ExportModuleField>(GetLocation());
  Export& export_ = field->export_;
  export_.name = name;
  export_.var = Var(item_index, GetLocation());
  export_.kind = kind;
  module_->AppendField(std::move(field));
  return Result::Ok;
}

Result BinaryReaderIR::OnStartFunction(Index func_index) {
  Var start(func_index, GetLocation());
  module_->AppendField(
      std::make_unique<StartModuleField>(start, GetLocation()));
  return Result::Ok;
}

Result BinaryReaderIR::OnFunctionBodyCount(Index count) {
  // Can hit this case on a malformed module if we don't stop on first error.
  if (module_->num_func_imports + count != module_->funcs.size()) {
    PrintError(
        "number of imported func + func count in code section does not match "
        "actual number of funcs in module");
    return Result::Error;
  }
  return Result::Ok;
}

Result BinaryReaderIR::BeginFunctionBody(Index index, Offset size) {
  current_func_ = module_->funcs[index];
  current_func_->loc = GetLocation();
  return PushLabel(LabelType::Func, &current_func_->exprs);
}

Result BinaryReaderIR::OnLocalDecl(Index decl_index, Index count, Type type) {
  current_func_->local_types.AppendDecl(type, count);

  if (current_func_->GetNumLocals() > kMaxFunctionLocals) {
    PrintError("function local count exceeds maximum value");
    return Result::Error;
  }

  module_->features_used.simd |= (type == Type::V128);
  module_->features_used.exceptions |= (type == Type::ExnRef);
  return Result::Ok;
}

Result BinaryReaderIR::OnOpcode(Opcode opcode) {
  std::unique_ptr<CodeMetadataExpr> metadata =
      code_metadata_queue_.pop_match(current_func_, GetLocation().offset - 1);
  if (metadata) {
    return AppendExpr(std::move(metadata));
  }
  module_->features_used.simd |= (opcode.GetResultType() == Type::V128);
  module_->features_used.threads |= (opcode.GetPrefix() == 0xfe);
  return Result::Ok;
}

Result BinaryReaderIR::OnAtomicLoadExpr(Opcode opcode,
                                        Index memidx,
                                        Address alignment_log2,
                                        Address offset) {
  return AppendExpr(std::make_unique<AtomicLoadExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnAtomicStoreExpr(Opcode opcode,
                                         Index memidx,
                                         Address alignment_log2,
                                         Address offset) {
  return AppendExpr(std::make_unique<AtomicStoreExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnAtomicRmwExpr(Opcode opcode,
                                       Index memidx,
                                       Address alignment_log2,
                                       Address offset) {
  return AppendExpr(std::make_unique<AtomicRmwExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnAtomicRmwCmpxchgExpr(Opcode opcode,
                                              Index memidx,
                                              Address alignment_log2,
                                              Address offset) {
  return AppendExpr(std::make_unique<AtomicRmwCmpxchgExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnAtomicWaitExpr(Opcode opcode,
                                        Index memidx,
                                        Address alignment_log2,
                                        Address offset) {
  return AppendExpr(std::make_unique<AtomicWaitExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnAtomicFenceExpr(uint32_t consistency_model) {
  return AppendExpr(std::make_unique<AtomicFenceExpr>(consistency_model));
}

Result BinaryReaderIR::OnAtomicNotifyExpr(Opcode opcode,
                                          Index memidx,
                                          Address alignment_log2,
                                          Address offset) {
  return AppendExpr(std::make_unique<AtomicNotifyExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnBinaryExpr(Opcode opcode) {
  return AppendExpr(std::make_unique<BinaryExpr>(opcode));
}

Result BinaryReaderIR::OnBlockExpr(Type sig_type) {
  auto expr = std::make_unique<BlockExpr>();
  SetBlockDeclaration(&expr->block.decl, sig_type);
  ExprList* expr_list = &expr->block.exprs;
  CHECK_RESULT(AppendExpr(std::move(expr)));
  return PushLabel(LabelType::Block, expr_list);
}

Result BinaryReaderIR::OnBrExpr(Index depth) {
  return AppendExpr(std::make_unique<BrExpr>(Var(depth, GetLocation())));
}

Result BinaryReaderIR::OnBrIfExpr(Index depth) {
  return AppendExpr(std::make_unique<BrIfExpr>(Var(depth, GetLocation())));
}

Result BinaryReaderIR::OnBrTableExpr(Index num_targets,
                                     Index* target_depths,
                                     Index default_target_depth) {
  auto expr = std::make_unique<BrTableExpr>();
  expr->default_target = Var(default_target_depth, GetLocation());
  expr->targets.resize(num_targets);
  for (Index i = 0; i < num_targets; ++i) {
    expr->targets[i] = Var(target_depths[i], GetLocation());
  }
  return AppendExpr(std::move(expr));
}

Result BinaryReaderIR::OnCallExpr(Index func_index) {
  return AppendExpr(std::make_unique<CallExpr>(Var(func_index, GetLocation())));
}

Result BinaryReaderIR::OnCallIndirectExpr(Index sig_index, Index table_index) {
  auto expr = std::make_unique<CallIndirectExpr>();
  SetFuncDeclaration(&expr->decl, Var(sig_index, GetLocation()));
  expr->table = Var(table_index, GetLocation());
  return AppendExpr(std::move(expr));
}

Result BinaryReaderIR::OnCallRefExpr() {
  return AppendExpr(std::make_unique<CallRefExpr>());
}

Result BinaryReaderIR::OnReturnCallExpr(Index func_index) {
  if (current_func_) {
    // syntactically, a return_call expr can occur in an init expression
    // (outside a function)
    current_func_->features_used.tailcall = true;
  }
  return AppendExpr(
      std::make_unique<ReturnCallExpr>(Var(func_index, GetLocation())));
}

Result BinaryReaderIR::OnReturnCallIndirectExpr(Index sig_index,
                                                Index table_index) {
  if (current_func_) {
    // syntactically, a return_call_indirect expr can occur in an init
    // expression (outside a function)
    current_func_->features_used.tailcall = true;
  }
  auto expr = std::make_unique<ReturnCallIndirectExpr>();
  SetFuncDeclaration(&expr->decl, Var(sig_index, GetLocation()));
  expr->table = Var(table_index, GetLocation());
  FuncType* type = module_->GetFuncType(Var(sig_index, GetLocation()));
  if (type) {
    type->features_used.tailcall = true;
  }
  return AppendExpr(std::move(expr));
}

Result BinaryReaderIR::OnCompareExpr(Opcode opcode) {
  return AppendExpr(std::make_unique<CompareExpr>(opcode));
}

Result BinaryReaderIR::OnConvertExpr(Opcode opcode) {
  return AppendExpr(std::make_unique<ConvertExpr>(opcode));
}

Result BinaryReaderIR::OnDropExpr() {
  return AppendExpr(std::make_unique<DropExpr>());
}

Result BinaryReaderIR::OnElseExpr() {
  LabelNode* label;
  Expr* expr;
  CHECK_RESULT(TopLabelExpr(&label, &expr));

  if (label->label_type == LabelType::If) {
    auto* if_expr = cast<IfExpr>(expr);
    if_expr->true_.end_loc = GetLocation();
    label->exprs = &if_expr->false_;
    label->label_type = LabelType::Else;
  } else {
    PrintError("else expression without matching if");
    return Result::Error;
  }

  return Result::Ok;
}

Result BinaryReaderIR::OnEndExpr() {
  if (label_stack_.size() > 1) {
    LabelNode* label;
    Expr* expr;
    CHECK_RESULT(TopLabelExpr(&label, &expr));
    switch (label->label_type) {
      case LabelType::Block:
        cast<BlockExpr>(expr)->block.end_loc = GetLocation();
        break;
      case LabelType::Loop:
        cast<LoopExpr>(expr)->block.end_loc = GetLocation();
        break;
      case LabelType::If:
        cast<IfExpr>(expr)->true_.end_loc = GetLocation();
        break;
      case LabelType::Else:
        cast<IfExpr>(expr)->false_end_loc = GetLocation();
        break;
      case LabelType::Try:
        cast<TryExpr>(expr)->block.end_loc = GetLocation();
        break;
      case LabelType::TryTable:
        cast<TryTableExpr>(expr)->block.end_loc = GetLocation();
        break;

      case LabelType::InitExpr:
      case LabelType::Func:
      case LabelType::Catch:
        break;
    }
  }

  return PopLabel();
}

Result BinaryReaderIR::OnF32ConstExpr(uint32_t value_bits) {
  return AppendExpr(
      std::make_unique<ConstExpr>(Const::F32(value_bits, GetLocation())));
}

Result BinaryReaderIR::OnF64ConstExpr(uint64_t value_bits) {
  return AppendExpr(
      std::make_unique<ConstExpr>(Const::F64(value_bits, GetLocation())));
}

Result BinaryReaderIR::OnV128ConstExpr(v128 value_bits) {
  return AppendExpr(
      std::make_unique<ConstExpr>(Const::V128(value_bits, GetLocation())));
}

Result BinaryReaderIR::OnGlobalGetExpr(Index global_index) {
  return AppendExpr(
      std::make_unique<GlobalGetExpr>(Var(global_index, GetLocation())));
}

Result BinaryReaderIR::OnLocalGetExpr(Index local_index) {
  return AppendExpr(
      std::make_unique<LocalGetExpr>(Var(local_index, GetLocation())));
}

Result BinaryReaderIR::OnI32ConstExpr(uint32_t value) {
  return AppendExpr(
      std::make_unique<ConstExpr>(Const::I32(value, GetLocation())));
}

Result BinaryReaderIR::OnI64ConstExpr(uint64_t value) {
  return AppendExpr(
      std::make_unique<ConstExpr>(Const::I64(value, GetLocation())));
}

Result BinaryReaderIR::OnIfExpr(Type sig_type) {
  auto expr = std::make_unique<IfExpr>();
  SetBlockDeclaration(&expr->true_.decl, sig_type);
  ExprList* expr_list = &expr->true_.exprs;
  CHECK_RESULT(AppendExpr(std::move(expr)));
  return PushLabel(LabelType::If, expr_list);
}

Result BinaryReaderIR::OnLoadExpr(Opcode opcode,
                                  Index memidx,
                                  Address alignment_log2,
                                  Address offset) {
  return AppendExpr(std::make_unique<LoadExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnLoopExpr(Type sig_type) {
  auto expr = std::make_unique<LoopExpr>();
  SetBlockDeclaration(&expr->block.decl, sig_type);
  ExprList* expr_list = &expr->block.exprs;
  CHECK_RESULT(AppendExpr(std::move(expr)));
  return PushLabel(LabelType::Loop, expr_list);
}

Result BinaryReaderIR::OnMemoryCopyExpr(Index destmemidx, Index srcmemidx) {
  return AppendExpr(std::make_unique<MemoryCopyExpr>(
      Var(destmemidx, GetLocation()), Var(srcmemidx, GetLocation())));
}

Result BinaryReaderIR::OnDataDropExpr(Index segment) {
  return AppendExpr(
      std::make_unique<DataDropExpr>(Var(segment, GetLocation())));
}

Result BinaryReaderIR::OnMemoryFillExpr(Index memidx) {
  return AppendExpr(
      std::make_unique<MemoryFillExpr>(Var(memidx, GetLocation())));
}

Result BinaryReaderIR::OnMemoryGrowExpr(Index memidx) {
  return AppendExpr(
      std::make_unique<MemoryGrowExpr>(Var(memidx, GetLocation())));
}

Result BinaryReaderIR::OnMemoryInitExpr(Index segment, Index memidx) {
  return AppendExpr(std::make_unique<MemoryInitExpr>(
      Var(segment, GetLocation()), Var(memidx, GetLocation())));
}

Result BinaryReaderIR::OnMemorySizeExpr(Index memidx) {
  return AppendExpr(
      std::make_unique<MemorySizeExpr>(Var(memidx, GetLocation())));
}

Result BinaryReaderIR::OnTableCopyExpr(Index dst_index, Index src_index) {
  return AppendExpr(std::make_unique<TableCopyExpr>(
      Var(dst_index, GetLocation()), Var(src_index, GetLocation())));
}

Result BinaryReaderIR::OnElemDropExpr(Index segment) {
  return AppendExpr(
      std::make_unique<ElemDropExpr>(Var(segment, GetLocation())));
}

Result BinaryReaderIR::OnTableInitExpr(Index segment, Index table_index) {
  return AppendExpr(std::make_unique<TableInitExpr>(
      Var(segment, GetLocation()), Var(table_index, GetLocation())));
}

Result BinaryReaderIR::OnTableGetExpr(Index table_index) {
  return AppendExpr(
      std::make_unique<TableGetExpr>(Var(table_index, GetLocation())));
}

Result BinaryReaderIR::OnTableSetExpr(Index table_index) {
  return AppendExpr(
      std::make_unique<TableSetExpr>(Var(table_index, GetLocation())));
}

Result BinaryReaderIR::OnTableGrowExpr(Index table_index) {
  return AppendExpr(
      std::make_unique<TableGrowExpr>(Var(table_index, GetLocation())));
}

Result BinaryReaderIR::OnTableSizeExpr(Index table_index) {
  return AppendExpr(
      std::make_unique<TableSizeExpr>(Var(table_index, GetLocation())));
}

Result BinaryReaderIR::OnTableFillExpr(Index table_index) {
  return AppendExpr(
      std::make_unique<TableFillExpr>(Var(table_index, GetLocation())));
}

Result BinaryReaderIR::OnRefFuncExpr(Index func_index) {
  module_->used_func_refs.insert(func_index);
  return AppendExpr(
      std::make_unique<RefFuncExpr>(Var(func_index, GetLocation())));
}

Result BinaryReaderIR::OnRefNullExpr(Type type) {
  module_->features_used.exceptions |= (type == Type::ExnRef);
  return AppendExpr(std::make_unique<RefNullExpr>(type));
}

Result BinaryReaderIR::OnRefIsNullExpr() {
  return AppendExpr(std::make_unique<RefIsNullExpr>());
}

Result BinaryReaderIR::OnNopExpr() {
  return AppendExpr(std::make_unique<NopExpr>());
}

Result BinaryReaderIR::OnRethrowExpr(Index depth) {
  return AppendExpr(std::make_unique<RethrowExpr>(Var(depth, GetLocation())));
}

Result BinaryReaderIR::OnReturnExpr() {
  return AppendExpr(std::make_unique<ReturnExpr>());
}

Result BinaryReaderIR::OnSelectExpr(Index result_count, Type* result_types) {
  TypeVector results;
  results.assign(result_types, result_types + result_count);
  return AppendExpr(std::make_unique<SelectExpr>(results));
}

Result BinaryReaderIR::OnGlobalSetExpr(Index global_index) {
  return AppendExpr(
      std::make_unique<GlobalSetExpr>(Var(global_index, GetLocation())));
}

Result BinaryReaderIR::OnLocalSetExpr(Index local_index) {
  return AppendExpr(
      std::make_unique<LocalSetExpr>(Var(local_index, GetLocation())));
}

Result BinaryReaderIR::OnStoreExpr(Opcode opcode,
                                   Index memidx,
                                   Address alignment_log2,
                                   Address offset) {
  return AppendExpr(std::make_unique<StoreExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnThrowExpr(Index tag_index) {
  module_->features_used.exceptions = true;
  return AppendExpr(std::make_unique<ThrowExpr>(Var(tag_index, GetLocation())));
}

Result BinaryReaderIR::OnThrowRefExpr() {
  module_->features_used.exceptions = true;
  return AppendExpr(std::make_unique<ThrowRefExpr>());
}

Result BinaryReaderIR::OnLocalTeeExpr(Index local_index) {
  return AppendExpr(
      std::make_unique<LocalTeeExpr>(Var(local_index, GetLocation())));
}

Result BinaryReaderIR::OnTryExpr(Type sig_type) {
  auto expr_ptr = std::make_unique<TryExpr>();
  // Save expr so it can be used below, after expr_ptr has been moved.
  TryExpr* expr = expr_ptr.get();
  ExprList* expr_list = &expr->block.exprs;
  SetBlockDeclaration(&expr->block.decl, sig_type);
  CHECK_RESULT(AppendExpr(std::move(expr_ptr)));
  module_->features_used.exceptions = true;
  return PushLabel(LabelType::Try, expr_list, expr);
}

Result BinaryReaderIR::AppendCatch(Catch&& catch_) {
  LabelNode* label = nullptr;
  CHECK_RESULT(TopLabel(&label));

  if (label->label_type != LabelType::Try) {
    PrintError("catch not inside try block");
    return Result::Error;
  }

  auto* try_ = cast<TryExpr>(label->context);

  if (catch_.IsCatchAll() && !try_->catches.empty() &&
      try_->catches.back().IsCatchAll()) {
    PrintError("only one catch_all allowed in try block");
    return Result::Error;
  }

  if (try_->kind == TryKind::Plain) {
    try_->kind = TryKind::Catch;
  } else if (try_->kind != TryKind::Catch) {
    PrintError("catch not allowed in try-delegate");
    return Result::Error;
  }

  try_->catches.push_back(std::move(catch_));
  label->exprs = &try_->catches.back().exprs;
  return Result::Ok;
}

Result BinaryReaderIR::OnCatchExpr(Index except_index) {
  return AppendCatch(Catch(Var(except_index, GetLocation())));
}

Result BinaryReaderIR::OnCatchAllExpr() {
  return AppendCatch(Catch(GetLocation()));
}

Result BinaryReaderIR::OnTryTableExpr(Type sig_type,
                                      const CatchClauseVector& catches) {
  auto expr_ptr = std::make_unique<TryTableExpr>();
  TryTableExpr* expr = expr_ptr.get();
  expr->catches.reserve(catches.size());
  SetBlockDeclaration(&expr->block.decl, sig_type);
  ExprList* expr_list = &expr->block.exprs;

  for (auto& raw_catch : catches) {
    TableCatch catch_;
    catch_.kind = raw_catch.kind;
    catch_.tag = Var(raw_catch.tag, GetLocation());
    catch_.target = Var(raw_catch.depth, GetLocation());
    expr->catches.push_back(std::move(catch_));
  }

  CHECK_RESULT(AppendExpr(std::move(expr_ptr)));
  module_->features_used.exceptions = true;
  return PushLabel(LabelType::TryTable, expr_list, expr);
}

Result BinaryReaderIR::OnDelegateExpr(Index depth) {
  LabelNode* label = nullptr;
  CHECK_RESULT(TopLabel(&label));

  if (label->label_type != LabelType::Try) {
    PrintError("delegate not inside try block");
    return Result::Error;
  }

  auto* try_ = cast<TryExpr>(label->context);

  if (try_->kind == TryKind::Plain) {
    try_->kind = TryKind::Delegate;
  } else if (try_->kind != TryKind::Delegate) {
    PrintError("delegate not allowed in try-catch");
    return Result::Error;
  }

  try_->delegate_target = Var(depth, GetLocation());

  PopLabel();
  return Result::Ok;
}

Result BinaryReaderIR::OnUnaryExpr(Opcode opcode) {
  return AppendExpr(std::make_unique<UnaryExpr>(opcode));
}

Result BinaryReaderIR::OnTernaryExpr(Opcode opcode) {
  return AppendExpr(std::make_unique<TernaryExpr>(opcode));
}

Result BinaryReaderIR::OnUnreachableExpr() {
  return AppendExpr(std::make_unique<UnreachableExpr>());
}

Result BinaryReaderIR::EndFunctionBody(Index index) {
  current_func_ = nullptr;
  if (!label_stack_.empty()) {
    PrintError("function %" PRIindex " missing end marker", index);
    return Result::Error;
  }
  return Result::Ok;
}

Result BinaryReaderIR::OnSimdLaneOpExpr(Opcode opcode, uint64_t value) {
  return AppendExpr(std::make_unique<SimdLaneOpExpr>(opcode, value));
}

Result BinaryReaderIR::OnSimdLoadLaneExpr(Opcode opcode,
                                          Index memidx,
                                          Address alignment_log2,
                                          Address offset,
                                          uint64_t value) {
  return AppendExpr(std::make_unique<SimdLoadLaneExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset,
      value));
}

Result BinaryReaderIR::OnSimdStoreLaneExpr(Opcode opcode,
                                           Index memidx,
                                           Address alignment_log2,
                                           Address offset,
                                           uint64_t value) {
  return AppendExpr(std::make_unique<SimdStoreLaneExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset,
      value));
}

Result BinaryReaderIR::OnSimdShuffleOpExpr(Opcode opcode, v128 value) {
  return AppendExpr(std::make_unique<SimdShuffleOpExpr>(opcode, value));
}

Result BinaryReaderIR::OnLoadSplatExpr(Opcode opcode,
                                       Index memidx,
                                       Address alignment_log2,
                                       Address offset) {
  return AppendExpr(std::make_unique<LoadSplatExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnLoadZeroExpr(Opcode opcode,
                                      Index memidx,
                                      Address alignment_log2,
                                      Address offset) {
  return AppendExpr(std::make_unique<LoadZeroExpr>(
      opcode, Var(memidx, GetLocation()), 1ull << alignment_log2, offset));
}

Result BinaryReaderIR::OnElemSegmentCount(Index count) {
  WABT_TRY
  module_->elem_segments.reserve(count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::BeginElemSegment(Index index,
                                        Index table_index,
                                        uint8_t flags) {
  auto field = std::make_unique<ElemSegmentModuleField>(GetLocation());
  ElemSegment& elem_segment = field->elem_segment;
  elem_segment.table_var = Var(table_index, GetLocation());
  if ((flags & SegDeclared) == SegDeclared) {
    elem_segment.kind = SegmentKind::Declared;
  } else if ((flags & SegPassive) == SegPassive) {
    elem_segment.kind = SegmentKind::Passive;
  } else {
    elem_segment.kind = SegmentKind::Active;
  }
  module_->AppendField(std::move(field));
  return Result::Ok;
}

Result BinaryReaderIR::BeginInitExpr(ExprList* expr) {
  return PushLabel(LabelType::InitExpr, expr);
}

Result BinaryReaderIR::BeginElemSegmentInitExpr(Index index) {
  assert(index == module_->elem_segments.size() - 1);
  ElemSegment* segment = module_->elem_segments[index];
  return BeginInitExpr(&segment->offset);
}

Result BinaryReaderIR::EndInitExpr() {
  if (!label_stack_.empty()) {
    PrintError("init expression missing end marker");
    return Result::Error;
  }
  return Result::Ok;
}

Result BinaryReaderIR::EndElemSegmentInitExpr(Index index) {
  return EndInitExpr();
}

Result BinaryReaderIR::OnElemSegmentElemType(Index index, Type elem_type) {
  assert(index == module_->elem_segments.size() - 1);
  ElemSegment* segment = module_->elem_segments[index];
  segment->elem_type = elem_type;
  return Result::Ok;
}

Result BinaryReaderIR::OnElemSegmentElemExprCount(Index index, Index count) {
  assert(index == module_->elem_segments.size() - 1);
  ElemSegment* segment = module_->elem_segments[index];
  WABT_TRY
  segment->elem_exprs.reserve(count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::BeginElemExpr(Index elem_index, Index expr_index) {
  assert(elem_index == module_->elem_segments.size() - 1);
  ElemSegment* segment = module_->elem_segments[elem_index];
  assert(expr_index == segment->elem_exprs.size());
  segment->elem_exprs.emplace_back();
  return BeginInitExpr(&segment->elem_exprs.back());
}

Result BinaryReaderIR::EndElemExpr(Index elem_index, Index expr_index) {
  return EndInitExpr();
}

Result BinaryReaderIR::OnDataSegmentCount(Index count) {
  WABT_TRY
  module_->data_segments.reserve(count);
  WABT_CATCH_BAD_ALLOC
  return Result::Ok;
}

Result BinaryReaderIR::BeginDataSegment(Index index,
                                        Index memory_index,
                                        uint8_t flags) {
  auto field = std::make_unique<DataSegmentModuleField>(GetLocation());
  DataSegment& data_segment = field->data_segment;
  data_segment.memory_var = Var(memory_index, GetLocation());
  if ((flags & SegPassive) == SegPassive) {
    data_segment.kind = SegmentKind::Passive;
  } else {
    data_segment.kind = SegmentKind::Active;
  }
  module_->AppendField(std::move(field));
  return Result::Ok;
}

Result BinaryReaderIR::BeginDataSegmentInitExpr(Index index) {
  assert(index == module_->data_segments.size() - 1);
  DataSegment* segment = module_->data_segments[index];
  return BeginInitExpr(&segment->offset);
}

Result BinaryReaderIR::EndDataSegmentInitExpr(Index index) {
  return EndInitExpr();
}

Result BinaryReaderIR::OnDataSegmentData(Index index,
                                         const void* data,
                                         Address size) {
  assert(index == module_->data_segments.size() - 1);
  DataSegment* segment = module_->data_segments[index];
  segment->data.resize(size);
  if (size > 0) {
    memcpy(segment->data.data(), data, size);
  }
  return Result::Ok;
}

Result BinaryReaderIR::OnFunctionNamesCount(Index count) {
  if (count > module_->funcs.size()) {
    PrintError("expected function name count (%" PRIindex
               ") <= function count (%" PRIzd ")",
               count, module_->funcs.size());
    return Result::Error;
  }
  return Result::Ok;
}

static std::string MakeDollarName(std::string_view name) {
  return std::string("$") + std::string(name);
}

Result BinaryReaderIR::OnModuleName(std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }

  module_->name = MakeDollarName(name);
  return Result::Ok;
}

Result BinaryReaderIR::SetGlobalName(Index index, std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (index >= module_->globals.size()) {
    PrintError("invalid global index: %" PRIindex, index);
    return Result::Error;
  }
  Global* glob = module_->globals[index];
  std::string dollar_name =
      GetUniqueName(&module_->global_bindings, MakeDollarName(name));
  glob->name = dollar_name;
  module_->global_bindings.emplace(dollar_name, Binding(index));
  return Result::Ok;
}

Result BinaryReaderIR::SetFunctionName(Index index, std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (index >= module_->funcs.size()) {
    PrintError("invalid function index: %" PRIindex, index);
    return Result::Error;
  }
  Func* func = module_->funcs[index];
  std::string dollar_name =
      GetUniqueName(&module_->func_bindings, MakeDollarName(name));
  func->name = dollar_name;
  module_->func_bindings.emplace(dollar_name, Binding(index));
  return Result::Ok;
}

Result BinaryReaderIR::SetTypeName(Index index, std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (index >= module_->types.size()) {
    PrintError("invalid type index: %" PRIindex, index);
    return Result::Error;
  }
  TypeEntry* type = module_->types[index];
  std::string dollar_name =
      GetUniqueName(&module_->type_bindings, MakeDollarName(name));
  type->name = dollar_name;
  module_->type_bindings.emplace(dollar_name, Binding(index));
  return Result::Ok;
}

Result BinaryReaderIR::SetTableName(Index index, std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (index >= module_->tables.size()) {
    PrintError("invalid table index: %" PRIindex, index);
    return Result::Error;
  }
  Table* table = module_->tables[index];
  std::string dollar_name =
      GetUniqueName(&module_->table_bindings, MakeDollarName(name));
  table->name = dollar_name;
  module_->table_bindings.emplace(dollar_name, Binding(index));
  return Result::Ok;
}

Result BinaryReaderIR::SetDataSegmentName(Index index, std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (index >= module_->data_segments.size()) {
    PrintError("invalid data segment index: %" PRIindex, index);
    return Result::Error;
  }
  DataSegment* segment = module_->data_segments[index];
  std::string dollar_name =
      GetUniqueName(&module_->data_segment_bindings, MakeDollarName(name));
  segment->name = dollar_name;
  module_->data_segment_bindings.emplace(dollar_name, Binding(index));
  return Result::Ok;
}

Result BinaryReaderIR::SetElemSegmentName(Index index, std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (index >= module_->elem_segments.size()) {
    PrintError("invalid elem segment index: %" PRIindex, index);
    return Result::Error;
  }
  ElemSegment* segment = module_->elem_segments[index];
  std::string dollar_name =
      GetUniqueName(&module_->elem_segment_bindings, MakeDollarName(name));
  segment->name = dollar_name;
  module_->elem_segment_bindings.emplace(dollar_name, Binding(index));
  return Result::Ok;
}

Result BinaryReaderIR::SetMemoryName(Index index, std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (index >= module_->memories.size()) {
    PrintError("invalid memory index: %" PRIindex, index);
    return Result::Error;
  }
  Memory* memory = module_->memories[index];
  std::string dollar_name =
      GetUniqueName(&module_->memory_bindings, MakeDollarName(name));
  memory->name = dollar_name;
  module_->memory_bindings.emplace(dollar_name, Binding(index));
  return Result::Ok;
}

Result BinaryReaderIR::SetTagName(Index index, std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (index >= module_->tags.size()) {
    PrintError("invalid tag index: %" PRIindex, index);
    return Result::Error;
  }
  Tag* tag = module_->tags[index];
  std::string dollar_name =
      GetUniqueName(&module_->tag_bindings, MakeDollarName(name));
  tag->name = dollar_name;
  module_->tag_bindings.emplace(dollar_name, Binding(index));
  return Result::Ok;
}

Result BinaryReaderIR::OnFunctionName(Index index, std::string_view name) {
  return SetFunctionName(index, name);
}

Result BinaryReaderIR::OnNameEntry(NameSectionSubsection type,
                                   Index index,
                                   std::string_view name) {
  switch (type) {
    // TODO(sbc): remove OnFunctionName in favor of just using
    // OnNameEntry so that this works
    case NameSectionSubsection::Function:
    case NameSectionSubsection::Local:
    case NameSectionSubsection::Module:
    case NameSectionSubsection::Label:
    case NameSectionSubsection::Field:
      break;
    case NameSectionSubsection::Type:
      SetTypeName(index, name);
      break;
    case NameSectionSubsection::Tag:
      SetTagName(index, name);
      break;
    case NameSectionSubsection::Global:
      SetGlobalName(index, name);
      break;
    case NameSectionSubsection::Table:
      SetTableName(index, name);
      break;
    case NameSectionSubsection::DataSegment:
      SetDataSegmentName(index, name);
      break;
    case NameSectionSubsection::Memory:
      SetMemoryName(index, name);
      break;
    case NameSectionSubsection::ElemSegment:
      SetElemSegmentName(index, name);
      break;
  }
  return Result::Ok;
}

Result BinaryReaderIR::OnLocalNameLocalCount(Index index, Index count) {
  assert(index < module_->funcs.size());
  Func* func = module_->funcs[index];
  Index num_params_and_locals = func->GetNumParamsAndLocals();
  if (count > num_params_and_locals) {
    PrintError("expected local name count (%" PRIindex
               ") <= local count (%" PRIindex ")",
               count, num_params_and_locals);
    return Result::Error;
  }
  return Result::Ok;
}

Result BinaryReaderIR::BeginCodeMetadataSection(std::string_view name,
                                                Offset size) {
  current_metadata_name_ = name;
  return Result::Ok;
}

Result BinaryReaderIR::OnCodeMetadataFuncCount(Index count) {
  return Result::Ok;
}

Result BinaryReaderIR::OnCodeMetadataCount(Index function_index, Index count) {
  code_metadata_queue_.push_func(module_->funcs[function_index]);
  return Result::Ok;
}

Result BinaryReaderIR::OnCodeMetadata(Offset offset,
                                      const void* data,
                                      Address size) {
  std::vector<uint8_t> data_(static_cast<const uint8_t*>(data),
                             static_cast<const uint8_t*>(data) + size);
  auto meta = std::make_unique<CodeMetadataExpr>(current_metadata_name_,
                                                 std::move(data_));
  meta->loc.offset = offset;
  code_metadata_queue_.push_metadata(std::move(meta));
  return Result::Ok;
}

Result BinaryReaderIR::OnLocalName(Index func_index,
                                   Index local_index,
                                   std::string_view name) {
  if (name.empty()) {
    return Result::Ok;
  }

  Func* func = module_->funcs[func_index];
  func->bindings.emplace(GetUniqueName(&func->bindings, MakeDollarName(name)),
                         Binding(local_index));
  return Result::Ok;
}

Result BinaryReaderIR::OnTagType(Index index, Index sig_index) {
  auto field = std::make_unique<TagModuleField>(GetLocation());
  Tag& tag = field->tag;
  SetFuncDeclaration(&tag.decl, Var(sig_index, GetLocation()));
  module_->AppendField(std::move(field));
  module_->features_used.exceptions = true;
  return Result::Ok;
}

Result BinaryReaderIR::OnDataSymbol(Index index,
                                    uint32_t flags,
                                    std::string_view name,
                                    Index segment,
                                    uint32_t offset,
                                    uint32_t size) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (flags & WABT_SYMBOL_FLAG_UNDEFINED) {
    // Refers to data in another file, `segment` not valid.
    return Result::Ok;
  }
  if (offset) {
    // If it is pointing into the data segment, then it's not really naming
    // the whole segment.
    return Result::Ok;
  }
  if (segment >= module_->data_segments.size()) {
    PrintError("invalid data segment index: %" PRIindex, segment);
    return Result::Error;
  }
  DataSegment* seg = module_->data_segments[segment];
  std::string dollar_name =
      GetUniqueName(&module_->data_segment_bindings, MakeDollarName(name));
  seg->name = dollar_name;
  module_->data_segment_bindings.emplace(dollar_name, Binding(segment));
  return Result::Ok;
}

Result BinaryReaderIR::OnFunctionSymbol(Index index,
                                        uint32_t flags,
                                        std::string_view name,
                                        Index func_index) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (func_index >= module_->funcs.size()) {
    PrintError("invalid function index: %" PRIindex, func_index);
    return Result::Error;
  }
  Func* func = module_->funcs[func_index];
  if (!func->name.empty()) {
    // The name section has already named this function.
    return Result::Ok;
  }
  std::string dollar_name =
      GetUniqueName(&module_->func_bindings, MakeDollarName(name));
  func->name = dollar_name;
  module_->func_bindings.emplace(dollar_name, Binding(func_index));
  return Result::Ok;
}

Result BinaryReaderIR::OnGlobalSymbol(Index index,
                                      uint32_t flags,
                                      std::string_view name,
                                      Index global_index) {
  return SetGlobalName(global_index, name);
}

Result BinaryReaderIR::OnSectionSymbol(Index index,
                                       uint32_t flags,
                                       Index section_index) {
  return Result::Ok;
}

Result BinaryReaderIR::OnTagSymbol(Index index,
                                   uint32_t flags,
                                   std::string_view name,
                                   Index tag_index) {
  if (name.empty()) {
    return Result::Ok;
  }
  if (tag_index >= module_->tags.size()) {
    PrintError("invalid tag index: %" PRIindex, tag_index);
    return Result::Error;
  }
  Tag* tag = module_->tags[tag_index];
  std::string dollar_name =
      GetUniqueName(&module_->tag_bindings, MakeDollarName(name));
  tag->name = dollar_name;
  module_->tag_bindings.emplace(dollar_name, Binding(tag_index));
  return Result::Ok;
}

Result BinaryReaderIR::OnTableSymbol(Index index,
                                     uint32_t flags,
                                     std::string_view name,
                                     Index table_index) {
  return SetTableName(table_index, name);
}

Result BinaryReaderIR::OnGenericCustomSection(std::string_view name,
                                              const void* data,
                                              Offset size) {
  Custom custom = Custom(GetLocation(), name);
  custom.data.resize(size);
  if (size > 0) {
    memcpy(custom.data.data(), data, size);
  }
  module_->customs.push_back(std::move(custom));
  return Result::Ok;
}

}  // end anonymous namespace

Result ReadBinaryIr(const char* filename,
                    const void* data,
                    size_t size,
                    const ReadBinaryOptions& options,
                    Errors* errors,
                    Module* out_module) {
  BinaryReaderIR reader(out_module, filename, errors);
  return ReadBinary(data, size, &reader, options);
}

}  // namespace wabt
