BasicVerifierpublic class BasicVerifier extends BasicInterpreter An extended {@link BasicInterpreter} that checks that bytecode instructions
are correctly used. |
Methods Summary |
---|
public Value | binaryOperation(oracle.toplink.libraries.asm.tree.AbstractInsnNode insn, Value value1, Value value2)
Value expected1;
Value expected2;
switch (insn.getOpcode()) {
case IALOAD:
case BALOAD:
case CALOAD:
case SALOAD:
expected1 = newValue(Type.getType("[I"));
expected2 = BasicValue.INT_VALUE;
break;
case LALOAD:
expected1 = newValue(Type.getType("[J"));
expected2 = BasicValue.INT_VALUE;
break;
case FALOAD:
expected1 = newValue(Type.getType("[F"));
expected2 = BasicValue.INT_VALUE;
break;
case DALOAD:
expected1 = newValue(Type.getType("[D"));
expected2 = BasicValue.INT_VALUE;
break;
case AALOAD:
expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
expected2 = BasicValue.INT_VALUE;
break;
case IADD:
case ISUB:
case IMUL:
case IDIV:
case IREM:
case ISHL:
case ISHR:
case IUSHR:
case IAND:
case IOR:
case IXOR:
case IF_ICMPEQ:
case IF_ICMPNE:
case IF_ICMPLT:
case IF_ICMPGE:
case IF_ICMPGT:
case IF_ICMPLE:
expected1 = BasicValue.INT_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case FADD:
case FSUB:
case FMUL:
case FDIV:
case FREM:
case FCMPL:
case FCMPG:
expected1 = BasicValue.FLOAT_VALUE;
expected2 = BasicValue.FLOAT_VALUE;
break;
case LADD:
case LSUB:
case LMUL:
case LDIV:
case LREM:
case LAND:
case LOR:
case LXOR:
case LCMP:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.LONG_VALUE;
break;
case LSHL:
case LSHR:
case LUSHR:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case DADD:
case DSUB:
case DMUL:
case DDIV:
case DREM:
case DCMPL:
case DCMPG:
expected1 = BasicValue.DOUBLE_VALUE;
expected2 = BasicValue.DOUBLE_VALUE;
break;
case IF_ACMPEQ:
case IF_ACMPNE:
expected1 = BasicValue.REFERENCE_VALUE;
expected2 = BasicValue.REFERENCE_VALUE;
break;
case PUTFIELD:
FieldInsnNode fin = (FieldInsnNode)insn;
expected1 = newValue(Type.getType("L" + fin.owner + ";"));
expected2 = newValue(Type.getType(fin.desc));
break;
default:
throw new RuntimeException("Internal error.");
}
if (!isSubTypeOf(value1, expected1)) {
throw new AnalyzerException("First argument", expected1, value1);
} else if (!isSubTypeOf(value2, expected2)) {
throw new AnalyzerException("Second argument", expected2, value2);
}
if (insn.getOpcode() == AALOAD) {
return getElementValue(value1);
} else {
return super.binaryOperation(insn, value1, value2);
}
| public Value | copyOperation(oracle.toplink.libraries.asm.tree.AbstractInsnNode insn, Value value)
Value expected;
switch (insn.getOpcode()) {
case ILOAD:
case ISTORE:
expected = BasicValue.INT_VALUE;
break;
case FLOAD:
case FSTORE:
expected = BasicValue.FLOAT_VALUE;
break;
case LLOAD:
case LSTORE:
expected = BasicValue.LONG_VALUE;
break;
case DLOAD:
case DSTORE:
expected = BasicValue.DOUBLE_VALUE;
break;
case ALOAD:
if (!((BasicValue)value).isReference()) {
throw new AnalyzerException(null, "an object reference", value);
}
return value;
case ASTORE:
if (!((BasicValue)value).isReference() &&
value != BasicValue.RETURNADDRESS_VALUE)
{
throw new AnalyzerException(
null, "an object reference or a return address", value);
}
return value;
default:
return value;
}
// type is necessarily a primitive type here,
// so value must be == to expected value
if (value != expected) {
throw new AnalyzerException(null, expected, value);
}
return value;
| protected Value | getElementValue(Value objectArrayValue)
return BasicValue.REFERENCE_VALUE;
| protected boolean | isArrayValue(Value value)
return ((BasicValue)value).isReference();
| protected boolean | isSubTypeOf(Value value, Value expected)
return value == expected;
| public Value | naryOperation(oracle.toplink.libraries.asm.tree.AbstractInsnNode insn, java.util.List values)
int opcode = insn.getOpcode();
if (opcode == MULTIANEWARRAY) {
for (int i = 0; i < values.size(); ++i) {
if (values.get(i) != BasicValue.INT_VALUE) {
throw new AnalyzerException(
null, BasicValue.INT_VALUE, (Value)values.get(i));
}
}
} else {
int i = 0;
int j = 0;
if (opcode != INVOKESTATIC) {
Type owner = Type.getType("L" + ((MethodInsnNode)insn).owner + ";");
if (!isSubTypeOf((Value)values.get(i++), newValue(owner))) {
throw new AnalyzerException(
"Method owner", newValue(owner), (Value)values.get(0));
}
}
Type[] args = Type.getArgumentTypes(((MethodInsnNode)insn).desc);
while (i < values.size()) {
Value expected = newValue(args[j++]);
Value encountered = (Value)values.get(i++);
if (!isSubTypeOf(encountered, expected)) {
throw new AnalyzerException("Argument " + j, expected, encountered);
}
}
}
return super.naryOperation(insn, values);
| public Value | ternaryOperation(oracle.toplink.libraries.asm.tree.AbstractInsnNode insn, Value value1, Value value2, Value value3)
Value expected1;
Value expected3;
switch (insn.getOpcode()) {
case IASTORE:
case BASTORE:
case CASTORE:
case SASTORE:
expected1 = newValue(Type.getType("[I"));
expected3 = BasicValue.INT_VALUE;
break;
case LASTORE:
expected1 = newValue(Type.getType("[J"));
expected3 = BasicValue.LONG_VALUE;
break;
case FASTORE:
expected1 = newValue(Type.getType("[F"));
expected3 = BasicValue.FLOAT_VALUE;
break;
case DASTORE:
expected1 = newValue(Type.getType("[D"));
expected3 = BasicValue.DOUBLE_VALUE;
break;
case AASTORE:
expected1 = value1;
expected3 = getElementValue(value1);
break;
default:
throw new RuntimeException("Internal error.");
}
if (!isSubTypeOf(value1, expected1)) {
throw new AnalyzerException(
"First argument", "a " + expected1 + " array reference", value1);
} else if (value2 != BasicValue.INT_VALUE) {
throw new AnalyzerException(
"Second argument", BasicValue.INT_VALUE, value2);
} else if (!isSubTypeOf(value3, expected3)) {
throw new AnalyzerException("Third argument", expected3, value3);
}
return null;
| public Value | unaryOperation(oracle.toplink.libraries.asm.tree.AbstractInsnNode insn, Value value)
Value expected;
switch (insn.getOpcode()) {
case INEG:
case IINC:
case I2F:
case I2L:
case I2D:
case I2B:
case I2C:
case I2S:
case IFEQ:
case IFNE:
case IFLT:
case IFGE:
case IFGT:
case IFLE:
case TABLESWITCH:
case LOOKUPSWITCH:
case IRETURN:
case NEWARRAY:
case ANEWARRAY:
expected = BasicValue.INT_VALUE;
break;
case FNEG:
case F2I:
case F2L:
case F2D:
case FRETURN:
expected = BasicValue.FLOAT_VALUE;
break;
case LNEG:
case L2I:
case L2F:
case L2D:
case LRETURN:
expected = BasicValue.LONG_VALUE;
break;
case DNEG:
case D2I:
case D2F:
case D2L:
case DRETURN:
expected = BasicValue.DOUBLE_VALUE;
break;
case GETFIELD:
expected = newValue(Type.getType("L" + ((FieldInsnNode)insn).owner + ";"));
break;
case CHECKCAST:
if (!((BasicValue)value).isReference()) {
throw new AnalyzerException(null, "an object reference", value);
}
return super.unaryOperation(insn, value);
case ARRAYLENGTH:
if (!isArrayValue(value)) {
throw new AnalyzerException(null, "an array reference", value);
}
return super.unaryOperation(insn, value);
case ARETURN:
case ATHROW:
case INSTANCEOF:
case MONITORENTER:
case MONITOREXIT:
case IFNULL:
case IFNONNULL:
if (!((BasicValue)value).isReference()) {
throw new AnalyzerException(null, "an object reference", value);
}
return super.unaryOperation(insn, value);
case PUTSTATIC:
expected = newValue(Type.getType(((FieldInsnNode)insn).desc));
break;
default:
throw new RuntimeException("Internal error.");
}
if (!isSubTypeOf(value, expected)) {
throw new AnalyzerException(null, expected, value);
}
return super.unaryOperation(insn, value);
|
|