1 package Analysis.SSJava;
3 import java.util.HashSet;
4 import java.util.Hashtable;
5 import java.util.Iterator;
8 import Analysis.Loops.LoopFinder;
9 import Analysis.Loops.Loops;
10 import IR.ClassDescriptor;
12 import IR.FieldDescriptor;
13 import IR.MethodDescriptor;
16 import IR.SymbolTable;
17 import IR.VarDescriptor;
19 import IR.Flat.FlatFieldNode;
20 import IR.Flat.FlatLiteralNode;
21 import IR.Flat.FlatMethod;
22 import IR.Flat.FlatNode;
23 import IR.Flat.FlatOpNode;
24 import IR.Flat.FlatSetFieldNode;
25 import IR.Flat.TempDescriptor;
27 public class DefinitelyWrittenCheck {
32 private Hashtable<FlatNode, Hashtable<Descriptor, Hashtable<FlatNode, Boolean>>> definitelyWrittenResults;
34 public DefinitelyWrittenCheck(State state) {
36 this.toanalyze = new HashSet();
37 this.definitelyWrittenResults =
38 new Hashtable<FlatNode, Hashtable<Descriptor, Hashtable<FlatNode, Boolean>>>();
41 public void definitelyWrittenCheck() {
43 SymbolTable classtable = state.getClassSymbolTable();
44 toanalyze.addAll(classtable.getValueSet());
45 toanalyze.addAll(state.getTaskSymbolTable().getValueSet());
46 while (!toanalyze.isEmpty()) {
47 Object obj = toanalyze.iterator().next();
48 ClassDescriptor cd = (ClassDescriptor) obj;
51 // if (cd.isClassLibrary()) {
52 // doesn't care about class libraries now
55 for (Iterator method_it = cd.getMethods(); method_it.hasNext(); ) {
56 MethodDescriptor md = (MethodDescriptor) method_it.next();
57 FlatMethod fm = state.getMethodFlat(md);
69 SymbolTable classtable = state.getClassSymbolTable();
70 toanalyze.addAll(classtable.getValueSet());
71 toanalyze.addAll(state.getTaskSymbolTable().getValueSet());
72 while (!toanalyze.isEmpty()) {
73 Object obj = toanalyze.iterator().next();
74 ClassDescriptor cd = (ClassDescriptor) obj;
77 if (cd.isClassLibrary()) {
78 // doesn't care about class libraries now
81 for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
82 MethodDescriptor md = (MethodDescriptor) method_it.next();
83 FlatMethod fm = state.getMethodFlat(md);
85 LoopFinder loopFinder = new LoopFinder(fm);
86 Loops loops = loopFinder.getRootloop(fm);
87 Set loopSet = loops.nestedLoops();
89 for (Iterator iterator = loopSet.iterator(); iterator.hasNext();) {
90 Loops rootLoops = (Loops) iterator.next();
91 Set loopEntranceSet = rootLoops.loopEntrances();
92 for (Iterator iterator2 = loopEntranceSet.iterator(); iterator2.hasNext();) {
93 FlatNode loopEnter = (FlatNode) iterator2.next();
94 String flatNodeLabel = (String) state.fn2labelMap.get(loopEnter);
95 if (flatNodeLabel != null && flatNodeLabel.equals("ssjava")) {
96 System.out.println("encounting ss loop:" + loopEnter);
97 definitelyWrittenForward(loopEnter);
106 // check if there is a read statement with flag=TRUE
107 toanalyze.addAll(classtable.getValueSet());
108 toanalyze.addAll(state.getTaskSymbolTable().getValueSet());
109 while (!toanalyze.isEmpty()) {
110 Object obj = toanalyze.iterator().next();
111 ClassDescriptor cd = (ClassDescriptor) obj;
112 toanalyze.remove(cd);
113 if (cd.isClassLibrary()) {
114 // doesn't care about class libraries now
117 for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
118 MethodDescriptor md = (MethodDescriptor) method_it.next();
119 FlatMethod fm = state.getMethodFlat(md);
123 System.out.println("Error in " + md);
135 private void checkMethodBody(FlatMethod fm) {
137 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
138 Set<FlatNode> visited = new HashSet<FlatNode>();
139 flatNodesToVisit.add(fm);
141 while (!flatNodesToVisit.isEmpty()) {
142 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
144 flatNodesToVisit.remove(fn);
146 checkMethodBody_nodeAction(fn);
148 // if a new result, schedule forward nodes for analysis
149 for (int i = 0; i < fn.numNext(); i++) {
150 FlatNode nn = fn.getNext(i);
151 if (!visited.contains(nn)) {
152 flatNodesToVisit.add(nn);
159 private void checkMethodBody_nodeAction(FlatNode fn) {
167 case FKind.FlatOpNode: {
169 FlatOpNode fon = (FlatOpNode) fn;
170 if (fon.getOp().getOp() == Operation.ASSIGN) {
174 Hashtable<Descriptor, Hashtable<FlatNode, Boolean>> map = definitelyWrittenResults.get(fn);
176 if (map.get(rhs).get(fn).booleanValue()) {
177 // throw new Error("variable " + rhs
179 // " was not overwritten in-between the same read statement by the out-most loop.");
188 case FKind.FlatFieldNode: {
190 FlatFieldNode ffn = (FlatFieldNode) fn;
193 fld = ffn.getField();
198 case FKind.FlatElementNode: {
203 case FKind.FlatSetFieldNode: {
207 case FKind.FlatSetElementNode: {
212 case FKind.FlatCall: {
221 private void definitelyWrittenForward(FlatNode entrance) {
223 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
224 flatNodesToVisit.add(entrance);
226 while (!flatNodesToVisit.isEmpty()) {
227 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
228 flatNodesToVisit.remove(fn);
230 Hashtable<Descriptor, Hashtable<FlatNode, Boolean>> prev = definitelyWrittenResults.get(fn);
232 Hashtable<Descriptor, Hashtable<FlatNode, Boolean>> curr =
233 new Hashtable<Descriptor, Hashtable<FlatNode, Boolean>>();
234 for (int i = 0; i < fn.numPrev(); i++) {
235 FlatNode nn = fn.getPrev(i);
236 Hashtable<Descriptor, Hashtable<FlatNode, Boolean>> dwIn = definitelyWrittenResults.get(nn);
238 mergeResults(curr, dwIn);
242 definitelyWritten_nodeActions(fn, curr, entrance);
244 // if a new result, schedule forward nodes for analysis
245 if (!curr.equals(prev)) {
246 definitelyWrittenResults.put(fn, curr);
248 for (int i = 0; i < fn.numNext(); i++) {
249 FlatNode nn = fn.getNext(i);
250 flatNodesToVisit.add(nn);
256 private void mergeResults(Hashtable<Descriptor, Hashtable<FlatNode, Boolean>> curr,
257 Hashtable<Descriptor, Hashtable<FlatNode, Boolean>> in) {
259 Set<Descriptor> inKeySet = in.keySet();
260 for (Iterator iterator = inKeySet.iterator(); iterator.hasNext(); ) {
261 Descriptor inKey = (Descriptor) iterator.next();
262 Hashtable<FlatNode, Boolean> inPair = in.get(inKey);
264 Set<FlatNode> pairKeySet = inPair.keySet();
265 for (Iterator iterator2 = pairKeySet.iterator(); iterator2.hasNext(); ) {
266 FlatNode pairKey = (FlatNode) iterator2.next();
267 Boolean inFlag = inPair.get(pairKey);
269 Hashtable<FlatNode, Boolean> currPair = curr.get(inKey);
270 if (currPair == null) {
271 currPair = new Hashtable<FlatNode, Boolean>();
272 curr.put(inKey, currPair);
275 Boolean currFlag = currPair.get(pairKey);
276 // by default, flag is set by false
277 if (currFlag == null) {
278 currFlag = Boolean.FALSE;
280 currFlag = Boolean.valueOf(inFlag.booleanValue() | currFlag.booleanValue());
281 currPair.put(pairKey, currFlag);
288 private void definitelyWritten_nodeActions(FlatNode fn,
289 Hashtable<Descriptor, Hashtable<FlatNode, Boolean>> curr, FlatNode entrance) {
291 if (fn == entrance) {
293 Set<Descriptor> keySet = curr.keySet();
294 for (Iterator iterator = keySet.iterator(); iterator.hasNext(); ) {
295 Descriptor key = (Descriptor) iterator.next();
296 Hashtable<FlatNode, Boolean> pair = curr.get(key);
298 Set<FlatNode> pairKeySet = pair.keySet();
299 for (Iterator iterator2 = pairKeySet.iterator(); iterator2.hasNext(); ) {
300 FlatNode pairKey = (FlatNode) iterator2.next();
301 pair.put(pairKey, Boolean.TRUE);
313 case FKind.FlatOpNode: {
315 FlatOpNode fon = (FlatOpNode) fn;
318 System.out.println("\nfon=" + fon);
320 if (fon.getOp().getOp() == Operation.ASSIGN) {
323 Hashtable<FlatNode, Boolean> gen = curr.get(rhs);
325 gen = new Hashtable<FlatNode, Boolean>();
328 System.out.println("READ LOC=" + rhs.getType().getExtension());
330 Boolean currentStatus = gen.get(fn);
331 if (currentStatus == null) {
332 gen.put(fn, Boolean.FALSE);
336 curr.put(lhs, new Hashtable<FlatNode, Boolean>());
337 System.out.println("WRITING LOC=" + lhs.getType().getExtension());
342 case FKind.FlatLiteralNode: {
343 FlatLiteralNode fln = (FlatLiteralNode) fn;
347 curr.put(lhs, new Hashtable<FlatNode, Boolean>());
349 System.out.println("WRITING LOC=" + lhs.getType().getExtension());
354 case FKind.FlatFieldNode:
355 case FKind.FlatElementNode: {
357 FlatFieldNode ffn = (FlatFieldNode) fn;
359 fld = ffn.getField();
362 Hashtable<FlatNode, Boolean> gen = curr.get(fld);
364 gen = new Hashtable<FlatNode, Boolean>();
367 Boolean currentStatus = gen.get(fn);
368 if (currentStatus == null) {
369 gen.put(fn, Boolean.FALSE);
372 System.out.println("\nffn=" + ffn);
373 System.out.println("READ LOCfld=" + fld.getType().getExtension());
374 System.out.println("READ LOClhs=" + lhs.getType().getExtension());
379 case FKind.FlatSetFieldNode:
380 case FKind.FlatSetElementNode: {
382 FlatSetFieldNode fsfn = (FlatSetFieldNode) fn;
383 fld = fsfn.getField();
386 curr.put(fld, new Hashtable<FlatNode, Boolean>());
388 System.out.println("\nfsfn=" + fsfn);
389 System.out.println("WRITELOC LOC=" + fld.getType().getExtension());
394 case FKind.FlatCall: {