1 30 package com.tc.asm.tree.analysis; 31 32 import java.util.List ; 33 34 import com.tc.asm.Opcodes; 35 import com.tc.asm.Type; 36 import com.tc.asm.tree.AbstractInsnNode; 37 import com.tc.asm.tree.FieldInsnNode; 38 import com.tc.asm.tree.IntInsnNode; 39 import com.tc.asm.tree.LdcInsnNode; 40 import com.tc.asm.tree.MethodInsnNode; 41 import com.tc.asm.tree.MultiANewArrayInsnNode; 42 import com.tc.asm.tree.TypeInsnNode; 43 44 50 public class BasicInterpreter implements Opcodes, Interpreter { 51 52 public Value newValue(final Type type) { 53 if (type == null) { 54 return BasicValue.UNINITIALIZED_VALUE; 55 } 56 switch (type.getSort()) { 57 case Type.VOID: 58 return null; 59 case Type.BOOLEAN: 60 case Type.CHAR: 61 case Type.BYTE: 62 case Type.SHORT: 63 case Type.INT: 64 return BasicValue.INT_VALUE; 65 case Type.FLOAT: 66 return BasicValue.FLOAT_VALUE; 67 case Type.LONG: 68 return BasicValue.LONG_VALUE; 69 case Type.DOUBLE: 70 return BasicValue.DOUBLE_VALUE; 71 case Type.ARRAY: 72 case Type.OBJECT: 73 return BasicValue.REFERENCE_VALUE; 74 default: 75 throw new RuntimeException ("Internal error."); 76 } 77 } 78 79 public Value newOperation(final AbstractInsnNode insn) { 80 switch (insn.getOpcode()) { 81 case ACONST_NULL: 82 return newValue(Type.getType("Lnull;")); 83 case ICONST_M1: 84 case ICONST_0: 85 case ICONST_1: 86 case ICONST_2: 87 case ICONST_3: 88 case ICONST_4: 89 case ICONST_5: 90 return BasicValue.INT_VALUE; 91 case LCONST_0: 92 case LCONST_1: 93 return BasicValue.LONG_VALUE; 94 case FCONST_0: 95 case FCONST_1: 96 case FCONST_2: 97 return BasicValue.FLOAT_VALUE; 98 case DCONST_0: 99 case DCONST_1: 100 return BasicValue.DOUBLE_VALUE; 101 case BIPUSH: 102 case SIPUSH: 103 return BasicValue.INT_VALUE; 104 case LDC: 105 Object cst = ((LdcInsnNode) insn).cst; 106 if (cst instanceof Integer ) { 107 return BasicValue.INT_VALUE; 108 } else if (cst instanceof Float ) { 109 return BasicValue.FLOAT_VALUE; 110 } else if (cst instanceof Long ) { 111 return BasicValue.LONG_VALUE; 112 } else if (cst instanceof Double ) { 113 return BasicValue.DOUBLE_VALUE; 114 } else if (cst instanceof Type) { 115 return newValue(Type.getType("Ljava/lang/Class;")); 116 } else { 117 return newValue(Type.getType(cst.getClass())); 118 } 119 case JSR: 120 return BasicValue.RETURNADDRESS_VALUE; 121 case GETSTATIC: 122 return newValue(Type.getType(((FieldInsnNode) insn).desc)); 123 case NEW: 124 return newValue(Type.getType("L" + ((TypeInsnNode) insn).desc 125 + ";")); 126 default: 127 throw new RuntimeException ("Internal error."); 128 } 129 } 130 131 public Value copyOperation(final AbstractInsnNode insn, final Value value) 132 throws AnalyzerException 133 { 134 return value; 135 } 136 137 public Value unaryOperation(final AbstractInsnNode insn, final Value value) 138 throws AnalyzerException 139 { 140 switch (insn.getOpcode()) { 141 case INEG: 142 case IINC: 143 case L2I: 144 case F2I: 145 case D2I: 146 case I2B: 147 case I2C: 148 case I2S: 149 return BasicValue.INT_VALUE; 150 case FNEG: 151 case I2F: 152 case L2F: 153 case D2F: 154 return BasicValue.FLOAT_VALUE; 155 case LNEG: 156 case I2L: 157 case F2L: 158 case D2L: 159 return BasicValue.LONG_VALUE; 160 case DNEG: 161 case I2D: 162 case L2D: 163 case F2D: 164 return BasicValue.DOUBLE_VALUE; 165 case IFEQ: 166 case IFNE: 167 case IFLT: 168 case IFGE: 169 case IFGT: 170 case IFLE: 171 case TABLESWITCH: 172 case LOOKUPSWITCH: 173 case IRETURN: 174 case LRETURN: 175 case FRETURN: 176 case DRETURN: 177 case ARETURN: 178 case PUTSTATIC: 179 return null; 180 case GETFIELD: 181 return newValue(Type.getType(((FieldInsnNode) insn).desc)); 182 case NEWARRAY: 183 switch (((IntInsnNode) insn).operand) { 184 case T_BOOLEAN: 185 return newValue(Type.getType("[Z")); 186 case T_CHAR: 187 return newValue(Type.getType("[C")); 188 case T_BYTE: 189 return newValue(Type.getType("[B")); 190 case T_SHORT: 191 return newValue(Type.getType("[S")); 192 case T_INT: 193 return newValue(Type.getType("[I")); 194 case T_FLOAT: 195 return newValue(Type.getType("[F")); 196 case T_DOUBLE: 197 return newValue(Type.getType("[D")); 198 case T_LONG: 199 return newValue(Type.getType("[J")); 200 default: 201 throw new AnalyzerException("Invalid array type"); 202 } 203 case ANEWARRAY: 204 String desc = ((TypeInsnNode) insn).desc; 205 if (desc.charAt(0) == '[') { 206 return newValue(Type.getType("[" + desc)); 207 } else { 208 return newValue(Type.getType("[L" + desc + ";")); 209 } 210 case ARRAYLENGTH: 211 return BasicValue.INT_VALUE; 212 case ATHROW: 213 return null; 214 case CHECKCAST: 215 desc = ((TypeInsnNode) insn).desc; 216 if (desc.charAt(0) == '[') { 217 return newValue(Type.getType(desc)); 218 } else { 219 return newValue(Type.getType("L" + desc + ";")); 220 } 221 case INSTANCEOF: 222 return BasicValue.INT_VALUE; 223 case MONITORENTER: 224 case MONITOREXIT: 225 case IFNULL: 226 case IFNONNULL: 227 return null; 228 default: 229 throw new RuntimeException ("Internal error."); 230 } 231 } 232 233 public Value binaryOperation( 234 final AbstractInsnNode insn, 235 final Value value1, 236 final Value value2) throws AnalyzerException 237 { 238 switch (insn.getOpcode()) { 239 case IALOAD: 240 case BALOAD: 241 case CALOAD: 242 case SALOAD: 243 case IADD: 244 case ISUB: 245 case IMUL: 246 case IDIV: 247 case IREM: 248 case ISHL: 249 case ISHR: 250 case IUSHR: 251 case IAND: 252 case IOR: 253 case IXOR: 254 return BasicValue.INT_VALUE; 255 case FALOAD: 256 case FADD: 257 case FSUB: 258 case FMUL: 259 case FDIV: 260 case FREM: 261 return BasicValue.FLOAT_VALUE; 262 case LALOAD: 263 case LADD: 264 case LSUB: 265 case LMUL: 266 case LDIV: 267 case LREM: 268 case LSHL: 269 case LSHR: 270 case LUSHR: 271 case LAND: 272 case LOR: 273 case LXOR: 274 return BasicValue.LONG_VALUE; 275 case DALOAD: 276 case DADD: 277 case DSUB: 278 case DMUL: 279 case DDIV: 280 case DREM: 281 return BasicValue.DOUBLE_VALUE; 282 case AALOAD: 283 Type t = ((BasicValue) value1).getType(); 284 if (t != null && t.getSort() == Type.ARRAY) { 285 return newValue(t.getElementType()); 286 } else { 287 return BasicValue.REFERENCE_VALUE; 288 } 289 case LCMP: 290 case FCMPL: 291 case FCMPG: 292 case DCMPL: 293 case DCMPG: 294 return BasicValue.INT_VALUE; 295 case IF_ICMPEQ: 296 case IF_ICMPNE: 297 case IF_ICMPLT: 298 case IF_ICMPGE: 299 case IF_ICMPGT: 300 case IF_ICMPLE: 301 case IF_ACMPEQ: 302 case IF_ACMPNE: 303 case PUTFIELD: 304 return null; 305 default: 306 throw new RuntimeException ("Internal error."); 307 } 308 } 309 310 public Value ternaryOperation( 311 final AbstractInsnNode insn, 312 final Value value1, 313 final Value value2, 314 final Value value3) throws AnalyzerException 315 { 316 return null; 317 } 318 319 public Value naryOperation(final AbstractInsnNode insn, final List values) 320 throws AnalyzerException 321 { 322 if (insn.getOpcode() == MULTIANEWARRAY) { 323 return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc)); 324 } else { 325 return newValue(Type.getReturnType(((MethodInsnNode) insn).desc)); 326 } 327 } 328 329 public Value merge(final Value v, final Value w) { 330 if (!v.equals(w)) { 331 return BasicValue.UNINITIALIZED_VALUE; 332 } 333 return v; 334 } 335 } 336 | Popular Tags |