/*
 * Copyright (C) 2017 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 VM;
using ExecState = CallFrame;

class VMTraps {
    typedef uint8_t BitField;
public:
    enum class Error {
        None,
        LockUnavailable,
        NotJITCode
    };

    enum EventType {
        // Sorted in servicing priority order from highest to lowest.
        NeedDebuggerBreak,
        NeedTermination,
        NeedWatchdogCheck,
        NumberOfEventTypes, // This entry must be last in this list.
        Invalid
    };

    class Mask {
    public:
        enum AllEventTypes { AllEventTypesTag };
        Mask(AllEventTypes)
            : m_mask(std::numeric_limits<BitField>::max())
        { }
        static Mask allEventTypes() { return Mask(AllEventTypesTag); }

        template<typename... Arguments>
        Mask(Arguments... args)
            : m_mask(0)
        {
            init(args...);
        }

        BitField bits() const { return m_mask; }

    private:
        template<typename... Arguments>
        void init(EventType eventType, Arguments... args)
        {
            ASSERT(eventType < NumberOfEventTypes);
            m_mask |= (1 << eventType);
            init(args...);
        }

        void init() { }

        BitField m_mask;
    };

    ~VMTraps();
    VMTraps();

    void willDestroyVM();

    bool needTrapHandling() { return m_needTrapHandling; }
    bool needTrapHandling(Mask mask) { return m_needTrapHandling & mask.bits(); }
    void* needTrapHandlingAddress() { return &m_needTrapHandling; }

    void notifyGrabAllLocks()
    {
        if (needTrapHandling())
            invalidateCodeBlocksOnStack();
    }

    JS_EXPORT_PRIVATE void fireTrap(EventType);

    void handleTraps(ExecState*, VMTraps::Mask);

    void tryInstallTrapBreakpoints(struct SignalContext&, StackBounds);

private:
    VM& vm() const;

    bool hasTrapForEvent(Locker<Lock>&, EventType eventType, Mask mask)
    {
        ASSERT(eventType < NumberOfEventTypes);
        return (m_trapsBitField & mask.bits() & (1 << eventType));
    }
    void setTrapForEvent(Locker<Lock>&, EventType eventType)
    {
        ASSERT(eventType < NumberOfEventTypes);
        m_trapsBitField |= (1 << eventType);
    }
    void clearTrapForEvent(Locker<Lock>&, EventType eventType)
    {
        ASSERT(eventType < NumberOfEventTypes);
        m_trapsBitField &= ~(1 << eventType);
    }

    EventType takeTopPriorityTrap(Mask);

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

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

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

    Box<Lock> m_lock;
    Ref<AutomaticThreadCondition> m_condition;
    union {
        BitField m_needTrapHandling { 0 };
        BitField m_trapsBitField;
    };
    bool m_needToInvalidatedCodeBlocks { false };
    bool m_isShuttingDown { false };

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

    friend class LLIntOffsetsExtractor;
    friend class SignalSender;
};

} // namespace JSC
