//===-- ThreadPlanCallUserExpression.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/Target/ThreadPlanCallUserExpression.h"


#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Address.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/DynamicCheckerFunctions.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"

using namespace lldb;
using namespace lldb_private;

// ThreadPlanCallUserExpression: Plan to call a single function

ThreadPlanCallUserExpression::ThreadPlanCallUserExpression(
    Thread &thread, Address &function, llvm::ArrayRef<lldb::addr_t> args,
    const EvaluateExpressionOptions &options,
    lldb::UserExpressionSP &user_expression_sp)
    : ThreadPlanCallFunction(thread, function, CompilerType(), args, options),
      m_user_expression_sp(user_expression_sp) {
  // User expressions are generally "User generated" so we should set them up
  // to stop when done.
  SetIsMasterPlan(true);
  SetOkayToDiscard(false);
}

ThreadPlanCallUserExpression::~ThreadPlanCallUserExpression() {}

void ThreadPlanCallUserExpression::GetDescription(
    Stream *s, lldb::DescriptionLevel level) {
  if (level == eDescriptionLevelBrief)
    s->Printf("User Expression thread plan");
  else
    ThreadPlanCallFunction::GetDescription(s, level);
}

void ThreadPlanCallUserExpression::DidPush() {
  ThreadPlanCallFunction::DidPush();
  if (m_user_expression_sp)
    m_user_expression_sp->WillStartExecuting();
}

void ThreadPlanCallUserExpression::WillPop() {
  ThreadPlanCallFunction::WillPop();
  if (m_user_expression_sp)
    m_user_expression_sp.reset();
}

bool ThreadPlanCallUserExpression::MischiefManaged() {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));

  if (IsPlanComplete()) {
    LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.",
              static_cast<void *>(this));

    if (m_manage_materialization && PlanSucceeded() && m_user_expression_sp) {
      lldb::addr_t function_stack_top;
      lldb::addr_t function_stack_bottom;
      lldb::addr_t function_stack_pointer = GetFunctionStackPointer();

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

      DiagnosticManager diagnostics;

      ExecutionContext exe_ctx(GetThread());

      m_user_expression_sp->FinalizeJITExecution(
          diagnostics, exe_ctx, m_result_var_sp, function_stack_bottom,
          function_stack_top);
    }

    ThreadPlan::MischiefManaged();
    return true;
  } else {
    return false;
  }
}

StopInfoSP ThreadPlanCallUserExpression::GetRealStopInfo() {
  StopInfoSP stop_info_sp = ThreadPlanCallFunction::GetRealStopInfo();

  if (stop_info_sp) {
    lldb::addr_t addr = GetStopAddress();
    DynamicCheckerFunctions *checkers = m_process.GetDynamicCheckers();
    StreamString s;

    if (checkers && checkers->DoCheckersExplainStop(addr, s))
      stop_info_sp->SetDescription(s.GetData());
  }

  return stop_info_sp;
}

void ThreadPlanCallUserExpression::DoTakedown(bool success) {
  ThreadPlanCallFunction::DoTakedown(success);
  m_user_expression_sp->DidFinishExecuting();
}
