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

#include "lldb/Target/ExecutionContext.h"

#include "lldb/Core/State.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

using namespace lldb_private;

ExecutionContext::ExecutionContext() :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
}

ExecutionContext::ExecutionContext (const ExecutionContext &rhs) :
    m_target_sp(rhs.m_target_sp),
    m_process_sp(rhs.m_process_sp),
    m_thread_sp(rhs.m_thread_sp),
    m_frame_sp(rhs.m_frame_sp)
{
}

ExecutionContext::ExecutionContext (const lldb::TargetSP &target_sp, bool get_process) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (target_sp)
        SetContext (target_sp, get_process);
}

ExecutionContext::ExecutionContext (const lldb::ProcessSP &process_sp) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (process_sp)
        SetContext (process_sp);
}

ExecutionContext::ExecutionContext (const lldb::ThreadSP &thread_sp) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (thread_sp)
        SetContext (thread_sp);
}

ExecutionContext::ExecutionContext (const lldb::StackFrameSP &frame_sp) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (frame_sp)
        SetContext (frame_sp);
}

ExecutionContext::ExecutionContext (const lldb::TargetWP &target_wp, bool get_process) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    lldb::TargetSP target_sp(target_wp.lock());
    if (target_sp)
        SetContext (target_sp, get_process);
}

ExecutionContext::ExecutionContext (const lldb::ProcessWP &process_wp) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    lldb::ProcessSP process_sp(process_wp.lock());
    if (process_sp)
        SetContext (process_sp);
}

ExecutionContext::ExecutionContext (const lldb::ThreadWP &thread_wp) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    lldb::ThreadSP thread_sp(thread_wp.lock());
    if (thread_sp)
        SetContext (thread_sp);
}

ExecutionContext::ExecutionContext (const lldb::StackFrameWP &frame_wp) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    lldb::StackFrameSP frame_sp(frame_wp.lock());
    if (frame_sp)
        SetContext (frame_sp);
}

ExecutionContext::ExecutionContext (Target* t, bool fill_current_process_thread_frame) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (t)
    {
        m_target_sp = t->shared_from_this();
        if (fill_current_process_thread_frame)
        {
            m_process_sp = t->GetProcessSP();
            if (m_process_sp)
            {
                m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
                if (m_thread_sp)
                    m_frame_sp = m_thread_sp->GetSelectedFrame();
            }
        }
    }
}

ExecutionContext::ExecutionContext(Process* process, Thread *thread, StackFrame *frame) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (process)
    {
        m_process_sp = process->shared_from_this();
        m_target_sp = process->GetTarget().shared_from_this();
    }
    if (thread)
        m_thread_sp = thread->shared_from_this();
    if (frame)
        m_frame_sp = frame->shared_from_this();
}

ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref) :
    m_target_sp (exe_ctx_ref.GetTargetSP()),
    m_process_sp (exe_ctx_ref.GetProcessSP()),
    m_thread_sp (exe_ctx_ref.GetThreadSP()),
    m_frame_sp (exe_ctx_ref.GetFrameSP())
{
}

ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, bool thread_and_frame_only_if_stopped) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (exe_ctx_ref_ptr)
    {
        m_target_sp  = exe_ctx_ref_ptr->GetTargetSP();
        m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
        if (!thread_and_frame_only_if_stopped || (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true)))
        {
            m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
            m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
        }
    }
}

ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, Mutex::Locker &locker) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (exe_ctx_ref_ptr)
    {
        m_target_sp  = exe_ctx_ref_ptr->GetTargetSP();
        if (m_target_sp)
        {
            locker.Lock(m_target_sp->GetAPIMutex());
            m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
            m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
            m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
        }
    }
}

ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker) :
    m_target_sp (exe_ctx_ref.GetTargetSP()),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (m_target_sp)
    {
        locker.Lock(m_target_sp->GetAPIMutex());
        m_process_sp = exe_ctx_ref.GetProcessSP();
        m_thread_sp  = exe_ctx_ref.GetThreadSP();
        m_frame_sp   = exe_ctx_ref.GetFrameSP();
    }
}

ExecutionContext::ExecutionContext (ExecutionContextScope *exe_scope_ptr) :
    m_target_sp (),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (exe_scope_ptr)
        exe_scope_ptr->CalculateExecutionContext (*this);
}

ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref)
{
    exe_scope_ref.CalculateExecutionContext (*this);
}

void
ExecutionContext::Clear()
{
    m_target_sp.reset();
    m_process_sp.reset();
    m_thread_sp.reset();
    m_frame_sp.reset();
}

ExecutionContext::~ExecutionContext()
{
}

uint32_t
ExecutionContext::GetAddressByteSize() const
{
    if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
        return m_target_sp->GetArchitecture().GetAddressByteSize();
    if (m_process_sp)
        return m_process_sp->GetAddressByteSize();
    return sizeof(void *);
}

lldb::ByteOrder
ExecutionContext::GetByteOrder() const
{
    if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
        m_target_sp->GetArchitecture().GetByteOrder();
    if (m_process_sp)
        m_process_sp->GetByteOrder();
    return endian::InlHostByteOrder();
}

RegisterContext *
ExecutionContext::GetRegisterContext () const
{
    if (m_frame_sp)
        return m_frame_sp->GetRegisterContext().get();
    else if (m_thread_sp)
        return m_thread_sp->GetRegisterContext().get();
    return NULL;
}

Target *
ExecutionContext::GetTargetPtr () const
{
    if (m_target_sp)
        return m_target_sp.get();
    if (m_process_sp)
        return &m_process_sp->GetTarget();
    return NULL;
}

Process *
ExecutionContext::GetProcessPtr () const
{
    if (m_process_sp)
        return m_process_sp.get();
    if (m_target_sp)
        return m_target_sp->GetProcessSP().get();
    return NULL;
}

ExecutionContextScope *
ExecutionContext::GetBestExecutionContextScope () const
{
    if (m_frame_sp)
        return m_frame_sp.get();
    if (m_thread_sp)
        return m_thread_sp.get();
    if (m_process_sp)
        return m_process_sp.get();
    return m_target_sp.get();
}

Target &
ExecutionContext::GetTargetRef () const
{
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
    assert (m_target_sp.get());
#endif
    return *m_target_sp;
}

Process &
ExecutionContext::GetProcessRef () const
{
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
    assert (m_process_sp.get());
#endif
    return *m_process_sp;
}

Thread &
ExecutionContext::GetThreadRef () const
{
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
    assert (m_thread_sp.get());
#endif
    return *m_thread_sp;
}

StackFrame &
ExecutionContext::GetFrameRef () const
{
#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
    assert (m_frame_sp.get());
#endif
    return *m_frame_sp;
}

void
ExecutionContext::SetTargetSP (const lldb::TargetSP &target_sp)
{
    m_target_sp = target_sp;
}

void
ExecutionContext::SetProcessSP (const lldb::ProcessSP &process_sp)
{
    m_process_sp = process_sp;
}

void
ExecutionContext::SetThreadSP (const lldb::ThreadSP &thread_sp)
{
    m_thread_sp = thread_sp;
}

void
ExecutionContext::SetFrameSP (const lldb::StackFrameSP &frame_sp)
{
    m_frame_sp = frame_sp;
}

void
ExecutionContext::SetTargetPtr (Target* target)
{
    if (target)
        m_target_sp = target->shared_from_this();
    else
        m_target_sp.reset();
}

void
ExecutionContext::SetProcessPtr (Process *process)
{
    if (process)
        m_process_sp = process->shared_from_this();
    else
        m_process_sp.reset();
}

void
ExecutionContext::SetThreadPtr (Thread *thread)
{
    if (thread)
        m_thread_sp = thread->shared_from_this();
    else
        m_thread_sp.reset();
}

void
ExecutionContext::SetFramePtr (StackFrame *frame)
{
    if (frame)
        m_frame_sp = frame->shared_from_this();
    else
        m_frame_sp.reset();
}

void
ExecutionContext::SetContext (const lldb::TargetSP &target_sp, bool get_process)
{
    m_target_sp = target_sp;
    if (get_process && target_sp)
        m_process_sp = target_sp->GetProcessSP();
    else
        m_process_sp.reset();
    m_thread_sp.reset();
    m_frame_sp.reset();
}

void
ExecutionContext::SetContext (const lldb::ProcessSP &process_sp)
{
    m_process_sp = process_sp;
    if (process_sp)
        m_target_sp = process_sp->GetTarget().shared_from_this();
    else
        m_target_sp.reset();
    m_thread_sp.reset();
    m_frame_sp.reset();
}

void
ExecutionContext::SetContext (const lldb::ThreadSP &thread_sp)
{
    m_frame_sp.reset();
    m_thread_sp = thread_sp;
    if (thread_sp)
    {
        m_process_sp = thread_sp->GetProcess();
        if (m_process_sp)
            m_target_sp = m_process_sp->GetTarget().shared_from_this();
        else
            m_target_sp.reset();
    }
    else
    {
        m_target_sp.reset();
        m_process_sp.reset();
    }
}

void
ExecutionContext::SetContext (const lldb::StackFrameSP &frame_sp)
{
    m_frame_sp = frame_sp;
    if (frame_sp)
    {
        m_thread_sp = frame_sp->CalculateThread();
        if (m_thread_sp)
        {
            m_process_sp = m_thread_sp->GetProcess();
            if (m_process_sp)
                m_target_sp = m_process_sp->GetTarget().shared_from_this();
            else
                m_target_sp.reset();
        }
        else
        {
            m_target_sp.reset();
            m_process_sp.reset();
        }
    }
    else
    {
        m_target_sp.reset();
        m_process_sp.reset();
        m_thread_sp.reset();
    }
}

ExecutionContext &
ExecutionContext::operator =(const ExecutionContext &rhs)
{
    if (this != &rhs)
    {
        m_target_sp  = rhs.m_target_sp;
        m_process_sp = rhs.m_process_sp;
        m_thread_sp  = rhs.m_thread_sp;
        m_frame_sp   = rhs.m_frame_sp;
    }
    return *this;
}

bool
ExecutionContext::operator ==(const ExecutionContext &rhs) const
{
    // Check that the frame shared pointers match, or both are valid and their stack
    // IDs match since sometimes we get new objects that represent the same 
    // frame within a thread.
    if ((m_frame_sp == rhs.m_frame_sp) || (m_frame_sp && rhs.m_frame_sp && m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID()))
    {
        // Check that the thread shared pointers match, or both are valid and 
        // their thread IDs match since sometimes we get new objects that 
        // represent the same thread within a process.
        if ((m_thread_sp == rhs.m_thread_sp) || (m_thread_sp && rhs.m_thread_sp && m_thread_sp->GetID() == rhs.m_thread_sp->GetID()))
        {
            // Processes and targets don't change much
            return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
        }
    }
    return false;
}

bool
ExecutionContext::operator !=(const ExecutionContext &rhs) const
{
    return !(*this == rhs);
}

bool
ExecutionContext::HasTargetScope () const
{
    return ((bool) m_target_sp
            && m_target_sp->IsValid());
}

bool
ExecutionContext::HasProcessScope () const
{
    return (HasTargetScope()
            && ((bool) m_process_sp && m_process_sp->IsValid()));
}

bool
ExecutionContext::HasThreadScope () const
{
    return (HasProcessScope()
           && ((bool) m_thread_sp && m_thread_sp->IsValid()));
}

bool
ExecutionContext::HasFrameScope () const
{
    return HasThreadScope() && m_frame_sp;
}

ExecutionContextRef::ExecutionContextRef() :
    m_target_wp (),
    m_process_wp (),
    m_thread_wp (),
    m_tid(LLDB_INVALID_THREAD_ID),
    m_stack_id ()
{
}

ExecutionContextRef::ExecutionContextRef (const ExecutionContext *exe_ctx) :
    m_target_wp (),
    m_process_wp (),
    m_thread_wp (),
    m_tid(LLDB_INVALID_THREAD_ID),
    m_stack_id ()
{
    if (exe_ctx)
        *this = *exe_ctx;
}

ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) :
    m_target_wp (),
    m_process_wp (),
    m_thread_wp (),
    m_tid(LLDB_INVALID_THREAD_ID),
    m_stack_id ()
{
    *this = exe_ctx;
}


ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) :
    m_target_wp(),
    m_process_wp(),
    m_thread_wp(),
    m_tid(LLDB_INVALID_THREAD_ID),
    m_stack_id ()
{
    SetTargetPtr (target, adopt_selected);
}




ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) :
    m_target_wp (rhs.m_target_wp),
    m_process_wp(rhs.m_process_wp),
    m_thread_wp (rhs.m_thread_wp),
    m_tid       (rhs.m_tid),
    m_stack_id  (rhs.m_stack_id)
{
}

ExecutionContextRef &
ExecutionContextRef::operator =(const ExecutionContextRef &rhs)
{
    if (this != &rhs)
    {
        m_target_wp  = rhs.m_target_wp;
        m_process_wp = rhs.m_process_wp;
        m_thread_wp  = rhs.m_thread_wp;
        m_tid        = rhs.m_tid;
        m_stack_id   = rhs.m_stack_id;
    }
    return *this;
}

ExecutionContextRef &
ExecutionContextRef::operator =(const ExecutionContext &exe_ctx)
{
    m_target_wp = exe_ctx.GetTargetSP();
    m_process_wp = exe_ctx.GetProcessSP();
    lldb::ThreadSP thread_sp (exe_ctx.GetThreadSP());
    m_thread_wp = thread_sp;
    if (thread_sp)
        m_tid = thread_sp->GetID();
    else
        m_tid = LLDB_INVALID_THREAD_ID;
    lldb::StackFrameSP frame_sp (exe_ctx.GetFrameSP());
    if (frame_sp)
        m_stack_id = frame_sp->GetStackID();
    else
        m_stack_id.Clear();
    return *this;
}

void
ExecutionContextRef::Clear()
{
    m_target_wp.reset();
    m_process_wp.reset();
    ClearThread();
    ClearFrame();
}

ExecutionContextRef::~ExecutionContextRef()
{
}

void
ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp)
{
    m_target_wp = target_sp;
}

void
ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp)
{
    if (process_sp)
    {
        m_process_wp = process_sp;
        SetTargetSP (process_sp->GetTarget().shared_from_this());
    }
    else
    {
        m_process_wp.reset();
        m_target_wp.reset();
    }
}

void
ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp)
{
    if (thread_sp)
    {
        m_thread_wp = thread_sp;
        m_tid = thread_sp->GetID();
        SetProcessSP (thread_sp->GetProcess());
    }
    else
    {
        ClearThread();
        m_process_wp.reset();
        m_target_wp.reset();
    }
}

void
ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp)
{
    if (frame_sp)
    {
        m_stack_id = frame_sp->GetStackID();
        SetThreadSP (frame_sp->GetThread());
    }
    else
    {
        ClearFrame();
        ClearThread();
        m_process_wp.reset();
        m_target_wp.reset();
    }

}

void
ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected)
{
    Clear();
    if (target)
    {
        lldb::TargetSP target_sp (target->shared_from_this());
        if (target_sp)
        {
            m_target_wp = target_sp;
            if (adopt_selected)
            {
                lldb::ProcessSP process_sp (target_sp->GetProcessSP());
                if (process_sp)
                {
                    m_process_wp = process_sp;
                    if (process_sp)
                    {
                        // Only fill in the thread and frame if our process is stopped
                        // Don't just check the state, since we might be in the middle of
                        // resuming.
                        Process::StopLocker stop_locker;

                        if (stop_locker.TryLock(&process_sp->GetRunLock()) && StateIsStoppedState (process_sp->GetState(), true))
                        {
                            lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
                            if (!thread_sp)
                                thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
                            
                            if (thread_sp)
                            {
                                SetThreadSP (thread_sp);
                                lldb::StackFrameSP frame_sp (thread_sp->GetSelectedFrame());
                                if (!frame_sp)
                                    frame_sp = thread_sp->GetStackFrameAtIndex(0);
                                if (frame_sp)
                                    SetFrameSP (frame_sp);
                            }
                        }
                    }
                }
            }
        }
    }
}

void
ExecutionContextRef::SetProcessPtr (Process *process)
{
    if (process)
    {
        SetProcessSP(process->shared_from_this());
    }
    else
    {
        m_process_wp.reset();
        m_target_wp.reset();
    }
}

void
ExecutionContextRef::SetThreadPtr (Thread *thread)
{
    if (thread)
    {
        SetThreadSP (thread->shared_from_this());
    }
    else
    {
        ClearThread();
        m_process_wp.reset();
        m_target_wp.reset();
    }
}

void
ExecutionContextRef::SetFramePtr (StackFrame *frame)
{
    if (frame)
        SetFrameSP (frame->shared_from_this());
    else
        Clear();
}

lldb::TargetSP
ExecutionContextRef::GetTargetSP () const
{
    lldb::TargetSP target_sp(m_target_wp.lock());
    if (target_sp && !target_sp->IsValid())
        target_sp.reset();
    return target_sp;
}

lldb::ProcessSP
ExecutionContextRef::GetProcessSP () const
{
    lldb::ProcessSP process_sp(m_process_wp.lock());
    if (process_sp && !process_sp->IsValid())
        process_sp.reset();
    return process_sp;
}

lldb::ThreadSP
ExecutionContextRef::GetThreadSP () const
{
    lldb::ThreadSP thread_sp (m_thread_wp.lock());
    
    if (m_tid != LLDB_INVALID_THREAD_ID)
    {
        // We check if the thread has been destroyed in cases where clients
        // might still have shared pointer to a thread, but the thread is
        // not valid anymore (not part of the process)
        if (!thread_sp || !thread_sp->IsValid())
        {
            lldb::ProcessSP process_sp(GetProcessSP());
            if (process_sp && process_sp->IsValid())
            {
                thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
                m_thread_wp = thread_sp;
            }
        }
    }
    
    // Check that we aren't about to return an invalid thread sp.  We might return a NULL thread_sp,
    // but don't return an invalid one.
    
    if (thread_sp && !thread_sp->IsValid())
        thread_sp.reset();
    
    return thread_sp;
}

lldb::StackFrameSP
ExecutionContextRef::GetFrameSP () const
{
    if (m_stack_id.IsValid())
    {
        lldb::ThreadSP thread_sp (GetThreadSP());
        if (thread_sp)
            return thread_sp->GetFrameWithStackID (m_stack_id);
    }
    return lldb::StackFrameSP();
}

ExecutionContext
ExecutionContextRef::Lock (bool thread_and_frame_only_if_stopped) const
{
    return ExecutionContext(this, thread_and_frame_only_if_stopped);
}


