1 /*
2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package org.graalvm.compiler.graph;
26 
27 import org.graalvm.compiler.nodeinfo.InputType;
28 
29 /**
30  * Describes an edge slot for a {@link NodeClass}.
31  */
32 public final class Position {
33 
34     /**
35      * The edges in which this position lies.
36      */
37     private final Edges edges;
38 
39     /**
40      * Index of the {@link Node} or {@link NodeList} field denoted by this position.
41      */
42     private final int index;
43 
44     /**
45      * Index within a {@link NodeList} if {@link #index} denotes a {@link NodeList} field otherwise
46      * {@link Node#NOT_ITERABLE}.
47      */
48     private final int subIndex;
49 
Position(Edges edges, int index, int subIndex)50     public Position(Edges edges, int index, int subIndex) {
51         this.edges = edges;
52         this.index = index;
53         this.subIndex = subIndex;
54     }
55 
get(Node node)56     public Node get(Node node) {
57         if (index < edges.getDirectCount()) {
58             return Edges.getNode(node, edges.getOffsets(), index);
59         } else {
60             return Edges.getNodeList(node, edges.getOffsets(), index).get(subIndex);
61         }
62     }
63 
getInputType()64     public InputType getInputType() {
65         return ((InputEdges) edges).getInputType(index);
66     }
67 
getName()68     public String getName() {
69         return edges.getName(index);
70     }
71 
isInputOptional()72     public boolean isInputOptional() {
73         return ((InputEdges) edges).isOptional(index);
74     }
75 
set(Node node, Node value)76     public void set(Node node, Node value) {
77         if (index < edges.getDirectCount()) {
78             edges.setNode(node, index, value);
79         } else {
80             Edges.getNodeList(node, edges.getOffsets(), index).set(subIndex, value);
81         }
82     }
83 
initialize(Node node, Node value)84     public void initialize(Node node, Node value) {
85         if (index < edges.getDirectCount()) {
86             edges.initializeNode(node, index, value);
87         } else {
88             Edges.getNodeList(node, edges.getOffsets(), index).initialize(subIndex, value);
89         }
90     }
91 
92     @Override
toString()93     public String toString() {
94         String res = edges.getType(index).getSimpleName() + ":" + edges.getName(index);
95         if (subIndex != Node.NOT_ITERABLE) {
96             res += "[" + subIndex + "]";
97         }
98         return res;
99     }
100 
101     @Override
hashCode()102     public int hashCode() {
103         final int prime = 31;
104         int result = 1;
105         result = prime * result + index;
106         result = prime * result + edges.hashCode();
107         result = prime * result + subIndex;
108         return result;
109     }
110 
111     @Override
equals(Object obj)112     public boolean equals(Object obj) {
113         if (this == obj) {
114             return true;
115         }
116         if (obj == null) {
117             return false;
118         }
119         if (getClass() != obj.getClass()) {
120             return false;
121         }
122         Position other = (Position) obj;
123         if (index != other.index) {
124             return false;
125         }
126         if (edges != other.edges) {
127             return false;
128         }
129         if (subIndex != other.subIndex) {
130             return false;
131         }
132         return true;
133     }
134 
135     /**
136      * Gets the index within a {@link NodeList} if {@link #getIndex()} denotes a {@link NodeList}
137      * field otherwise {@link Node#NOT_ITERABLE}.
138      */
getSubIndex()139     public int getSubIndex() {
140         return subIndex;
141     }
142 
143     /**
144      * Gets the index of the {@link Node} or {@link NodeList} field denoted by this position.
145      */
getIndex()146     public int getIndex() {
147         return index;
148     }
149 }
150