@Override public BasicValue naryOperation( final AbstractInsnNode insn, final List<? extends BasicValue> values) throws AnalyzerException { int opcode = insn.getOpcode(); if (opcode == MULTIANEWARRAY) { for (int i = 0; i < values.size(); ++i) { if (!BasicValue.INT_VALUE.equals(values.get(i))) { throw new AnalyzerException(insn, null, BasicValue.INT_VALUE, values.get(i)); } } } else { int i = 0; int j = 0; if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) { Type owner = Type.getObjectType(((MethodInsnNode) insn).owner); if (!isSubTypeOf(values.get(i++), newValue(owner))) { throw new AnalyzerException(insn, "Method owner", newValue(owner), values.get(0)); } } String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc : ((MethodInsnNode) insn).desc; Type[] args = Type.getArgumentTypes(desc); while (i < values.size()) { BasicValue expected = newValue(args[j++]); BasicValue encountered = values.get(i++); if (!isSubTypeOf(encountered, expected)) { throw new AnalyzerException(insn, "Argument " + j, expected, encountered); } } } return super.naryOperation(insn, values); }
@Override public BasicValue ternaryOperation( final AbstractInsnNode insn, final BasicValue value1, final BasicValue value2, final BasicValue value3) throws AnalyzerException { BasicValue expected1; BasicValue expected3; switch (insn.getOpcode()) { case IASTORE: expected1 = newValue(Type.getType("[I")); expected3 = BasicValue.INT_VALUE; break; case BASTORE: if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) { expected1 = newValue(Type.getType("[Z")); } else { expected1 = newValue(Type.getType("[B")); } expected3 = BasicValue.INT_VALUE; break; case CASTORE: expected1 = newValue(Type.getType("[C")); expected3 = BasicValue.INT_VALUE; break; case SASTORE: expected1 = newValue(Type.getType("[S")); 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 = BasicValue.REFERENCE_VALUE; break; default: throw new Error("Internal error."); } if (!isSubTypeOf(value1, expected1)) { throw new AnalyzerException( insn, "First argument", "a " + expected1 + " array reference", value1); } else if (!BasicValue.INT_VALUE.equals(value2)) { throw new AnalyzerException(insn, "Second argument", BasicValue.INT_VALUE, value2); } else if (!isSubTypeOf(value3, expected3)) { throw new AnalyzerException(insn, "Third argument", expected3, value3); } return null; }