1/*
2 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef DFGAdjacencyList_h
27#define DFGAdjacencyList_h
28
29#include <wtf/Platform.h>
30
31#if ENABLE(DFG_JIT)
32
33#include "DFGCommon.h"
34#include "DFGEdge.h"
35
36namespace JSC { namespace DFG {
37
38class AdjacencyList {
39public:
40    enum Kind {
41        Fixed,
42        Variable
43    };
44
45    enum { Size = 3 };
46
47    AdjacencyList() { }
48
49    AdjacencyList(Kind kind)
50    {
51        if (kind == Variable) {
52            m_words[0].m_encodedWord = UINT_MAX;
53            m_words[1].m_encodedWord = UINT_MAX;
54        }
55    }
56
57    AdjacencyList(Kind kind, Edge child1, Edge child2, Edge child3)
58    {
59        ASSERT_UNUSED(kind, kind == Fixed);
60        initialize(child1, child2, child3);
61    }
62
63    AdjacencyList(Kind kind, unsigned firstChild, unsigned numChildren)
64    {
65        ASSERT_UNUSED(kind, kind == Variable);
66        setFirstChild(firstChild);
67        setNumChildren(numChildren);
68    }
69
70    const Edge& child(unsigned i) const
71    {
72        ASSERT(i < Size);
73        return m_words[i];
74    }
75
76    Edge& child(unsigned i)
77    {
78        ASSERT(i < Size);
79        return m_words[i];
80    }
81
82    void setChild(unsigned i, Edge nodeUse)
83    {
84        ASSERT(i < Size);
85        m_words[i] = nodeUse;
86    }
87
88    Edge child1() const { return child(0); }
89    Edge child2() const { return child(1); }
90    Edge child3() const { return child(2); }
91
92    Edge& child1() { return child(0); }
93    Edge& child2() { return child(1); }
94    Edge& child3() { return child(2); }
95
96    void setChild1(Edge nodeUse) { setChild(0, nodeUse); }
97    void setChild2(Edge nodeUse) { setChild(1, nodeUse); }
98    void setChild3(Edge nodeUse) { setChild(2, nodeUse); }
99
100    Edge child1Unchecked() const { return m_words[0]; }
101
102    void initialize(Edge child1, Edge child2, Edge child3)
103    {
104        child(0) = child1;
105        child(1) = child2;
106        child(2) = child3;
107    }
108
109    void initialize(Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
110    {
111        initialize(Edge(child1), Edge(child2), Edge(child3));
112    }
113
114    void reset()
115    {
116        initialize();
117    }
118
119    // Call this if you wish to remove an edge and the node treats the list of children.
120    void removeEdge(unsigned edgeIndex)
121    {
122        for (unsigned i = edgeIndex; i < Size - 1; ++i)
123            setChild(i, child(i + 1));
124        setChild(Size - 1, Edge());
125    }
126
127    unsigned firstChild() const
128    {
129        return m_words[0].m_encodedWord;
130    }
131    void setFirstChild(unsigned firstChild)
132    {
133        m_words[0].m_encodedWord = firstChild;
134    }
135
136    unsigned numChildren() const
137    {
138        return m_words[1].m_encodedWord;
139    }
140    void setNumChildren(unsigned numChildren)
141    {
142        m_words[1].m_encodedWord = numChildren;
143    }
144
145private:
146    Edge m_words[Size];
147};
148
149} } // namespace JSC::DFG
150
151#endif // ENABLE(DFG_JIT)
152
153#endif // DFGAdjacencyList_h
154