porting effects analysis to new disjoint analysis
[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 paramTaints;
33   protected TaintSet rblockTaints;
34
35   
36   public RefEdge( RefSrcNode     src,
37                   HeapRegionNode dst,
38                   TypeDescriptor type,
39                   String         field,
40                   ReachSet       beta,
41                   ExistPredSet   preds,
42                   TaintSet       paramTaints,
43                   TaintSet       rblockTaints ) {
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     if( paramTaints != null ) {
71       this.paramTaints = paramTaints;
72     } else {
73       this.paramTaints = TaintSet.factory();
74     }
75
76     if( rblockTaints != null ) {
77       this.rblockTaints = rblockTaints;
78     } else {
79       this.rblockTaints = TaintSet.factory();
80     }
81   }
82
83
84   public RefEdge copy() {
85     RefEdge copy = new RefEdge( src,
86                                 dst,
87                                 type,
88                                 field,
89                                 beta,
90                                 preds,
91                                 paramTaints,
92                                 rblockTaints );
93     return copy;
94   }
95
96
97   public boolean equals( Object o ) {
98     if( o == null ) {
99       return false;
100     }
101
102     if( !(o instanceof RefEdge) ) {
103       return false;
104     }
105     
106     RefEdge edge = (RefEdge) o;
107     
108     if( !typeEquals( edge.type ) ) {
109       return false;
110     }
111
112     if( !fieldEquals( edge.field ) ) {
113       return false;
114     }
115
116     // Equality of edges is only valid within a graph, so
117     // compare src and dst by reference
118     if( !(src == edge.src) ||
119         !(dst == edge.dst)   ) {
120       return false;
121     }
122
123     return true;
124   }
125
126
127   // beta and preds contribute towards reaching the
128   // fixed point, so use this method to determine if
129   // an edge is "equal" to some previous visit, basically
130   // AND EDGE TAINTS!
131   public boolean equalsIncludingBetaPredsTaints( RefEdge edge ) {
132     return equals( edge ) && 
133       beta.equals( edge.beta ) &&
134       preds.equals( edge.preds ) &&
135       paramTaints.equals( edge.paramTaints ) &&
136       rblockTaints.equals( edge.rblockTaints );
137   }
138
139   public boolean equalsPreds( RefEdge edge ) {
140     return preds.equals( edge.preds );
141   }
142
143
144   // this method SPECIFICALLY does not use the
145   // beta/preds/taints in the hash code--it uses
146   // the same fields as normal equals.  Again,
147   // there are two meanings of equality for edges,
148   // one is "this edge is the same edge object" like when
149   // deciding if an edge is already in a set, which
150   // is represented by this hashcode.  The other
151   // meaning is "this edge equals an edge from another
152   // graph that is abstractly the same edge"
153   public int hashCode() {
154     int hash = 0;
155
156     hash += type.hashCode()*17;
157
158     if( field != null ) {
159       hash += field.hashCode()*7;
160     }
161     
162     hash += src.hashCode()*11;
163     hash += dst.hashCode();
164
165     return hash;
166   }
167
168
169   public RefSrcNode getSrc() {
170     return src;
171   }
172
173   public void setSrc( RefSrcNode rsn ) {
174     assert rsn != null;
175     src = rsn;
176   }
177
178   public HeapRegionNode getDst() {
179     return dst;
180   }
181
182   public void setDst( HeapRegionNode hrn ) {
183     assert hrn != null;
184     dst = hrn;
185   }
186
187
188   public TypeDescriptor getType() {
189     return type;
190   }
191
192   public void setType( TypeDescriptor td ) {
193     assert td != null;
194     type = td;
195   }
196
197   public String getField() {
198     return field;
199   }
200
201   public void setField( String s ) {
202     field = s;
203   }
204
205
206   public boolean typeEquals( TypeDescriptor td ) {
207     return type.equals( td );
208   }
209
210   public boolean fieldEquals( String s ) {
211     if( field == null && s == null ) {
212       return true;
213     }
214     if( field == null ) {
215       return false;
216     }
217     return field.equals( s );
218   }
219
220   public boolean typeAndFieldEquals( RefEdge e ) {
221     return typeEquals ( e.getType()  ) &&
222            fieldEquals( e.getField() );
223   }
224
225
226   public ReachSet getBeta() {
227     return beta;
228   }
229
230   public void setBeta( ReachSet beta ) {
231     assert beta != null;
232     this.beta = beta;
233   }
234
235   public ReachSet getBetaNew() {
236     return betaNew;
237   }
238
239   public void setBetaNew( ReachSet beta ) {
240     assert beta != null;
241     this.betaNew = beta;
242   }
243   
244   public void applyBetaNew() {
245     assert betaNew != null;
246     beta    = betaNew;
247     betaNew = ReachSet.factory();
248   }
249
250
251   public ExistPredSet getPreds() {
252     return preds;
253   }
254
255   public void setPreds( ExistPredSet preds ) {
256     this.preds = preds;
257   }
258
259
260   public TaintSet getParamTaints() {
261     return paramTaints;
262   }
263
264   public TaintSet getRblockTaints() {
265     return rblockTaints;
266   }
267
268  
269
270   public String toStringDOT( boolean hideReach,
271                              boolean hideSubsetReach,
272                              boolean hidePreds,
273                              boolean hideEdgeTaints,
274                              String  otherAttributes ) {
275     String s = 
276       "[label=\""+
277       type.toPrettyString()+"\\n"+
278       field;
279     if( !hideReach ) {
280       s += "\\n"+beta.toStringEscNewline( hideSubsetReach );
281     }
282
283     if( !hidePreds ) {
284       s += "\\n"+preds.toStringEscNewline();
285     }
286
287     if( !hideEdgeTaints ) {      
288       if( !paramTaints.isEmpty() ) {
289         s += "\\npt: "+paramTaints.toString();
290       }
291
292       if( !rblockTaints.isEmpty() ) {
293         s += "\\nrt: "+rblockTaints.toString();
294       }
295     }
296
297     return s+"\",decorate"+otherAttributes+"]";
298   }
299
300   public String toString() {
301     return new String( "("+src+
302                        "->"+type.toPrettyString()+
303                        " "+field+
304                        "->"+dst+")"
305                        );
306   }  
307
308   public String toStringAndBeta() {
309     return toString()+beta.toString();
310   }
311 }