didnt get what I wanted before
[IRC.git] / Robust / src / Analysis / Disjoint / RefEdge.java
1 package Analysis.Disjoint;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6
7
8 public class RefEdge {
9
10   // all edges should have a non-null
11   // TypeDescriptor now
12   protected TypeDescriptor type;
13
14   // the field name may be null if this
15   // edge models a variable reference
16   protected String field;
17
18   protected ReachSet beta;
19   protected ReachSet betaNew;
20
21   protected RefSrcNode src;
22   protected HeapRegionNode dst;
23
24   // existence predicates must be true in a caller
25   // context for this edge to transfer from this
26   // callee to that context--NOTE, existence predicates
27   // do not factor into edge comparisons
28   protected ExistPredSet preds;
29
30   // taint sets indicate which heap roots have
31   // tainted this edge-->meaning which heap roots
32   // code must have had access to in order to
33   // read or write through this edge
34   protected TaintSet taints;
35
36
37   public RefEdge(RefSrcNode src,
38                  HeapRegionNode dst,
39                  TypeDescriptor type,
40                  String field,
41                  ReachSet beta,
42                  ExistPredSet preds,
43                  TaintSet taints) {
44
45     assert src  != null;
46     assert dst  != null;
47     assert type != null;
48
49     this.src     = src;
50     this.dst     = dst;
51     this.type    = type;
52     this.field   = field;
53
54     if( preds != null ) {
55       this.preds = preds;
56     } else {
57       this.preds = ExistPredSet.factory();
58     }
59
60     if( beta != null ) {
61       this.beta = beta;
62     } else {
63       this.beta = ReachSet.factory();
64     }
65
66     // when edges are not undergoing an operation that
67     // is changing beta info, betaNew is always empty
68     betaNew = ReachSet.factory();
69
70     setTaints( taints != null ? taints : TaintSet.factory() );
71   }
72
73
74   public RefEdge copy() {
75     RefEdge copy = new RefEdge(src,
76                                dst,
77                                type,
78                                field,
79                                beta,
80                                preds,
81                                taints);
82     return copy;
83   }
84
85
86   public boolean equals(Object o) {
87     if( o == null ) {
88       return false;
89     }
90
91     if( !(o instanceof RefEdge) ) {
92       return false;
93     }
94
95     RefEdge edge = (RefEdge) o;
96
97     if( !typeEquals(edge.type) ) {
98       return false;
99     }
100
101     if( !fieldEquals(edge.field) ) {
102       return false;
103     }
104
105     if( src instanceof VariableNode ) {
106       VariableNode vsrc = (VariableNode) src;
107       
108       if( !(edge.src instanceof VariableNode) ) {
109         return false;
110       }
111       
112       if( !vsrc.equals( (VariableNode) edge.src ) ) {
113         return false;
114       }
115     } else {
116       HeapRegionNode hsrc = (HeapRegionNode) src;
117
118       if( !(edge.src instanceof HeapRegionNode) ) {
119         return false;
120       }
121
122       if( !hsrc.equalsIncludingAlphaAndPreds( (HeapRegionNode) edge.src ) ) {
123         return false;
124       }
125     }
126     
127     if( !dst.equalsIncludingAlphaAndPreds( edge.dst ) ) {
128       return false;
129     }
130
131     return true;
132   }
133
134
135   // beta and preds contribute towards reaching the
136   // fixed point, so use this method to determine if
137   // an edge is "equal" to some previous visit, basically
138   // and taints!
139   public boolean equalsIncludingBetaPredsTaints(RefEdge edge) {
140     return equals(edge) &&
141            beta.equals(edge.beta) &&
142            preds.equals(edge.preds) &&
143            taints.equals(edge.taints);
144   }
145
146   public boolean equalsPreds(RefEdge edge) {
147     return preds.equals(edge.preds);
148   }
149
150
151   // this method SPECIFICALLY does not use the
152   // beta/preds/taints in the hash code--it uses
153   // the same fields as normal equals.  Again,
154   // there are two meanings of equality for edges,
155   // one is "this edge is the same edge object" like when
156   // deciding if an edge is already in a set, which
157   // is represented by this hashcode.  The other
158   // meaning is "this edge equals an edge from another
159   // graph that is abstractly the same edge"
160   public int hashCode() {
161     int hash = 0;
162
163     hash += type.hashCode()*17;
164
165     if( field != null ) {
166       hash += field.hashCode()*7;
167     }
168
169     hash += src.hashCode()*11;
170     hash += dst.hashCode();
171
172     return hash;
173   }
174
175
176   public RefSrcNode getSrc() {
177     return src;
178   }
179
180   public void setSrc(RefSrcNode rsn) {
181     assert rsn != null;
182     src = rsn;
183   }
184
185   public HeapRegionNode getDst() {
186     return dst;
187   }
188
189   public void setDst(HeapRegionNode hrn) {
190     assert hrn != null;
191     dst = hrn;
192   }
193
194
195   public TypeDescriptor getType() {
196     return type;
197   }
198
199   public void setType(TypeDescriptor td) {
200     assert td != null;
201     type = td;
202   }
203
204   public String getField() {
205     return field;
206   }
207
208   public void setField(String s) {
209     field = s;
210   }
211
212
213   public boolean typeEquals(TypeDescriptor td) {
214     return type.equals(td);
215   }
216
217   public boolean fieldEquals(String s) {
218     if( field == null && s == null ) {
219       return true;
220     }
221     if( field == null ) {
222       return false;
223     }
224     return field.equals(s);
225   }
226
227   public boolean typeAndFieldEquals(RefEdge e) {
228     return typeEquals(e.getType()  ) &&
229            fieldEquals(e.getField() );
230   }
231
232
233   public ReachSet getBeta() {
234     return beta;
235   }
236
237   public void setBeta(ReachSet beta) {
238     assert beta != null;
239     this.beta = beta;
240   }
241
242   public ReachSet getBetaNew() {
243     return betaNew;
244   }
245
246   public void setBetaNew(ReachSet beta) {
247     assert beta != null;
248     this.betaNew = beta;
249   }
250
251   public void applyBetaNew() {
252     assert betaNew != null;
253     beta    = betaNew;
254     betaNew = ReachSet.factory();
255   }
256
257
258   public ExistPredSet getPreds() {
259     return preds;
260   }
261
262   public void setPreds(ExistPredSet preds) {
263     this.preds = preds;
264   }
265
266
267   public TaintSet getTaints() {
268     return taints;
269   }
270
271   public void setTaints(TaintSet taints) {
272     this.taints = taints;
273   }
274
275
276   public String toStringDOT(boolean hideReach,
277                             boolean hideSubsetReach,
278                             boolean hidePreds,
279                             boolean hideEdgeTaints,
280                             String otherAttributes) {
281     String s =
282       "[label=\""+
283       type.toPrettyString()+"\\n"+
284       field;
285     if( !hideReach ) {
286       s += "\\n"+beta.toStringEscNewline(hideSubsetReach, hidePreds);
287     }
288
289     if( !hidePreds ) {
290       s += "\\n"+preds.toStringEscNewline();
291     }
292
293     if( !hideEdgeTaints ) {
294       if( !taints.isEmpty() ) {
295         s += "\\n"+taints.toStringEscNewline( hidePreds );
296       }
297     }
298
299     return s+"\",decorate"+otherAttributes+"]";
300   }
301
302   public String toString() {
303     return new String("("+src+
304                       "->"+type.toPrettyString()+
305                       " "+field+
306                       "->"+dst+")"
307                       );
308   }
309
310   public String toStringAndBeta() {
311     return toString()+beta.toString();
312   }
313 }