/*
 * Copyright (C) 2013-2018 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(DFG_JIT)

#include "DFGAbstractValue.h"
#include "DFGGraph.h"
#include "DFGNode.h"
#include "DFGNodeFlowProjection.h"
#include "DFGPhiChildren.h"

namespace JSC { namespace DFG {

template<typename AbstractStateType>
class AbstractInterpreter {
public:
    AbstractInterpreter(Graph&, AbstractStateType&);
    ~AbstractInterpreter();
    
    ALWAYS_INLINE AbstractValue& forNode(NodeFlowProjection node)
    {
        return m_state.forNode(node);
    }
    
    ALWAYS_INLINE AbstractValue& forNode(Edge edge)
    {
        return forNode(edge.node());
    }
    
    ALWAYS_INLINE void clearForNode(NodeFlowProjection node)
    {
        m_state.clearForNode(node);
    }
    
    ALWAYS_INLINE void clearForNode(Edge edge)
    {
        clearForNode(edge.node());
    }

    template<typename... Arguments>
    ALWAYS_INLINE void setForNode(NodeFlowProjection node, Arguments&&... arguments)
    {
        m_state.setForNode(node, std::forward<Arguments>(arguments)...);
    }

    template<typename... Arguments>
    ALWAYS_INLINE void setForNode(Edge edge, Arguments&&... arguments)
    {
        setForNode(edge.node(), std::forward<Arguments>(arguments)...);
    }

    template<typename... Arguments>
    ALWAYS_INLINE void setTypeForNode(NodeFlowProjection node, Arguments&&... arguments)
    {
        m_state.setTypeForNode(node, std::forward<Arguments>(arguments)...);
    }

    template<typename... Arguments>
    ALWAYS_INLINE void setTypeForNode(Edge edge, Arguments&&... arguments)
    {
        setTypeForNode(edge.node(), std::forward<Arguments>(arguments)...);
    }
    
    template<typename... Arguments>
    ALWAYS_INLINE void setNonCellTypeForNode(NodeFlowProjection node, Arguments&&... arguments)
    {
        m_state.setNonCellTypeForNode(node, std::forward<Arguments>(arguments)...);
    }

    template<typename... Arguments>
    ALWAYS_INLINE void setNonCellTypeForNode(Edge edge, Arguments&&... arguments)
    {
        setNonCellTypeForNode(edge.node(), std::forward<Arguments>(arguments)...);
    }
    
    ALWAYS_INLINE void makeBytecodeTopForNode(NodeFlowProjection node)
    {
        m_state.makeBytecodeTopForNode(node);
    }
    
    ALWAYS_INLINE void makeBytecodeTopForNode(Edge edge)
    {
        makeBytecodeTopForNode(edge.node());
    }
    
    ALWAYS_INLINE void makeHeapTopForNode(NodeFlowProjection node)
    {
        m_state.makeHeapTopForNode(node);
    }
    
    ALWAYS_INLINE void makeHeapTopForNode(Edge edge)
    {
        makeHeapTopForNode(edge.node());
    }
    
    bool needsTypeCheck(Node* node, SpeculatedType typesPassedThrough)
    {
        return !forNode(node).isType(typesPassedThrough);
    }
    
    bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough)
    {
        return needsTypeCheck(edge.node(), typesPassedThrough);
    }
    
    bool needsTypeCheck(Edge edge)
    {
        return needsTypeCheck(edge, typeFilterFor(edge.useKind()));
    }
    
    // Abstractly executes the given node. The new abstract state is stored into an
    // abstract stack stored in *this. Loads of local variables (that span
    // basic blocks) interrogate the basic block's notion of the state at the head.
    // Stores to local variables are handled in endBasicBlock(). This returns true
    // if execution should continue past this node. Notably, it will return true
    // for block terminals, so long as those terminals are not Return or Unreachable.
    //
    // This is guaranteed to be equivalent to doing:
    //
    // state.startExecuting()
    // state.executeEdges(node);
    // result = state.executeEffects(index);
    bool execute(unsigned indexInBlock);
    bool execute(Node*);
    
    // Indicate the start of execution of a node. It resets any state in the node
    // that is progressively built up by executeEdges() and executeEffects().
    void startExecuting();
    
    // Abstractly execute the edges of the given node. This runs filterEdgeByUse()
    // on all edges of the node. You can skip this step, if you have already used
    // filterEdgeByUse() (or some equivalent) on each edge.
    void executeEdges(Node*);

    void executeKnownEdgeTypes(Node*);
    
    ALWAYS_INLINE void filterEdgeByUse(Edge& edge)
    {
        UseKind useKind = edge.useKind();
        if (useKind == UntypedUse)
            return;
        filterByType(edge, typeFilterFor(useKind));
    }
    
    // Abstractly execute the effects of the given node. This changes the abstract
    // state assuming that edges have already been filtered.
    bool executeEffects(unsigned indexInBlock);
    bool executeEffects(unsigned clobberLimit, Node*);
    
    void dump(PrintStream& out) const;
    void dump(PrintStream& out);
    
    template<typename T>
    FiltrationResult filter(T node, const RegisteredStructureSet& set, SpeculatedType admittedTypes = SpecNone)
    {
        return filter(forNode(node), set, admittedTypes);
    }
    
    template<typename T>
    FiltrationResult filterArrayModes(T node, ArrayModes arrayModes)
    {
        return filterArrayModes(forNode(node), arrayModes);
    }
    
    template<typename T>
    FiltrationResult filter(T node, SpeculatedType type)
    {
        return filter(forNode(node), type);
    }
    
    template<typename T>
    FiltrationResult filterByValue(T node, FrozenValue value)
    {
        return filterByValue(forNode(node), value);
    }
    
    template<typename T>
    FiltrationResult filterClassInfo(T node, const ClassInfo* classInfo)
    {
        return filterClassInfo(forNode(node), classInfo);
    }

    FiltrationResult filter(AbstractValue&, const RegisteredStructureSet&, SpeculatedType admittedTypes = SpecNone);
    FiltrationResult filterArrayModes(AbstractValue&, ArrayModes);
    FiltrationResult filter(AbstractValue&, SpeculatedType);
    FiltrationResult filterByValue(AbstractValue&, FrozenValue);
    FiltrationResult filterClassInfo(AbstractValue&, const ClassInfo*);
    
    PhiChildren* phiChildren() { return m_phiChildren.get(); }
    
    void filterICStatus(Node*);
    
private:
    void clobberWorld();
    void didFoldClobberWorld();
    
    bool handleConstantBinaryBitwiseOp(Node*);

    template<typename Functor>
    void forAllValues(unsigned indexInBlock, Functor&);
    
    void clobberStructures();
    void didFoldClobberStructures();
    
    void observeTransition(unsigned indexInBlock, RegisteredStructure from, RegisteredStructure to);
    void observeTransitions(unsigned indexInBlock, const TransitionVector&);
    
    enum BooleanResult {
        UnknownBooleanResult,
        DefinitelyFalse,
        DefinitelyTrue
    };
    BooleanResult booleanResult(Node*, AbstractValue&);
    
    void setBuiltInConstant(Node* node, FrozenValue value)
    {
        AbstractValue& abstractValue = forNode(node);
        abstractValue.set(m_graph, value, m_state.structureClobberState());
        abstractValue.fixTypeForRepresentation(m_graph, node);
    }
    
    void setConstant(Node* node, FrozenValue value)
    {
        setBuiltInConstant(node, value);
        m_state.setFoundConstants(true);
    }
    
    ALWAYS_INLINE void filterByType(Edge& edge, SpeculatedType type);
    
    void verifyEdge(Node*, Edge);
    void verifyEdges(Node*);
    void executeDoubleUnaryOpEffects(Node*, double(*equivalentFunction)(double));
    
    bool handleConstantDivOp(Node*);

    CodeBlock* m_codeBlock;
    Graph& m_graph;
    VM& m_vm;
    AbstractStateType& m_state;
    std::unique_ptr<PhiChildren> m_phiChildren;
};

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)
