//===-- 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/Policy.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 (!PolicyStack::Get().Current().capabilities.can_evaluate_expressions) {
    LLDB_LOG(log, "== [UserExpression::Evaluate] The current policy doesn't "
                  "allow evaluating expressions ==");
    set_error(Status::FromErrorString(
        "expression evaluation is not allowed in this context"));
    return lldb::eExpressionSetupError;
  }

  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;
}
