//===-- ExpressionVariable.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 "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#include "llvm/Support/Error.h"

#include <optional>

using namespace lldb_private;

char ExpressionVariable::ID;

ExpressionVariable::ExpressionVariable() : m_flags(0) {}

uint8_t *ExpressionVariable::GetValueBytes() {
  lldb::ValueObjectSP valobj_sp = GetValueObject();
  std::optional<uint64_t> byte_size =
      llvm::expectedToOptional(valobj_sp->GetByteSize());
  if (byte_size && *byte_size) {
    if (valobj_sp->GetDataExtractor().GetByteSize() < *byte_size) {
      valobj_sp->GetValue().ResizeData(*byte_size);
      valobj_sp->GetValue().GetData(valobj_sp->GetDataExtractor());
    }
    return const_cast<uint8_t *>(valobj_sp->GetDataExtractor().GetDataStart());
  }
  return nullptr;
}

char PersistentExpressionState::ID;

PersistentExpressionState::PersistentExpressionState() = default;

void ExpressionVariable::TransferAddress(bool force) {
  if (!m_live_sp)
    return;

  if (!m_frozen_sp)
    return;

  if (force || (m_frozen_sp->GetLiveAddress() == LLDB_INVALID_ADDRESS)) {
    lldb::addr_t live_addr = m_live_sp->GetLiveAddress();
    m_frozen_sp->SetLiveAddress(live_addr);
    // One more detail, if there's an offset_to_top in the frozen_sp, then we
    // need to appy that offset by hand.  The live_sp can't compute this
    // itself as its type is the type of the contained object which confuses
    // the dynamic type calculation.  So we have to update the contents of the
    // m_live_sp with the dynamic value.
    // Note: We could get this right when we originally write the address, but
    // that happens in different ways for the various flavors of
    // Entity*::Materialize, but everything comes through here, and it's just
    // one extra memory write.

    // You can only have an "offset_to_top" with pointers or references:
    if (!m_frozen_sp->GetCompilerType().IsPointerOrReferenceType())
      return;

    lldb::ProcessSP process_sp = m_frozen_sp->GetProcessSP();
    // If there's no dynamic value, then there can't be an offset_to_top:
    if (!process_sp ||
        !process_sp->IsPossibleDynamicValue(*(m_frozen_sp.get())))
      return;

    lldb::ValueObjectSP dyn_sp = m_frozen_sp->GetDynamicValue(m_dyn_option);
    if (!dyn_sp)
      return;
    ValueObject::AddrAndType static_addr = m_frozen_sp->GetPointerValue();
    if (static_addr.type != eAddressTypeLoad)
      return;

    ValueObject::AddrAndType dynamic_addr = dyn_sp->GetPointerValue();
    if (dynamic_addr.type != eAddressTypeLoad ||
        static_addr.address == dynamic_addr.address)
      return;

    Status error;
    Log *log = GetLog(LLDBLog::Expressions);
    llvm::Expected<lldb::addr_t> cur_value =
        process_sp->ReadPointerFromMemory(live_addr);
    if (!cur_value) {
      llvm::consumeError(cur_value.takeError());
      return;
    }

    if (*cur_value != static_addr.address) {
      LLDB_LOG(log,
               "Stored value: {0} read from {1} doesn't "
               "match static addr: {2}",
               *cur_value, live_addr, static_addr.address);
      return;
    }

    if (!process_sp->WritePointerToMemory(live_addr, dynamic_addr.address,
                                          error)) {
      LLDB_LOG(log, "Got error: {0} writing dynamic value: {1} to {2}", error,
               dynamic_addr.address, live_addr);
      return;
    }
  }
}

PersistentExpressionState::~PersistentExpressionState() = default;

lldb::addr_t PersistentExpressionState::LookupSymbol(ConstString name) {
  SymbolMap::iterator si = m_symbol_map.find(name.GetCString());

  if (si != m_symbol_map.end())
    return si->second;
  else
    return LLDB_INVALID_ADDRESS;
}

void PersistentExpressionState::RegisterExecutionUnit(
    lldb::IRExecutionUnitSP &execution_unit_sp) {
  Log *log = GetLog(LLDBLog::Expressions);

  m_execution_units.insert(execution_unit_sp);

  LLDB_LOGF(log, "Registering JITted Functions:\n");

  for (const IRExecutionUnit::JittedFunction &jitted_function :
       execution_unit_sp->GetJittedFunctions()) {
    if (jitted_function.m_external &&
        jitted_function.m_name != execution_unit_sp->GetFunctionName() &&
        jitted_function.m_remote_addr != LLDB_INVALID_ADDRESS) {
      m_symbol_map[jitted_function.m_name.GetCString()] =
          jitted_function.m_remote_addr;
      LLDB_LOGF(log, "  Function: %s at 0x%" PRIx64 ".",
                jitted_function.m_name.GetCString(),
                jitted_function.m_remote_addr);
    }
  }

  LLDB_LOGF(log, "Registering JIIted Symbols:\n");

  for (const IRExecutionUnit::JittedGlobalVariable &global_var :
       execution_unit_sp->GetJittedGlobalVariables()) {
    if (global_var.m_remote_addr != LLDB_INVALID_ADDRESS) {
      // Demangle the name before inserting it, so that lookups by the ConstStr
      // of the demangled name will find the mangled one (needed for looking up
      // metadata pointers.)
      Mangled mangler(global_var.m_name);
      mangler.GetDemangledName();
      m_symbol_map[global_var.m_name.GetCString()] = global_var.m_remote_addr;
      LLDB_LOGF(log, "  Symbol: %s at 0x%" PRIx64 ".",
                global_var.m_name.GetCString(), global_var.m_remote_addr);
    }
  }
}
