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