/*
 * 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 BeginTable(Index index,
                    Type elem_type,
                    const Limits* elem_limits,
                    TableInitExprStatus init_provided) override;
  Result BeginTableInitExpr(Index index) override;
  Result EndTableInitExpr(Index index) 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 OnUnaryExpr(Opcode opcode) override;
  Result OnBinaryExpr(Opcode opcode) override;
  Result OnTernaryExpr(Opcode opcode) override;
  Result OnQuaternaryExpr(Opcode opcode) override;
  Result OnBlockExpr(Type sig_type) override;
  Result OnBrExpr(Index depth) override;
  Result OnBrIfExpr(Index depth) override;
  Result OnBrOnNonNullExpr(Index depth) override;
  Result OnBrOnNullExpr(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(Type sig_type) override;
  Result OnReturnCallExpr(Index func_index) override;
  Result OnReturnCallIndirectExpr(Index sig_index, Index table_index) override;
  Result OnReturnCallRefExpr(Type sig_type) 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 OnRefAsNonNullExpr() 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 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_;

  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) {
  out_module->filename = filename;
}

Location BinaryReaderIR::GetLocation() const {
  Location loc;
  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),
                        std::string_view(), 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::BeginTable(Index index,
                                  Type elem_type,
                                  const Limits* elem_limits,
                                  TableInitExprStatus) {
  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::BeginTableInitExpr(Index index) {
  assert(index == module_->tables.size() - 1);
  Table* table = module_->tables[index];
  return BeginInitExpr(&table->init_expr);
}

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

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::OnBrOnNonNullExpr(Index depth) {
  return AppendExpr(
      std::make_unique<BrOnNonNullExpr>(Var(depth, GetLocation())));
}

Result BinaryReaderIR::OnBrOnNullExpr(Index depth) {
  return AppendExpr(std::make_unique<BrOnNullExpr>(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(Type sig_type) {
  auto expr = std::make_unique<CallRefExpr>();
  expr->sig_type = Var(sig_type, GetLocation());
  return AppendExpr(std::move(expr));
}

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::OnReturnCallRefExpr(Type sig_type) {
  auto expr = std::make_unique<ReturnCallRefExpr>();
  expr->sig_type = Var(sig_type, GetLocation());
  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::OnRefAsNonNullExpr() {
  return AppendExpr(
      std::make_unique<RefAsNonNullExpr>(Opcode::RefAsNonNull, 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>(Var(type, GetLocation())));
}

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) {
  auto expr_ptr = std::make_unique<SelectExpr>();
  expr_ptr->result_type.assign(result_types, result_types + result_count);
  return AppendExpr(std::move(expr_ptr));
}

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::OnQuaternaryExpr(Opcode opcode) {
  return AppendExpr(std::make_unique<QuaternaryExpr>(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) {
  if (function_index < module_->funcs.size()) {
    code_metadata_queue_.push_func(module_->funcs[function_index]);
    return Result::Ok;
  }
  return Result::Error;
}

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
