//===-- 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, 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())
        m_target_sp->GetArchitecture().GetAddressByteSize();
    if (m_process_sp)
        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 lldb::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
                        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 (bool thread_and_frame_only_if_stopped) const
{
    return ExecutionContext(this, thread_and_frame_only_if_stopped);
}


