1 30 package org.objectweb.asm.tree.analysis; 31 32 import java.util.List ; 33 34 import org.objectweb.asm.Type; 35 import org.objectweb.asm.tree.AbstractInsnNode; 36 import org.objectweb.asm.tree.FieldInsnNode; 37 import org.objectweb.asm.tree.MethodInsnNode; 38 39 46 public class BasicVerifier extends BasicInterpreter { 47 48 public Value copyOperation(final AbstractInsnNode insn, final Value value) 49 throws AnalyzerException 50 { 51 Value expected; 52 switch (insn.getOpcode()) { 53 case ILOAD: 54 case ISTORE: 55 expected = BasicValue.INT_VALUE; 56 break; 57 case FLOAD: 58 case FSTORE: 59 expected = BasicValue.FLOAT_VALUE; 60 break; 61 case LLOAD: 62 case LSTORE: 63 expected = BasicValue.LONG_VALUE; 64 break; 65 case DLOAD: 66 case DSTORE: 67 expected = BasicValue.DOUBLE_VALUE; 68 break; 69 case ALOAD: 70 if (!((BasicValue) value).isReference()) { 71 throw new AnalyzerException(null, 72 "an object reference", 73 value); 74 } 75 return value; 76 case ASTORE: 77 if (!((BasicValue) value).isReference() 78 && value != BasicValue.RETURNADDRESS_VALUE) 79 { 80 throw new AnalyzerException(null, 81 "an object reference or a return address", 82 value); 83 } 84 return value; 85 default: 86 return value; 87 } 88 if (value != expected) { 91 throw new AnalyzerException(null, expected, value); 92 } 93 return value; 94 } 95 96 public Value unaryOperation(final AbstractInsnNode insn, Value value) 97 throws AnalyzerException 98 { 99 Value expected; 100 switch (insn.getOpcode()) { 101 case INEG: 102 case IINC: 103 case I2F: 104 case I2L: 105 case I2D: 106 case I2B: 107 case I2C: 108 case I2S: 109 case IFEQ: 110 case IFNE: 111 case IFLT: 112 case IFGE: 113 case IFGT: 114 case IFLE: 115 case TABLESWITCH: 116 case LOOKUPSWITCH: 117 case IRETURN: 118 case NEWARRAY: 119 case ANEWARRAY: 120 expected = BasicValue.INT_VALUE; 121 break; 122 case FNEG: 123 case F2I: 124 case F2L: 125 case F2D: 126 case FRETURN: 127 expected = BasicValue.FLOAT_VALUE; 128 break; 129 case LNEG: 130 case L2I: 131 case L2F: 132 case L2D: 133 case LRETURN: 134 expected = BasicValue.LONG_VALUE; 135 break; 136 case DNEG: 137 case D2I: 138 case D2F: 139 case D2L: 140 case DRETURN: 141 expected = BasicValue.DOUBLE_VALUE; 142 break; 143 case GETFIELD: 144 expected = newValue(Type.getType("L" 145 + ((FieldInsnNode) insn).owner + ";")); 146 break; 147 case CHECKCAST: 148 if (!((BasicValue) value).isReference()) { 149 throw new AnalyzerException(null, 150 "an object reference", 151 value); 152 } 153 return super.unaryOperation(insn, value); 154 case ARRAYLENGTH: 155 if (!isArrayValue(value)) { 156 throw new AnalyzerException(null, 157 "an array reference", 158 value); 159 } 160 return super.unaryOperation(insn, value); 161 case ARETURN: 162 case ATHROW: 163 case INSTANCEOF: 164 case MONITORENTER: 165 case MONITOREXIT: 166 case IFNULL: 167 case IFNONNULL: 168 if (!((BasicValue) value).isReference()) { 169 throw new AnalyzerException(null, 170 "an object reference", 171 value); 172 } 173 return super.unaryOperation(insn, value); 174 case PUTSTATIC: 175 expected = newValue(Type.getType(((FieldInsnNode) insn).desc)); 176 break; 177 default: 178 throw new RuntimeException ("Internal error."); 179 } 180 if (!isSubTypeOf(value, expected)) { 181 throw new AnalyzerException(null, expected, value); 182 } 183 return super.unaryOperation(insn, value); 184 } 185 186 public Value binaryOperation( 187 final AbstractInsnNode insn, 188 final Value value1, 189 final Value value2) throws AnalyzerException 190 { 191 Value expected1; 192 Value expected2; 193 switch (insn.getOpcode()) { 194 case IALOAD: 195 case BALOAD: 196 case CALOAD: 197 case SALOAD: 198 expected1 = newValue(Type.getType("[I")); 199 expected2 = BasicValue.INT_VALUE; 200 break; 201 case LALOAD: 202 expected1 = newValue(Type.getType("[J")); 203 expected2 = BasicValue.INT_VALUE; 204 break; 205 case FALOAD: 206 expected1 = newValue(Type.getType("[F")); 207 expected2 = BasicValue.INT_VALUE; 208 break; 209 case DALOAD: 210 expected1 = newValue(Type.getType("[D")); 211 expected2 = BasicValue.INT_VALUE; 212 break; 213 case AALOAD: 214 expected1 = newValue(Type.getType("[Ljava/lang/Object;")); 215 expected2 = BasicValue.INT_VALUE; 216 break; 217 case IADD: 218 case ISUB: 219 case IMUL: 220 case IDIV: 221 case IREM: 222 case ISHL: 223 case ISHR: 224 case IUSHR: 225 case IAND: 226 case IOR: 227 case IXOR: 228 case IF_ICMPEQ: 229 case IF_ICMPNE: 230 case IF_ICMPLT: 231 case IF_ICMPGE: 232 case IF_ICMPGT: 233 case IF_ICMPLE: 234 expected1 = BasicValue.INT_VALUE; 235 expected2 = BasicValue.INT_VALUE; 236 break; 237 case FADD: 238 case FSUB: 239 case FMUL: 240 case FDIV: 241 case FREM: 242 case FCMPL: 243 case FCMPG: 244 expected1 = BasicValue.FLOAT_VALUE; 245 expected2 = BasicValue.FLOAT_VALUE; 246 break; 247 case LADD: 248 case LSUB: 249 case LMUL: 250 case LDIV: 251 case LREM: 252 case LAND: 253 case LOR: 254 case LXOR: 255 case LCMP: 256 expected1 = BasicValue.LONG_VALUE; 257 expected2 = BasicValue.LONG_VALUE; 258 break; 259 case LSHL: 260 case LSHR: 261 case LUSHR: 262 expected1 = BasicValue.LONG_VALUE; 263 expected2 = BasicValue.INT_VALUE; 264 break; 265 case DADD: 266 case DSUB: 267 case DMUL: 268 case DDIV: 269 case DREM: 270 case DCMPL: 271 case DCMPG: 272 expected1 = BasicValue.DOUBLE_VALUE; 273 expected2 = BasicValue.DOUBLE_VALUE; 274 break; 275 case IF_ACMPEQ: 276 case IF_ACMPNE: 277 expected1 = BasicValue.REFERENCE_VALUE; 278 expected2 = BasicValue.REFERENCE_VALUE; 279 break; 280 case PUTFIELD: 281 FieldInsnNode fin = (FieldInsnNode) insn; 282 expected1 = newValue(Type.getType("L" + fin.owner + ";")); 283 expected2 = newValue(Type.getType(fin.desc)); 284 break; 285 default: 286 throw new RuntimeException ("Internal error."); 287 } 288 if (!isSubTypeOf(value1, expected1)) { 289 throw new AnalyzerException("First argument", expected1, value1); 290 } else if (!isSubTypeOf(value2, expected2)) { 291 throw new AnalyzerException("Second argument", expected2, value2); 292 } 293 if (insn.getOpcode() == AALOAD) { 294 return getElementValue(value1); 295 } else { 296 return super.binaryOperation(insn, value1, value2); 297 } 298 } 299 300 public Value ternaryOperation( 301 final AbstractInsnNode insn, 302 final Value value1, 303 final Value value2, 304 final Value value3) throws AnalyzerException 305 { 306 Value expected1; 307 Value expected3; 308 switch (insn.getOpcode()) { 309 case IASTORE: 310 case BASTORE: 311 case CASTORE: 312 case SASTORE: 313 expected1 = newValue(Type.getType("[I")); 314 expected3 = BasicValue.INT_VALUE; 315 break; 316 case LASTORE: 317 expected1 = newValue(Type.getType("[J")); 318 expected3 = BasicValue.LONG_VALUE; 319 break; 320 case FASTORE: 321 expected1 = newValue(Type.getType("[F")); 322 expected3 = BasicValue.FLOAT_VALUE; 323 break; 324 case DASTORE: 325 expected1 = newValue(Type.getType("[D")); 326 expected3 = BasicValue.DOUBLE_VALUE; 327 break; 328 case AASTORE: 329 expected1 = value1; 330 expected3 = BasicValue.REFERENCE_VALUE; 331 break; 332 default: 333 throw new RuntimeException ("Internal error."); 334 } 335 if (!isSubTypeOf(value1, expected1)) { 336 throw new AnalyzerException("First argument", "a " + expected1 337 + " array reference", value1); 338 } else if (value2 != BasicValue.INT_VALUE) { 339 throw new AnalyzerException("Second argument", 340 BasicValue.INT_VALUE, 341 value2); 342 } else if (!isSubTypeOf(value3, expected3)) { 343 throw new AnalyzerException("Third argument", expected3, value3); 344 } 345 return null; 346 } 347 348 public Value naryOperation(final AbstractInsnNode insn, final List values) 349 throws AnalyzerException 350 { 351 int opcode = insn.getOpcode(); 352 if (opcode == MULTIANEWARRAY) { 353 for (int i = 0; i < values.size(); ++i) { 354 if (values.get(i) != BasicValue.INT_VALUE) { 355 throw new AnalyzerException(null, 356 BasicValue.INT_VALUE, 357 (Value) values.get(i)); 358 } 359 } 360 } else { 361 int i = 0; 362 int j = 0; 363 if (opcode != INVOKESTATIC) { 364 String own = ((MethodInsnNode) insn).owner; 365 if (own.charAt(0) != '[') { own = "L" + own + ";"; 367 } 368 Type owner = Type.getType(own); 369 if (!isSubTypeOf((Value) values.get(i++), newValue(owner))) { 370 throw new AnalyzerException("Method owner", 371 newValue(owner), 372 (Value) values.get(0)); 373 } 374 } 375 Type[] args = Type.getArgumentTypes(((MethodInsnNode) insn).desc); 376 while (i < values.size()) { 377 Value expected = newValue(args[j++]); 378 Value encountered = (Value) values.get(i++); 379 if (!isSubTypeOf(encountered, expected)) { 380 throw new AnalyzerException("Argument " + j, 381 expected, 382 encountered); 383 } 384 } 385 } 386 return super.naryOperation(insn, values); 387 } 388 389 protected boolean isArrayValue(final Value value) { 390 return ((BasicValue) value).isReference(); 391 } 392 393 protected Value getElementValue(final Value objectArrayValue) 394 throws AnalyzerException 395 { 396 return BasicValue.REFERENCE_VALUE; 397 } 398 399 protected boolean isSubTypeOf(final Value value, final Value expected) { 400 return value == expected; 401 } 402 } 403
| Popular Tags
|