1 19 20 package soot.jimple.toolkits.pointer; 21 import java.util.*; 22 import soot.*; 23 24 25 public class MethodRWSet extends RWSet { 26 public Set globals; 27 public Map fields; 28 protected boolean callsNative = false; 29 protected boolean isFull = false; 30 public static final int MAX_SIZE = Integer.MAX_VALUE; 31 32 public String toString() { 33 boolean empty = true; 34 StringBuffer ret = new StringBuffer (); 35 if( fields != null ) { 36 for( Iterator fieldIt = fields.keySet().iterator(); fieldIt.hasNext(); ) { 37 final Object field = (Object ) fieldIt.next(); 38 ret.append( "[Field: "+field+" "+fields.get(field)+"]\n" ); 39 empty = false; 40 } 41 } 42 if( globals != null ) { 43 for( Iterator globalIt = globals.iterator(); globalIt.hasNext(); ) { 44 final Object global = (Object ) globalIt.next(); 45 ret.append( "[Global: "+global+"]\n" ); 46 empty = false; 47 } 48 } 49 if(empty) ret.append("empty"); 50 return ret.toString(); 51 } 52 53 public MethodRWSet() { 55 61 } 62 public boolean getCallsNative() { 63 return callsNative; 64 } 65 66 public boolean setCallsNative() { 67 boolean ret = !callsNative; 68 callsNative = true; 69 return ret; 70 } 71 72 73 public Set getGlobals() { 74 if( isFull ) return G.v().MethodRWSet_allGlobals; 75 if( globals == null ) return Collections.EMPTY_SET; 76 return globals; 77 } 78 79 80 public Set getFields() { 81 if( isFull ) return G.v().MethodRWSet_allFields; 82 if( fields == null ) return Collections.EMPTY_SET; 83 return fields.keySet(); 84 } 85 86 87 public PointsToSet getBaseForField( Object f ) { 88 if( isFull ) return FullObjectSet.v(); 89 if( fields == null ) return null; 90 return (PointsToSet) fields.get( f ); 91 } 92 93 public boolean hasNonEmptyIntersection( RWSet oth ) { 94 if( isFull ) return oth != null; 95 if( !(oth instanceof MethodRWSet) ) { 96 return oth.hasNonEmptyIntersection( this ); 97 } 98 MethodRWSet other = (MethodRWSet) oth; 99 if( globals != null && other.globals != null 100 && !globals.isEmpty() && !other.globals.isEmpty() ) { 101 for( Iterator it = other.globals.iterator(); it.hasNext(); ) { 102 if( globals.contains( it.next() ) ) return true; 103 } 104 } 105 if( fields != null && other.fields != null 106 && !fields.isEmpty() && !other.fields.isEmpty() ) { 107 for( Iterator fieldIt = other.fields.keySet().iterator(); fieldIt.hasNext(); ) { 108 final Object field = (Object ) fieldIt.next(); 109 if( fields.containsKey( field ) ) { 110 if( Union.hasNonEmptyIntersection( 111 getBaseForField( field ), 112 other.getBaseForField( field ) ) ) { 113 return true; 114 } 115 } 116 } 117 } 118 return false; 119 } 120 121 122 public boolean union( RWSet other ) { 123 if( other == null ) return false; 124 if( isFull ) return false; 125 boolean ret = false; 126 if( other instanceof MethodRWSet ) { 127 MethodRWSet o = (MethodRWSet) other; 128 if( o.getCallsNative() ) { 129 ret = !getCallsNative() | ret; 130 setCallsNative(); 131 } 132 if( o.isFull ) { 133 ret = !isFull | ret; 134 isFull = true; 135 if( true ) throw new RuntimeException ( "attempt to add full set "+o+" into "+this ); 136 globals = null; 137 fields = null; 138 return ret; 139 } 140 if( o.globals != null ) { 141 if( globals == null ) globals = new HashSet(); 142 ret = globals.addAll( o.globals ) | ret; 143 if( globals.size() > MAX_SIZE ) { 144 globals = null; 145 isFull = true; 146 throw new RuntimeException ( "attempt to add full set "+o+" into "+this ); 147 } 148 } 149 if( o.fields != null ) { 150 for( Iterator fieldIt = o.fields.keySet().iterator(); fieldIt.hasNext(); ) { 151 final Object field = (Object ) fieldIt.next(); 152 PointsToSet os = o.getBaseForField( field ); 153 ret = addFieldRef( os, field ) | ret; 154 } 155 } 156 } else { 157 StmtRWSet oth = (StmtRWSet) other; 158 if( oth.base != null ) { 159 ret = addFieldRef( oth.base, oth.field ) | ret; 160 } else if( oth.field != null ) { 161 ret = addGlobal( (SootField) oth.field ) | ret; 162 } 163 } 164 if( !getCallsNative() && other.getCallsNative() ) { 165 setCallsNative(); 166 return true; 167 } 168 return ret; 169 } 170 171 public boolean addGlobal( SootField global ) { 172 if( globals == null ) globals = new HashSet(); 173 boolean ret = globals.add( global ); 174 if( globals.size() > MAX_SIZE ) { 175 globals = null; 176 isFull = true; 177 throw new RuntimeException ( "attempt to add more than "+MAX_SIZE+" globals into "+this ); 178 } 179 return ret; 180 } 181 public boolean addFieldRef( PointsToSet otherBase, Object field ) { 182 boolean ret = false; 183 if( fields == null ) fields = new HashMap(); 184 PointsToSet base = getBaseForField( field ); 185 if( base instanceof FullObjectSet ) return false; 186 if( otherBase instanceof FullObjectSet ) { 187 fields.put( field, otherBase ); 188 return true; 189 } 190 if( otherBase.equals( base ) ) return false; 191 Union u; 192 if( base == null || !(base instanceof Union) ) { 193 u = G.v().Union_factory.newUnion(); 194 if( base != null) u.addAll( base ); 195 fields.put( field, u ); 196 if( base == null ) addedField( fields.size() ); 197 ret = true; 198 if( fields.keySet().size() > MAX_SIZE ) { 199 fields = null; 200 isFull = true; 201 if( true ) throw new RuntimeException ( "attempt to add more than "+MAX_SIZE+" fields into "+this ); 202 return true; 203 } 204 } else { 205 u = (Union) base; 206 } 207 ret = u.addAll( otherBase ) | ret; 208 return ret; 209 } 210 static void addedField( int size ) { 211 } 212 public boolean isEquivTo( RWSet other ) { 213 return other == this; 214 } 215 } 216 | Popular Tags |