//===-- 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 (t->shared_from_this()),
    m_process_sp (),
    m_thread_sp (),
    m_frame_sp ()
{
    if (t && 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 (process->shared_from_this()),
    m_thread_sp (thread->shared_from_this()),
    m_frame_sp (frame->shared_from_this())
{
    if (process)
        m_target_sp = process->GetTarget().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) :
    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();
        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())
        m_target_sp->GetArchitecture().GetAddressByteSize();
    if (m_process_sp)
        m_process_sp->GetAddressByteSize();
    return sizeof(void *);
}



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
                        if (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 () const
{
    return ExecutionContext(this);
}


