//===-- LLVMUserExpression.cpp ----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes

// Project includes
#include "lldb/Expression/LLVMUserExpression.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionSourceCode.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/ClangASTContext.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"

using namespace lldb_private;

LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope, 
                                       const char *expr, 
                                       const char *expr_prefix,
                                       lldb::LanguageType language, 
                                       ResultType desired_type, 
                                       const EvaluateExpressionOptions &options)
    : UserExpression(exe_scope, expr, expr_prefix, language, desired_type, options),
      m_stack_frame_bottom(LLDB_INVALID_ADDRESS),
      m_stack_frame_top(LLDB_INVALID_ADDRESS),
      m_transformed_text(),
      m_execution_unit_sp(),
      m_materializer_ap(),
      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(NULL),
      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.PutCString(eDiagnosticSeverityError, "supposed to interpret, but nothing is there");
                return lldb::eExpressionSetupError;
            }

            Error 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.get(), 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.PutCString(eDiagnosticSeverityError, ss.GetData());
                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;

            if (log)
                log->Printf("-- [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);

            if (log)
                log->Printf("-- [UserExpression::Execute] Execution of expression completed --");

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

                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.PutCString(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.PutCString(
                    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.PutCString(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));

    if (log)
        log->Printf("-- [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;
    }

    Error 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.PutCString(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)
        {
            Error 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_ap->GetStructByteSize(), 
                                                                 m_materializer_ap->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)
        {
            Error 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;
            }
        }

        Error materialize_error;

        m_dematerializer_sp =
            m_materializer_ap->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();
}
