//===-- StackFrameList.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/StackFrameList.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Unwind.h"

//#define DEBUG_STACK_FRAMES 1

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// StackFrameList constructor
//----------------------------------------------------------------------
StackFrameList::StackFrameList
(
    Thread &thread, 
    const lldb::StackFrameListSP &prev_frames_sp, 
    bool show_inline_frames
) :
    m_thread (thread),
    m_prev_frames_sp (prev_frames_sp),
    m_show_inlined_frames (show_inline_frames),
    m_mutex (Mutex::eMutexTypeRecursive),
    m_frames (),
    m_selected_frame_idx (0)
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
StackFrameList::~StackFrameList()
{
}


uint32_t
StackFrameList::GetNumFrames (bool can_create)
{
    Mutex::Locker locker (m_mutex);

    if (can_create && m_frames.size() <= 1)
    {
        if (m_show_inlined_frames)
        {
#if defined (DEBUG_STACK_FRAMES)
            StreamFile s(stdout);
#endif
            Unwind *unwinder = m_thread.GetUnwinder ();
            addr_t pc = LLDB_INVALID_ADDRESS;
            addr_t cfa = LLDB_INVALID_ADDRESS;

            // If we are going to show inlined stack frames as actual frames,
            // we need to calculate all concrete frames first, then iterate
            // through all of them and count up how many inlined functions are
            // in each frame. 
            const uint32_t unwind_frame_count = unwinder->GetFrameCount();
            
            StackFrameSP unwind_frame_sp;
            for (uint32_t idx=0; idx<unwind_frame_count; ++idx)
            {
                if (idx == 0)
                {
                    // We might have already created frame zero, only create it
                    // if we need to
                    if (m_frames.empty())
                    {
                        cfa = m_thread.m_reg_context_sp->GetSP();
                        m_thread.GetRegisterContext();
                        unwind_frame_sp.reset (new StackFrame (m_frames.size(), 
                                                               idx, 
                                                               m_thread, 
                                                               m_thread.m_reg_context_sp, 
                                                               cfa, 
                                                               m_thread.m_reg_context_sp->GetPC(), 
                                                               NULL));
                        m_frames.push_back (unwind_frame_sp);
                    }
                    else
                    {
                        unwind_frame_sp = m_frames.front();
                        cfa = unwind_frame_sp->m_id.GetCallFrameAddress();
                    }
                }
                else
                {
                    const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
                    assert (success);
                    unwind_frame_sp.reset (new StackFrame (m_frames.size(), idx, m_thread, cfa, pc, NULL));
                    m_frames.push_back (unwind_frame_sp);
                }

                Block *unwind_block = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock).block;
                
                if (unwind_block)
                {
                    Block *inlined_block = unwind_block->GetContainingInlinedBlock();
                    if (inlined_block)
                    {
                        for (; inlined_block != NULL; inlined_block = inlined_block->GetInlinedParent ())
                        {
                            SymbolContext inline_sc;
                            Block *parent_block = inlined_block->GetInlinedParent();

                            const bool is_inlined_frame = parent_block != NULL;
                        
                            if (parent_block == NULL)
                                parent_block = inlined_block->GetParent();
                            
                            parent_block->CalculateSymbolContext (&inline_sc);
                        
                            Address previous_frame_lookup_addr (m_frames.back()->GetFrameCodeAddress());
                            if (unwind_frame_sp->GetFrameIndex() > 0 && m_frames.back().get() == unwind_frame_sp.get())
                                previous_frame_lookup_addr.Slide (-1);
                        
                            AddressRange range;
                            inlined_block->GetRangeContainingAddress (previous_frame_lookup_addr, range);
                        
                            const InlineFunctionInfo* inline_info = inlined_block->GetInlinedFunctionInfo();
                            assert (inline_info);
                            inline_sc.line_entry.range.GetBaseAddress() = m_frames.back()->GetFrameCodeAddress();
                            inline_sc.line_entry.file = inline_info->GetCallSite().GetFile();
                            inline_sc.line_entry.line = inline_info->GetCallSite().GetLine();
                            inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
                                            
                            StackFrameSP frame_sp(new StackFrame (m_frames.size(),
                                                                  idx,
                                                                  m_thread,
                                                                  unwind_frame_sp->GetRegisterContextSP (),
                                                                  cfa,
                                                                  range.GetBaseAddress(),
                                                                  &inline_sc));                                           // The symbol context for this inline frame
                            
                            if (is_inlined_frame)
                            {
                                // Use the block with the inlined function info
                                // as the symbol context since we want this frame
                                // to have only the variables for the inlined function
                                frame_sp->SetSymbolContextScope (parent_block);
                            }
                            else
                            {
                                // This block is not inlined with means it has no
                                // inlined parents either, so we want to use the top
                                // most function block.
                                frame_sp->SetSymbolContextScope (&unwind_frame_sp->GetSymbolContext (eSymbolContextFunction).function->GetBlock(false));
                            }
                            
                            m_frames.push_back (frame_sp);
                        }
                    }
                }
            }

            if (m_prev_frames_sp)
            {
                StackFrameList *prev_frames = m_prev_frames_sp.get();
                StackFrameList *curr_frames = this;

#if defined (DEBUG_STACK_FRAMES)
                s.PutCString("\nprev_frames:\n");
                prev_frames->Dump (&s);
                s.PutCString("\ncurr_frames:\n");
                curr_frames->Dump (&s);
                s.EOL();
#endif
                size_t curr_frame_num, prev_frame_num;
                
                for (curr_frame_num = curr_frames->m_frames.size(), prev_frame_num = prev_frames->m_frames.size();
                     curr_frame_num > 0 && prev_frame_num > 0;
                     --curr_frame_num, --prev_frame_num)
                {
                    const size_t curr_frame_idx = curr_frame_num-1;
                    const size_t prev_frame_idx = prev_frame_num-1;
                    StackFrameSP curr_frame_sp (curr_frames->m_frames[curr_frame_idx]);
                    StackFrameSP prev_frame_sp (prev_frames->m_frames[prev_frame_idx]);

#if defined (DEBUG_STACK_FRAMES)
                    s.Printf("\n\nCurr frame #%u ", curr_frame_idx);
                    if (curr_frame_sp)
                        curr_frame_sp->Dump (&s, true, false);
                    else
                        s.PutCString("NULL");
                    s.Printf("\nPrev frame #%u ", prev_frame_idx);
                    if (prev_frame_sp)
                        prev_frame_sp->Dump (&s, true, false);
                    else
                        s.PutCString("NULL");
#endif

                    StackFrame *curr_frame = curr_frame_sp.get();
                    StackFrame *prev_frame = prev_frame_sp.get();
                    
                    if (curr_frame == NULL || prev_frame == NULL)
                        break;

                    // Check the stack ID to make sure they are equal
                    if (curr_frame->GetStackID() != prev_frame->GetStackID())
                        break;

                    prev_frame->UpdatePreviousFrameFromCurrentFrame (*curr_frame);
                    // Now copy the fixed up previous frame into the current frames
                    // so the pointer doesn't change
                    m_frames[curr_frame_idx] = prev_frame_sp;
                    //curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame);
                    
#if defined (DEBUG_STACK_FRAMES)
                    s.Printf("\n    Copying previous frame to current frame");
#endif
                }
                // We are done with the old stack frame list, we can release it now
                m_prev_frames_sp.reset();
            }
            
#if defined (DEBUG_STACK_FRAMES)
                s.PutCString("\n\nNew frames:\n");
                Dump (&s);
                s.EOL();
#endif
        }
        else
        {
            m_frames.resize(m_thread.GetUnwinder()->GetFrameCount());
        }
    }
    return m_frames.size();
}

void
StackFrameList::Dump (Stream *s)
{
    if (s == NULL)
        return;
    Mutex::Locker locker (m_mutex);

    const_iterator pos, begin = m_frames.begin(), end = m_frames.end();
    for (pos = begin; pos != end; ++pos)
    {
        StackFrame *frame = (*pos).get();
        s->Printf("%p: ", frame);
        if (frame)
        {
            frame->GetStackID().Dump (s);
            frame->DumpUsingSettingsFormat (s);
        }
        else
            s->Printf("frame #%u", std::distance (begin, pos));
        s->EOL();
    }
    s->EOL();
}

StackFrameSP
StackFrameList::GetFrameAtIndex (uint32_t idx)
{
    StackFrameSP frame_sp;
    Mutex::Locker locker (m_mutex);
    if (idx < m_frames.size())
        frame_sp = m_frames[idx];

    if (frame_sp)
        return frame_sp;

    // Special case the first frame (idx == 0) so that we don't need to
    // know how many stack frames there are to get it. If we need any other
    // frames, then we do need to know if "idx" is a valid index.
    if (idx == 0)
    {
        // If this is the first frame, we want to share the thread register
        // context with the stack frame at index zero.
        m_thread.GetRegisterContext();
        assert (m_thread.m_reg_context_sp.get());
        frame_sp.reset (new StackFrame (0, 
                                        0, 
                                        m_thread, 
                                        m_thread.m_reg_context_sp, 
                                        m_thread.m_reg_context_sp->GetSP(), 
                                        m_thread.m_reg_context_sp->GetPC(), 
                                        NULL));
        
        SetFrameAtIndex(idx, frame_sp);
    }
    else if (idx < GetNumFrames())
    {
        if (m_show_inlined_frames)
        {
            // When inline frames are enabled we cache up all frames in GetNumFrames()
            frame_sp = m_frames[idx];
        }
        else
        {
            Unwind *unwinder = m_thread.GetUnwinder ();
            if (unwinder)
            {
                addr_t pc, cfa;
                if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
                {
                    frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, pc, NULL));
                    
                    Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function;
                    if (function)
                    {
                        // When we aren't showing inline functions we always use
                        // the top most function block as the scope.
                        frame_sp->SetSymbolContextScope (&function->GetBlock(false));
                    }
                    else 
                    {
                        // Set the symbol scope from the symbol regardless if it is NULL or valid.
                        frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
                    }
                    SetFrameAtIndex(idx, frame_sp);
                }
            }
        }
    }
    return frame_sp;
}

StackFrameSP
StackFrameList::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx)
{
    // First try assuming the unwind index is the same as the frame index. The 
    // unwind index is always greater than or equal to the frame index, so it
    // is a good place to start. If we have inlined frames we might have 5
    // concrete frames (frame unwind indexes go from 0-4), but we might have 15
    // frames after we make all the inlined frames. Most of the time the unwind
    // frame index (or the concrete frame index) is the same as the frame index.
    uint32_t frame_idx = unwind_idx;
    StackFrameSP frame_sp (GetFrameAtIndex (frame_idx));
    while (frame_sp)
    {
        if (frame_sp->GetFrameIndex() == unwind_idx)
            break;
        frame_sp = GetFrameAtIndex (++frame_idx);
    }
    return frame_sp;
}


bool
StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
{
    if (idx >= m_frames.size())
        m_frames.resize(idx + 1);
    // Make sure allocation succeeded by checking bounds again
    if (idx < m_frames.size())
    {
        m_frames[idx] = frame_sp;
        return true;
    }
    return false;   // resize failed, out of memory?
}

uint32_t
StackFrameList::GetSelectedFrameIndex () const
{
    Mutex::Locker locker (m_mutex);
    return m_selected_frame_idx;
}


uint32_t
StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame)
{
    Mutex::Locker locker (m_mutex);
    const_iterator pos;
    const_iterator begin = m_frames.begin();
    const_iterator end = m_frames.end();
    for (pos = begin; pos != end; ++pos)
    {
        if (pos->get() == frame)
        {
            m_selected_frame_idx = std::distance (begin, pos);
            return m_selected_frame_idx;
        }
    }
    m_selected_frame_idx = 0;
    return m_selected_frame_idx;
}

// Mark a stack frame as the current frame using the frame index
void
StackFrameList::SetSelectedFrameByIndex (uint32_t idx)
{
    Mutex::Locker locker (m_mutex);
    m_selected_frame_idx = idx;
}

// The thread has been run, reset the number stack frames to zero so we can
// determine how many frames we have lazily.
void
StackFrameList::Clear ()
{
    Mutex::Locker locker (m_mutex);
    m_frames.clear();
}

void
StackFrameList::InvalidateFrames (uint32_t start_idx)
{
    Mutex::Locker locker (m_mutex);
    if (m_show_inlined_frames)
    {
        Clear();
    }
    else
    {
        const size_t num_frames = m_frames.size();
        while (start_idx < num_frames)
        {
            m_frames[start_idx].reset();
            ++start_idx;
        }
    }
}

void
StackFrameList::Merge (std::auto_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
{
    Mutex::Locker curr_locker (curr_ap.get() ? curr_ap->m_mutex.GetMutex() : NULL);
    Mutex::Locker prev_locker (prev_sp.get() ? prev_sp->m_mutex.GetMutex() : NULL);

#if defined (DEBUG_STACK_FRAMES)
    StreamFile s(stdout);
    s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n");
    if (prev_sp.get())
        prev_sp->Dump (&s);
    else
        s.PutCString ("NULL");
    s.PutCString("\nCurr:\n");
    if (curr_ap.get())
        curr_ap->Dump (&s);
    else
        s.PutCString ("NULL");
    s.EOL();
#endif

    if (curr_ap.get() == NULL || curr_ap->GetNumFrames (false) == 0)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.PutCString("No current frames, leave previous frames alone...\n");
#endif
        curr_ap.release();
        return;
    }

    if (prev_sp.get() == NULL || prev_sp->GetNumFrames (false) == 0)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.PutCString("No previous frames, so use current frames...\n");
#endif
        // We either don't have any previous frames, or since we have more than
        // one current frames it means we have all the frames and can safely
        // replace our previous frames.
        prev_sp.reset (curr_ap.release());
        return;
    }

    const uint32_t num_curr_frames = curr_ap->GetNumFrames (false);
    
    if (num_curr_frames > 1)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.PutCString("We have more than one current frame, so use current frames...\n");
#endif
        // We have more than one current frames it means we have all the frames 
        // and can safely replace our previous frames.
        prev_sp.reset (curr_ap.release());

#if defined (DEBUG_STACK_FRAMES)
        s.PutCString("\nMerged:\n");
        prev_sp->Dump (&s);
#endif
        return;
    }

    StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex (0));
    StackFrameSP curr_frame_zero_sp(curr_ap->GetFrameAtIndex (0));
    StackID curr_stack_id (curr_frame_zero_sp->GetStackID());
    StackID prev_stack_id (prev_frame_zero_sp->GetStackID());

    //const uint32_t num_prev_frames = prev_sp->GetNumFrames (false);

#if defined (DEBUG_STACK_FRAMES)
    s.Printf("\n%u previous frames with one current frame\n", num_prev_frames);
#endif

    // We have only a single current frame
    // Our previous stack frames only had a single frame as well...
    if (curr_stack_id == prev_stack_id)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.Printf("\nPrevious frame #0 is same as current frame #0, merge the cached data\n");
#endif

        curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame (*prev_frame_zero_sp);
//        prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame (*curr_frame_zero_sp);
//        prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp);
    }
    else if (curr_stack_id < prev_stack_id)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.Printf("\nCurrent frame #0 has a stack ID that is less than the previous frame #0, insert current frame zero in front of previous\n");
#endif
        prev_sp->m_frames.insert (prev_sp->m_frames.begin(), curr_frame_zero_sp);
    }
    
    curr_ap.release();

#if defined (DEBUG_STACK_FRAMES)
    s.PutCString("\nMerged:\n");
    prev_sp->Dump (&s);
#endif


}

lldb::StackFrameSP
StackFrameList::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)
{
    const_iterator pos;
    const_iterator begin = m_frames.begin();
    const_iterator end = m_frames.end();
    lldb::StackFrameSP ret_sp;
    
    for (pos = begin; pos != end; ++pos)
    {
        if (pos->get() == stack_frame_ptr)
        {
            ret_sp = (*pos);
            break;
        }
    }
    return ret_sp;
}

