/*
 * Copyright (C) 2009, 2012 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#ifndef MacroAssemblerCodeRef_h
#define MacroAssemblerCodeRef_h

#include "Disassembler.h"
#include <wtf/Platform.h>
#include "ExecutableAllocator.h"
#include "LLIntData.h"
#include <wtf/DataLog.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/UnusedParam.h>
#include <qglobal.h>

// ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
// instruction address on the platform (for example, check any alignment requirements).
#if CPU(ARM_THUMB2)
// ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded
// into the processor are decorated with the bottom bit set, indicating that this is
// thumb code (as oposed to 32-bit traditional ARM).  The first test checks for both
// decorated and undectorated null, and the second test ensures that the pointer is
// decorated.
#define ASSERT_VALID_CODE_POINTER(ptr) \
    ASSERT(reinterpret_cast<intptr_t>(ptr) & ~1);
#define ASSERT_VALID_CODE_OFFSET(offset) \
    ASSERT(!(offset & 1)) // Must be multiple of 2.
#else
#define ASSERT_VALID_CODE_POINTER(ptr) \
    ASSERT(ptr)
#define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes!
#endif

#if CPU(X86) && OS(WINDOWS)
#define CALLING_CONVENTION_IS_STDCALL 1
#ifndef CDECL
#if COMPILER(MSVC)
#define CDECL __cdecl
#else
#define CDECL __attribute__ ((__cdecl))
#endif // COMPILER(MSVC)
#endif // CDECL
#else
#define CALLING_CONVENTION_IS_STDCALL 0
#endif

#if CPU(X86) && !OS(INTEGRITY)
#define HAS_FASTCALL_CALLING_CONVENTION 1
#ifndef FASTCALL
#if COMPILER(MSVC)
#define FASTCALL __fastcall
#else
#define FASTCALL  __attribute__ ((fastcall))
#endif // COMPILER(MSVC)
#endif // FASTCALL
#else
#define HAS_FASTCALL_CALLING_CONVENTION 0
#endif // CPU(X86)

namespace JSC {

// FunctionPtr:
//
// FunctionPtr should be used to wrap pointers to C/C++ functions in JSC
// (particularly, the stub functions).
class FunctionPtr {
public:
    FunctionPtr()
        : m_value(0)
    {
    }

    template<typename returnType>
    FunctionPtr(returnType(*value)())
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1>
    FunctionPtr(returnType(*value)(argType1))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2>
    FunctionPtr(returnType(*value)(argType1, argType2))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2, typename argType3>
    FunctionPtr(returnType(*value)(argType1, argType2, argType3))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4>
    FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4, typename argType5>
    FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4, typename argType5, typename argType6>
    FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5, argType6))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    inline FunctionPtr(MacroAssemblerCodePtr ptr);

// MSVC doesn't seem to treat functions with different calling conventions as
// different types; these methods already defined for fastcall, below.
#if CALLING_CONVENTION_IS_STDCALL && !OS(WINDOWS)

    template<typename returnType>
    FunctionPtr(returnType (CDECL *value)())
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1>
    FunctionPtr(returnType (CDECL *value)(argType1))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2>
    FunctionPtr(returnType (CDECL *value)(argType1, argType2))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2, typename argType3>
    FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4>
    FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3, argType4))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }
#endif

#if HAS_FASTCALL_CALLING_CONVENTION

    template<typename returnType>
    FunctionPtr(returnType (FASTCALL *value)())
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1>
    FunctionPtr(returnType (FASTCALL *value)(argType1))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2>
    FunctionPtr(returnType (FASTCALL *value)(argType1, argType2))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2, typename argType3>
    FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4>
    FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3, argType4))
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }
#endif

    template<typename FunctionType>
    explicit FunctionPtr(FunctionType* value)
        // Using a C-ctyle cast here to avoid compiler error on RVTC:
        // Error:  #694: reinterpret_cast cannot cast away const or other type qualifiers
        // (I guess on RVTC function pointers have a different constness to GCC/MSVC?)
        : m_value((void*)value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    void* value() const { return m_value; }
    void* executableAddress() const { return m_value; }


private:
    void* m_value;
};

// ReturnAddressPtr:
//
// ReturnAddressPtr should be used to wrap return addresses generated by processor
// 'call' instructions exectued in JIT code.  We use return addresses to look up
// exception and optimization information, and to repatch the call instruction
// that is the source of the return address.
class ReturnAddressPtr {
public:
    ReturnAddressPtr()
        : m_value(0)
    {
    }

    explicit ReturnAddressPtr(void* value)
        : m_value(value)
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    explicit ReturnAddressPtr(FunctionPtr function)
        : m_value(function.value())
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    void* value() const { return m_value; }

private:
    void* m_value;
};

// MacroAssemblerCodePtr:
//
// MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code.
class MacroAssemblerCodePtr {
public:
    MacroAssemblerCodePtr()
        : m_value(0)
    {
    }

    explicit MacroAssemblerCodePtr(void* value)
#if CPU(ARM_THUMB2)
        // Decorate the pointer as a thumb code pointer.
        : m_value(reinterpret_cast<char*>(value) + 1)
#else
        : m_value(value)
#endif
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }
    
    static MacroAssemblerCodePtr createFromExecutableAddress(void* value)
    {
        ASSERT_VALID_CODE_POINTER(value);
        MacroAssemblerCodePtr result;
        result.m_value = value;
        return result;
    }

#if ENABLE(LLINT)
    static MacroAssemblerCodePtr createLLIntCodePtr(LLIntCode codeId)
    {
        return createFromExecutableAddress(LLInt::getCodePtr(codeId));
    }
#endif

    explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
        : m_value(ra.value())
    {
        ASSERT_VALID_CODE_POINTER(m_value);
    }

    void* executableAddress() const { return m_value; }
#if CPU(ARM_THUMB2)
    // To use this pointer as a data address remove the decoration.
    void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
#else
    void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
#endif

    bool operator!() const
    {
        return !m_value;
    }

private:
    void* m_value;
};


FunctionPtr::FunctionPtr(MacroAssemblerCodePtr ptr)
    : m_value(ptr.executableAddress())
{
}

// MacroAssemblerCodeRef:
//
// A reference to a section of JIT generated code.  A CodeRef consists of a
// pointer to the code, and a ref pointer to the pool from within which it
// was allocated.
class MacroAssemblerCodeRef {
private:
    // This is private because it's dangerous enough that we want uses of it
    // to be easy to find - hence the static create method below.
    explicit MacroAssemblerCodeRef(MacroAssemblerCodePtr codePtr)
        : m_codePtr(codePtr)
    {
        ASSERT(m_codePtr);
    }

public:
    MacroAssemblerCodeRef()
    {
    }

    MacroAssemblerCodeRef(PassRefPtr<ExecutableMemoryHandle> executableMemory)
        : m_codePtr(executableMemory->start())
        , m_executableMemory(executableMemory)
    {
        ASSERT(m_executableMemory->isManaged());
        ASSERT(m_executableMemory->start());
        ASSERT(m_codePtr);
    }
    
    // Use this only when you know that the codePtr refers to code that is
    // already being kept alive through some other means. Typically this means
    // that codePtr is immortal.
    static MacroAssemblerCodeRef createSelfManagedCodeRef(MacroAssemblerCodePtr codePtr)
    {
        return MacroAssemblerCodeRef(codePtr);
    }
    
#if ENABLE(LLINT)
    // Helper for creating self-managed code refs from LLInt.
    static MacroAssemblerCodeRef createLLIntCodeRef(LLIntCode codeId)
    {
        return createSelfManagedCodeRef(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(codeId)));
    }
#endif

    ExecutableMemoryHandle* executableMemory() const
    {
        return m_executableMemory.get();
    }
    
    MacroAssemblerCodePtr code() const
    {
        return m_codePtr;
    }
    
    size_t size() const
    {
        if (!m_executableMemory)
            return 0;
        return m_executableMemory->sizeInBytes();
    }
    
    bool tryToDisassemble(const char* prefix) const
    {
        return JSC::tryToDisassemble(m_codePtr, size(), prefix, WTF::dataFile());
    }
    
    bool operator!() const { return !m_codePtr; }

private:
    MacroAssemblerCodePtr m_codePtr;
    RefPtr<ExecutableMemoryHandle> m_executableMemory;
};

} // namespace JSC

#endif // MacroAssemblerCodeRef_h
