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


// C Includes
// C++ Includes
// Other libraries and framework includes
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Module.h"

// Project includes
#include "lldb/Expression/ASTStructExtractor.h"
#include "lldb/Expression/ClangExpressionParser.h"
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/State.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Core/Log.h"

using namespace lldb_private;

//----------------------------------------------------------------------
// ClangFunction constructor
//----------------------------------------------------------------------
ClangFunction::ClangFunction 
(
    ExecutionContextScope *exe_scope,
    ClangASTContext *ast_context, 
    void *return_qualtype, 
    const Address& functionAddress, 
    const ValueList &arg_value_list
) :
    m_arch (),
    m_function_ptr (NULL),
    m_function_addr (functionAddress),
    m_function_return_qual_type(return_qualtype),
    m_clang_ast_context (ast_context),
    m_wrapper_function_name ("__lldb_caller_function"),
    m_wrapper_struct_name ("__lldb_caller_struct"),
    m_wrapper_args_addrs (),
    m_arg_values (arg_value_list),
    m_compiled (false),
    m_JITted (false)
{
    if (exe_scope)
    {
        Target *target = exe_scope->CalculateTarget();
        if (target)
            m_arch = target->GetArchitecture();
    }
}

ClangFunction::ClangFunction
(
    ExecutionContextScope *exe_scope,
    Function &function, 
    ClangASTContext *ast_context, 
    const ValueList &arg_value_list
) :
    m_arch (),
    m_function_ptr (&function),
    m_function_addr (),
    m_function_return_qual_type (),
    m_clang_ast_context (ast_context),
    m_wrapper_function_name ("__lldb_function_caller"),
    m_wrapper_struct_name ("__lldb_caller_struct"),
    m_wrapper_args_addrs (),
    m_arg_values (arg_value_list),
    m_compiled (false),
    m_JITted (false)
{
    if (exe_scope)
    {
        Target *target = exe_scope->CalculateTarget();
        if (target)
            m_arch = target->GetArchitecture();
    }

    m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
    m_function_return_qual_type = m_function_ptr->GetReturnClangType();
}

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

unsigned
ClangFunction::CompileFunction (Stream &errors)
{
    if (m_compiled)
        return 0;
    
    // FIXME: How does clang tell us there's no return value?  We need to handle that case.
    unsigned num_errors = 0;
    
    std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type);
    
    // Cons up the function we're going to wrap our call in, then compile it...
    // We declare the function "extern "C"" because the compiler might be in C++
    // mode which would mangle the name and then we couldn't find it again...
    m_wrapper_function_text.clear();
    m_wrapper_function_text.append ("extern \"C\" void ");
    m_wrapper_function_text.append (m_wrapper_function_name);
    m_wrapper_function_text.append (" (void *input)\n{\n    struct ");
    m_wrapper_function_text.append (m_wrapper_struct_name);
    m_wrapper_function_text.append (" \n  {\n");
    m_wrapper_function_text.append ("    ");
    m_wrapper_function_text.append (return_type_str);
    m_wrapper_function_text.append (" (*fn_ptr) (");

    // Get the number of arguments.  If we have a function type and it is prototyped,
    // trust that, otherwise use the values we were given.

    // FIXME: This will need to be extended to handle Variadic functions.  We'll need
    // to pull the defined arguments out of the function, then add the types from the
    // arguments list for the variable arguments.

    uint32_t num_args = UINT32_MAX;
    bool trust_function = false;
    // GetArgumentCount returns -1 for an unprototyped function.
    if (m_function_ptr)
    {
        int num_func_args = m_function_ptr->GetArgumentCount();
        if (num_func_args >= 0)
            trust_function = true;
        else
            num_args = num_func_args;
    }

    if (num_args == UINT32_MAX)
        num_args = m_arg_values.GetSize();

    std::string args_buffer;  // This one stores the definition of all the args in "struct caller".
    std::string args_list_buffer;  // This one stores the argument list called from the structure.
    for (size_t i = 0; i < num_args; i++)
    {
        std::string type_name;

        if (trust_function)
        {
            lldb::clang_type_t arg_clang_type = m_function_ptr->GetArgumentTypeAtIndex(i);
            type_name = ClangASTContext::GetTypeName(arg_clang_type);
        }
        else
        {
            Value *arg_value = m_arg_values.GetValueAtIndex(i);
            void *clang_qual_type = arg_value->GetClangType ();
            if (clang_qual_type != NULL)
            {
                type_name = ClangASTContext::GetTypeName(clang_qual_type);
            }
            else
            {   
                errors.Printf("Could not determine type of input value %d.", i);
                return 1;
            }
        }

        m_wrapper_function_text.append (type_name);
        if (i < num_args - 1)
            m_wrapper_function_text.append (", ");

        char arg_buf[32];
        args_buffer.append ("    ");
        args_buffer.append (type_name);
        snprintf(arg_buf, 31, "arg_%zd", i);
        args_buffer.push_back (' ');
        args_buffer.append (arg_buf);
        args_buffer.append (";\n");

        args_list_buffer.append ("__lldb_fn_data->");
        args_list_buffer.append (arg_buf);
        if (i < num_args - 1)
            args_list_buffer.append (", ");

    }
    m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.

    m_wrapper_function_text.append (args_buffer);

    m_wrapper_function_text.append ("    ");
    m_wrapper_function_text.append (return_type_str);
    m_wrapper_function_text.append (" return_value;");
    m_wrapper_function_text.append ("\n  };\n  struct ");
    m_wrapper_function_text.append (m_wrapper_struct_name);
    m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
    m_wrapper_function_text.append (m_wrapper_struct_name);
    m_wrapper_function_text.append (" *) input;\n");

    m_wrapper_function_text.append ("  __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
    m_wrapper_function_text.append (args_list_buffer);
    m_wrapper_function_text.append (");\n}\n");

    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    if (log)
        log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
        
    // Okay, now compile this expression
    
    m_parser.reset(new ClangExpressionParser(NULL, *this));
    
    num_errors = m_parser->Parse (errors);
    
    m_compiled = (num_errors == 0);
    
    if (!m_compiled)
        return num_errors;

    return num_errors;
}

bool
ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
{
    Process *process = exe_ctx.process;

    if (!process)
        return false;
    
    if (!m_compiled)
        return false;

    if (m_JITted)
        return true;
    
    Error jit_error (m_parser->MakeJIT (m_jit_alloc, m_jit_start_addr, m_jit_end_addr, exe_ctx));
    
    if (!jit_error.Success())
        return false;
    if (exe_ctx.process && m_jit_alloc != LLDB_INVALID_ADDRESS)
        m_jit_process_sp = exe_ctx.process->GetSP();

    return true;
}

bool
ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
{
    return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors);    
}

// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.

bool
ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, 
                                       lldb::addr_t &args_addr_ref, 
                                       Address function_address, 
                                       ValueList &arg_values, 
                                       Stream &errors)
{
    // All the information to reconstruct the struct is provided by the
    // StructExtractor.
    if (!m_struct_valid)
    {
        errors.Printf("Argument information was not correctly parsed, so the function cannot be called.");
        return false;
    }
        
    Error error;
    using namespace clang;
    lldb::ExecutionResults return_value = lldb::eExecutionSetupError;

    Process *process = exe_ctx.process;

    if (process == NULL)
        return return_value;
                
    if (args_addr_ref == LLDB_INVALID_ADDRESS)
    {
        args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
        if (args_addr_ref == LLDB_INVALID_ADDRESS)
            return false;
        m_wrapper_args_addrs.push_back (args_addr_ref);
    } 
    else 
    {
        // Make sure this is an address that we've already handed out.
        if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
        {
            return false;
        }
    }

    // FIXME: This is fake, and just assumes that it matches that architecture.
    // Make a data extractor and put the address into the right byte order & size.

    uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.target);
    int first_offset = m_member_offsets[0];
    process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error);

    // FIXME: We will need to extend this for Variadic functions.

    Error value_error;
    
    size_t num_args = arg_values.GetSize();
    if (num_args != m_arg_values.GetSize())
    {
        errors.Printf ("Wrong number of arguments - was: %d should be: %d", num_args, m_arg_values.GetSize());
        return false;
    }
    
    for (size_t i = 0; i < num_args; i++)
    {
        // FIXME: We should sanity check sizes.

        int offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
        Value *arg_value = arg_values.GetValueAtIndex(i);
        
        // FIXME: For now just do scalars:
        
        // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
        
        if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
            arg_value->GetContextType() == Value::eContextTypeClangType &&
            ClangASTContext::IsPointerType(arg_value->GetClangType()))
            continue;
        
        const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext());

        int byte_size = arg_scalar.GetByteSize();
        std::vector<uint8_t> buffer;
        buffer.resize(byte_size);
        DataExtractor value_data;
        arg_scalar.GetData (value_data);
        value_data.ExtractBytes(0, byte_size, process->GetByteOrder(), &buffer.front());
        process->WriteMemory(args_addr_ref + offset, &buffer.front(), byte_size, error);
    }

    return true;
}

bool
ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
{
    using namespace clang;
    
    if (CompileFunction(errors) != 0)
        return false;
    if (!WriteFunctionWrapper(exe_ctx, errors))
        return false;
    if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
        return false;

    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    if (log)
        log->Printf ("Call Address: 0x%llx Struct Address: 0x%llx.\n", m_jit_start_addr, args_addr_ref);
        
    return true;
}

ThreadPlan *
ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, 
                                            lldb::addr_t func_addr, 
                                            lldb::addr_t &args_addr, 
                                            Stream &errors, 
                                            bool stop_others, 
                                            bool discard_on_error, 
                                            lldb::addr_t *this_arg,
                                            lldb::addr_t *cmd_arg)
{
    // FIXME: Use the errors Stream for better error reporting.

    Process *process = exe_ctx.process;

    if (process == NULL)
    {
        errors.Printf("Can't call a function without a process.");
        return NULL;
    }

    // Okay, now run the function:

    Address wrapper_address (NULL, func_addr);
    ThreadPlan *new_plan = new ThreadPlanCallFunction (*exe_ctx.thread, 
                                                       wrapper_address,
                                                       args_addr,
                                                       stop_others, 
                                                       discard_on_error,
                                                       this_arg,
                                                       cmd_arg);
    return new_plan;
}

bool
ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
{
    // Read the return value - it is the last field in the struct:
    // FIXME: How does clang tell us there's no return value?  We need to handle that case.
    
    std::vector<uint8_t> data_buffer;
    data_buffer.resize(m_return_size);
    Process *process = exe_ctx.process;
    Error error;
    size_t bytes_read = process->ReadMemory(args_addr + m_return_offset, &data_buffer.front(), m_return_size, error);

    if (bytes_read == 0)
    {
        return false;
    }

    if (bytes_read < m_return_size)
        return false;

    DataExtractor data(&data_buffer.front(), m_return_size, process->GetByteOrder(), process->GetAddressByteSize());
    // FIXME: Assuming an integer scalar for now:
    
    uint32_t offset = 0;
    uint64_t return_integer = data.GetMaxU64(&offset, m_return_size);
    
    ret_value.SetContext (Value::eContextTypeClangType, m_function_return_qual_type);
    ret_value.SetValueType(Value::eValueTypeScalar);
    ret_value.GetScalar() = return_integer;
    return true;
}

void
ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
{
    std::list<lldb::addr_t>::iterator pos;
    pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
    if (pos != m_wrapper_args_addrs.end())
        m_wrapper_args_addrs.erase(pos);
    
    exe_ctx.process->DeallocateMemory(args_addr);
}

lldb::ExecutionResults
ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results)
{
    return ExecuteFunction (exe_ctx, errors, 1000, true, results);
}

lldb::ExecutionResults
ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
{
    const bool try_all_threads = false;
    const bool discard_on_error = true;
    return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, try_all_threads, discard_on_error, results);
}

lldb::ExecutionResults
ClangFunction::ExecuteFunction(
        ExecutionContext &exe_ctx, 
        Stream &errors, 
        uint32_t single_thread_timeout_usec, 
        bool try_all_threads, 
        Value &results)
{
    const bool stop_others = true;
    const bool discard_on_error = true;
    return ExecuteFunction (exe_ctx, NULL, errors, stop_others, single_thread_timeout_usec, 
                            try_all_threads, discard_on_error, results);
}

// This is the static function
lldb::ExecutionResults 
ClangFunction::ExecuteFunction (
        ExecutionContext &exe_ctx, 
        lldb::addr_t function_address, 
        lldb::addr_t &void_arg,
        bool stop_others,
        bool try_all_threads,
        bool discard_on_error,
        uint32_t single_thread_timeout_usec,
        Stream &errors,
        lldb::addr_t *this_arg)
{
    lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exe_ctx, function_address, void_arg, 
                                                                               errors, stop_others, discard_on_error, 
                                                                               this_arg));
    if (call_plan_sp == NULL)
        return lldb::eExecutionSetupError;
    
    call_plan_sp->SetPrivate(true);
    
    return exe_ctx.process->RunThreadPlan (exe_ctx, call_plan_sp, stop_others, try_all_threads, discard_on_error,
                                            single_thread_timeout_usec, errors);
}  

lldb::ExecutionResults
ClangFunction::ExecuteFunction(
        ExecutionContext &exe_ctx, 
        lldb::addr_t *args_addr_ptr, 
        Stream &errors, 
        bool stop_others, 
        uint32_t single_thread_timeout_usec, 
        bool try_all_threads,
        bool discard_on_error, 
        Value &results)
{
    using namespace clang;
    lldb::ExecutionResults return_value = lldb::eExecutionSetupError;
    
    lldb::addr_t args_addr;
    
    if (args_addr_ptr != NULL)
        args_addr = *args_addr_ptr;
    else
        args_addr = LLDB_INVALID_ADDRESS;
        
    if (CompileFunction(errors) != 0)
        return lldb::eExecutionSetupError;
    
    if (args_addr == LLDB_INVALID_ADDRESS)
    {
        if (!InsertFunction(exe_ctx, args_addr, errors))
            return lldb::eExecutionSetupError;
    }
    
    return_value = ClangFunction::ExecuteFunction (exe_ctx, 
                                                   m_jit_start_addr, 
                                                   args_addr, 
                                                   stop_others, 
                                                   try_all_threads, 
                                                   discard_on_error, 
                                                   single_thread_timeout_usec, 
                                                   errors);

    if (args_addr_ptr != NULL)
        *args_addr_ptr = args_addr;
    
    if (return_value != lldb::eExecutionCompleted)
        return return_value;

    FetchFunctionResults(exe_ctx, args_addr, results);
    
    if (args_addr_ptr == NULL)
        DeallocateFunctionResults(exe_ctx, args_addr);
        
    return lldb::eExecutionCompleted;
}

clang::ASTConsumer *
ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough)
{
    return new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this);
}
