| 1 19 20 21 25 26 27 35 36 37 38 package soot.dava.toolkits.base.AST.structuredAnalysis; 39 40 import soot.toolkits.scalar.*; 41 import java.util.*; 42 import soot.dava.internal.AST.*; 43 import soot.dava.internal.SET.*; 44 import soot.dava.internal.javaRep.*; 45 import soot.dava.toolkits.base.AST.traversals.ClosestAbruptTargetFinder; 46 47 public class DavaFlowSet extends AbstractFlowSet{ 48 49 50 static final int DEFAULT_SIZE = 8; 51 52 int numElements; 53 int maxElements; 54 public Object [] elements; 55 56 61 HashMap breakList; 62 HashMap continueList; 63 64 68 HashMap implicitBreaks; HashMap implicitContinues; 71 public DavaFlowSet(){ 72 maxElements = DEFAULT_SIZE; 73 elements = new Object [DEFAULT_SIZE]; 74 numElements = 0; 75 breakList = new HashMap(); 76 continueList = new HashMap(); 77 implicitBreaks = new HashMap(); 78 implicitContinues = new HashMap(); 79 } 80 81 private DavaFlowSet(DavaFlowSet other){ 82 numElements = other.numElements; 83 maxElements = other.maxElements; 84 elements = (Object []) other.elements.clone(); 85 breakList = (HashMap)other.breakList.clone(); 86 continueList = (HashMap)other.continueList.clone(); 87 implicitBreaks = (HashMap)other.implicitBreaks.clone(); 88 implicitContinues = (HashMap)other.implicitContinues.clone(); 89 } 90 91 92 private boolean sameType(Object flowSet) 93 { 94 return (flowSet instanceof DavaFlowSet); 95 } 96 97 public Object clone() 98 { 99 return new DavaFlowSet(this); 100 } 101 102 public Object emptySet() 103 { 104 return new DavaFlowSet(); 105 } 106 107 public void clear() 108 { 109 numElements = 0; 110 } 111 112 public int size() 113 { 114 return numElements; 115 } 116 117 public boolean isEmpty() 118 { 119 return numElements == 0; 120 } 121 122 123 public List toList() 124 { 125 Object [] copiedElements = new Object [numElements]; 126 System.arraycopy(elements, 0, copiedElements, 0, numElements); 127 return Arrays.asList(copiedElements); 128 } 129 130 133 public void add(Object e){ 134 135 if(!contains(e)) { 137 if(numElements == maxElements) 139 doubleCapacity(); 140 elements[numElements++] = e; 141 } 142 } 143 144 private void doubleCapacity() 145 { 146 int newSize = maxElements * 2; 147 148 Object [] newElements = new Object [newSize]; 149 150 System.arraycopy(elements, 0, newElements, 0, numElements); 151 elements = newElements; 152 maxElements = newSize; 153 } 154 155 public void remove(Object obj) 156 { 157 int i = 0; 158 while (i < this.numElements) { 159 if (elements[i].equals(obj)) 160 { 161 elements[i] = elements[--numElements]; 162 return; 163 } else 164 i++; 165 } 166 } 167 168 172 private void removeElementAt(int index) 173 { 174 elements[index] = elements[--numElements]; 175 } 176 177 182 public void union(FlowSet otherFlow, FlowSet destFlow){ 183 if (sameType(otherFlow) && sameType(destFlow)) { 184 DavaFlowSet other = (DavaFlowSet) otherFlow; 185 DavaFlowSet dest = (DavaFlowSet) destFlow; 186 187 if(dest == other) 189 { 190 for(int i = 0; i < this.numElements; i++) 191 dest.add(this.elements[i]); 192 } 193 194 else { 196 if(this != dest) 197 copy(dest); 198 199 for(int i = 0; i < other.numElements; i++) 200 dest.add(other.elements[i]); 201 } 202 } else 203 super.union(otherFlow, destFlow); 204 } 205 206 207 212 public void intersection(FlowSet otherFlow, FlowSet destFlow) 213 { 214 if (sameType(otherFlow) && 215 sameType(destFlow)) { 216 DavaFlowSet other = (DavaFlowSet) otherFlow; 217 DavaFlowSet dest = (DavaFlowSet) destFlow; 218 DavaFlowSet workingSet; 219 220 if(dest == other || dest == this) 221 workingSet = new DavaFlowSet(); 222 else { 223 workingSet = dest; 224 workingSet.clear(); 225 } 226 227 for(int i = 0; i < this.numElements; i++) 228 { 229 if(other.contains(this.elements[i])) 230 workingSet.add(this.elements[i]); 231 } 232 233 if(workingSet != dest) 234 workingSet.copy(dest); 235 } else 236 super.intersection(otherFlow, destFlow); 237 } 238 239 240 241 public void difference(FlowSet otherFlow, FlowSet destFlow) 242 { 243 if (sameType(otherFlow) && 244 sameType(destFlow)) { 245 DavaFlowSet other = (DavaFlowSet) otherFlow; 246 DavaFlowSet dest = (DavaFlowSet) destFlow; 247 DavaFlowSet workingSet; 248 249 if(dest == other || dest == this) 250 workingSet = new DavaFlowSet(); 251 else { 252 workingSet = dest; 253 workingSet.clear(); 254 } 255 256 for(int i = 0; i < this.numElements; i++) 257 { 258 if(!other.contains(this.elements[i])) 259 workingSet.add(this.elements[i]); 260 } 261 262 if(workingSet != dest) 263 workingSet.copy(dest); 264 } else 265 super.difference(otherFlow, destFlow); 266 } 267 268 269 270 public boolean contains(Object obj) 271 { 272 for(int i = 0; i < numElements; i++) 273 if(elements[i].equals(obj)) 274 return true; 275 276 return false; 277 } 278 279 280 281 282 287 288 public boolean equals(Object otherFlow) 289 { 290 if (sameType(otherFlow)) { 291 DavaFlowSet other = (DavaFlowSet) otherFlow; 292 293 if(other.numElements != this.numElements) 294 return false; 295 296 int size = this.numElements; 297 298 for(int i = 0; i < size; i++) 300 if(!other.contains(this.elements[i])) 301 return false; 302 303 311 312 return true; 313 } else 314 return super.equals(otherFlow); 315 } 316 317 public void copy(FlowSet destFlow) 318 { 319 if (sameType(destFlow)) { 320 DavaFlowSet dest = (DavaFlowSet) destFlow; 321 322 while(dest.maxElements < this.maxElements) 323 dest.doubleCapacity(); 324 325 dest.numElements = this.numElements; 326 327 System.arraycopy(this.elements, 0, 328 dest.elements, 0, this.numElements); 329 } else 330 super.copy(destFlow); 331 } 332 333 334 335 338 private List addIfNotDuplicate(List into, DavaFlowSet addThis){ 339 Iterator it = into.iterator(); 341 boolean found=false; 342 while(it.hasNext()){ 343 DavaFlowSet temp = (DavaFlowSet)it.next(); 344 if(temp.equals(addThis) && temp.internalDataMatchesTo(addThis)){ 345 found=true; 346 break; 347 } 348 } 349 if(!found) 350 into.add(addThis); 351 return into; 352 } 353 354 355 359 public void addToBreakList(String labelBroken, DavaFlowSet set){ 360 Object obj = breakList.get(labelBroken); 361 if(obj == null){ 362 List labelsBreakList = new ArrayList(); 363 labelsBreakList.add(set); 364 breakList.put(labelBroken,labelsBreakList); 365 } 367 else{ 368 List labelsBreakList = (List)obj; 369 breakList.put(labelBroken,addIfNotDuplicate(labelsBreakList,set)); 371 } 372 } 373 374 375 376 377 381 public void addToContinueList(String labelContinued, DavaFlowSet set){ 382 Object obj = continueList.get(labelContinued); 383 if(obj == null){ 384 List labelsContinueList = new ArrayList(); 385 labelsContinueList.add(set); 386 continueList.put(labelContinued,labelsContinueList); 387 388 } 389 else{ 390 List labelsContinueList = (List)obj; 391 continueList.put(labelContinued,addIfNotDuplicate(labelsContinueList,set)); 392 } 393 } 394 395 396 397 401 private boolean checkImplicit(DAbruptStmt ab){ 402 SETNodeLabel label = ab.getLabel(); 403 if(label==null) 404 return true; 405 if(label.toString()==null) 406 return true; 407 return false; 408 } 409 410 417 public void addToImplicitBreaks(DAbruptStmt ab, DavaFlowSet set){ 418 if(!checkImplicit(ab)) 419 throw new RuntimeException ("Tried to add explicit break statement in the implicit list in"); 420 421 if(!ab.is_Break()) 422 throw new RuntimeException ("Tried to add continue statement in the break list in DavaFlowSet.addToImplicitBreaks"); 423 424 ASTNode node = ClosestAbruptTargetFinder.v().getTarget(ab); 427 428 Object list = implicitBreaks.get(node); 430 ArrayList listSets = null; 431 if(list == null){ 432 listSets = new ArrayList(); 433 } 434 else{ 435 listSets = (ArrayList)list; 437 } 438 439 implicitBreaks.put(node,addIfNotDuplicate(listSets,set)); 441 } 442 443 public void addToImplicitContinues(DAbruptStmt ab, DavaFlowSet set){ 444 if(!checkImplicit(ab)) 445 throw new RuntimeException ("Tried to add explicit continue statement in the implicit list "); 446 447 if(!ab.is_Continue()) 448 throw new RuntimeException ("Tried to add break statement in the continue list"); 449 450 ASTNode node = ClosestAbruptTargetFinder.v().getTarget(ab); 453 454 Object list = implicitContinues.get(node); 456 ArrayList listSets = null; 457 if(list == null){ 458 listSets = new ArrayList(); 459 } 460 else{ 461 listSets = (ArrayList)list; 463 } 464 465 implicitContinues.put(node,addIfNotDuplicate(listSets,set)); 467 } 468 469 470 471 private HashMap getBreakList(){ 472 return breakList; 473 } 474 475 private HashMap getContinueList(){ 476 return continueList; 477 } 478 479 public HashMap getImplicitBreaks(){ 480 return implicitBreaks; 481 } 482 483 public HashMap getImplicitContinues(){ 484 return implicitContinues; 485 } 486 487 488 public List getImplicitlyBrokenSets(ASTNode node){ 489 Object toReturn = implicitBreaks.get(node); 490 if(toReturn != null) 491 return (List)toReturn; 492 return null; 493 } 494 495 public List getImplicitlyContinuedSets(ASTNode node){ 496 Object toReturn = implicitContinues.get(node); 497 if(toReturn != null) 498 return (List)toReturn; 499 return null; 500 } 501 502 503 504 505 506 510 private List copyDavaFlowSetList(List currentList, List temp){ 511 Iterator tempIt = temp.iterator(); 512 while(tempIt.hasNext()){ 513 DavaFlowSet check = (DavaFlowSet)tempIt.next(); 514 Iterator currentListIt = currentList.iterator(); 515 boolean found=false; 516 while(currentListIt.hasNext()){ 517 DavaFlowSet currentSet = (DavaFlowSet)currentListIt.next(); 519 if(check.equals(currentSet) && check.internalDataMatchesTo(currentSet)){ 520 found=true; 521 break; 522 } 523 } 524 if(!found){ 525 currentList.add(check); 526 } 527 } 528 return currentList; 529 } 530 531 public void copyInternalDataFrom(Object fromThis){ 532 if(!sameType(fromThis)) 533 return; 534 535 { 537 HashMap fromThisBreakList = ((DavaFlowSet)fromThis).getBreakList(); 538 539 Iterator keys = fromThisBreakList.keySet().iterator(); 540 while(keys.hasNext()){ 541 String labelBroken = (String )keys.next(); 542 List temp = (List)fromThisBreakList.get(labelBroken); 543 544 Object list = breakList.get(labelBroken); 545 546 if(list == null){ 547 breakList.put(labelBroken,temp); 548 } 549 else{ 550 List currentList = (List)list; 551 List complete = copyDavaFlowSetList(currentList,temp); 552 breakList.put(labelBroken,complete); 553 } 554 } 555 } 556 557 558 559 560 { 562 HashMap fromThisContinueList = ((DavaFlowSet)fromThis).getContinueList(); 563 564 Iterator keys = fromThisContinueList.keySet().iterator(); 565 while(keys.hasNext()){ 566 String labelContinued = (String )keys.next(); 567 List temp = (List)fromThisContinueList.get(labelContinued); 568 569 Object list = (List)continueList.get(labelContinued); 570 if(list == null){ 571 continueList.put(labelContinued,temp); 572 } 573 else{ 574 List currentList = (List)list; 575 List complete = copyDavaFlowSetList(currentList,temp); 576 continueList.put(labelContinued,currentList); 577 } 578 } 579 } 580 581 { 584 HashMap copyThis = ((DavaFlowSet)fromThis).getImplicitBreaks(); 585 Iterator it = copyThis.keySet().iterator(); 586 while(it.hasNext()){ ASTNode node = (ASTNode)it.next(); 589 ArrayList fromDavaFlowSets = (ArrayList)copyThis.get(node); 591 593 594 Object list = implicitBreaks.get(node); 595 if(list==null){ 596 implicitBreaks.put(node,fromDavaFlowSets); 599 } 600 else{ 601 ArrayList toDavaFlowSets = (ArrayList)list; 602 List complete = copyDavaFlowSetList(toDavaFlowSets,fromDavaFlowSets); 603 implicitBreaks.put(node,complete); 604 } 605 } 606 } 607 608 { 611 HashMap copyThis = ((DavaFlowSet)fromThis).getImplicitContinues(); 612 Iterator it = copyThis.keySet().iterator(); 613 while(it.hasNext()){ ASTNode node = (ASTNode)it.next(); 616 ArrayList fromDavaFlowSets = (ArrayList)copyThis.get(node); 618 620 621 622 Object list = implicitContinues.get(node); 623 if(list==null){ 624 implicitContinues.put(node,fromDavaFlowSets); 627 } 628 else{ 629 ArrayList toDavaFlowSets = (ArrayList)list; 630 List complete = copyDavaFlowSetList(toDavaFlowSets,fromDavaFlowSets); 631 implicitContinues.put(node,complete); 632 } 633 } 634 635 } 636 637 } 638 639 private boolean compareLists(Object One , Object Two){ 640 if(One==null && Two == null) 641 return true; 642 643 if(One == null || Two == null) 644 return false; 645 646 List listOne = (List)One; 647 List listTwo = (List)Two; 648 649 if(listOne.size()!= listTwo.size()){ 651 return false; 653 } 654 Iterator listOneIt = listOne.iterator(); 655 boolean found=false; 656 while(listOneIt.hasNext()){ 657 Object listOneObj = listOneIt.next(); 659 660 661 Iterator listTwoIt = listTwo.iterator(); 662 while(listTwoIt.hasNext()){ 663 Object listTwoObj = listTwoIt.next(); 665 if(listOneObj.equals(listTwoObj)){ 666 found=true; 668 break; 669 } 670 } 671 if(!found){ 672 return false; 674 } 675 found=false; 676 } 677 return true; 678 } 679 680 public boolean internalDataMatchesTo(Object otherObj){ 681 if(!(otherObj instanceof DavaFlowSet)) 682 return false; 683 684 DavaFlowSet other = (DavaFlowSet)otherObj; 685 686 HashMap otherMap = other.getBreakList(); 688 if( ! compareHashMaps(breakList,otherMap) ) 689 return false; 690 691 692 otherMap = other.getContinueList(); 694 if( ! compareHashMaps(continueList,otherMap) ) 695 return false; 696 697 698 otherMap = other.getImplicitBreaks(); 700 if( ! compareHashMaps(implicitBreaks,otherMap) ) 701 return false; 702 703 otherMap = other.getImplicitContinues(); 705 if( ! compareHashMaps(implicitContinues,otherMap) ) 706 return false; 707 708 return true; 709 } 710 711 712 private boolean compareHashMaps(HashMap thisMap,HashMap otherMap){ 713 List otherKeyList = new ArrayList(); 714 715 Iterator keys = otherMap.keySet().iterator(); 716 while(keys.hasNext()){ 717 String otherKey = (String )keys.next(); 718 otherKeyList.add(otherKey); 719 720 Object listOther = otherMap.get(otherKey); 721 Object listThis = thisMap.get(otherKey); 722 723 if(!compareLists(listOther,listThis)){ 725 return false; 727 } 728 } 729 731 keys = thisMap.keySet().iterator(); 733 while(keys.hasNext()){ 734 String key = (String )keys.next(); 735 736 Iterator keyListIt = otherKeyList.iterator(); 737 boolean alreadyDone=false; 738 739 while(keyListIt.hasNext()){ 740 String doneKey = (String )keyListIt.next(); 741 if(key.equals(doneKey)){ 742 alreadyDone=true; 743 break; 744 } 745 } 746 if(!alreadyDone){ 747 752 return false; 753 } 754 } 755 return true; 756 } 757 758 759 public List getContinueSet(String label){ 760 return (List)continueList.remove(label); 761 } 762 763 764 public List getBreakSet(String label){ 765 return (List)breakList.remove(label); 766 } 767 768 769 770 public String toString(){ 771 StringBuffer b = new StringBuffer (); 772 b.append(" SET={"); 773 for(int i = 0; i < this.numElements; i++){ 774 if(i!=0) 775 b.append(" , "); 776 777 b.append(this.elements[i].toString()); 778 } 779 b.append(" }"); 780 return b.toString(); 781 } 782 783 784 785 786 804 } 805 | Popular Tags |