@Override public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value) throws AnalyzerException { 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 (!value.isReference()) { throw new AnalyzerException(insn, null, "an object reference", value); } return value; case ASTORE: if (!value.isReference() && !BasicValue.RETURNADDRESS_VALUE.equals(value)) { throw new AnalyzerException(insn, null, "an object reference or a return address", value); } return value; default: return value; } if (!expected.equals(value)) { throw new AnalyzerException(insn, null, expected, value); } return value; }
@Override public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value) throws AnalyzerException { BasicValue 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.getObjectType(((FieldInsnNode) insn).owner)); break; case CHECKCAST: if (!value.isReference()) { throw new AnalyzerException(insn, null, "an object reference", value); } return super.unaryOperation(insn, value); case ARRAYLENGTH: if (!isArrayValue(value)) { throw new AnalyzerException(insn, 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 (!value.isReference()) { throw new AnalyzerException(insn, null, "an object reference", value); } return super.unaryOperation(insn, value); case PUTSTATIC: expected = newValue(Type.getType(((FieldInsnNode) insn).desc)); break; default: throw new Error("Internal error."); } if (!isSubTypeOf(value, expected)) { throw new AnalyzerException(insn, null, expected, value); } return super.unaryOperation(insn, value); }
protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) { return value.equals(expected); }
protected boolean isArrayValue(final BasicValue value) { return value.isReference(); }