//===-- SBInstruction.cpp ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBInstruction.h"
#include "SBReproducerPrivate.h"

#include "lldb/API/SBAddress.h"
#include "lldb/API/SBFrame.h"

#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBTarget.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"

#include <memory>

// We recently fixed a leak in one of the Instruction subclasses where the
// instruction will only hold a weak reference to the disassembler to avoid a
// cycle that was keeping both objects alive (leak) and we need the
// InstructionImpl class to make sure our public API behaves as users would
// expect. Calls in our public API allow clients to do things like:
//
// 1  lldb::SBInstruction inst;
// 2  inst = target.ReadInstructions(pc, 1).GetInstructionAtIndex(0)
// 3  if (inst.DoesBranch())
// 4  ...
//
// There was a temporary lldb::DisassemblerSP object created in the
// SBInstructionList that was returned by lldb.target.ReadInstructions() that
// will go away after line 2 but the "inst" object should be able to still
// answer questions about itself. So we make sure that any SBInstruction
// objects that are given out have a strong reference to the disassembler and
// the instruction so that the object can live and successfully respond to all
// queries.
class InstructionImpl {
public:
  InstructionImpl(const lldb::DisassemblerSP &disasm_sp,
                  const lldb::InstructionSP &inst_sp)
      : m_disasm_sp(disasm_sp), m_inst_sp(inst_sp) {}

  lldb::InstructionSP GetSP() const { return m_inst_sp; }

  bool IsValid() const { return (bool)m_inst_sp; }

protected:
  lldb::DisassemblerSP m_disasm_sp; // Can be empty/invalid
  lldb::InstructionSP m_inst_sp;
};

using namespace lldb;
using namespace lldb_private;

SBInstruction::SBInstruction() : m_opaque_sp() {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBInstruction);
}

SBInstruction::SBInstruction(const lldb::DisassemblerSP &disasm_sp,
                             const lldb::InstructionSP &inst_sp)
    : m_opaque_sp(new InstructionImpl(disasm_sp, inst_sp)) {}

SBInstruction::SBInstruction(const SBInstruction &rhs)
    : m_opaque_sp(rhs.m_opaque_sp) {
  LLDB_RECORD_CONSTRUCTOR(SBInstruction, (const lldb::SBInstruction &), rhs);
}

const SBInstruction &SBInstruction::operator=(const SBInstruction &rhs) {
  LLDB_RECORD_METHOD(const lldb::SBInstruction &,
                     SBInstruction, operator=,(const lldb::SBInstruction &),
                     rhs);

  if (this != &rhs)
    m_opaque_sp = rhs.m_opaque_sp;
  return LLDB_RECORD_RESULT(*this);
}

SBInstruction::~SBInstruction() {}

bool SBInstruction::IsValid() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBInstruction, IsValid);
  return this->operator bool();
}
SBInstruction::operator bool() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBInstruction, operator bool);

  return m_opaque_sp && m_opaque_sp->IsValid();
}

SBAddress SBInstruction::GetAddress() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBInstruction, GetAddress);

  SBAddress sb_addr;
  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp && inst_sp->GetAddress().IsValid())
    sb_addr.SetAddress(&inst_sp->GetAddress());
  return LLDB_RECORD_RESULT(sb_addr);
}

const char *SBInstruction::GetMnemonic(SBTarget target) {
  LLDB_RECORD_METHOD(const char *, SBInstruction, GetMnemonic, (lldb::SBTarget),
                     target);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    ExecutionContext exe_ctx;
    TargetSP target_sp(target.GetSP());
    std::unique_lock<std::recursive_mutex> lock;
    if (target_sp) {
      lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());

      target_sp->CalculateExecutionContext(exe_ctx);
      exe_ctx.SetProcessSP(target_sp->GetProcessSP());
    }
    return inst_sp->GetMnemonic(&exe_ctx);
  }
  return nullptr;
}

const char *SBInstruction::GetOperands(SBTarget target) {
  LLDB_RECORD_METHOD(const char *, SBInstruction, GetOperands, (lldb::SBTarget),
                     target);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    ExecutionContext exe_ctx;
    TargetSP target_sp(target.GetSP());
    std::unique_lock<std::recursive_mutex> lock;
    if (target_sp) {
      lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());

      target_sp->CalculateExecutionContext(exe_ctx);
      exe_ctx.SetProcessSP(target_sp->GetProcessSP());
    }
    return inst_sp->GetOperands(&exe_ctx);
  }
  return nullptr;
}

const char *SBInstruction::GetComment(SBTarget target) {
  LLDB_RECORD_METHOD(const char *, SBInstruction, GetComment, (lldb::SBTarget),
                     target);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    ExecutionContext exe_ctx;
    TargetSP target_sp(target.GetSP());
    std::unique_lock<std::recursive_mutex> lock;
    if (target_sp) {
      lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());

      target_sp->CalculateExecutionContext(exe_ctx);
      exe_ctx.SetProcessSP(target_sp->GetProcessSP());
    }
    return inst_sp->GetComment(&exe_ctx);
  }
  return nullptr;
}

size_t SBInstruction::GetByteSize() {
  LLDB_RECORD_METHOD_NO_ARGS(size_t, SBInstruction, GetByteSize);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->GetOpcode().GetByteSize();
  return 0;
}

SBData SBInstruction::GetData(SBTarget target) {
  LLDB_RECORD_METHOD(lldb::SBData, SBInstruction, GetData, (lldb::SBTarget),
                     target);

  lldb::SBData sb_data;
  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    DataExtractorSP data_extractor_sp(new DataExtractor());
    if (inst_sp->GetData(*data_extractor_sp)) {
      sb_data.SetOpaque(data_extractor_sp);
    }
  }
  return LLDB_RECORD_RESULT(sb_data);
}

bool SBInstruction::DoesBranch() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBInstruction, DoesBranch);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->DoesBranch();
  return false;
}

bool SBInstruction::HasDelaySlot() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBInstruction, HasDelaySlot);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->HasDelaySlot();
  return false;
}

bool SBInstruction::CanSetBreakpoint() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBInstruction, CanSetBreakpoint);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->CanSetBreakpoint();
  return false;
}

lldb::InstructionSP SBInstruction::GetOpaque() {
  if (m_opaque_sp)
    return m_opaque_sp->GetSP();
  else
    return lldb::InstructionSP();
}

void SBInstruction::SetOpaque(const lldb::DisassemblerSP &disasm_sp,
                              const lldb::InstructionSP &inst_sp) {
  m_opaque_sp = std::make_shared<InstructionImpl>(disasm_sp, inst_sp);
}

bool SBInstruction::GetDescription(lldb::SBStream &s) {
  LLDB_RECORD_METHOD(bool, SBInstruction, GetDescription, (lldb::SBStream &),
                     s);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    SymbolContext sc;
    const Address &addr = inst_sp->GetAddress();
    ModuleSP module_sp(addr.GetModule());
    if (module_sp)
      module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything,
                                                sc);
    // Use the "ref()" instead of the "get()" accessor in case the SBStream
    // didn't have a stream already created, one will get created...
    FormatEntity::Entry format;
    FormatEntity::Parse("${addr}: ", format);
    inst_sp->Dump(&s.ref(), 0, true, false, nullptr, &sc, nullptr, &format, 0);
    return true;
  }
  return false;
}

void SBInstruction::Print(FILE *out) {
  LLDB_RECORD_METHOD(void, SBInstruction, Print, (FILE *), out);

  if (out == nullptr)
    return;

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    SymbolContext sc;
    const Address &addr = inst_sp->GetAddress();
    ModuleSP module_sp(addr.GetModule());
    if (module_sp)
      module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything,
                                                sc);
    StreamFile out_stream(out, false);
    FormatEntity::Entry format;
    FormatEntity::Parse("${addr}: ", format);
    inst_sp->Dump(&out_stream, 0, true, false, nullptr, &sc, nullptr, &format,
                  0);
  }
}

bool SBInstruction::EmulateWithFrame(lldb::SBFrame &frame,
                                     uint32_t evaluate_options) {
  LLDB_RECORD_METHOD(bool, SBInstruction, EmulateWithFrame,
                     (lldb::SBFrame &, uint32_t), frame, evaluate_options);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp) {
    lldb::StackFrameSP frame_sp(frame.GetFrameSP());

    if (frame_sp) {
      lldb_private::ExecutionContext exe_ctx;
      frame_sp->CalculateExecutionContext(exe_ctx);
      lldb_private::Target *target = exe_ctx.GetTargetPtr();
      lldb_private::ArchSpec arch = target->GetArchitecture();

      return inst_sp->Emulate(
          arch, evaluate_options, (void *)frame_sp.get(),
          &lldb_private::EmulateInstruction::ReadMemoryFrame,
          &lldb_private::EmulateInstruction::WriteMemoryFrame,
          &lldb_private::EmulateInstruction::ReadRegisterFrame,
          &lldb_private::EmulateInstruction::WriteRegisterFrame);
    }
  }
  return false;
}

bool SBInstruction::DumpEmulation(const char *triple) {
  LLDB_RECORD_METHOD(bool, SBInstruction, DumpEmulation, (const char *),
                     triple);

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp && triple) {
    return inst_sp->DumpEmulation(HostInfo::GetAugmentedArchSpec(triple));
  }
  return false;
}

bool SBInstruction::TestEmulation(lldb::SBStream &output_stream,
                                  const char *test_file) {
  LLDB_RECORD_METHOD(bool, SBInstruction, TestEmulation,
                     (lldb::SBStream &, const char *), output_stream,
                     test_file);

  if (!m_opaque_sp)
    SetOpaque(lldb::DisassemblerSP(),
              lldb::InstructionSP(new PseudoInstruction()));

  lldb::InstructionSP inst_sp(GetOpaque());
  if (inst_sp)
    return inst_sp->TestEmulation(output_stream.get(), test_file);
  return false;
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBInstruction>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBInstruction, ());
  LLDB_REGISTER_CONSTRUCTOR(SBInstruction, (const lldb::SBInstruction &));
  LLDB_REGISTER_METHOD(
      const lldb::SBInstruction &,
      SBInstruction, operator=,(const lldb::SBInstruction &));
  LLDB_REGISTER_METHOD(bool, SBInstruction, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBInstruction, operator bool, ());
  LLDB_REGISTER_METHOD(lldb::SBAddress, SBInstruction, GetAddress, ());
  LLDB_REGISTER_METHOD(const char *, SBInstruction, GetMnemonic,
                       (lldb::SBTarget));
  LLDB_REGISTER_METHOD(const char *, SBInstruction, GetOperands,
                       (lldb::SBTarget));
  LLDB_REGISTER_METHOD(const char *, SBInstruction, GetComment,
                       (lldb::SBTarget));
  LLDB_REGISTER_METHOD(size_t, SBInstruction, GetByteSize, ());
  LLDB_REGISTER_METHOD(lldb::SBData, SBInstruction, GetData,
                       (lldb::SBTarget));
  LLDB_REGISTER_METHOD(bool, SBInstruction, DoesBranch, ());
  LLDB_REGISTER_METHOD(bool, SBInstruction, HasDelaySlot, ());
  LLDB_REGISTER_METHOD(bool, SBInstruction, CanSetBreakpoint, ());
  LLDB_REGISTER_METHOD(bool, SBInstruction, GetDescription,
                       (lldb::SBStream &));
  LLDB_REGISTER_METHOD(void, SBInstruction, Print, (FILE *));
  LLDB_REGISTER_METHOD(bool, SBInstruction, EmulateWithFrame,
                       (lldb::SBFrame &, uint32_t));
  LLDB_REGISTER_METHOD(bool, SBInstruction, DumpEmulation, (const char *));
  LLDB_REGISTER_METHOD(bool, SBInstruction, TestEmulation,
                       (lldb::SBStream &, const char *));
}

}
}
