//===-- LLVMUserExpression.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/Expression/LLVMUserExpression.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanCallUserExpression.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb_private;

LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope,
                                       llvm::StringRef expr,
                                       llvm::StringRef prefix,
                                       lldb::LanguageType language,
                                       ResultType desired_type,
                                       const EvaluateExpressionOptions &options,
                                       ExpressionKind kind)
    : UserExpression(exe_scope, expr, prefix, language, desired_type, options,
                     kind),
      m_stack_frame_bottom(LLDB_INVALID_ADDRESS),
      m_stack_frame_top(LLDB_INVALID_ADDRESS), m_allow_cxx(false),
      m_allow_objc(false), m_transformed_text(), m_execution_unit_sp(),
      m_materializer_up(), m_jit_module_wp(), m_enforce_valid_object(true),
      m_in_cplusplus_method(false), m_in_objectivec_method(false),
      m_in_static_method(false), m_needs_object_ptr(false), m_target(nullptr),
      m_can_interpret(false), m_materialized_address(LLDB_INVALID_ADDRESS) {}

LLVMUserExpression::~LLVMUserExpression() {
  if (m_target) {
    lldb::ModuleSP jit_module_sp(m_jit_module_wp.lock());
    if (jit_module_sp)
      m_target->GetImages().Remove(jit_module_sp);
  }
}

lldb::ExpressionResults
LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
                              ExecutionContext &exe_ctx,
                              const EvaluateExpressionOptions &options,
                              lldb::UserExpressionSP &shared_ptr_to_me,
                              lldb::ExpressionVariableSP &result) {
  // The expression log is quite verbose, and if you're just tracking the
  // execution of the expression, it's quite convenient to have these logs come
  // out with the STEP log as well.
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
                                                  LIBLLDB_LOG_STEP));

  if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) {
    lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;

    if (!PrepareToExecuteJITExpression(diagnostic_manager, exe_ctx,
                                       struct_address)) {
      diagnostic_manager.Printf(
          eDiagnosticSeverityError,
          "errored out in %s, couldn't PrepareToExecuteJITExpression",
          __FUNCTION__);
      return lldb::eExpressionSetupError;
    }

    lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
    lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;

    if (m_can_interpret) {
      llvm::Module *module = m_execution_unit_sp->GetModule();
      llvm::Function *function = m_execution_unit_sp->GetFunction();

      if (!module || !function) {
        diagnostic_manager.PutString(
            eDiagnosticSeverityError,
            "supposed to interpret, but nothing is there");
        return lldb::eExpressionSetupError;
      }

      Status interpreter_error;

      std::vector<lldb::addr_t> args;

      if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) {
        diagnostic_manager.Printf(eDiagnosticSeverityError,
                                  "errored out in %s, couldn't AddArguments",
                                  __FUNCTION__);
        return lldb::eExpressionSetupError;
      }

      function_stack_bottom = m_stack_frame_bottom;
      function_stack_top = m_stack_frame_top;

      IRInterpreter::Interpret(*module, *function, args, *m_execution_unit_sp,
                               interpreter_error, function_stack_bottom,
                               function_stack_top, exe_ctx);

      if (!interpreter_error.Success()) {
        diagnostic_manager.Printf(eDiagnosticSeverityError,
                                  "supposed to interpret, but failed: %s",
                                  interpreter_error.AsCString());
        return lldb::eExpressionDiscarded;
      }
    } else {
      if (!exe_ctx.HasThreadScope()) {
        diagnostic_manager.Printf(eDiagnosticSeverityError,
                                  "%s called with no thread selected",
                                  __FUNCTION__);
        return lldb::eExpressionSetupError;
      }

      Address wrapper_address(m_jit_start_addr);

      std::vector<lldb::addr_t> args;

      if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) {
        diagnostic_manager.Printf(eDiagnosticSeverityError,
                                  "errored out in %s, couldn't AddArguments",
                                  __FUNCTION__);
        return lldb::eExpressionSetupError;
      }

      lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression(
          exe_ctx.GetThreadRef(), wrapper_address, args, options,
          shared_ptr_to_me));

      StreamString ss;
      if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) {
        diagnostic_manager.PutString(eDiagnosticSeverityError, ss.GetString());
        return lldb::eExpressionSetupError;
      }

      ThreadPlanCallUserExpression *user_expression_plan =
          static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());

      lldb::addr_t function_stack_pointer =
          user_expression_plan->GetFunctionStackPointer();

      function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
      function_stack_top = function_stack_pointer;

      LLDB_LOGF(
          log,
          "-- [UserExpression::Execute] Execution of expression begins --");

      if (exe_ctx.GetProcessPtr())
        exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);

      lldb::ExpressionResults execution_result =
          exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options,
                                                diagnostic_manager);

      if (exe_ctx.GetProcessPtr())
        exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);

      LLDB_LOGF(log, "-- [UserExpression::Execute] Execution of expression "
                     "completed --");

      if (execution_result == lldb::eExpressionInterrupted ||
          execution_result == lldb::eExpressionHitBreakpoint) {
        const char *error_desc = nullptr;

        if (call_plan_sp) {
          lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
          if (real_stop_info_sp)
            error_desc = real_stop_info_sp->GetDescription();
        }
        if (error_desc)
          diagnostic_manager.Printf(eDiagnosticSeverityError,
                                    "Execution was interrupted, reason: %s.",
                                    error_desc);
        else
          diagnostic_manager.PutString(eDiagnosticSeverityError,
                                       "Execution was interrupted.");

        if ((execution_result == lldb::eExpressionInterrupted &&
             options.DoesUnwindOnError()) ||
            (execution_result == lldb::eExpressionHitBreakpoint &&
             options.DoesIgnoreBreakpoints()))
          diagnostic_manager.AppendMessageToDiagnostic(
              "The process has been returned to the state before expression "
              "evaluation.");
        else {
          if (execution_result == lldb::eExpressionHitBreakpoint)
            user_expression_plan->TransferExpressionOwnership();
          diagnostic_manager.AppendMessageToDiagnostic(
              "The process has been left at the point where it was "
              "interrupted, "
              "use \"thread return -x\" to return to the state before "
              "expression evaluation.");
        }

        return execution_result;
      } else if (execution_result == lldb::eExpressionStoppedForDebug) {
        diagnostic_manager.PutString(
            eDiagnosticSeverityRemark,
            "Execution was halted at the first instruction of the expression "
            "function because \"debug\" was requested.\n"
            "Use \"thread return -x\" to return to the state before expression "
            "evaluation.");
        return execution_result;
      } else if (execution_result != lldb::eExpressionCompleted) {
        diagnostic_manager.Printf(
            eDiagnosticSeverityError,
            "Couldn't execute function; result was %s",
            Process::ExecutionResultAsCString(execution_result));
        return execution_result;
      }
    }

    if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result,
                             function_stack_bottom, function_stack_top)) {
      return lldb::eExpressionCompleted;
    } else {
      return lldb::eExpressionResultUnavailable;
    }
  } else {
    diagnostic_manager.PutString(
        eDiagnosticSeverityError,
        "Expression can't be run, because there is no JIT compiled function");
    return lldb::eExpressionSetupError;
  }
}

bool LLVMUserExpression::FinalizeJITExecution(
    DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
    lldb::ExpressionVariableSP &result, lldb::addr_t function_stack_bottom,
    lldb::addr_t function_stack_top) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  LLDB_LOGF(log, "-- [UserExpression::FinalizeJITExecution] Dematerializing "
                 "after execution --");

  if (!m_dematerializer_sp) {
    diagnostic_manager.Printf(eDiagnosticSeverityError,
                              "Couldn't apply expression side effects : no "
                              "dematerializer is present");
    return false;
  }

  Status dematerialize_error;

  m_dematerializer_sp->Dematerialize(dematerialize_error, function_stack_bottom,
                                     function_stack_top);

  if (!dematerialize_error.Success()) {
    diagnostic_manager.Printf(eDiagnosticSeverityError,
                              "Couldn't apply expression side effects : %s",
                              dematerialize_error.AsCString("unknown error"));
    return false;
  }

  result =
      GetResultAfterDematerialization(exe_ctx.GetBestExecutionContextScope());

  if (result)
    result->TransferAddress();

  m_dematerializer_sp.reset();

  return true;
}

bool LLVMUserExpression::PrepareToExecuteJITExpression(
    DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
    lldb::addr_t &struct_address) {
  lldb::TargetSP target;
  lldb::ProcessSP process;
  lldb::StackFrameSP frame;

  if (!LockAndCheckContext(exe_ctx, target, process, frame)) {
    diagnostic_manager.PutString(
        eDiagnosticSeverityError,
        "The context has changed before we could JIT the expression!");
    return false;
  }

  if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) {
    if (m_materialized_address == LLDB_INVALID_ADDRESS) {
      Status alloc_error;

      IRMemoryMap::AllocationPolicy policy =
          m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly
                          : IRMemoryMap::eAllocationPolicyMirror;

      const bool zero_memory = false;

      m_materialized_address = m_execution_unit_sp->Malloc(
          m_materializer_up->GetStructByteSize(),
          m_materializer_up->GetStructAlignment(),
          lldb::ePermissionsReadable | lldb::ePermissionsWritable, policy,
          zero_memory, alloc_error);

      if (!alloc_error.Success()) {
        diagnostic_manager.Printf(
            eDiagnosticSeverityError,
            "Couldn't allocate space for materialized struct: %s",
            alloc_error.AsCString());
        return false;
      }
    }

    struct_address = m_materialized_address;

    if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) {
      Status alloc_error;

      const size_t stack_frame_size = 512 * 1024;

      const bool zero_memory = false;

      m_stack_frame_bottom = m_execution_unit_sp->Malloc(
          stack_frame_size, 8,
          lldb::ePermissionsReadable | lldb::ePermissionsWritable,
          IRMemoryMap::eAllocationPolicyHostOnly, zero_memory, alloc_error);

      m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;

      if (!alloc_error.Success()) {
        diagnostic_manager.Printf(
            eDiagnosticSeverityError,
            "Couldn't allocate space for the stack frame: %s",
            alloc_error.AsCString());
        return false;
      }
    }

    Status materialize_error;

    m_dematerializer_sp = m_materializer_up->Materialize(
        frame, *m_execution_unit_sp, struct_address, materialize_error);

    if (!materialize_error.Success()) {
      diagnostic_manager.Printf(eDiagnosticSeverityError,
                                "Couldn't materialize: %s",
                                materialize_error.AsCString());
      return false;
    }
  }
  return true;
}

lldb::ModuleSP LLVMUserExpression::GetJITModule() {
  if (m_execution_unit_sp)
    return m_execution_unit_sp->GetJITModule();
  return lldb::ModuleSP();
}
