//===-- UserExpression.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 <cstdio>
#include <sys/types.h>

#include <cstdlib>
#include <map>
#include <string>

#include "lldb/Core/Module.h"
#include "lldb/Core/Progress.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/Expression/UserExpression.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeSystem.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/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/BinaryFormat/Dwarf.h"

using namespace lldb_private;

char UserExpression::ID;

UserExpression::UserExpression(ExecutionContextScope &exe_scope,
                               llvm::StringRef expr, llvm::StringRef prefix,
                               SourceLanguage language, ResultType desired_type,
                               const EvaluateExpressionOptions &options)
    : Expression(exe_scope), m_expr_text(std::string(expr)),
      m_expr_prefix(std::string(prefix)), m_language(language),
      m_desired_type(desired_type), m_options(options) {}

UserExpression::~UserExpression() = default;

void UserExpression::InstallContext(ExecutionContext &exe_ctx) {
  m_jit_process_wp = exe_ctx.GetProcessSP();

  lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();

  if (frame_sp)
    m_address = frame_sp->GetFrameCodeAddress();
}

bool UserExpression::LockAndCheckContext(ExecutionContext &exe_ctx,
                                         lldb::TargetSP &target_sp,
                                         lldb::ProcessSP &process_sp,
                                         lldb::StackFrameSP &frame_sp) {
  lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock();
  process_sp = exe_ctx.GetProcessSP();

  if (process_sp != expected_process_sp)
    return false;

  process_sp = exe_ctx.GetProcessSP();
  target_sp = exe_ctx.GetTargetSP();
  frame_sp = exe_ctx.GetFrameSP();

  if (m_address.IsValid()) {
    if (!frame_sp)
      return false;
    return (Address::CompareLoadAddress(m_address,
                                        frame_sp->GetFrameCodeAddress(),
                                        target_sp.get()) == 0);
  }

  return true;
}

bool UserExpression::MatchesContext(ExecutionContext &exe_ctx) {
  lldb::TargetSP target_sp;
  lldb::ProcessSP process_sp;
  lldb::StackFrameSP frame_sp;

  return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
}

lldb::ValueObjectSP UserExpression::GetObjectPointerValueObject(
    lldb::StackFrameSP frame_sp, llvm::StringRef object_name, Status &err) {
  err.Clear();

  if (!frame_sp) {
    err = Status::FromErrorStringWithFormatv(
        "Couldn't load '{0}' because the context is incomplete", object_name);
    return {};
  }

  if (auto var_list_sp = frame_sp->GetInScopeVariableList(false))
    if (auto var_sp =
            var_list_sp->FindVariable(ConstString(object_name), false))
      return frame_sp->GetValueObjectForFrameVariable(var_sp,
                                                      lldb::eNoDynamicValues);

  return {};
}

lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp,
                                              llvm::StringRef object_name,
                                              Status &err) {
  auto valobj_sp =
      GetObjectPointerValueObject(std::move(frame_sp), object_name, err);

  if (!err.Success() || !valobj_sp.get())
    return LLDB_INVALID_ADDRESS;

  lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);

  if (ret == LLDB_INVALID_ADDRESS) {
    err = Status::FromErrorStringWithFormatv(
        "Couldn't load '{0}' because its value couldn't be evaluated",
        object_name);
    return LLDB_INVALID_ADDRESS;
  }

  return ret;
}

lldb::ExpressionResults
UserExpression::Evaluate(ExecutionContext &exe_ctx,
                         const EvaluateExpressionOptions &options,
                         llvm::StringRef expr, llvm::StringRef prefix,
                         lldb::ValueObjectSP &result_valobj_sp,
                         std::string *fixed_expression, ValueObject *ctx_obj) {
  Log *log(GetLog(LLDBLog::Expressions | LLDBLog::Step));
  auto set_error = [&](Status error) {
    result_valobj_sp = ValueObjectConstResult::Create(
        exe_ctx.GetBestExecutionContextScope(), std::move(error));
  };

  if (ctx_obj) {
    static unsigned const ctx_type_mask = lldb::TypeFlags::eTypeIsClass |
                                          lldb::TypeFlags::eTypeIsStructUnion |
                                          lldb::TypeFlags::eTypeIsReference;
    if (!(ctx_obj->GetTypeInfo() & ctx_type_mask)) {
      LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of "
                    "an invalid type, can't run expressions.");
      set_error(Status("a context object of an invalid type passed"));
      return lldb::eExpressionSetupError;
    }
  }

  if (ctx_obj && ctx_obj->GetTypeInfo() & lldb::TypeFlags::eTypeIsReference) {
    Status error;
    lldb::ValueObjectSP deref_ctx_sp = ctx_obj->Dereference(error);
    if (!error.Success()) {
      LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of "
                    "a reference type that can't be dereferenced, can't run "
                    "expressions.");
      set_error(Status(
          "passed context object of an reference type cannot be deferenced"));
      return lldb::eExpressionSetupError;
    }

    ctx_obj = deref_ctx_sp.get();
  }

  lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
  SourceLanguage language = options.GetLanguage();
  const ResultType desired_type = options.DoesCoerceToId()
                                      ? UserExpression::eResultTypeId
                                      : UserExpression::eResultTypeAny;
  Target *target = exe_ctx.GetTargetPtr();
  if (!target) {
    LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a NULL target, can't "
                  "run expressions.");
    set_error(Status("expression passed a null target"));
    return lldb::eExpressionSetupError;
  }

  Process *process = exe_ctx.GetProcessPtr();

  if (!process && execution_policy == eExecutionPolicyAlways) {
    LLDB_LOG(log, "== [UserExpression::Evaluate] No process, but the policy is "
                  "eExecutionPolicyAlways");

    set_error(Status("expression needed to run but couldn't: no process"));

    return lldb::eExpressionSetupError;
  }

  // Since we might need to allocate memory, we need to be stopped to run
  // an expression.
  if (process && process->GetState() != lldb::eStateStopped) {
    set_error(Status::FromErrorStringWithFormatv(
        "unable to evaluate expression while the process is {0}: the process "
        "must be stopped because the expression might require allocating "
        "memory.",
        StateAsCString(process->GetState())));
    return lldb::eExpressionSetupError;
  }

  // Explicitly force the IR interpreter to evaluate the expression when the
  // there is no process that supports running the expression for us. Don't
  // change the execution policy if we have the special top-level policy that
  // doesn't contain any expression and there is nothing to interpret.
  if (execution_policy != eExecutionPolicyTopLevel &&
      (process == nullptr || !process->CanJIT()))
    execution_policy = eExecutionPolicyNever;

  // We need to set the expression execution thread here, turns out parse can
  // call functions in the process of looking up symbols, which will escape the
  // context set by exe_ctx passed to Execute.
  lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP();
  ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(
      thread_sp);

  llvm::StringRef full_prefix;
  llvm::StringRef option_prefix(options.GetPrefix());
  std::string full_prefix_storage;
  if (!prefix.empty() && !option_prefix.empty()) {
    full_prefix_storage = std::string(prefix);
    full_prefix_storage.append(std::string(option_prefix));
    full_prefix = full_prefix_storage;
  } else if (!prefix.empty())
    full_prefix = prefix;
  else
    full_prefix = option_prefix;

  // If the language was not specified in the expression command, set it to the
  // language in the target's properties if specified, else default to the
  // langage for the frame.
  if (!language) {
    if (target->GetLanguage())
      language = target->GetLanguage();
    else if (StackFrame *frame = exe_ctx.GetFramePtr())
      language = frame->GetLanguage();
  }

  Status error;
  lldb::UserExpressionSP user_expression_sp(
      target->GetUserExpressionForLanguage(
          expr, full_prefix, language, desired_type, options, ctx_obj, error));
  if (error.Fail() || !user_expression_sp) {
    LLDB_LOG(log, "== [UserExpression::Evaluate] Getting expression: {0} ==",
             error.AsCString());
    set_error(std::move(error));
    return lldb::eExpressionSetupError;
  }

  LLDB_LOG(log, "== [UserExpression::Evaluate] Parsing expression {0} ==",
           expr.str());

  const bool keep_expression_in_memory = true;
  const bool generate_debug_info = options.GetGenerateDebugInfo();

  if (options.InvokeCancelCallback(lldb::eExpressionEvaluationParse)) {
    set_error(Status("expression interrupted by callback before parse"));
    return lldb::eExpressionInterrupted;
  }

  DiagnosticManager diagnostic_manager;

  bool parse_success =
      user_expression_sp->Parse(diagnostic_manager, exe_ctx, execution_policy,
                                keep_expression_in_memory, generate_debug_info);

  // Calculate the fixed expression always, since we need it for errors.
  std::string tmp_fixed_expression;
  if (fixed_expression == nullptr)
    fixed_expression = &tmp_fixed_expression;

  *fixed_expression = user_expression_sp->GetFixedText().str();
  lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;

  // If there is a fixed expression, try to parse it:
  if (!parse_success) {
    execution_results = lldb::eExpressionParseError;
    if (!fixed_expression->empty() && options.GetAutoApplyFixIts()) {
      const uint64_t max_fix_retries = options.GetRetriesWithFixIts();
      for (uint64_t i = 0; i < max_fix_retries; ++i) {
        // Try parsing the fixed expression.
        user_expression_sp.reset(target->GetUserExpressionForLanguage(
            fixed_expression->c_str(), full_prefix, language, desired_type,
            options, ctx_obj, error));
        if (!user_expression_sp)
          break;

        DiagnosticManager fixed_diagnostic_manager;
        parse_success = user_expression_sp->Parse(
            fixed_diagnostic_manager, exe_ctx, execution_policy,
            keep_expression_in_memory, generate_debug_info);
        if (parse_success) {
          diagnostic_manager.Clear();
          break;
        }
        // The fixed expression also didn't parse. Let's check for any new
        // fixits we could try.
        if (!user_expression_sp->GetFixedText().empty()) {
          *fixed_expression = user_expression_sp->GetFixedText().str();
        } else {
          // Fixed expression didn't compile without a fixit, don't retry and
          // don't tell the user about it.
          fixed_expression->clear();
          break;
        }
      }
    }

    if (!parse_success) {
      if (user_expression_sp)
        user_expression_sp->FixupParseErrorDiagnostics(diagnostic_manager);

      if (target->GetEnableNotifyAboutFixIts() && fixed_expression &&
          !fixed_expression->empty()) {
        std::string fixit =
            "fixed expression suggested:\n  " + *fixed_expression;
        diagnostic_manager.AddDiagnostic(fixit, lldb::eSeverityInfo,
                                         eDiagnosticOriginLLDB);
      }
      if (diagnostic_manager.Diagnostics().empty())
        error = Status::FromError(llvm::make_error<ExpressionError>(
            execution_results,
            "expression failed to parse (no further compiler diagnostics)"));
      else
        error =
            Status::FromError(diagnostic_manager.GetAsError(execution_results));
    }
  }

  if (parse_success) {
    lldb::ExpressionVariableSP expr_result;

    if (execution_policy == eExecutionPolicyNever &&
        !user_expression_sp->CanInterpret()) {
      LLDB_LOG(log, "== [UserExpression::Evaluate] Expression may not run, but "
                    "is not constant ==");

      if (diagnostic_manager.Diagnostics().empty())
        error = Status::FromError(llvm::make_error<ExpressionError>(
            lldb::eExpressionSetupError,
            "expression needed to run but couldn't"));
    } else if (execution_policy == eExecutionPolicyTopLevel) {
      set_error(Status(UserExpression::kNoResult, lldb::eErrorTypeGeneric));
      return lldb::eExpressionCompleted;
    } else {
      if (options.InvokeCancelCallback(lldb::eExpressionEvaluationExecution)) {
        set_error(Status::FromError(llvm::make_error<ExpressionError>(
            lldb::eExpressionInterrupted,
            "expression interrupted by callback before execution")));
        return lldb::eExpressionInterrupted;
      }

      diagnostic_manager.Clear();

      LLDB_LOG(log, "== [UserExpression::Evaluate] Executing expression ==");

      execution_results =
          user_expression_sp->Execute(diagnostic_manager, exe_ctx, options,
                                      user_expression_sp, expr_result);

      if (execution_results != lldb::eExpressionCompleted) {
        LLDB_LOG(log, "== [UserExpression::Evaluate] Execution completed "
                      "abnormally ==");

        if (diagnostic_manager.Diagnostics().empty())
          error = Status::FromError(llvm::make_error<ExpressionError>(
              execution_results,
              "expression failed to execute, unknown error"));
        else
          error = Status::FromError(
              diagnostic_manager.GetAsError(execution_results));
      } else {
        if (expr_result) {
          result_valobj_sp = expr_result->GetValueObject();
          result_valobj_sp->SetPreferredDisplayLanguage(
              language.AsLanguageType());

          LLDB_LOG(log,
                   "== [UserExpression::Evaluate] Execution completed "
                   "normally with result {0} ==",
                   result_valobj_sp->GetValueAsCString());
        } else {
          LLDB_LOG(log, "== [UserExpression::Evaluate] Execution completed "
                        "normally with no result ==");

          error = Status(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
        }
      }
    }
  }

  if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete)) {
    set_error(Status::FromError(llvm::make_error<ExpressionError>(
        lldb::eExpressionInterrupted,
        "expression interrupted by callback after complete")));
    return lldb::eExpressionInterrupted;
  }

  if (error.Fail())
    set_error(std::move(error));
  return execution_results;
}

lldb::ExpressionResults
UserExpression::Execute(DiagnosticManager &diagnostic_manager,
                        ExecutionContext &exe_ctx,
                        const EvaluateExpressionOptions &options,
                        lldb::UserExpressionSP &shared_ptr_to_me,
                        lldb::ExpressionVariableSP &result_var) {
  Debugger *debugger =
      exe_ctx.GetTargetPtr() ? &exe_ctx.GetTargetPtr()->GetDebugger() : nullptr;

  Progress progress("Running expression",
                    m_options.IsForUtilityExpr() ? "LLDB utility" : m_expr_text,
                    {}, debugger);

  lldb::ExpressionResults expr_result = DoExecute(
      diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var);
  Target *target = exe_ctx.GetTargetPtr();
  if (options.GetSuppressPersistentResult() && result_var && target) {
    if (auto *persistent_state =
            target->GetPersistentExpressionStateForLanguage(
                m_language.AsLanguageType()))
      persistent_state->RemovePersistentVariable(result_var);
  }
  return expr_result;
}
