// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_TORQUE_INSTRUCTIONS_H_
#define V8_TORQUE_INSTRUCTIONS_H_

#include <memory>

#include "src/torque/ast.h"
#include "src/torque/source-positions.h"
#include "src/torque/types.h"
#include "src/torque/utils.h"

namespace v8 {
namespace internal {
namespace torque {

class Block;
class Builtin;
class ControlFlowGraph;
class Intrinsic;
class Macro;
class NamespaceConstant;
class RuntimeFunction;

// Instructions where all backends generate code the same way.
#define TORQUE_BACKEND_AGNOSTIC_INSTRUCTION_LIST(V) \
  V(PeekInstruction)                                \
  V(PokeInstruction)                                \
  V(DeleteRangeInstruction)

// Instructions where different backends may generate different code.
#define TORQUE_BACKEND_DEPENDENT_INSTRUCTION_LIST(V) \
  V(PushUninitializedInstruction)                    \
  V(PushBuiltinPointerInstruction)                   \
  V(LoadReferenceInstruction)                        \
  V(StoreReferenceInstruction)                       \
  V(LoadBitFieldInstruction)                         \
  V(StoreBitFieldInstruction)                        \
  V(CallCsaMacroInstruction)                         \
  V(CallIntrinsicInstruction)                        \
  V(NamespaceConstantInstruction)                    \
  V(CallCsaMacroAndBranchInstruction)                \
  V(CallBuiltinInstruction)                          \
  V(CallRuntimeInstruction)                          \
  V(CallBuiltinPointerInstruction)                   \
  V(BranchInstruction)                               \
  V(ConstexprBranchInstruction)                      \
  V(GotoInstruction)                                 \
  V(GotoExternalInstruction)                         \
  V(ReturnInstruction)                               \
  V(PrintConstantStringInstruction)                  \
  V(AbortInstruction)                                \
  V(UnsafeCastInstruction)

#define TORQUE_INSTRUCTION_LIST(V)            \
  TORQUE_BACKEND_AGNOSTIC_INSTRUCTION_LIST(V) \
  TORQUE_BACKEND_DEPENDENT_INSTRUCTION_LIST(V)

#define TORQUE_INSTRUCTION_BOILERPLATE()                                  \
  static const InstructionKind kKind;                                     \
  std::unique_ptr<InstructionBase> Clone() const override;                \
  void Assign(const InstructionBase& other) override;                     \
  void TypeInstruction(Stack<const Type*>* stack, ControlFlowGraph* cfg)  \
      const override;                                                     \
  void RecomputeDefinitionLocations(Stack<DefinitionLocation>* locations, \
                                    Worklist<Block*>* worklist)           \
      const override;

enum class InstructionKind {
#define ENUM_ITEM(name) k##name,
  TORQUE_INSTRUCTION_LIST(ENUM_ITEM)
#undef ENUM_ITEM
};

struct InstructionBase;

class DefinitionLocation {
 public:
  enum class Kind {
    kInvalid,
    kParameter,
    kPhi,
    kInstruction,
  };

  DefinitionLocation() : kind_(Kind::kInvalid), location_(nullptr), index_(0) {}

  static DefinitionLocation Parameter(std::size_t index) {
    return DefinitionLocation(Kind::kParameter, nullptr, index);
  }

  static DefinitionLocation Phi(const Block* block, std::size_t index) {
    return DefinitionLocation(Kind::kPhi, block, index);
  }

  static DefinitionLocation Instruction(const InstructionBase* instruction,
                                        std::size_t index = 0) {
    return DefinitionLocation(Kind::kInstruction, instruction, index);
  }

  Kind GetKind() const { return kind_; }
  bool IsValid() const { return kind_ != Kind::kInvalid; }
  bool IsParameter() const { return kind_ == Kind::kParameter; }
  bool IsPhi() const { return kind_ == Kind::kPhi; }
  bool IsInstruction() const { return kind_ == Kind::kInstruction; }

  std::size_t GetParameterIndex() const {
    DCHECK(IsParameter());
    return index_;
  }

  const Block* GetPhiBlock() const {
    DCHECK(IsPhi());
    return reinterpret_cast<const Block*>(location_);
  }

  bool IsPhiFromBlock(const Block* block) const {
    return IsPhi() && GetPhiBlock() == block;
  }

  std::size_t GetPhiIndex() const {
    DCHECK(IsPhi());
    return index_;
  }

  const InstructionBase* GetInstruction() const {
    DCHECK(IsInstruction());
    return reinterpret_cast<const InstructionBase*>(location_);
  }

  std::size_t GetInstructionIndex() const {
    DCHECK(IsInstruction());
    return index_;
  }

  bool operator==(const DefinitionLocation& other) const {
    if (kind_ != other.kind_) return false;
    if (location_ != other.location_) return false;
    return index_ == other.index_;
  }

  bool operator!=(const DefinitionLocation& other) const {
    return !operator==(other);
  }

  bool operator<(const DefinitionLocation& other) const {
    if (kind_ != other.kind_) {
      return static_cast<int>(kind_) < static_cast<int>(other.kind_);
    }
    if (location_ != other.location_) {
      return location_ < other.location_;
    }
    return index_ < other.index_;
  }

 private:
  DefinitionLocation(Kind kind, const void* location, std::size_t index)
      : kind_(kind), location_(location), index_(index) {}

  Kind kind_;
  const void* location_;
  std::size_t index_;
};

inline std::ostream& operator<<(std::ostream& stream,
                                const DefinitionLocation& loc) {
  switch (loc.GetKind()) {
    case DefinitionLocation::Kind::kInvalid:
      return stream << "DefinitionLocation::Invalid()";
    case DefinitionLocation::Kind::kParameter:
      return stream << "DefinitionLocation::Parameter("
                    << loc.GetParameterIndex() << ")";
    case DefinitionLocation::Kind::kPhi:
      return stream << "DefinitionLocation::Phi(" << std::hex
                    << loc.GetPhiBlock() << std::dec << ", "
                    << loc.GetPhiIndex() << ")";
    case DefinitionLocation::Kind::kInstruction:
      return stream << "DefinitionLocation::Instruction(" << std::hex
                    << loc.GetInstruction() << std::dec << ", "
                    << loc.GetInstructionIndex() << ")";
  }
}

struct InstructionBase {
  InstructionBase() : pos(CurrentSourcePosition::Get()) {}
  virtual std::unique_ptr<InstructionBase> Clone() const = 0;
  virtual void Assign(const InstructionBase& other) = 0;
  virtual ~InstructionBase() = default;

  virtual void TypeInstruction(Stack<const Type*>* stack,
                               ControlFlowGraph* cfg) const = 0;
  virtual void RecomputeDefinitionLocations(
      Stack<DefinitionLocation>* locations,
      Worklist<Block*>* worklist) const = 0;
  void InvalidateTransientTypes(Stack<const Type*>* stack) const;
  virtual bool IsBlockTerminator() const { return false; }
  virtual void AppendSuccessorBlocks(std::vector<Block*>* block_list) const {}

  SourcePosition pos;
};

class Instruction {
 public:
  template <class T>
  Instruction(T instr)  // NOLINT(runtime/explicit)
      : kind_(T::kKind), instruction_(new T(std::move(instr))) {}

  template <class T>
  T& Cast() {
    DCHECK(Is<T>());
    return static_cast<T&>(*instruction_);
  }

  template <class T>
  const T& Cast() const {
    DCHECK(Is<T>());
    return static_cast<const T&>(*instruction_);
  }

  template <class T>
  bool Is() const {
    return kind_ == T::kKind;
  }

  template <class T>
  T* DynamicCast() {
    if (Is<T>()) return &Cast<T>();
    return nullptr;
  }

  template <class T>
  const T* DynamicCast() const {
    if (Is<T>()) return &Cast<T>();
    return nullptr;
  }

  Instruction(const Instruction& other) V8_NOEXCEPT
      : kind_(other.kind_),
        instruction_(other.instruction_->Clone()) {}
  Instruction& operator=(const Instruction& other) V8_NOEXCEPT {
    if (kind_ == other.kind_) {
      instruction_->Assign(*other.instruction_);
    } else {
      kind_ = other.kind_;
      instruction_ = other.instruction_->Clone();
    }
    return *this;
  }

  InstructionKind kind() const { return kind_; }
  const char* Mnemonic() const {
    switch (kind()) {
#define ENUM_ITEM(name)          \
  case InstructionKind::k##name: \
    return #name;
      TORQUE_INSTRUCTION_LIST(ENUM_ITEM)
#undef ENUM_ITEM
      default:
        UNREACHABLE();
    }
  }
  void TypeInstruction(Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
    return instruction_->TypeInstruction(stack, cfg);
  }
  void RecomputeDefinitionLocations(Stack<DefinitionLocation>* locations,
                                    Worklist<Block*>* worklist) const {
    instruction_->RecomputeDefinitionLocations(locations, worklist);
  }

  InstructionBase* operator->() { return instruction_.get(); }
  const InstructionBase* operator->() const { return instruction_.get(); }

 private:
  InstructionKind kind_;
  std::unique_ptr<InstructionBase> instruction_;
};

struct PeekInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()

  PeekInstruction(BottomOffset slot, base::Optional<const Type*> widened_type)
      : slot(slot), widened_type(widened_type) {}

  BottomOffset slot;
  base::Optional<const Type*> widened_type;
};

struct PokeInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()

  PokeInstruction(BottomOffset slot, base::Optional<const Type*> widened_type)
      : slot(slot), widened_type(widened_type) {}

  BottomOffset slot;
  base::Optional<const Type*> widened_type;
};

// Preserve the top {preserved_slots} number of slots, and delete
// {deleted_slots} number or slots below.
struct DeleteRangeInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  explicit DeleteRangeInstruction(StackRange range) : range(range) {}

  StackRange range;
};

struct PushUninitializedInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  explicit PushUninitializedInstruction(const Type* type) : type(type) {}

  DefinitionLocation GetValueDefinition() const;

  const Type* type;
};

struct PushBuiltinPointerInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  PushBuiltinPointerInstruction(std::string external_name, const Type* type)
      : external_name(std::move(external_name)), type(type) {
    DCHECK(type->IsBuiltinPointerType());
  }

  DefinitionLocation GetValueDefinition() const;

  std::string external_name;
  const Type* type;
};

struct NamespaceConstantInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  explicit NamespaceConstantInstruction(NamespaceConstant* constant)
      : constant(constant) {}

  std::size_t GetValueDefinitionCount() const;
  DefinitionLocation GetValueDefinition(std::size_t index) const;

  NamespaceConstant* constant;
};

struct LoadReferenceInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  explicit LoadReferenceInstruction(const Type* type) : type(type) {}

  DefinitionLocation GetValueDefinition() const;

  const Type* type;
};

struct StoreReferenceInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  explicit StoreReferenceInstruction(const Type* type) : type(type) {}
  const Type* type;
};

// Pops a bitfield struct; pushes a bitfield value extracted from it.
struct LoadBitFieldInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  LoadBitFieldInstruction(const Type* bit_field_struct_type, BitField bit_field)
      : bit_field_struct_type(bit_field_struct_type),
        bit_field(std::move(bit_field)) {}

  DefinitionLocation GetValueDefinition() const;

  const Type* bit_field_struct_type;
  BitField bit_field;
};

// Pops a bitfield value and a bitfield struct; pushes a new bitfield struct
// containing the updated value.
struct StoreBitFieldInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  StoreBitFieldInstruction(const Type* bit_field_struct_type,
                           BitField bit_field, bool starts_as_zero)
      : bit_field_struct_type(bit_field_struct_type),
        bit_field(std::move(bit_field)),
        starts_as_zero(starts_as_zero) {}

  DefinitionLocation GetValueDefinition() const;

  const Type* bit_field_struct_type;
  BitField bit_field;
  // Allows skipping the mask step if we know the starting value is zero.
  bool starts_as_zero;
};

struct CallIntrinsicInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  CallIntrinsicInstruction(Intrinsic* intrinsic,
                           TypeVector specialization_types,
                           std::vector<std::string> constexpr_arguments)
      : intrinsic(intrinsic),
        specialization_types(std::move(specialization_types)),
        constexpr_arguments(constexpr_arguments) {}

  std::size_t GetValueDefinitionCount() const;
  DefinitionLocation GetValueDefinition(std::size_t index) const;

  Intrinsic* intrinsic;
  TypeVector specialization_types;
  std::vector<std::string> constexpr_arguments;
};

struct CallCsaMacroInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  CallCsaMacroInstruction(Macro* macro,
                          std::vector<std::string> constexpr_arguments,
                          base::Optional<Block*> catch_block)
      : macro(macro),
        constexpr_arguments(constexpr_arguments),
        catch_block(catch_block) {}
  void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
    if (catch_block) block_list->push_back(*catch_block);
  }

  base::Optional<DefinitionLocation> GetExceptionObjectDefinition() const;
  std::size_t GetValueDefinitionCount() const;
  DefinitionLocation GetValueDefinition(std::size_t index) const;

  Macro* macro;
  std::vector<std::string> constexpr_arguments;
  base::Optional<Block*> catch_block;
};

struct CallCsaMacroAndBranchInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  CallCsaMacroAndBranchInstruction(Macro* macro,
                                   std::vector<std::string> constexpr_arguments,
                                   base::Optional<Block*> return_continuation,
                                   std::vector<Block*> label_blocks,
                                   base::Optional<Block*> catch_block)
      : macro(macro),
        constexpr_arguments(constexpr_arguments),
        return_continuation(return_continuation),
        label_blocks(label_blocks),
        catch_block(catch_block) {}
  bool IsBlockTerminator() const override { return true; }
  void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
    if (catch_block) block_list->push_back(*catch_block);
    if (return_continuation) block_list->push_back(*return_continuation);
    for (Block* block : label_blocks) block_list->push_back(block);
  }

  std::size_t GetLabelCount() const;
  std::size_t GetLabelValueDefinitionCount(std::size_t label) const;
  DefinitionLocation GetLabelValueDefinition(std::size_t label,
                                             std::size_t index) const;
  std::size_t GetValueDefinitionCount() const;
  DefinitionLocation GetValueDefinition(std::size_t index) const;
  base::Optional<DefinitionLocation> GetExceptionObjectDefinition() const;

  Macro* macro;
  std::vector<std::string> constexpr_arguments;
  base::Optional<Block*> return_continuation;
  std::vector<Block*> label_blocks;
  base::Optional<Block*> catch_block;
};

struct CallBuiltinInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  bool IsBlockTerminator() const override { return is_tailcall; }
  CallBuiltinInstruction(bool is_tailcall, Builtin* builtin, size_t argc,
                         base::Optional<Block*> catch_block)
      : is_tailcall(is_tailcall),
        builtin(builtin),
        argc(argc),
        catch_block(catch_block) {}
  void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
    if (catch_block) block_list->push_back(*catch_block);
  }

  std::size_t GetValueDefinitionCount() const;
  DefinitionLocation GetValueDefinition(std::size_t index) const;
  base::Optional<DefinitionLocation> GetExceptionObjectDefinition() const;

  bool is_tailcall;
  Builtin* builtin;
  size_t argc;
  base::Optional<Block*> catch_block;
};

struct CallBuiltinPointerInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  bool IsBlockTerminator() const override { return is_tailcall; }
  CallBuiltinPointerInstruction(bool is_tailcall,
                                const BuiltinPointerType* type, size_t argc)
      : is_tailcall(is_tailcall), type(type), argc(argc) {}

  std::size_t GetValueDefinitionCount() const;
  DefinitionLocation GetValueDefinition(std::size_t index) const;

  bool is_tailcall;
  const BuiltinPointerType* type;
  size_t argc;
};

struct CallRuntimeInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  bool IsBlockTerminator() const override;

  CallRuntimeInstruction(bool is_tailcall, RuntimeFunction* runtime_function,
                         size_t argc, base::Optional<Block*> catch_block)
      : is_tailcall(is_tailcall),
        runtime_function(runtime_function),
        argc(argc),
        catch_block(catch_block) {}
  void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
    if (catch_block) block_list->push_back(*catch_block);
  }

  std::size_t GetValueDefinitionCount() const;
  DefinitionLocation GetValueDefinition(std::size_t index) const;
  base::Optional<DefinitionLocation> GetExceptionObjectDefinition() const;

  bool is_tailcall;
  RuntimeFunction* runtime_function;
  size_t argc;
  base::Optional<Block*> catch_block;
};

struct BranchInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  bool IsBlockTerminator() const override { return true; }
  void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
    block_list->push_back(if_true);
    block_list->push_back(if_false);
  }

  BranchInstruction(Block* if_true, Block* if_false)
      : if_true(if_true), if_false(if_false) {}

  Block* if_true;
  Block* if_false;
};

struct ConstexprBranchInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  bool IsBlockTerminator() const override { return true; }
  void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
    block_list->push_back(if_true);
    block_list->push_back(if_false);
  }

  ConstexprBranchInstruction(std::string condition, Block* if_true,
                             Block* if_false)
      : condition(condition), if_true(if_true), if_false(if_false) {}

  std::string condition;
  Block* if_true;
  Block* if_false;
};

struct GotoInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  bool IsBlockTerminator() const override { return true; }
  void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
    block_list->push_back(destination);
  }

  explicit GotoInstruction(Block* destination) : destination(destination) {}

  Block* destination;
};

struct GotoExternalInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  bool IsBlockTerminator() const override { return true; }

  GotoExternalInstruction(std::string destination,
                          std::vector<std::string> variable_names)
      : destination(std::move(destination)),
        variable_names(std::move(variable_names)) {}

  std::string destination;
  std::vector<std::string> variable_names;
};

struct ReturnInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  bool IsBlockTerminator() const override { return true; }
};

struct PrintConstantStringInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  explicit PrintConstantStringInstruction(std::string message)
      : message(std::move(message)) {}

  std::string message;
};

struct AbortInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  enum class Kind { kDebugBreak, kUnreachable, kAssertionFailure };
  bool IsBlockTerminator() const override { return kind != Kind::kDebugBreak; }
  explicit AbortInstruction(Kind kind, std::string message = "")
      : kind(kind), message(std::move(message)) {}

  Kind kind;
  std::string message;
};

struct UnsafeCastInstruction : InstructionBase {
  TORQUE_INSTRUCTION_BOILERPLATE()
  explicit UnsafeCastInstruction(const Type* destination_type)
      : destination_type(destination_type) {}

  DefinitionLocation GetValueDefinition() const;

  const Type* destination_type;
};

}  // namespace torque
}  // namespace internal
}  // namespace v8

#endif  // V8_TORQUE_INSTRUCTIONS_H_
