/*
 * Copyright (C) 2011, 2013, 2015 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 "DFGEdge.h"

namespace JSC { namespace DFG {

class AdjacencyList {
public:
    enum Kind {
        Fixed,
        Variable
    };
    
    enum { Size = 3 };
    
    AdjacencyList() { }
    
    AdjacencyList(Kind kind)
    {
        if (kind == Variable) {
            m_words[0].m_encodedWord = UINT_MAX;
            m_words[1].m_encodedWord = UINT_MAX;
        }
    }
    
    AdjacencyList(Kind kind, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
    {
        ASSERT_UNUSED(kind, kind == Fixed);
        initialize(child1, child2, child3);
    }
    
    AdjacencyList(Kind kind, unsigned firstChild, unsigned numChildren)
    {
        ASSERT_UNUSED(kind, kind == Variable);
        setFirstChild(firstChild);
        setNumChildren(numChildren);
        // We need to make sure this is the empty value so equivalent adjacency
        // lists produce identical hashes.
        m_words[2] = Edge(); 
    }
    
    bool isEmpty() const { return !child1(); }
    
    const Edge& child(unsigned i) const
    {
        ASSERT(i < Size);
        return m_words[i];
    }    
    
    Edge& child(unsigned i)
    {
        ASSERT(i < Size);
        return m_words[i];
    }
    
    void setChild(unsigned i, Edge nodeUse)
    {
        ASSERT(i < Size);
        m_words[i] = nodeUse;
    }
    
    Edge child1() const { return child(0); }
    Edge child2() const { return child(1); }
    Edge child3() const { return child(2); }

    Edge& child1() { return child(0); }
    Edge& child2() { return child(1); }
    Edge& child3() { return child(2); }
    
    void setChild1(Edge nodeUse) { setChild(0, nodeUse); }
    void setChild2(Edge nodeUse) { setChild(1, nodeUse); }
    void setChild3(Edge nodeUse) { setChild(2, nodeUse); }
    
    Edge child1Unchecked() const { return m_words[0]; }
    
    Edge justOneChild() const
    {
        if (!!child1() && !child2()) {
            ASSERT(!child3());
            return child1();
        }
        return Edge();
    }
    
    void initialize(Edge child1, Edge child2, Edge child3)
    {
        child(0) = child1;
        child(1) = child2;
        child(2) = child3;
    }
    
    void initialize(Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
    {
        initialize(Edge(child1), Edge(child2), Edge(child3));
    }
    
    void reset()
    {
        initialize();
    }
    
    // Call this if you wish to remove an edge and the node treats the list of children.
    void removeEdge(unsigned edgeIndex)
    {
        for (unsigned i = edgeIndex; i < Size - 1; ++i)
            setChild(i, child(i + 1));
        setChild(Size - 1, Edge());
    }
    
    unsigned firstChild() const
    {
        return m_words[0].m_encodedWord;
    }
    void setFirstChild(unsigned firstChild)
    {
        m_words[0].m_encodedWord = firstChild;
    }
    
    unsigned numChildren() const
    {
        return m_words[1].m_encodedWord;
    }
    void setNumChildren(unsigned numChildren)
    {
        m_words[1].m_encodedWord = numChildren;
    }
    
    AdjacencyList sanitized() const
    {
        return AdjacencyList(Fixed, child1().sanitized(), child2().sanitized(), child3().sanitized());
    }
    
    AdjacencyList justChecks() const
    {
        AdjacencyList result(Fixed);
        unsigned sourceIndex = 0;
        unsigned targetIndex = 0;
        while (sourceIndex < AdjacencyList::Size) {
            Edge edge = child(sourceIndex++);
            if (!edge)
                break;
            if (edge.willHaveCheck())
                result.child(targetIndex++) = edge;
        }
        return result;
    }
    
    unsigned hash() const
    {
        unsigned result = 0;
        if (!child1())
            return result;
        
        result += child1().hash();
        
        if (!child2())
            return result;
        
        result *= 3;
        result += child2().hash();
        
        if (!child3())
            return result;
        
        result *= 3;
        result += child3().hash();
        
        return result;
    }
    
    bool operator==(const AdjacencyList& other) const
    {
        return child1() == other.child1()
            && child2() == other.child2()
            && child3() == other.child3();
    }
    
private:
    Edge m_words[Size];
};

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)
