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