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

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

Value::Value() :
    m_value(),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(const Scalar& scalar) :
    m_value(scalar),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(int v) :
    m_value(v),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(unsigned int v) :
    m_value(v),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(long v) :
    m_value(v),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(unsigned long v) :
    m_value(v),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(long long v) :
    m_value(v),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(unsigned long long v) :
    m_value(v),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(float v) :
    m_value(v),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(double v) :
    m_value(v),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(long double v) :
    m_value(v),
    m_value_type(eValueTypeScalar),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
}

Value::Value(const uint8_t *bytes, int len) :
    m_value(),
    m_value_type(eValueTypeHostAddress),
    m_context(NULL),
    m_context_type(eContextTypeInvalid)
{
    m_data_buffer.CopyData(bytes, len);
    m_value = (uintptr_t)m_data_buffer.GetBytes();
}

Value::Value(const Value &v) :
    m_value(v.m_value),
    m_value_type(v.m_value_type),
    m_context(v.m_context),
    m_context_type(v.m_context_type)
{
    if ((uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)v.m_data_buffer.GetBytes())
    {
        m_data_buffer.CopyData(v.m_data_buffer.GetBytes(),
                               v.m_data_buffer.GetByteSize());
    
        m_value = (uintptr_t)m_data_buffer.GetBytes();
    }
}

Value &
Value::operator=(const Value &rhs)
{
    if (this != &rhs)
    {
        m_value = rhs.m_value;
        m_value_type = rhs.m_value_type;
        m_context = rhs.m_context;
        m_context_type = rhs.m_context_type;
        if ((uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)rhs.m_data_buffer.GetBytes())
        {
            m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(),
                                   rhs.m_data_buffer.GetByteSize());
        
            m_value = (uintptr_t)m_data_buffer.GetBytes();
        }
    }
    return *this;
}

Value *
Value::CreateProxy()
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->CreateProxy ();
    
    Value *ret = new Value;
    ret->SetContext(eContextTypeValue, this);
    return ret;
}

Value *
Value::GetProxyTarget()
{
    if (m_context_type == eContextTypeValue)
        return (Value*)m_context;
    else
        return NULL;
}

void
Value::Dump (Stream* strm)
{
    if (m_context_type == eContextTypeValue)
    {
        ((Value*)m_context)->Dump (strm);
        return;
    }
    
    m_value.GetValue (strm, true);
    strm->Printf(", value_type = %s, context = %p, context_type = %s",
                Value::GetValueTypeAsCString(m_value_type),
                m_context,
                Value::GetContextTypeAsCString(m_context_type));
}

Value::ValueType
Value::GetValueType() const
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetValueType ();
    
    return m_value_type;
}

lldb::AddressType
Value::GetValueAddressType () const
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetValueAddressType ();
    
    switch (m_value_type)
    {
    default:
    case eValueTypeScalar:
        break;
    case eValueTypeLoadAddress: return eAddressTypeLoad;
    case eValueTypeFileAddress: return eAddressTypeFile;
    case eValueTypeHostAddress: return eAddressTypeHost;
    }
    return eAddressTypeInvalid;
}


Value::ContextType
Value::GetContextType() const
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetContextType ();
    
    return m_context_type;
}

void
Value::SetValueType (Value::ValueType value_type)
{
    if (m_context_type == eContextTypeValue)
    {
        ((Value*)m_context)->SetValueType(value_type);
        return;
    }
        
    m_value_type = value_type;
}

void
Value::ClearContext ()
{
    if (m_context_type == eContextTypeValue)
    {
        ((Value*)m_context)->ClearContext();
        return;
    }
    
    m_context = NULL;
    m_context_type = eContextTypeInvalid;
}

void
Value::SetContext (Value::ContextType context_type, void *p)
{
    if (m_context_type == eContextTypeValue)
    {
        ((Value*)m_context)->SetContext(context_type, p);
        return;
    }
    
    m_context_type = context_type;
    m_context = p;
}

RegisterInfo *
Value::GetRegisterInfo()
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetRegisterInfo();
        
    if (m_context_type == eContextTypeRegisterInfo)
        return static_cast<RegisterInfo *> (m_context);
    return NULL;
}

Type *
Value::GetType()
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetType();
    
    if (m_context_type == eContextTypeLLDBType)
        return static_cast<Type *> (m_context);
    return NULL;
}

Scalar &
Value::GetScalar()
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetScalar();
    
    return m_value;
}

void
Value::ResizeData(int len)
{
    if (m_context_type == eContextTypeValue)
    {
        ((Value*)m_context)->ResizeData(len);
        return;
    }
    
    m_value_type = eValueTypeHostAddress;
    m_data_buffer.SetByteSize(len);
    m_value = (uintptr_t)m_data_buffer.GetBytes();
}

bool
Value::ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->ValueOf(exe_ctx, ast_context);
    
    switch (m_context_type)
    {
    default:
    case eContextTypeInvalid:
    case eContextTypeClangType:          // clang::Type *
    case eContextTypeRegisterInfo:     // RegisterInfo *
    case eContextTypeLLDBType:             // Type *
        break;

    case eContextTypeVariable:         // Variable *
        ResolveValue(exe_ctx, ast_context);
        return true;
    }
    return false;
}

size_t
Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr)
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetValueByteSize(ast_context, error_ptr);
    
    size_t byte_size = 0;

    switch (m_context_type)
    {
    default:
    case eContextTypeInvalid:
        // If we have no context, there is no way to know how much memory to read
        if (error_ptr)
            error_ptr->SetErrorString ("Invalid context type, there is no way to know how much memory to read.");
        break;

    case eContextTypeClangType:
        if (ast_context == NULL)
        {
            if (error_ptr)
                error_ptr->SetErrorString ("Can't determine size of opaque clang type with NULL ASTContext *.");
        }
        else
        {
            uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (ast_context, m_context);
            byte_size = (bit_width + 7 ) / 8;
        }
        break;

    case eContextTypeRegisterInfo:     // RegisterInfo *
        if (GetRegisterInfo())
            byte_size = GetRegisterInfo()->byte_size;
        else if (error_ptr)
                error_ptr->SetErrorString ("Can't determine byte size with NULL RegisterInfo *.");

        break;

    case eContextTypeLLDBType:             // Type *
        if (GetType())
            byte_size = GetType()->GetByteSize();
        else if (error_ptr)
            error_ptr->SetErrorString ("Can't determine byte size with NULL Type *.");
        break;

    case eContextTypeVariable:         // Variable *
        if (GetVariable())
            byte_size = GetVariable()->GetType()->GetByteSize();
        else if (error_ptr)
            error_ptr->SetErrorString ("Can't determine byte size with NULL Variable *.");
        break;
    }

    if (error_ptr)
    {
        if (byte_size == 0)
        {
            if (error_ptr->Success())
                error_ptr->SetErrorString("Unable to determine byte size.");
        }
        else
        {
            error_ptr->Clear();
        }
    }
    return byte_size;
}

clang_type_t
Value::GetClangType ()
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetClangType();
    
    switch (m_context_type)
    {
    default:
    case eContextTypeInvalid:
        break;

    case eContextTypeClangType:
        return m_context;

    case eContextTypeRegisterInfo:
        break;    // TODO: Eventually convert into a clang type?

    case eContextTypeLLDBType:
        if (GetType())
            return GetType()->GetClangForwardType();
        break;

    case eContextTypeVariable:
        if (GetVariable())
            return GetVariable()->GetType()->GetClangForwardType();
        break;
    }

    return NULL;
}

lldb::Format
Value::GetValueDefaultFormat ()
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetValueDefaultFormat();
    
    switch (m_context_type)
    {
    default:
    case eContextTypeInvalid:
        break;

    case eContextTypeClangType:
        return ClangASTType::GetFormat (m_context);

    case eContextTypeRegisterInfo:
        if (GetRegisterInfo())
            return GetRegisterInfo()->format;
        break;

    case eContextTypeLLDBType:
        if (GetType())
            return GetType()->GetFormat();
        break;

    case eContextTypeVariable:
        if (GetVariable())
            return GetVariable()->GetType()->GetFormat();
        break;

    }

    // Return a good default in case we can't figure anything out
    return eFormatHex;
}

bool
Value::GetData (DataExtractor &data)
{
    switch (m_value_type)
    {
    default:
        break;

    case eValueTypeScalar:
        if (m_value.GetData (data))
            return true;
        break;

    case eValueTypeLoadAddress:
    case eValueTypeFileAddress:
    case eValueTypeHostAddress:
        if (m_data_buffer.GetByteSize())
        {
            data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(), data.GetByteOrder());
            return true;
        }
        break;
    }

    return false;

}

Error
Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context, DataExtractor &data, uint32_t data_offset)
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetValueAsData(exe_ctx, ast_context, data, data_offset);
    
    data.Clear();

    Error error;
    lldb::addr_t address = LLDB_INVALID_ADDRESS;
    lldb::AddressType address_type = eAddressTypeFile;
    switch (m_value_type)
    {
    default:
        error.SetErrorStringWithFormat("invalid value type %i", m_value_type);
        break;

    case eValueTypeScalar:
        data.SetByteOrder (lldb::endian::InlHostByteOrder());
        if (m_context_type == eContextTypeClangType && ast_context)
        {
            uint32_t ptr_bit_width = ClangASTType::GetClangTypeBitWidth (ast_context, 
                                                                     ClangASTContext::GetVoidPtrType(ast_context, false));
            uint32_t ptr_byte_size = (ptr_bit_width + 7) / 8;
            data.SetAddressByteSize (ptr_byte_size);
        }
        else
            data.SetAddressByteSize(sizeof(void *));
        if (m_value.GetData (data))
            return error;   // Success;
        error.SetErrorStringWithFormat("extracting data from value failed");
        break;

    case eValueTypeLoadAddress:
        if (exe_ctx == NULL)
        {
            error.SetErrorString ("can't read memory (no execution context)");
        }
        else if (exe_ctx->process == NULL)
        {
            error.SetErrorString ("can't read memory (invalid process)");
        }
        else
        {
            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
            address_type = eAddressTypeLoad;
            data.SetByteOrder(exe_ctx->process->GetTarget().GetArchitecture().GetByteOrder());
            data.SetAddressByteSize(exe_ctx->process->GetTarget().GetArchitecture().GetAddressByteSize());
        }
        break;

    case eValueTypeFileAddress:
        {
            // The only thing we can currently lock down to a module so that
            // we can resolve a file address, is a variable.
            Variable *variable = GetVariable();

            if (GetVariable())
            {
                lldb::addr_t file_addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
                if (file_addr != LLDB_INVALID_ADDRESS)
                {
                    SymbolContext var_sc;
                    variable->CalculateSymbolContext(&var_sc);
                    if (var_sc.module_sp)
                    {
                        ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
                        if (objfile)
                        {
                            Address so_addr(file_addr, objfile->GetSectionList());
                            address = so_addr.GetLoadAddress (exe_ctx->target);
                            if (address != LLDB_INVALID_ADDRESS)
                            {
                                address_type = eAddressTypeLoad;
                                data.SetByteOrder(exe_ctx->target->GetArchitecture().GetByteOrder());
                                data.SetAddressByteSize(exe_ctx->target->GetArchitecture().GetAddressByteSize());
                            }
                            else
                            {
                                data.SetByteOrder(objfile->GetByteOrder());
                                data.SetAddressByteSize(objfile->GetAddressByteSize());
                            }
                        }
                        if (address_type == eAddressTypeFile)
                            error.SetErrorStringWithFormat ("%s is not loaded.\n", var_sc.module_sp->GetFileSpec().GetFilename().AsCString());
                    }
                    else
                    {
                        error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'", file_addr, variable->GetName().AsCString(""));
                    }
                }
                else
                {
                    error.SetErrorString ("Invalid file address.");
                }
            }
            else
            {
                // Can't convert a file address to anything valid without more
                // context (which Module it came from)
                error.SetErrorString ("can't read memory from file address without more context");
            }
        }
        break;

    case eValueTypeHostAddress:
        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
        data.SetByteOrder(lldb::endian::InlHostByteOrder());
        data.SetAddressByteSize(sizeof(void *));
        address_type = eAddressTypeHost;
        break;
    }

    // Bail if we encountered any errors
    if (error.Fail())
        return error;

    if (address == LLDB_INVALID_ADDRESS)
    {
        error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
        return error;
    }

    // If we got here, we need to read the value from memory
    uint32_t byte_size = GetValueByteSize (ast_context, &error);

    // Bail if we encountered any errors getting the byte size
    if (error.Fail())
        return error;

    // Make sure we have enough room within "data", and if we don't make
    // something large enough that does
    if (!data.ValidOffsetForDataOfSize (data_offset, byte_size))
    {
        DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0'));
        data.SetData(data_sp);
    }

    uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size));
    if (dst != NULL)
    {
        if (address_type == eAddressTypeHost)
        {
            // The address is an address in this process, so just copy it
            memcpy (dst, (uint8_t*)NULL + address, byte_size);
        }
        else if (address_type == eAddressTypeLoad)
        {
            if (exe_ctx->process->ReadMemory(address, dst, byte_size, error) != byte_size)
            {
                if (error.Success())
                    error.SetErrorStringWithFormat("read %u bytes of memory from 0x%llx failed", (uint64_t)address, byte_size);
                else
                    error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
            }
        }
        else
        {
            error.SetErrorStringWithFormat ("unsupported lldb::AddressType value (%i)", address_type);
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("out of memory");
    }

    return error;
}

Scalar &
Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
{    
    Scalar scalar;
    if (m_context_type == eContextTypeValue)
    {
        // Resolve the proxy
        
        Value * rhs = (Value*)m_context;
        
        m_value = rhs->m_value;
        m_value_type = rhs->m_value_type;
        m_context = rhs->m_context;
        m_context_type = rhs->m_context_type;
        
        if ((uintptr_t)rhs->m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)rhs->m_data_buffer.GetBytes())
        {
            m_data_buffer.CopyData(rhs->m_data_buffer.GetBytes(),
                                   rhs->m_data_buffer.GetByteSize());
            
            m_value = (uintptr_t)m_data_buffer.GetBytes();
        }
    }
    
    if (m_context_type == eContextTypeClangType)
    {
        void *opaque_clang_qual_type = GetClangType();
        switch (m_value_type)
        {
        case eValueTypeScalar:               // raw scalar value
            break;

        default:
        case eValueTypeFileAddress:
            m_value.Clear();
            break;

        case eValueTypeLoadAddress:          // load address value
        case eValueTypeHostAddress:          // host address value (for memory in the process that is using liblldb)
            {
                lldb::AddressType address_type = m_value_type == eValueTypeLoadAddress ? eAddressTypeLoad : eAddressTypeHost;
                lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
                DataExtractor data;
                if (ClangASTType::ReadFromMemory (ast_context, opaque_clang_qual_type, exe_ctx, addr, address_type, data))
                {
                    if (ClangASTType::GetValueAsScalar (ast_context, opaque_clang_qual_type, data, 0, data.GetByteSize(), scalar))
                    {
                        m_value = scalar;
                        m_value_type = eValueTypeScalar;
                    }
                    else
                    {
                        if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
                        {
                            m_value.Clear();
                            m_value_type = eValueTypeScalar;
                        }
                    }
                }
                else
                {
                    if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
                    {
                        m_value.Clear();
                        m_value_type = eValueTypeScalar;
                    }
                }
            }
            break;
        }


    }
    return m_value;
}

Variable *
Value::GetVariable()
{
    if (m_context_type == eContextTypeValue)
        return ((Value*)m_context)->GetVariable();
    
    if (m_context_type == eContextTypeVariable)
        return static_cast<Variable *> (m_context);
    return NULL;
}



const char *
Value::GetValueTypeAsCString (ValueType value_type)
{    
    switch (value_type)
    {
    case eValueTypeScalar:      return "scalar";
    case eValueTypeFileAddress: return "file address";
    case eValueTypeLoadAddress: return "load address";
    case eValueTypeHostAddress: return "host address";
    };
    return "???";
}

const char *
Value::GetContextTypeAsCString (ContextType context_type)
{
    switch (context_type)
    {
    case eContextTypeInvalid:               return "invalid";
    case eContextTypeClangType:   return "clang::Type *";
    case eContextTypeRegisterInfo:        return "RegisterInfo *";
    case eContextTypeLLDBType:                return "Type *";
    case eContextTypeVariable:            return "Variable *";
    case eContextTypeValue:                 return "Value"; // TODO: Sean, more description here?
    };
    return "???";
}

ValueList::ValueList (const ValueList &rhs)
{
    m_values = rhs.m_values;
}

const ValueList &
ValueList::operator= (const ValueList &rhs)
{
    m_values = rhs.m_values;
    return *this;
}

void
ValueList::PushValue (const Value &value)
{
    m_values.push_back (value);
}

size_t
ValueList::GetSize()
{
    return m_values.size();
}

Value *
ValueList::GetValueAtIndex (size_t idx)
{
    if (idx < GetSize())
    {
        return &(m_values[idx]);
    }
    else
        return NULL;
}

void
ValueList::Clear ()
{
    m_values.clear();
}
