/*
 * Copyright (C) 2009-2021 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. 
 */

#pragma once

#if ENABLE(ASSEMBLER)

#define DUMP_LINK_STATISTICS 0
#define DUMP_CODE 0

#define GLOBAL_THUNK_ID reinterpret_cast<void*>(static_cast<intptr_t>(-1))
#define REGEXP_CODE_ID reinterpret_cast<void*>(static_cast<intptr_t>(-2))
#define CSS_CODE_ID reinterpret_cast<void*>(static_cast<intptr_t>(-3))

#include "JITCompilationEffort.h"
#include "MacroAssembler.h"
#include "MacroAssemblerCodeRef.h"
#include <wtf/DataLog.h>
#include <wtf/FastMalloc.h>
#include <wtf/Noncopyable.h>

namespace JSC {

// LinkBuffer:
//
// This class assists in linking code generated by the macro assembler, once code generation
// has been completed, and the code has been copied to is final location in memory.  At this
// time pointers to labels within the code may be resolved, and relative offsets to external
// addresses may be fixed.
//
// Specifically:
//   * Jump objects may be linked to external targets,
//   * The address of Jump objects may taken, such that it can later be relinked.
//   * The return address of a Call may be acquired.
//   * The address of a Label pointing into the code may be resolved.
//   * The value referenced by a DataLabel may be set.
//
class LinkBuffer {
    WTF_MAKE_NONCOPYABLE(LinkBuffer); WTF_MAKE_FAST_ALLOCATED;
    
    template<PtrTag tag> using CodePtr = MacroAssemblerCodePtr<tag>;
    template<PtrTag tag> using CodeRef = MacroAssemblerCodeRef<tag>;
    typedef MacroAssembler::Label Label;
    typedef MacroAssembler::Jump Jump;
    typedef MacroAssembler::PatchableJump PatchableJump;
    typedef MacroAssembler::JumpList JumpList;
    typedef MacroAssembler::Call Call;
    typedef MacroAssembler::DataLabelCompact DataLabelCompact;
    typedef MacroAssembler::DataLabel32 DataLabel32;
    typedef MacroAssembler::DataLabelPtr DataLabelPtr;
    typedef MacroAssembler::ConvertibleLoadLabel ConvertibleLoadLabel;
#if ENABLE(BRANCH_COMPACTION)
    typedef MacroAssembler::LinkRecord LinkRecord;
    typedef MacroAssembler::JumpLinkType JumpLinkType;
#endif

public:

#define FOR_EACH_LINKBUFFER_PROFILE(v) \
    v(BaselineJIT) \
    v(DFG) \
    v(FTL) \
    v(DFGOSREntry) \
    v(DFGOSRExit) \
    v(FTLOSRExit) \
    v(InlineCache) \
    v(JumpIsland) \
    v(Thunk) \
    v(LLIntThunk) \
    v(DFGThunk) \
    v(FTLThunk) \
    v(BoundFunctionThunk) \
    v(SpecializedThunk) \
    v(VirtualThunk) \
    v(WasmThunk) \
    v(ExtraCTIThunk) \
    v(Wasm) \
    v(YarrJIT) \
    v(CSSJIT) \
    v(Uncategorized) \
    v(Total) \

#define DECLARE_LINKBUFFER_PROFILE(name) name,
    enum class Profile {
        FOR_EACH_LINKBUFFER_PROFILE(DECLARE_LINKBUFFER_PROFILE)
    };
#undef DECLARE_LINKBUFFER_PROFILE

#define COUNT_LINKBUFFER_PROFILE(name) + 1
    static constexpr unsigned numberOfProfiles = FOR_EACH_LINKBUFFER_PROFILE(COUNT_LINKBUFFER_PROFILE);
#undef COUNT_LINKBUFFER_PROFILE
    static constexpr unsigned numberOfProfilesExcludingTotal = numberOfProfiles - 1;

    LinkBuffer(MacroAssembler& macroAssembler, void* ownerUID, Profile profile = Profile::Uncategorized, JITCompilationEffort effort = JITCompilationMustSucceed)
        : m_size(0)
        , m_didAllocate(false)
#ifndef NDEBUG
        , m_completed(false)
#endif
        , m_profile(profile)
    {
        UNUSED_PARAM(ownerUID);
        linkCode(macroAssembler, effort);
    }

    template<PtrTag tag>
    LinkBuffer(MacroAssembler& macroAssembler, MacroAssemblerCodePtr<tag> code, size_t size, Profile profile = Profile::Uncategorized, JITCompilationEffort effort = JITCompilationMustSucceed, bool shouldPerformBranchCompaction = true)
        : m_size(size)
        , m_didAllocate(false)
#ifndef NDEBUG
        , m_completed(false)
#endif
        , m_profile(profile)
        , m_code(code.template retagged<LinkBufferPtrTag>())
    {
#if ENABLE(BRANCH_COMPACTION)
        m_shouldPerformBranchCompaction = shouldPerformBranchCompaction;
#else
        UNUSED_PARAM(shouldPerformBranchCompaction);
#endif
        linkCode(macroAssembler, effort);
    }

    ~LinkBuffer()
    {
    }

    void runMainThreadFinalizationTasks();
    
    bool didFailToAllocate() const
    {
        return !m_didAllocate;
    }

    bool isValid() const
    {
        return !didFailToAllocate();
    }

    void setIsJumpIsland()
    {
#if ASSERT_ENABLED
        m_isJumpIsland = true;
#endif
    }
    
    // These methods are used to link or set values at code generation time.

    template<PtrTag tag, typename Func, typename = std::enable_if_t<std::is_function<typename std::remove_pointer<Func>::type>::value>>
    void link(Call call, Func funcName)
    {
        FunctionPtr<tag> function(funcName);
        link(call, function);
    }

    template<PtrTag tag>
    void link(Call call, FunctionPtr<tag> function)
    {
        ASSERT(call.isFlagSet(Call::Linkable));
        call.m_label = applyOffset(call.m_label);
        MacroAssembler::linkCall(code(), call, function);
    }
    
    template<PtrTag tag>
    void link(Call call, CodeLocationLabel<tag> label)
    {
        link(call, FunctionPtr<tag>(label));
    }
    
    template<PtrTag tag>
    void link(Jump jump, CodeLocationLabel<tag> label)
    {
        jump.m_label = applyOffset(jump.m_label);
        MacroAssembler::linkJump(code(), jump, label);
    }

    template<PtrTag tag>
    void link(const JumpList& list, CodeLocationLabel<tag> label)
    {
        for (const Jump& jump : list.jumps())
            link(jump, label);
    }

    void patch(DataLabelPtr label, void* value)
    {
        AssemblerLabel target = applyOffset(label.m_label);
        MacroAssembler::linkPointer(code(), target, value);
    }

    template<PtrTag tag>
    void patch(DataLabelPtr label, CodeLocationLabel<tag> value)
    {
        AssemblerLabel target = applyOffset(label.m_label);
        MacroAssembler::linkPointer(code(), target, value);
    }

    // These methods are used to obtain handles to allow the code to be relinked / repatched later.
    
    template<PtrTag tag>
    CodeLocationLabel<tag> entrypoint()
    {
        return CodeLocationLabel<tag>(tagCodePtr<tag>(code()));
    }

    template<PtrTag tag>
    CodeLocationCall<tag> locationOf(Call call)
    {
        ASSERT(call.isFlagSet(Call::Linkable));
        ASSERT(!call.isFlagSet(Call::Near));
        return CodeLocationCall<tag>(getLinkerAddress<tag>(applyOffset(call.m_label)));
    }

    template<PtrTag tag>
    CodeLocationNearCall<tag> locationOfNearCall(Call call)
    {
        ASSERT(call.isFlagSet(Call::Linkable));
        ASSERT(call.isFlagSet(Call::Near));
        return CodeLocationNearCall<tag>(getLinkerAddress<tag>(applyOffset(call.m_label)),
            call.isFlagSet(Call::Tail) ? NearCallMode::Tail : NearCallMode::Regular);
    }

    template<PtrTag tag>
    CodeLocationLabel<tag> locationOf(PatchableJump jump)
    {
        return CodeLocationLabel<tag>(getLinkerAddress<tag>(applyOffset(jump.m_jump.m_label)));
    }

    template<PtrTag tag>
    CodeLocationLabel<tag> locationOf(Label label)
    {
        return CodeLocationLabel<tag>(getLinkerAddress<tag>(applyOffset(label.m_label)));
    }

    template<PtrTag tag>
    CodeLocationDataLabelPtr<tag> locationOf(DataLabelPtr label)
    {
        return CodeLocationDataLabelPtr<tag>(getLinkerAddress<tag>(applyOffset(label.m_label)));
    }

    template<PtrTag tag>
    CodeLocationDataLabel32<tag> locationOf(DataLabel32 label)
    {
        return CodeLocationDataLabel32<tag>(getLinkerAddress<tag>(applyOffset(label.m_label)));
    }
    
    template<PtrTag tag>
    CodeLocationDataLabelCompact<tag> locationOf(DataLabelCompact label)
    {
        return CodeLocationDataLabelCompact<tag>(getLinkerAddress<tag>(applyOffset(label.m_label)));
    }

    template<PtrTag tag>
    CodeLocationConvertibleLoad<tag> locationOf(ConvertibleLoadLabel label)
    {
        return CodeLocationConvertibleLoad<tag>(getLinkerAddress<tag>(applyOffset(label.m_label)));
    }

    // This method obtains the return address of the call, given as an offset from
    // the start of the code.
    unsigned returnAddressOffset(Call call)
    {
        call.m_label = applyOffset(call.m_label);
        return MacroAssembler::getLinkerCallReturnOffset(call);
    }

    uint32_t offsetOf(Label label)
    {
        return applyOffset(label.m_label).offset();
    }

    unsigned offsetOf(PatchableJump jump)
    {
        return applyOffset(jump.m_jump.m_label).offset();
    }

    // Upon completion of all patching 'FINALIZE_CODE()' should be called once to
    // complete generation of the code. Alternatively, call
    // finalizeCodeWithoutDisassembly() directly if you have your own way of
    // displaying disassembly.

    template<PtrTag tag>
    CodeRef<tag> finalizeCodeWithoutDisassembly()
    {
        return finalizeCodeWithoutDisassemblyImpl().template retagged<tag>();
    }

    template<PtrTag tag, typename... Args>
    CodeRef<tag> finalizeCodeWithDisassembly(bool dumpDisassembly, const char* format, Args... args)
    {
        ALLOW_NONLITERAL_FORMAT_BEGIN
        IGNORE_WARNINGS_BEGIN("format-security")
        return finalizeCodeWithDisassemblyImpl(dumpDisassembly, format, args...).template retagged<tag>();
        IGNORE_WARNINGS_END
        ALLOW_NONLITERAL_FORMAT_END
    }

    template<PtrTag tag>
    CodePtr<tag> trampolineAt(Label label)
    {
        return CodePtr<tag>(MacroAssembler::AssemblerType_T::getRelocatedAddress(code(), applyOffset(label.m_label)));
    }

    void* debugAddress()
    {
        return m_code.dataLocation();
    }

    size_t size() const { return m_size; }
    
    bool wasAlreadyDisassembled() const { return m_alreadyDisassembled; }
    void didAlreadyDisassemble() { m_alreadyDisassembled = true; }

    JS_EXPORT_PRIVATE static void clearProfileStatistics();
    JS_EXPORT_PRIVATE static void dumpProfileStatistics(std::optional<PrintStream*> = std::nullopt);

    template<typename Functor>
    void addMainThreadFinalizationTask(const Functor& functor)
    {
        m_mainThreadFinalizationTasks.append(createSharedTask<void()>(functor));
    }

private:
    JS_EXPORT_PRIVATE CodeRef<LinkBufferPtrTag> finalizeCodeWithoutDisassemblyImpl();
    JS_EXPORT_PRIVATE CodeRef<LinkBufferPtrTag> finalizeCodeWithDisassemblyImpl(bool dumpDisassembly, const char* format, ...) WTF_ATTRIBUTE_PRINTF(3, 4);

#if ENABLE(BRANCH_COMPACTION)
    int executableOffsetFor(int location)
    {
        // Returning 0 in this case works because at location <
        // sizeof(int32_t), no compaction could have happened before this
        // point as the assembler could not have placed a branch instruction
        // within this space that required compaction.
        if (location < static_cast<int>(sizeof(int32_t)))
            return 0;
        return bitwise_cast<int32_t*>(m_assemblerStorage.buffer())[location / sizeof(int32_t) - 1];
    }
#endif
    
    template <typename T> T applyOffset(T src)
    {
#if ENABLE(BRANCH_COMPACTION)
        src = src.labelAtOffset(-executableOffsetFor(src.offset()));
#endif
        return src;
    }

    // Keep this private! - the underlying code should only be obtained externally via finalizeCode().
    void* code()
    {
        return m_code.dataLocation();
    }
    
    void allocate(MacroAssembler&, JITCompilationEffort);

    template<PtrTag tag, typename T>
    void* getLinkerAddress(T src)
    {
        void *code = this->code();
        void* address = MacroAssembler::getLinkerAddress<tag>(code, src);
        RELEASE_ASSERT(code <= untagCodePtr<tag>(address) && untagCodePtr<tag>(address) <= static_cast<char*>(code) + size());
        return address;
    }

    JS_EXPORT_PRIVATE void linkCode(MacroAssembler&, JITCompilationEffort);
#if ENABLE(BRANCH_COMPACTION)
    template <typename InstructionType>
    void copyCompactAndLinkCode(MacroAssembler&, JITCompilationEffort);
#endif

    void performFinalization();

#if DUMP_LINK_STATISTICS
    static void dumpLinkStatistics(void* code, size_t initialSize, size_t finalSize);
#endif
    
#if DUMP_CODE
    static void dumpCode(void* code, size_t);
#endif

    RefPtr<ExecutableMemoryHandle> m_executableMemory;
    size_t m_size;
#if ENABLE(BRANCH_COMPACTION)
    AssemblerData m_assemblerStorage;
#if CPU(ARM64E)
    AssemblerData m_assemblerHashesStorage;
#endif
    bool m_shouldPerformBranchCompaction { true };
#endif
    bool m_didAllocate;
#ifndef NDEBUG
    bool m_completed;
#endif
#if ASSERT_ENABLED
    bool m_isJumpIsland { false };
#endif
    bool m_alreadyDisassembled { false };
    Profile m_profile { Profile::Uncategorized };
    MacroAssemblerCodePtr<LinkBufferPtrTag> m_code;
    Vector<RefPtr<SharedTask<void(LinkBuffer&)>>> m_linkTasks;
    Vector<RefPtr<SharedTask<void(LinkBuffer&)>>> m_lateLinkTasks;
    Vector<RefPtr<SharedTask<void()>>> m_mainThreadFinalizationTasks;

    static size_t s_profileCummulativeLinkedSizes[numberOfProfiles];
    static size_t s_profileCummulativeLinkedCounts[numberOfProfiles];
};

#if OS(LINUX)
#define FINALIZE_CODE_IF(condition, linkBufferReference, resultPtrTag, ...) \
    (UNLIKELY((condition) || JSC::Options::logJIT()) \
        ? (linkBufferReference).finalizeCodeWithDisassembly<resultPtrTag>((condition), __VA_ARGS__) \
        : (UNLIKELY(JSC::Options::logJITCodeForPerf()) \
            ? (linkBufferReference).finalizeCodeWithDisassembly<resultPtrTag>(false, __VA_ARGS__) \
            : (linkBufferReference).finalizeCodeWithoutDisassembly<resultPtrTag>()))
#else
#define FINALIZE_CODE_IF(condition, linkBufferReference, resultPtrTag, ...) \
    (UNLIKELY((condition) || JSC::Options::logJIT()) \
        ? (linkBufferReference).finalizeCodeWithDisassembly<resultPtrTag>((condition), __VA_ARGS__) \
        : (linkBufferReference).finalizeCodeWithoutDisassembly<resultPtrTag>())
#endif

#define FINALIZE_CODE_FOR(codeBlock, linkBufferReference, resultPtrTag, ...)  \
    FINALIZE_CODE_IF((shouldDumpDisassemblyFor(codeBlock) || Options::asyncDisassembly()), linkBufferReference, resultPtrTag, __VA_ARGS__)

// Use this to finalize code, like so:
//
// CodeRef code = FINALIZE_CODE(linkBuffer, tag, "my super thingy number %d", number);
//
// Which, in disassembly mode, will print:
//
// Generated JIT code for my super thingy number 42:
//     Code at [0x123456, 0x234567]:
//         0x123456: mov $0, 0
//         0x12345a: ret
//
// ... and so on.
//
// Note that the format string and print arguments are only evaluated when dumpDisassembly
// is true, so you can hide expensive disassembly-only computations inside there.

#define FINALIZE_CODE(linkBufferReference, resultPtrTag, ...)  \
    FINALIZE_CODE_IF((JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly()), linkBufferReference, resultPtrTag, __VA_ARGS__)

#define FINALIZE_DFG_CODE(linkBufferReference, resultPtrTag, ...)  \
    FINALIZE_CODE_IF((JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly() || Options::dumpDFGDisassembly()), linkBufferReference, resultPtrTag, __VA_ARGS__)

#define FINALIZE_REGEXP_CODE(linkBufferReference, resultPtrTag, dataLogFArgumentsForHeading)  \
    FINALIZE_CODE_IF(JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly() || Options::dumpRegExpDisassembly(), linkBufferReference, resultPtrTag, dataLogFArgumentsForHeading)

#define FINALIZE_WASM_CODE(linkBufferReference, resultPtrTag, ...)  \
    FINALIZE_CODE_IF((JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly() || Options::dumpWasmDisassembly()), linkBufferReference, resultPtrTag, __VA_ARGS__)

#define FINALIZE_WASM_CODE_FOR_MODE(mode, linkBufferReference, resultPtrTag, ...)  \
    FINALIZE_CODE_IF(shouldDumpDisassemblyFor(mode), linkBufferReference, resultPtrTag, __VA_ARGS__)



} // namespace JSC

#endif // ENABLE(ASSEMBLER)
