//===-- ObjCLanguageRuntime.cpp -------------------------------------------===//
//
// 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 "clang/AST/Type.h"

#include "ObjCLanguageRuntime.h"

#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
#include "lldb/ValueObject/ValueObject.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DJB.h"
#include <optional>

using namespace lldb;
using namespace lldb_private;

char ObjCLanguageRuntime::ID = 0;

// Destructor
ObjCLanguageRuntime::~ObjCLanguageRuntime() = default;

bool ObjCLanguageRuntime::IsSupportedForArchitecture(const ArchSpec &arch) {
  // These are the only object file formats clang can emit Objective-C
  // metadata for; it aborts on any other.
  switch (arch.GetTriple().getObjectFormat()) {
  case llvm::Triple::MachO:
  case llvm::Triple::ELF:
  case llvm::Triple::COFF:
    return true;
  default:
    return false;
  }
}

ObjCLanguageRuntime::ObjCLanguageRuntime(Process *process)
    : LanguageRuntime(process), m_impl_cache(), m_impl_str_cache(),
      m_has_new_literals_and_indexing(eLazyBoolCalculate),
      m_isa_to_descriptor(), m_hash_to_isa_map(), m_type_size_cache(),
      m_isa_to_descriptor_stop_id(UINT32_MAX), m_complete_class_cache(),
      m_negative_complete_class_cache() {}

bool ObjCLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
  static ConstString g_self = ConstString("self");
  static ConstString g_cmd = ConstString("_cmd");
  return name == g_self || name == g_cmd;
}

bool ObjCLanguageRuntime::AddClass(ObjCISA isa,
                                   const ClassDescriptorSP &descriptor_sp,
                                   const char *class_name) {
  return AddClass(isa, descriptor_sp, llvm::djbHash(class_name));
}

void ObjCLanguageRuntime::AddToMethodCache(lldb::addr_t class_addr,
                                           lldb::addr_t selector,
                                           lldb::addr_t impl_addr) {
  Log *log = GetLog(LLDBLog::Step);
  LLDB_LOGF(log,
            "Caching: class 0x%" PRIx64 " selector 0x%" PRIx64
            " implementation 0x%" PRIx64 ".",
            class_addr, selector, impl_addr);
  m_impl_cache.insert(std::pair<ClassAndSel, lldb::addr_t>(
      ClassAndSel(class_addr, selector), impl_addr));
}

void ObjCLanguageRuntime::AddToMethodCache(lldb::addr_t class_addr,
                                           llvm::StringRef sel_str,
                                           lldb::addr_t impl_addr) {
  Log *log = GetLog(LLDBLog::Step);

  LLDB_LOG(log, "Caching: class {0} selector {1} implementation {2}.",
           class_addr, sel_str, impl_addr);

  m_impl_str_cache.insert(std::pair<ClassAndSelStr, lldb::addr_t>(
      ClassAndSelStr(class_addr, sel_str), impl_addr));
}

lldb::addr_t ObjCLanguageRuntime::LookupInMethodCache(lldb::addr_t class_addr,
                                                      lldb::addr_t selector) {
  MsgImplMap::iterator pos, end = m_impl_cache.end();
  pos = m_impl_cache.find(ClassAndSel(class_addr, selector));
  if (pos != end)
    return (*pos).second;
  return LLDB_INVALID_ADDRESS;
}

lldb::addr_t ObjCLanguageRuntime::LookupInMethodCache(lldb::addr_t class_addr,
                                                      llvm::StringRef sel_str) {
  MsgImplStrMap::iterator pos, end = m_impl_str_cache.end();
  pos = m_impl_str_cache.find(ClassAndSelStr(class_addr, sel_str));
  if (pos != end)
    return (*pos).second;
  return LLDB_INVALID_ADDRESS;
}

lldb::TypeSP
ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) {
  CompleteClassMap::iterator complete_class_iter =
      m_complete_class_cache.find(name);

  if (complete_class_iter != m_complete_class_cache.end()) {
    // Check the weak pointer to make sure the type hasn't been unloaded
    TypeSP complete_type_sp(complete_class_iter->second.lock());

    if (complete_type_sp)
      return complete_type_sp;
    else
      m_complete_class_cache.erase(name);
  }

  if (m_negative_complete_class_cache.count(name) > 0)
    return TypeSP();

  const ModuleList &modules = m_process->GetTarget().GetImages();

  SymbolContextList sc_list;
  modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list);
  const size_t matching_symbols = sc_list.GetSize();

  if (matching_symbols) {
    SymbolContext sc;

    sc_list.GetContextAtIndex(0, sc);

    ModuleSP module_sp(sc.module_sp);

    if (!module_sp)
      return TypeSP();

    TypeQuery query(name.GetStringRef(), TypeQueryOptions::e_exact_match);
    TypeResults results;
    module_sp->FindTypes(query, results);
    for (const TypeSP &type_sp : results.GetTypeMap().Types()) {
      if (TypeSystemClang::IsObjCObjectOrInterfaceType(
              type_sp->GetForwardCompilerType())) {
        if (TypePayloadClang(type_sp->GetPayload()).IsCompleteObjCClass()) {
          m_complete_class_cache[name] = type_sp;
          return type_sp;
        }
      }
    }
  }
  m_negative_complete_class_cache.insert(name);
  return TypeSP();
}

size_t ObjCLanguageRuntime::GetByteOffsetForIvar(CompilerType &parent_qual_type,
                                                 const char *ivar_name) {
  return LLDB_INVALID_IVAR_OFFSET;
}

bool ObjCLanguageRuntime::ClassDescriptor::IsPointerValid(
    lldb::addr_t value, uint32_t ptr_size, bool allow_NULLs, bool allow_tagged,
    bool check_version_specific) const {
  if (!value)
    return allow_NULLs;
  if ((value % 2) == 1 && allow_tagged)
    return true;
  if ((value % ptr_size) == 0)
    return (check_version_specific ? CheckPointer(value, ptr_size) : true);
  else
    return false;
}

ObjCLanguageRuntime::ObjCISA
ObjCLanguageRuntime::GetISA(ConstString name) {
  ISAToDescriptorIterator pos = GetDescriptorIterator(name);
  if (pos != m_isa_to_descriptor.end())
    return pos->first;
  return 0;
}

ObjCLanguageRuntime::ISAToDescriptorIterator
ObjCLanguageRuntime::GetDescriptorIterator(ConstString name) {
  if (!name)
    return m_isa_to_descriptor.end();

  UpdateISAToDescriptorMap();

  if (m_hash_to_isa_map.empty()) {
    // No name hashes were provided, we need to just linearly power through
    // the names and find a match
    for (auto it = m_isa_to_descriptor.begin(), end = m_isa_to_descriptor.end();
         it != end; ++it)
      if (it->second->GetClassName() == name)
        return it;
    return m_isa_to_descriptor.end();
  }

  // Name hashes were provided, so use them to efficiently lookup name to
  // isa/descriptor
  const uint32_t name_hash = llvm::djbHash(name.GetStringRef());
  auto matches_it = m_hash_to_isa_map.find(name_hash);
  if (matches_it == m_hash_to_isa_map.end())
    return m_isa_to_descriptor.end();

  for (auto isa : matches_it->second)
    if (auto pos = m_isa_to_descriptor.find(isa);
        pos != m_isa_to_descriptor.end() && pos->second->GetClassName() == name)
      return pos;

  return m_isa_to_descriptor.end();
}

std::pair<ObjCLanguageRuntime::ISAToDescriptorIterator,
          ObjCLanguageRuntime::ISAToDescriptorIterator>
ObjCLanguageRuntime::GetDescriptorIteratorPair(bool update_if_needed) {
  if (update_if_needed)
    UpdateISAToDescriptorMapIfNeeded();

  return std::pair<ObjCLanguageRuntime::ISAToDescriptorIterator,
                   ObjCLanguageRuntime::ISAToDescriptorIterator>(
      m_isa_to_descriptor.begin(), m_isa_to_descriptor.end());
}

void ObjCLanguageRuntime::ReadObjCLibraryIfNeeded(
    const ModuleList &module_list) {
  if (!HasReadObjCLibrary()) {
    std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());

    size_t num_modules = module_list.GetSize();
    for (size_t i = 0; i < num_modules; i++) {
      auto mod = module_list.GetModuleAtIndex(i);
      if (IsModuleObjCLibrary(mod)) {
        ReadObjCLibrary(mod);
        break;
      }
    }
  }
}

ObjCLanguageRuntime::ObjCISA
ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa) {
  ClassDescriptorSP objc_class_sp(GetClassDescriptorFromISA(isa));
  if (objc_class_sp) {
    ClassDescriptorSP objc_super_class_sp(objc_class_sp->GetSuperclass());
    if (objc_super_class_sp)
      return objc_super_class_sp->GetISA();
  }
  return 0;
}

ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetClassDescriptorFromClassName(
    ConstString class_name) {
  ISAToDescriptorIterator pos = GetDescriptorIterator(class_name);
  if (pos != m_isa_to_descriptor.end())
    return pos->second;
  return ClassDescriptorSP();
}

ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetClassDescriptor(ValueObject &valobj) {
  ClassDescriptorSP objc_class_sp;
  // if we get an invalid VO (which might still happen when playing around with
  // pointers returned by the expression parser, don't consider this a valid
  // ObjC object)
  if (valobj.GetCompilerType().IsValid()) {
    addr_t isa_pointer = valobj.GetPointerValue().address;
    if (isa_pointer != LLDB_INVALID_ADDRESS) {
      ExecutionContext exe_ctx(valobj.GetExecutionContextRef());

      Process *process = exe_ctx.GetProcessPtr();
      if (process) {
        Status error;
        ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
        if (isa != LLDB_INVALID_ADDRESS)
          objc_class_sp = GetClassDescriptorFromISA(isa);
      }
    }
  }
  return objc_class_sp;
}

bool ObjCLanguageRuntime::IsTaggedPointerValue(ValueObject &in_value) {
  TaggedPointerVendor *tagged_pointer_vendor = GetTaggedPointerVendor();
  if (!tagged_pointer_vendor)
    return false;

  // Only Objective-C object values can be tagged pointers.
  if (!(in_value.GetTypeInfo() & lldb::eTypeIsObjC))
    return false;

  addr_t ptr = in_value.IsPointerType() ? in_value.GetPointerValue().address
                                        : in_value.GetAddressOf().address;
  if (ptr == LLDB_INVALID_ADDRESS)
    return false;

  return tagged_pointer_vendor->IsPossibleTaggedPointer(ptr);
}

ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetNonKVOClassDescriptor(ValueObject &valobj) {
  ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp(
      GetClassDescriptor(valobj));
  if (objc_class_sp) {
    if (!objc_class_sp->IsKVO())
      return objc_class_sp;

    ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
    if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
      return non_kvo_objc_class_sp;
  }
  return ClassDescriptorSP();
}

ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetClassDescriptorFromISA(ObjCISA isa) {
  if (isa) {
    UpdateISAToDescriptorMap();

    ObjCLanguageRuntime::ISAToDescriptorIterator pos =
        m_isa_to_descriptor.find(isa);
    if (pos != m_isa_to_descriptor.end())
      return pos->second;

    if (ABISP abi_sp = m_process->GetABI()) {
      pos = m_isa_to_descriptor.find(abi_sp->FixCodeAddress(isa));
      if (pos != m_isa_to_descriptor.end())
        return pos->second;
    }
  }
  return ClassDescriptorSP();
}

ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetNonKVOClassDescriptor(ObjCISA isa) {
  if (isa) {
    ClassDescriptorSP objc_class_sp = GetClassDescriptorFromISA(isa);
    if (objc_class_sp && objc_class_sp->IsValid()) {
      if (!objc_class_sp->IsKVO())
        return objc_class_sp;

      ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
      if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
        return non_kvo_objc_class_sp;
    }
  }
  return ClassDescriptorSP();
}

CompilerType
ObjCLanguageRuntime::EncodingToType::RealizeType(const char *name,
                                                 bool for_expression) {
  if (m_scratch_ast_ctx_sp)
    return RealizeType(*m_scratch_ast_ctx_sp, name, for_expression);
  return CompilerType();
}

ObjCLanguageRuntime::EncodingToType::~EncodingToType() = default;

ObjCLanguageRuntime::EncodingToTypeSP ObjCLanguageRuntime::GetEncodingToType() {
  return nullptr;
}

std::optional<uint64_t>
ObjCLanguageRuntime::GetTypeBitSize(const CompilerType &compiler_type) {
  void *opaque_ptr = compiler_type.GetOpaqueQualType();
  uint64_t cached_size = m_type_size_cache.Lookup(opaque_ptr);
  if (cached_size > 0)
    return cached_size;

  ClassDescriptorSP class_descriptor_sp =
      GetClassDescriptorFromClassName(compiler_type.GetTypeName());
  if (!class_descriptor_sp)
    return {};

  int32_t max_offset = INT32_MIN;
  uint64_t sizeof_max = 0;
  bool found = false;

  for (size_t idx = 0; idx < class_descriptor_sp->GetNumIVars(); idx++) {
    const auto &ivar = class_descriptor_sp->GetIVarAtIndex(idx);
    int32_t cur_offset = ivar.m_offset;
    if (cur_offset > max_offset) {
      max_offset = cur_offset;
      sizeof_max = ivar.m_size;
      found = true;
    }
  }

  uint64_t size = 8 * (max_offset + sizeof_max);
  if (found && size > 0) {
    m_type_size_cache.Insert(opaque_ptr, size);
    return size;
  }

  return {};
}

lldb::BreakpointPreconditionSP
ObjCLanguageRuntime::GetBreakpointExceptionPrecondition(LanguageType language,
                                                        bool throw_bp) {
  if (language != eLanguageTypeObjC)
    return lldb::BreakpointPreconditionSP();
  if (!throw_bp)
    return lldb::BreakpointPreconditionSP();
  BreakpointPreconditionSP precondition_sp(
      new ObjCLanguageRuntime::ObjCExceptionPrecondition());
  return precondition_sp;
}

// Exception breakpoint Precondition class for ObjC:
void ObjCLanguageRuntime::ObjCExceptionPrecondition::AddClassName(
    const char *class_name) {
  m_class_names.insert(class_name);
}

ObjCLanguageRuntime::ObjCExceptionPrecondition::ObjCExceptionPrecondition() =
    default;

bool ObjCLanguageRuntime::ObjCExceptionPrecondition::EvaluatePrecondition(
    StoppointCallbackContext &context) {
  return true;
}

void ObjCLanguageRuntime::ObjCExceptionPrecondition::GetDescription(
    Stream &stream, lldb::DescriptionLevel level) {}

Status ObjCLanguageRuntime::ObjCExceptionPrecondition::ConfigurePrecondition(
    Args &args) {
  Status error;
  if (args.GetArgumentCount() > 0)
    error = Status::FromErrorString(
        "The ObjC Exception breakpoint doesn't support extra options.");
  return error;
}

CompilerType ObjCLanguageRuntime::LookupInModulesVendor(ConstString class_name,
                                                        Target &target) {
  assert(class_name);

  auto *persistent_state = llvm::cast<ClangPersistentVariables>(
      target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
  if (!persistent_state)
    return {};

  auto clang_modules_decl_vendor_sp =
      persistent_state->GetClangModulesDeclVendor();
  if (!clang_modules_decl_vendor_sp)
    return {};

  auto types = clang_modules_decl_vendor_sp->FindTypes(
      class_name, /*max_matches*/ UINT32_MAX);
  if (types.empty())
    return {};

  return types.front();
}

CompilerType ObjCLanguageRuntime::LookupInRuntime(ConstString class_name) {
  auto *runtime_vendor = GetDeclVendor();
  if (!runtime_vendor)
    return {};

  std::vector<CompilerDecl> compiler_decls;
  runtime_vendor->FindDecls(class_name, false, UINT32_MAX, compiler_decls);
  if (compiler_decls.empty())
    return {};

  auto *ctx =
      llvm::dyn_cast<TypeSystemClang>(compiler_decls[0].GetTypeSystem());
  if (!ctx)
    return {};

  return ctx->GetTypeForDecl(compiler_decls[0].GetOpaqueDecl());
}

std::optional<CompilerType>
ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) {
  CompilerType class_type;
  bool is_pointer_type = false;

  if (TypeSystemClang::IsObjCObjectPointerType(base_type, &class_type))
    is_pointer_type = true;
  else if (TypeSystemClang::IsObjCObjectOrInterfaceType(base_type))
    class_type = base_type;
  else
    return std::nullopt;

  if (!class_type)
    return std::nullopt;

  ConstString class_name(class_type.GetTypeName());
  if (!class_name)
    return std::nullopt;

  if (TypeSP complete_objc_class_type_sp =
          LookupInCompleteClassCache(class_name)) {
    if (CompilerType complete_class =
            complete_objc_class_type_sp->GetFullCompilerType();
        complete_class.GetCompleteType())
      return is_pointer_type ? complete_class.GetPointerType() : complete_class;
  }

  assert(m_process);
  if (CompilerType found =
          LookupInModulesVendor(class_name, m_process->GetTarget()))
    return is_pointer_type ? found.GetPointerType() : found;

  if (CompilerType found = LookupInRuntime(class_name))
    return is_pointer_type ? found.GetPointerType() : found;

  return std::nullopt;
}
