1 30 package com.tc.asm.tree.analysis; 31 32 import java.util.List ; 33 34 import com.tc.asm.Type; 35 import com.tc.asm.tree.AbstractInsnNode; 36 import com.tc.asm.tree.FieldInsnNode; 37 import com.tc.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 expected1 = newValue(Type.getType("[I")); 196 expected2 = BasicValue.INT_VALUE; 197 break; 198 case BALOAD: 199 if (!isSubTypeOf(value1, newValue(Type.getType("[Z")))) { 200 expected1 = newValue(Type.getType("[B")); 201 } else { 202 expected1 = newValue(Type.getType("[Z")); 203 } 204 expected2 = BasicValue.INT_VALUE; 205 break; 206 case CALOAD: 207 expected1 = newValue(Type.getType("[C")); 208 expected2 = BasicValue.INT_VALUE; 209 break; 210 case SALOAD: 211 expected1 = newValue(Type.getType("[S")); 212 expected2 = BasicValue.INT_VALUE; 213 break; 214 case LALOAD: 215 expected1 = newValue(Type.getType("[J")); 216 expected2 = BasicValue.INT_VALUE; 217 break; 218 case FALOAD: 219 expected1 = newValue(Type.getType("[F")); 220 expected2 = BasicValue.INT_VALUE; 221 break; 222 case DALOAD: 223 expected1 = newValue(Type.getType("[D")); 224 expected2 = BasicValue.INT_VALUE; 225 break; 226 case AALOAD: 227 expected1 = newValue(Type.getType("[Ljava/lang/Object;")); 228 expected2 = BasicValue.INT_VALUE; 229 break; 230 case IADD: 231 case ISUB: 232 case IMUL: 233 case IDIV: 234 case IREM: 235 case ISHL: 236 case ISHR: 237 case IUSHR: 238 case IAND: 239 case IOR: 240 case IXOR: 241 case IF_ICMPEQ: 242 case IF_ICMPNE: 243 case IF_ICMPLT: 244 case IF_ICMPGE: 245 case IF_ICMPGT: 246 case IF_ICMPLE: 247 expected1 = BasicValue.INT_VALUE; 248 expected2 = BasicValue.INT_VALUE; 249 break; 250 case FADD: 251 case FSUB: 252 case FMUL: 253 case FDIV: 254 case FREM: 255 case FCMPL: 256 case FCMPG: 257 expected1 = BasicValue.FLOAT_VALUE; 258 expected2 = BasicValue.FLOAT_VALUE; 259 break; 260 case LADD: 261 case LSUB: 262 case LMUL: 263 case LDIV: 264 case LREM: 265 case LAND: 266 case LOR: 267 case LXOR: 268 case LCMP: 269 expected1 = BasicValue.LONG_VALUE; 270 expected2 = BasicValue.LONG_VALUE; 271 break; 272 case LSHL: 273 case LSHR: 274 case LUSHR: 275 expected1 = BasicValue.LONG_VALUE; 276 expected2 = BasicValue.INT_VALUE; 277 break; 278 case DADD: 279 case DSUB: 280 case DMUL: 281 case DDIV: 282 case DREM: 283 case DCMPL: 284 case DCMPG: 285 expected1 = BasicValue.DOUBLE_VALUE; 286 expected2 = BasicValue.DOUBLE_VALUE; 287 break; 288 case IF_ACMPEQ: 289 case IF_ACMPNE: 290 expected1 = BasicValue.REFERENCE_VALUE; 291 expected2 = BasicValue.REFERENCE_VALUE; 292 break; 293 case PUTFIELD: 294 FieldInsnNode fin = (FieldInsnNode) insn; 295 expected1 = newValue(Type.getType("L" + fin.owner + ";")); 296 expected2 = newValue(Type.getType(fin.desc)); 297 break; 298 default: 299 throw new RuntimeException ("Internal error."); 300 } 301 if (!isSubTypeOf(value1, expected1)) { 302 throw new AnalyzerException("First argument", expected1, value1); 303 } else if (!isSubTypeOf(value2, expected2)) { 304 throw new AnalyzerException("Second argument", expected2, value2); 305 } 306 if (insn.getOpcode() == AALOAD) { 307 return getElementValue(value1); 308 } else { 309 return super.binaryOperation(insn, value1, value2); 310 } 311 } 312 313 public Value ternaryOperation( 314 final AbstractInsnNode insn, 315 final Value value1, 316 final Value value2, 317 final Value value3) throws AnalyzerException 318 { 319 Value expected1; 320 Value expected3; 321 switch (insn.getOpcode()) { 322 case IASTORE: 323 expected1 = newValue(Type.getType("[I")); 324 expected3 = BasicValue.INT_VALUE; 325 break; 326 case BASTORE: 327 if (!isSubTypeOf(value1, newValue(Type.getType("[Z")))) { 328 expected1 = newValue(Type.getType("[B")); 329 } else { 330 expected1 = newValue(Type.getType("[Z")); 331 } 332 expected3 = BasicValue.INT_VALUE; 333 break; 334 case CASTORE: 335 expected1 = newValue(Type.getType("[C")); 336 expected3 = BasicValue.INT_VALUE; 337 break; 338 case SASTORE: 339 expected1 = newValue(Type.getType("[S")); 340 expected3 = BasicValue.INT_VALUE; 341 break; 342 case LASTORE: 343 expected1 = newValue(Type.getType("[J")); 344 expected3 = BasicValue.LONG_VALUE; 345 break; 346 case FASTORE: 347 expected1 = newValue(Type.getType("[F")); 348 expected3 = BasicValue.FLOAT_VALUE; 349 break; 350 case DASTORE: 351 expected1 = newValue(Type.getType("[D")); 352 expected3 = BasicValue.DOUBLE_VALUE; 353 break; 354 case AASTORE: 355 expected1 = value1; 356 expected3 = BasicValue.REFERENCE_VALUE; 357 break; 358 default: 359 throw new RuntimeException ("Internal error."); 360 } 361 if (!isSubTypeOf(value1, expected1)) { 362 throw new AnalyzerException("First argument", "a " + expected1 363 + " array reference", value1); 364 } else if (value2 != BasicValue.INT_VALUE) { 365 throw new AnalyzerException("Second argument", 366 BasicValue.INT_VALUE, 367 value2); 368 } else if (!isSubTypeOf(value3, expected3)) { 369 throw new AnalyzerException("Third argument", expected3, value3); 370 } 371 return null; 372 } 373 374 public Value naryOperation(final AbstractInsnNode insn, final List values) 375 throws AnalyzerException 376 { 377 int opcode = insn.getOpcode(); 378 if (opcode == MULTIANEWARRAY) { 379 for (int i = 0; i < values.size(); ++i) { 380 if (values.get(i) != BasicValue.INT_VALUE) { 381 throw new AnalyzerException(null, 382 BasicValue.INT_VALUE, 383 (Value) values.get(i)); 384 } 385 } 386 } else { 387 int i = 0; 388 int j = 0; 389 if (opcode != INVOKESTATIC) { 390 String own = ((MethodInsnNode) insn).owner; 391 if (own.charAt(0) != '[') { own = "L" + own + ";"; 393 } 394 Type owner = Type.getType(own); 395 if (!isSubTypeOf((Value) values.get(i++), newValue(owner))) { 396 throw new AnalyzerException("Method owner", 397 newValue(owner), 398 (Value) values.get(0)); 399 } 400 } 401 Type[] args = Type.getArgumentTypes(((MethodInsnNode) insn).desc); 402 while (i < values.size()) { 403 Value expected = newValue(args[j++]); 404 Value encountered = (Value) values.get(i++); 405 if (!isSubTypeOf(encountered, expected)) { 406 throw new AnalyzerException("Argument " + j, 407 expected, 408 encountered); 409 } 410 } 411 } 412 return super.naryOperation(insn, values); 413 } 414 415 protected boolean isArrayValue(final Value value) { 416 return ((BasicValue) value).isReference(); 417 } 418 419 protected Value getElementValue(final Value objectArrayValue) 420 throws AnalyzerException 421 { 422 return BasicValue.REFERENCE_VALUE; 423 } 424 425 protected boolean isSubTypeOf(final Value value, final Value expected) { 426 return value == expected; 427 } 428 } 429 | Popular Tags |