1 30 package org.objectweb.asm.tree.analysis; 31 32 import java.util.List ; 33 34 import org.objectweb.asm.Opcodes; 35 import org.objectweb.asm.Type; 36 import org.objectweb.asm.tree.AbstractInsnNode; 37 import org.objectweb.asm.tree.FieldInsnNode; 38 import org.objectweb.asm.tree.IntInsnNode; 39 import org.objectweb.asm.tree.LdcInsnNode; 40 import org.objectweb.asm.tree.MethodInsnNode; 41 import org.objectweb.asm.tree.MultiANewArrayInsnNode; 42 import org.objectweb.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 case T_CHAR: 186 case T_BYTE: 187 case T_SHORT: 188 case T_INT: 189 return newValue(Type.getType("[I")); 190 case T_FLOAT: 191 return newValue(Type.getType("[F")); 192 case T_DOUBLE: 193 return newValue(Type.getType("[D")); 194 case T_LONG: 195 return newValue(Type.getType("[J")); 196 default: 197 throw new AnalyzerException("Invalid array type"); 198 } 199 case ANEWARRAY: 200 String desc = ((TypeInsnNode) insn).desc; 201 if (desc.charAt(0) == '[') { 202 return newValue(Type.getType("[" + desc)); 203 } else { 204 return newValue(Type.getType("[L" + desc + ";")); 205 } 206 case ARRAYLENGTH: 207 return BasicValue.INT_VALUE; 208 case ATHROW: 209 return null; 210 case CHECKCAST: 211 desc = ((TypeInsnNode) insn).desc; 212 if (desc.charAt(0) == '[') { 213 return newValue(Type.getType(desc)); 214 } else { 215 return newValue(Type.getType("L" + desc + ";")); 216 } 217 case INSTANCEOF: 218 return BasicValue.INT_VALUE; 219 case MONITORENTER: 220 case MONITOREXIT: 221 case IFNULL: 222 case IFNONNULL: 223 return null; 224 default: 225 throw new RuntimeException ("Internal error."); 226 } 227 } 228 229 public Value binaryOperation( 230 final AbstractInsnNode insn, 231 final Value value1, 232 final Value value2) throws AnalyzerException 233 { 234 switch (insn.getOpcode()) { 235 case IALOAD: 236 case BALOAD: 237 case CALOAD: 238 case SALOAD: 239 case IADD: 240 case ISUB: 241 case IMUL: 242 case IDIV: 243 case IREM: 244 case ISHL: 245 case ISHR: 246 case IUSHR: 247 case IAND: 248 case IOR: 249 case IXOR: 250 return BasicValue.INT_VALUE; 251 case FALOAD: 252 case FADD: 253 case FSUB: 254 case FMUL: 255 case FDIV: 256 case FREM: 257 return BasicValue.FLOAT_VALUE; 258 case LALOAD: 259 case LADD: 260 case LSUB: 261 case LMUL: 262 case LDIV: 263 case LREM: 264 case LSHL: 265 case LSHR: 266 case LUSHR: 267 case LAND: 268 case LOR: 269 case LXOR: 270 return BasicValue.LONG_VALUE; 271 case DALOAD: 272 case DADD: 273 case DSUB: 274 case DMUL: 275 case DDIV: 276 case DREM: 277 return BasicValue.DOUBLE_VALUE; 278 case AALOAD: 279 Type t = ((BasicValue) value1).getType(); 280 if (t != null && t.getSort() == Type.ARRAY) { 281 return newValue(t.getElementType()); 282 } else { 283 return BasicValue.REFERENCE_VALUE; 284 } 285 case LCMP: 286 case FCMPL: 287 case FCMPG: 288 case DCMPL: 289 case DCMPG: 290 return BasicValue.INT_VALUE; 291 case IF_ICMPEQ: 292 case IF_ICMPNE: 293 case IF_ICMPLT: 294 case IF_ICMPGE: 295 case IF_ICMPGT: 296 case IF_ICMPLE: 297 case IF_ACMPEQ: 298 case IF_ACMPNE: 299 case PUTFIELD: 300 return null; 301 default: 302 throw new RuntimeException ("Internal error."); 303 } 304 } 305 306 public Value ternaryOperation( 307 final AbstractInsnNode insn, 308 final Value value1, 309 final Value value2, 310 final Value value3) throws AnalyzerException 311 { 312 return null; 313 } 314 315 public Value naryOperation(final AbstractInsnNode insn, final List values) 316 throws AnalyzerException 317 { 318 if (insn.getOpcode() == MULTIANEWARRAY) { 319 return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc)); 320 } else { 321 return newValue(Type.getReturnType(((MethodInsnNode) insn).desc)); 322 } 323 } 324 325 public Value merge(final Value v, final Value w) { 326 if (!v.equals(w)) { 327 return BasicValue.UNINITIALIZED_VALUE; 328 } 329 return v; 330 } 331 } 332
| Popular Tags
|