/*
 * Copyright (C) 2017-2022 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

#include <wtf/AutomaticThread.h>
#include <wtf/Box.h>
#include <wtf/Expected.h>
#include <wtf/HashSet.h>
#include <wtf/Lock.h>
#include <wtf/Locker.h>
#include <wtf/RefPtr.h>
#include <wtf/StackBounds.h>

namespace JSC {

class CallFrame;
class JSGlobalObject;
class VM;

class VMTraps {
public:
    using BitField = uint32_t;
    static constexpr size_t bitsInBitField = sizeof(BitField) * CHAR_BIT;

    // The following are the type of VMTrap events / signals that can be fired.
    // This list should be sorted in servicing priority order from highest to
    // lowest.
    //
    // The currently imlemented events are (in highest to lowest priority):
    //
    //  NeedShellTimeoutCheck
    //  - Only used by the jsc shell to check if we need to force a hard shutdown.
    //  - This event may fire more than once before the jsc shell forces the
    //    shutdown (see NeedWatchdogCheck's discussion of CPU time for why
    //    this may be).
    //
    //  NeedTermination
    //  - Used to request the termination of execution of the "current" stack.
    //    Note: "Termination" here simply means we terminate whatever is currently
    //    executing on the stack. It does not mean termination of the VM, and hence,
    //    is not permanent. Permanent VM termination mechanisms (like stopping the
    //    request to stop a woker thread) may use this Event to terminate the
    //    "current" stack, but it needs to do some additional work to prevent
    //    re-entry into the VM.
    //
    //  - The mechanism for achieving this stack termination is by throwing the
    //    uncatchable TerminationException that piggy back on the VM's exception
    //    handling machinery to the unwind stack. The TerminationException is
    //    uncatchable in the sense that the VM will refuse to let JS code's
    //    catch handlers catch the exception. C++ code in the VM (that calls into
    //    JS) needs to do exception checks, and make sure to propagate the
    //    exception if it is the TerminationException.
    //
    //  - Again, the termination request is not permanent. Once the VM unwinds out
    //    of the "current" execution state on the stack, the client may choose to
    //    clear the exception, and re-enter the VM to executing JS code again.
    //    See NeedWatchdogCheck below on why the VM watchdog needs this ability
    //    to re-enter the VM after terminating the current stack.
    //
    //  - Many clients enter the VM via APIs that return an uncaught exception
    //    in a NakedPointer<Exception>&. Those APIs would automatically clear
    //    the uncaught TerminationException and return it via the
    //    NakedPointer<Exception>&. Hence, the VM is ready for re-entry upon
    //    returning to the client.
    //
    //  - In the above notes, "current" (as in "current" stack) is in quotes because
    //    NeedTermination needs to guarantee that the TerminationException has
    //    been thrown in response to this event. If the event fires just before
    //    the VM exits and the TerminationException was not thrown yet, then we'll
    //    keep the NeedTermination trap bit set for the next VM entry. In this case,
    //    the termination will actual happen on the next stack of execution.
    //
    //    This behavior is needed because some clients rely on seeing an uncaught
    //    TerminationException to know that a termination has been requested.
    //    Technically, there are better ways for the client to know about the
    //    termination request (after all, the termination is initiated by the
    //    client). However, this is how some current client code works. So, we need
    //    to retain this behavior until we can change all the clients that rely on
    //    it.
    //
    //  NeedWatchdogCheck
    //  - Used to request a check as to whether the watchdog timer has expired.
    //    Note: the watchdog timeout is logically measured in CPU time. However,
    //    the real timer implementation (that fires this NeedWatchdogCheck event)
    //    has to operate on wall clock time. Hence, NeedWatchdogCheck firing does not
    //    necessarily mean that the watchdog timeout has expired, and we can expect
    //    to see NeedWatchdogCheck firing more than once for a single watchdog
    //    timeout.
    //
    //  - The watchdog mechanism has the option to request termination of the
    //    the current execution stack on watchdog timeout (see
    //    Watchdog::shouldTerminate()). If termination is requested, it will
    //    be executed via the same mechanism as NeedTermination (see how the
    //    NeedWatchdogCheck case can fall through to the NeedTermination case in
    //    VMTraps::handleTraps()).
    //
    //  - The watchdog timing out is not permanent i.e. after terminating the
    //    current stack, the client may choose to re-enter the VM to execute more
    //    JS. For example, a client may use the watchdog to ensure that an untrusted
    //    3rd party script (that it runs) does not get trapped in an infinite loop.
    //    If so, the watchdog timeout can terminate that script. After terminating
    //    that bad script, the client may choose to allow other 3rd party scripts
    //    to execute, or even allow more tries on the current one that timed out.
    //    Hence, the timeout and termination must not be permanent.
    //
    //    This is why termination via the NeedTermination event is not permanent,
    //    but only terminates the "current" stack.
    //
    //  NeedDebuggerBreak
    //  - Services asynchronous debugger break requests.
    //
    //  NeedExceptionHandling
    //  - Unlike the other events (which are asynchronous to the mutator thread),
    //    NeedExceptionHandling is set when the mutator thread throws a JS exception
    //    and cleared when the exception is handled / caught.
    //
    //  - The reason why NeedExceptionHandling is a bit on VMTraps as well is so
    //    that we can piggy back on all the RETURN_IF_EXCEPTION checks in C++ code
    //    to service VMTraps as well. Having the NeedExceptionHandling event as
    //    part of VMTraps allows RETURN_IF_EXCEPTION to optimally only do a single
    //    check to determine if the VM possibly has a pending exception to handle,
    //    as well as if there are asynchronous VMTraps events to handle.

#define FOR_EACH_VMTRAPS_EVENTS(v) \
    v(NeedShellTimeoutCheck) \
    v(NeedTermination) \
    v(NeedWatchdogCheck) \
    v(NeedDebuggerBreak) \
    v(NeedExceptionHandling) \
    v(DeferTrapHandling) // Must come last in the enum. This defers all events except NeedExceptionHandling.

#define DECLARE_VMTRAPS_EVENT_BIT_SHIFT(event__)  event__##BitShift,
    enum EventBitShift {
        FOR_EACH_VMTRAPS_EVENTS(DECLARE_VMTRAPS_EVENT_BIT_SHIFT)
    };
#undef DECLARE_VMTRAPS_EVENT_BIT_SHIFT


#define COUNT_EVENT(event) + 1
    static constexpr BitField NumberOfEvents = FOR_EACH_VMTRAPS_EVENTS(COUNT_EVENT) - 1; // Don't count DeferTrapHandling.
    static constexpr BitField NumberOfEventsIncludingDefer = FOR_EACH_VMTRAPS_EVENTS(COUNT_EVENT);
#undef COUNT_EVENT

    using Event = BitField;

#define DECLARE_VMTRAPS_EVENT(event__) \
    static_assert(event__##BitShift < bitsInBitField); \
    static constexpr Event event__ = (1 << event__##BitShift);
    FOR_EACH_VMTRAPS_EVENTS(DECLARE_VMTRAPS_EVENT)
#undef DECLARE_VMTRAPS_EVENT

#undef FOR_EACH_VMTRAPS_EVENTS

    static constexpr Event NoEvent = 0;

    static_assert(NumberOfEventsIncludingDefer <= bitsInBitField);
    static constexpr BitField AllEvents = (1ull << NumberOfEvents) - 1;
    static constexpr BitField AllEventsIncludingDefer = (1ull << NumberOfEventsIncludingDefer) - 1;
    static constexpr BitField AsyncEvents = AllEvents & ~NeedExceptionHandling;
    static constexpr BitField NonDebuggerEvents = AllEvents & ~NeedDebuggerBreak;
    static constexpr BitField NonDebuggerAsyncEvents = AsyncEvents & ~NeedDebuggerBreak;

    static constexpr bool onlyContainsAsyncEvents(BitField events)
    {
        return (AsyncEvents & events) && !(~AsyncEvents & events);
    }

    ~VMTraps();
    VMTraps();

    static void initializeSignals();

    void willDestroyVM();

    ALWAYS_INLINE bool needHandling(BitField mask) const
    {
        auto maskedValue = m_trapBits.loadRelaxed() & (mask | DeferTrapHandling);
        if (UNLIKELY(maskedValue))
            return (maskedValue & NeedExceptionHandling) || !(maskedValue & DeferTrapHandling);
        return false;
    }
    // Designed to be a fast check to rule out if we might need handling, and we need to ensure needHandling on the slow path.
    ALWAYS_INLINE bool maybeNeedHandling() const { return m_trapBits.loadRelaxed(); }
    void* trapBitsAddress() { return &m_trapBits; }

    enum class DeferAction {
        DeferForAWhile,
        DeferUntilEndOfScope
    };

    bool isDeferringTermination() const { return m_deferTerminationCount; }
    void deferTermination(DeferAction);
    void undoDeferTermination(DeferAction);

    void notifyGrabAllLocks()
    {
        if (needHandling(AsyncEvents))
            invalidateCodeBlocksOnStack();
    }

    bool hasTrapBit(Event event)
    {
        return m_trapBits.loadRelaxed() & event;
    }
    bool hasTrapBit(Event event, BitField mask)
    {
        BitField maskedBits = event & mask;
        return m_trapBits.loadRelaxed() & maskedBits;
    }
    void clearTrapBit(Event event) { m_trapBits.exchangeAnd(~event); }
    void setTrapBit(Event event)
    {
        ASSERT((event & ~AllEventsIncludingDefer) == 0);
        m_trapBits.exchangeOr(event);
    }

    JS_EXPORT_PRIVATE void fireTrap(Event);
    void handleTraps(BitField mask = AsyncEvents);

#if ENABLE(SIGNAL_BASED_VM_TRAPS)
    struct SignalContext;
    void tryInstallTrapBreakpoints(struct VMTraps::SignalContext&, StackBounds);
#endif

private:
    VM& vm() const;

    JS_EXPORT_PRIVATE void deferTerminationSlow(DeferAction);
    JS_EXPORT_PRIVATE void undoDeferTerminationSlow(DeferAction);
    Event takeTopPriorityTrap(BitField mask);

#if ENABLE(SIGNAL_BASED_VM_TRAPS)
    class SignalSender;
    friend class SignalSender;

    void invalidateCodeBlocksOnStack();
    void invalidateCodeBlocksOnStack(CallFrame* topCallFrame);
    void invalidateCodeBlocksOnStack(Locker<Lock>& codeBlockSetLocker, CallFrame* topCallFrame);

    void addSignalSender(SignalSender*);
    void removeSignalSender(SignalSender*);
#else
    void invalidateCodeBlocksOnStack() { }
    void invalidateCodeBlocksOnStack(CallFrame*) { }
#endif

    static constexpr BitField NeedExceptionHandlingMask = ~(1 << NeedExceptionHandling);

    Box<Lock> m_lock;
    Ref<AutomaticThreadCondition> m_condition;
    Atomic<BitField> m_trapBits { 0 };
    bool m_needToInvalidatedCodeBlocks { false };
    bool m_isShuttingDown { false };
    bool m_suspendedTerminationException { false };
    unsigned m_deferTerminationCount { 0 };

#if ENABLE(SIGNAL_BASED_VM_TRAPS)
    RefPtr<SignalSender> m_signalSender;
#endif

    friend class LLIntOffsetsExtractor;
    friend class SignalSender;
};

class DeferTraps {
public:
    DeferTraps(VM&);
    ~DeferTraps();
private:
    VMTraps& m_traps;
    bool m_isActive;
};

} // namespace JSC
