1 18 19 package org.objectweb.jac.core.translators; 20 21 import java.io.Serializable ; 22 import java.util.Arrays ; 23 import java.util.HashSet ; 24 import java.util.Set ; 25 import java.util.Vector ; 26 import org.apache.bcel.classfile.*; 27 import org.apache.bcel.generic.*; 28 import org.apache.log4j.Logger; 29 import org.objectweb.jac.util.Stack; 30 31 34 public class VMStack extends Stack { 35 static Logger logger = Logger.getLogger("translator.bytecode"); 36 37 public static final ThisPointer thisPointer = new ThisPointer(); 38 public static final DontCare dontCare = new DontCare(); 39 40 static final int UNPREDICTABLE = -1; 41 static final int UNDEFINED = -2; 42 43 Vector locals = new Vector (); 45 ConstantPoolGen cp; 46 int[] exceptionHandlers; 47 int currentHandler = 0; 48 int nbArgs; 49 int localsOffest; 50 boolean isStatic; 51 public VMStack(ConstantPoolGen cp, Code code, int nbArgs, boolean isStatic) { 52 this.cp = cp; 53 this.nbArgs = nbArgs; 54 this.isStatic = isStatic; 55 this.localsOffest = nbArgs+(isStatic?1:0); 56 if (code!=null) { 57 CodeException[] exceptions = code.getExceptionTable(); 58 exceptionHandlers = new int[exceptions.length]; 59 for (int i=0; i<exceptions.length; i++) { 60 exceptionHandlers[i] = exceptions[i].getHandlerPC(); 61 logger.debug("Exception handler at "+exceptionHandlers[i]); 62 } 63 Arrays.sort(exceptionHandlers); 64 } 65 } 66 67 public void preExecute(InstructionHandle ih) { 68 if (currentHandler<exceptionHandlers.length) 69 logger.debug("position="+ih.getPosition()+", nextHandler="+exceptionHandlers[currentHandler]); 70 if ( currentHandler<exceptionHandlers.length && 71 ih.getPosition()==exceptionHandlers[currentHandler] ) { 72 logger.debug("entering exception handler"); 73 currentHandler++; 74 push(dontCare); 75 } 76 } 77 78 static Set primitiveWrapperTypes = new HashSet (); 79 static { 80 primitiveWrapperTypes.add("java.lang.Float"); 81 primitiveWrapperTypes.add("java.lang.Double"); 82 primitiveWrapperTypes.add("java.lang.Integer"); 83 primitiveWrapperTypes.add("java.lang.Long"); 84 primitiveWrapperTypes.add("java.lang.Boolean"); 85 primitiveWrapperTypes.add("java.lang.Character"); 86 primitiveWrapperTypes.add("java.lang.Byte"); 87 } 88 89 public void execute(Instruction i, InstructionHandle ih) { 90 logger.debug("execute "+i.toString(cp.getConstantPool())); 91 92 if (i instanceof SWAP) { 93 swap(); 94 } else if (i instanceof DUP || i instanceof DUP2) { 95 push(peek()); 96 } else if (i instanceof DUP_X1 || i instanceof DUP2_X2 || 97 i instanceof DUP2_X1 || i instanceof DUP_X2) { 98 swap(); 99 push(peek(1)); 100 } else if (i instanceof ALOAD && ((ALOAD)i).getIndex() == 0 101 && !isStatic) { 102 push(thisPointer); 103 } else if (i instanceof NEW) { 104 if (primitiveWrapperTypes.contains( 105 ((NEW)i).getLoadClassType(cp).getClassName())) { 106 push(new PrimitiveValue(((NEW)i).getLoadClassType(cp).getClassName())); 107 } else { 108 push(new Instance( 109 ((NEW)i).getLoadClassType(cp).getClassName(),ih)); 110 } 111 } else if (i instanceof LoadInstruction) { 112 LoadInstruction load = (LoadInstruction)i; 113 if (load.getIndex()<=nbArgs) { 114 push(new Argument(load.getIndex())); 115 } else { 116 int index = load.getIndex()-nbArgs; 117 if (locals.size()<index+1) 121 locals.setSize(index+1); 122 push(locals.get(index)); 123 } 124 } else if (i instanceof StoreInstruction) { 125 StoreInstruction store = (StoreInstruction)i; 126 if (store.getIndex()<=nbArgs) { 127 } else { 128 int index = store.getIndex()-nbArgs; 129 if (locals.size()<store.getIndex()+1) 130 locals.setSize(store.getIndex()+1); 131 locals.set(store.getIndex(),peek()); 132 } 133 consume(i); 134 } else if (i instanceof GETFIELD) { 135 Object substance = peek(); 136 consume(i); 137 push(new FieldValue(substance, 138 ((GETFIELD)i).getIndex(), 139 ((GETFIELD)i).getFieldName(cp))); 140 } else if (i instanceof GETSTATIC) { 141 consume(i); 142 push(new FieldValue(null, 143 ((GETSTATIC)i).getIndex(), 144 ((GETSTATIC)i).getFieldName(cp))); 145 } else if (i instanceof INVOKESPECIAL && 146 ((INVOKESPECIAL)i).getMethodName(cp).equals("<init>")) { 147 Object invoked = invokedObject((INVOKESPECIAL)i); 148 if (invoked instanceof PrimitiveValue) 149 ((PrimitiveValue)invoked).wrappedValue = peek(); 150 consume(i); 151 produce(i); 152 167 } else if (i instanceof CHECKCAST || i instanceof ATHROW) { 168 } else if (i instanceof ANEWARRAY) { 170 pop(1); 173 push(dontCare); 174 } else { 175 consume(i); 176 produce(i); 177 } 178 logger.debug("stack: "+this); 179 } 180 181 185 public Object invokedObject(InvokeInstruction i) { 186 return peek(i.getArgumentTypes(cp).length); 187 } 188 189 192 public void consume(Instruction i) { 193 if (i instanceof StackConsumer) 194 pop(getConsumed(i,cp)); 195 } 196 public void produce(Instruction i) { 197 if (i instanceof StackProducer) { 198 for(int j=0; j<getProduced(i,cp); j++) 199 push(dontCare); 200 } 201 } 202 206 public static int getConsumed(Instruction i, ConstantPoolGen cp) { 207 if (i instanceof INVOKESTATIC) 208 return ((InvokeInstruction)i).getArgumentTypes(cp).length; 209 else if (i instanceof InvokeInstruction) 210 return ((InvokeInstruction)i).getArgumentTypes(cp).length+1; 211 else if (i instanceof MULTIANEWARRAY) 212 return ((MULTIANEWARRAY)i).getDimensions(); 213 else 214 return CONSUME_STACK[i.getOpcode()]; 215 } 216 217 220 public static int getProduced(Instruction i, ConstantPoolGen cp) { 221 if (i instanceof InvokeInstruction) { 222 return ((InvokeInstruction)i).getReturnType(cp)==Type.VOID ? 0 : 1; 223 } else { 224 return PRODUCE_STACK[i.getOpcode()]; 225 } 226 } 227 228 232 public Object getSubstance(InvokeInstruction invoke) { 233 return peek(invoke.getArgumentTypes(cp).length); 234 } 235 236 static final int[] CONSUME_STACK = { 237 0, 0, 0, 0, 0, 238 0, 0, 0, 0, 0, 239 0, 0, 0, 0, 0, 240 0, 0, 0, 0, 0, 0, 0, 241 0, 0, 0, 0, 0, 0, 0, 242 0, 0, 0, 0, 0, 0, 243 0, 0, 0, 0, 0, 0, 244 0, 0, 0, 0, 0, 2, 245 2, 2, 2, 2, 2, 2, 2, 246 1, 1, 1, 1, 1, 1, 247 1, 1, 1, 1, 1, 248 1, 1, 1, 1, 1, 249 1, 1, 1, 1, 1, 250 1, 1, 1, 1, 3, 3, 251 3, 3, 3, 3, 3, 3, 252 1, 1, 1, 2, 3, 1, 3, 253 4, 2, 2, 2, 2, 2, 2, 2, 254 2, 2, 2, 2, 2, 2, 2, 2, 255 2, 2, 2, 2, 2, 2, 1, 1, 256 1, 1, 2, 2, 2, 2, 2, 2, 257 2, 2, 2, 2, 2, 2, 0, 258 1, 1, 1, 1, 1, 1, 1, 1, 259 1, 1, 1, 1, 1, 1, 1, 260 2, 2, 2, 2, 2, 1, 1, 261 1, 1, 1, 1, 2, 2, 2, 262 2 , 2, 2, 2, 2, 263 0, 0, 0, 1, 1, 1, 264 1, 1, 1, 1, 0, 0, 265 1, 1, 2, 266 UNPREDICTABLE, UNPREDICTABLE, 267 UNPREDICTABLE, 268 UNPREDICTABLE, UNDEFINED, 0, 1, 1, 269 1, 1, 1, 1, 1, 270 1, 0, UNPREDICTABLE, 1, 1, 271 0, 0, 0, UNDEFINED, UNDEFINED, 272 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 273 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 274 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 275 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 276 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 277 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 278 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 279 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 280 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 281 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 282 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 283 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 284 UNDEFINED, UNPREDICTABLE, UNPREDICTABLE 285 }; 286 287 public static final int[] PRODUCE_STACK = { 288 0, 1, 1, 1, 1, 289 1, 1, 1, 1, 1, 290 1, 1, 1, 1, 1, 291 1, 1, 1, 1, 1, 1, 1, 292 1, 1, 1, 1, 1, 1, 1, 293 1, 1, 1, 1, 1, 1, 294 1, 1, 1, 1, 1, 1, 295 1, 1, 1, 1, 1, 1, 296 1, 1, 1, 1, 1, 1, 1, 297 0, 0, 0, 0, 0, 0, 298 0, 0, 0, 0, 0, 299 0, 0, 0, 0, 0, 300 0, 0, 0, 0, 0, 301 0, 0, 0, 0, 0, 0, 302 0, 0, 0, 0, 0, 0, 303 0, 0, 2, 3, 4, 4, 5, 304 6, 2, 1, 1, 1, 1, 1, 1, 305 1, 1, 1, 1, 1, 1, 1, 1, 306 1, 1, 1, 1, 1, 1, 1, 1, 307 1, 1, 1, 1, 1, 1, 1, 1, 308 1, 1, 1, 1, 1, 1, 309 0, 1, 1, 1, 1, 1, 1, 1, 310 1, 1, 1, 1, 1, 311 1, 1, 1, 1, 1, 1, 312 1, 1, 0, 0, 0, 0, 0, 0, 313 0, 0, 0, 0, 0, 314 0, 0, 0, 0, 1, 0, 315 0, 0, 0, 0, 0, 316 0, 0, 0, 1, 0, 317 1, 0, UNPREDICTABLE, 318 UNPREDICTABLE, UNPREDICTABLE, 319 UNPREDICTABLE, UNDEFINED, 1, 1, 1, 320 1, 1, 1, 1, 0, 321 0, 0, 1, 0, 0, 322 0, 1, 0, UNDEFINED, UNDEFINED, 323 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 324 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 325 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 326 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 327 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 328 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 329 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 330 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 331 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 332 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 333 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 334 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, 335 UNDEFINED, UNPREDICTABLE, UNPREDICTABLE 336 }; 337 338 public static class ThisPointer implements Serializable { 340 public String toString() { return "This"; } 341 } 342 343 344 public static class DontCare implements Serializable { 345 public String toString() { return "???"; } 346 } 347 348 349 public static class Instance implements Serializable { 350 public String type; 351 352 public transient InstructionHandle newHandle; 353 public transient InstructionHandle initHandle; 354 public Instance(String type, InstructionHandle newHandle) { 355 this.type = type; 356 this.newHandle = newHandle; 357 } 358 public String toString() { return type; } 359 } 360 361 362 public static class Argument implements Serializable { 363 public int n; 364 public Argument(int n) { this.n = n; } 365 public String toString() { return "arg["+n+"]"; } 366 } 367 368 369 public static class FieldValue implements Serializable { 370 int index; String field; Object substance; public FieldValue(Object substance, int index, String field) { 374 this.field = field; 375 this.index = index; 376 this.substance = substance; 377 } 378 public String toString() { return substance+"."+field; } 379 } 380 381 382 public static class PrimitiveValue implements Serializable { 383 public Object wrappedValue; 384 public String type; 385 public PrimitiveValue(String type) { 386 this.type = type; 387 this.wrappedValue = null; 388 } 389 public String toString() { 390 return type+"("+wrappedValue+")"; 391 } 392 } 393 394 395 public static class IteratorValue { 396 public Object collection; 397 public IteratorValue(Object collection) { 398 this.collection = collection; 399 } 400 public String toString() { 401 return "iterator("+collection.toString()+")"; 402 } 403 } 404 405 406 public static class CollectionValue { 407 public Object collection; 408 public CollectionValue(Object collection) { 409 this.collection = collection; 410 } 411 public String toString() { 412 return "iterator("+collection.toString()+")"; 413 } 414 } 415 } 416 417 | Popular Tags |