1 19 20 package soot.jimple.spark.internal; 21 import soot.jimple.spark.*; 22 import soot.jimple.spark.pag.*; 23 import soot.*; 24 import soot.util.*; 25 import java.util.Iterator ; 26 import soot.util.queue.*; 27 import soot.Type; 28 import soot.options.SparkOptions; 29 30 33 public final class TypeManager { 34 public TypeManager( PAG pag ) { 35 this.pag = pag; 36 } 37 public static boolean isUnresolved(Type type) { 38 if( !(type instanceof RefType) ) return false; 39 RefType rt = (RefType) type; 40 if( !rt.hasSootClass() ) return true; 41 SootClass cl = rt.getSootClass(); 42 return cl.resolvingLevel() < SootClass.HIERARCHY; 43 } 44 final public BitVector get( Type type ) { 45 if( type == null ) return null; 46 while(allocNodeListener.hasNext()) { 47 AllocNode n = (AllocNode) allocNodeListener.next(); 48 for( Iterator tIt = Scene.v().getTypeNumberer().iterator(); tIt.hasNext(); ) { 49 final Type t = (Type) tIt.next(); 50 if( !(t instanceof RefLikeType) ) continue; 51 if( t instanceof AnySubType ) continue; 52 if( isUnresolved(t) ) continue; 53 if( castNeverFails( n.getType(), t ) ) { 54 BitVector mask = (BitVector) typeMask.get( t ); 55 if( mask == null ) { 56 typeMask.put( t, mask = new BitVector() ); 57 for( Iterator anIt = pag.getAllocNodeNumberer().iterator(); anIt.hasNext(); ) { 58 final AllocNode an = (AllocNode) anIt.next(); 59 if( castNeverFails( an.getType(), t ) ) { 60 mask.set( an.getNumber() ); 61 } 62 } 63 continue; 64 } 65 mask.set( n.getNumber() ); 66 } 67 } 68 } 69 BitVector ret = (BitVector) typeMask.get( type ); 70 if( ret == null && fh != null ) throw new RuntimeException ( "oops"+type ); 71 return ret; 72 } 73 final public void clearTypeMask() { 74 typeMask = null; 75 } 76 final public void makeTypeMask() { 77 RefType.v( "java.lang.Class" ); 78 typeMask = new LargeNumberedMap( Scene.v().getTypeNumberer() ); 79 if( fh == null ) return; 80 81 int numTypes = Scene.v().getTypeNumberer().size(); 82 if( pag.getOpts().verbose() ) 83 G.v().out.println( "Total types: "+numTypes ); 84 85 ArrayNumberer allocNodes = pag.getAllocNodeNumberer(); 86 for( Iterator tIt = Scene.v().getTypeNumberer().iterator(); tIt.hasNext(); ) { 87 final Type t = (Type) tIt.next(); 88 if( !(t instanceof RefLikeType) ) continue; 89 if( t instanceof AnySubType ) continue; 90 if( isUnresolved(t) ) continue; 91 BitVector mask = new BitVector( allocNodes.size() ); 92 for( Iterator nIt = allocNodes.iterator(); nIt.hasNext(); ) { 93 final Node n = (Node) nIt.next(); 94 if( castNeverFails( n.getType(), t ) ) { 95 mask.set( n.getNumber() ); 96 } 97 } 98 typeMask.put( t, mask ); 99 } 100 101 allocNodeListener = pag.allocNodeListener(); 102 } 103 104 private LargeNumberedMap typeMask = null; 105 final public boolean castNeverFails( Type src, Type dst ) { 106 if( fh == null ) return true; 107 if( dst == null ) return true; 108 if( dst == src ) return true; 109 if( src == null ) return false; 110 if( dst.equals( src ) ) return true; 111 if( src instanceof NullType ) return true; 112 if( src instanceof AnySubType ) return true; 113 if( dst instanceof NullType ) return false; 114 if( dst instanceof AnySubType ) throw new RuntimeException ( "oops SRC="+src+" dst="+dst ); 115 return fh.canStoreType( src, dst ); 116 } 117 public void setFastHierarchy( FastHierarchy fh ) { this.fh = fh; } 118 public FastHierarchy getFastHierarchy() { return fh; } 119 120 protected FastHierarchy fh = null; 121 protected PAG pag; 122 protected QueueReader allocNodeListener = null; 123 } 124 125 | Popular Tags |