1 21 package proguard.evaluation; 22 23 import proguard.evaluation.value.*; 24 25 32 public class Variables 33 { 34 private static final TopValue TOP_VALUE = new TopValue(); 35 36 37 protected Value[] values; 38 protected int size; 39 40 41 44 public Variables(int size) 45 { 46 this.values = new Value[size]; 47 this.size = size; 48 } 49 50 51 54 public Variables(Variables variables) 55 { 56 this(variables.size); 58 59 initialize(variables); 61 } 62 63 64 67 public void reset(int size) 68 { 69 if (size > values.length) 71 { 72 values = new Value[size]; 74 } 75 else 76 { 77 for (int index = 0; index < values.length; index++) 79 { 80 values[index] = null; 81 } 82 } 83 84 this.size = size; 85 } 86 87 88 93 public void initialize(Variables other) 94 { 95 if (this.size < other.size) 96 { 97 throw new IllegalArgumentException ("Variable frame is too small ["+this.size+"] compared to other frame ["+other.size+"]"); 98 } 99 100 System.arraycopy(other.values, 0, this.values, 0, other.size); 102 } 103 104 105 113 public boolean generalize(Variables other, 114 boolean clearConflictingOtherVariables) 115 { 116 if (this.size != other.size) 117 { 118 throw new IllegalArgumentException ("Variable frames have different sizes ["+this.size+"] and ["+other.size+"]"); 119 } 120 121 boolean changed = false; 122 123 for (int index = 0; index < size; index++) 124 { 125 Value thisValue = this.values[index]; 126 Value otherValue = other.values[index]; 127 128 if (thisValue != null && 134 otherValue != null && 135 thisValue.computationalType() == otherValue.computationalType()) 136 { 137 Value newValue = thisValue.generalize(otherValue); 138 139 changed = changed || !thisValue.equals(newValue); 140 141 this.values[index] = newValue; 142 } 143 else 144 { 145 changed = changed || thisValue != null; 146 147 this.values[index] = null; 148 149 if (clearConflictingOtherVariables) 150 { 151 other.values[index] = null; 152 } 153 } 154 } 155 156 return changed; 157 } 158 159 160 163 public int size() 164 { 165 return size; 166 } 167 168 169 172 public Value getValue(int index) 173 { 174 if (index < 0 || 175 index >= size) 176 { 177 throw new IndexOutOfBoundsException ("Variable index ["+index+"] out of bounds ["+size+"]"); 178 } 179 180 return values[index]; 181 } 182 183 184 187 public void store(int index, Value value) 188 { 189 if (index < 0 || 190 index >= size) 191 { 192 throw new IndexOutOfBoundsException ("Variable index ["+index+"] out of bounds ["+size+"]"); 193 } 194 195 values[index] = value; 197 198 if (value.isCategory2()) 200 { 201 values[index + 1] = TOP_VALUE; 202 } 203 } 204 205 206 209 public Value load(int index) 210 { 211 if (index < 0 || 212 index >= size) 213 { 214 throw new IndexOutOfBoundsException ("Variable index ["+index+"] out of bounds ["+size+"]"); 215 } 216 217 return values[index]; 218 } 219 220 221 223 226 public IntegerValue iload(int index) 227 { 228 return load(index).integerValue(); 229 } 230 231 232 235 public LongValue lload(int index) 236 { 237 return load(index).longValue(); 238 } 239 240 241 244 public FloatValue fload(int index) 245 { 246 return load(index).floatValue(); 247 } 248 249 250 253 public DoubleValue dload(int index) 254 { 255 return load(index).doubleValue(); 256 } 257 258 259 262 public ReferenceValue aload(int index) 263 { 264 return load(index).referenceValue(); 265 } 266 267 268 271 public InstructionOffsetValue oload(int index) 272 { 273 return load(index).instructionOffsetValue(); 274 } 275 276 277 279 public boolean equals(Object object) 280 { 281 if (object == null || 282 this.getClass() != object.getClass()) 283 { 284 return false; 285 } 286 287 Variables other = (Variables)object; 288 289 if (this.size != other.size) 290 { 291 return false; 292 } 293 294 for (int index = 0; index < size; index++) 295 { 296 Value thisValue = this.values[index]; 297 Value otherValue = other.values[index]; 298 299 if (thisValue != null && 305 otherValue != null && 306 thisValue.computationalType() == otherValue.computationalType() && 307 !thisValue.equals(otherValue)) 308 { 309 return false; 310 } 311 } 312 313 return true; 314 } 315 316 317 public int hashCode() 318 { 319 int hashCode = size; 320 321 for (int index = 0; index < size; index++) 322 { 323 Value value = values[index]; 324 if (value != null) 325 { 326 hashCode ^= value.hashCode(); 327 } 328 } 329 330 return hashCode; 331 } 332 333 334 public String toString() 335 { 336 StringBuffer buffer = new StringBuffer (); 337 338 for (int index = 0; index < size; index++) 339 { 340 Value value = values[index]; 341 buffer = buffer.append('[') 342 .append(value == null ? "empty" : value.toString()) 343 .append(']'); 344 } 345 346 return buffer.toString(); 347 } 348 } 349
| Popular Tags
|