//===-- 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_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)
{
    Process *process = exe_scope.CalculateProcess();
    // Can't make a ClangFunction without a process.
    assert (process != NULL);
        
    m_jit_process_sp = process->GetSP();
}

ClangFunction::ClangFunction
(
    ExecutionContextScope &exe_scope,
    Function &function, 
    ClangASTContext *ast_context, 
    const ValueList &arg_value_list
) :
    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)
{
    Process *process = exe_scope.CalculateProcess();
    // Can't make a ClangFunction without a process.
    assert (process != NULL);
        
    m_jit_process_sp = process->GetSP();

    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(m_jit_process_sp.get(), *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 (process != m_jit_process_sp.get())
        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;
    ExecutionResults return_value = eExecutionSetupError;

    Process *process = exe_ctx.process;

    if (process == NULL)
        return return_value;

    if (process != m_jit_process_sp.get())
        return false;
                
    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;
    
    if (process == NULL)
        return false;
    if (process != m_jit_process_sp.get())
        return false;
                
    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);
}

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

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);
}

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
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 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);
}  

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;
    ExecutionResults return_value = 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 eExecutionSetupError;
    
    if (args_addr == LLDB_INVALID_ADDRESS)
    {
        if (!InsertFunction(exe_ctx, args_addr, errors))
            return 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 != eExecutionCompleted)
        return return_value;

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

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