Example #1
0
 /// <exception cref="AnalyzerException" />
 public override void ReturnOperation(AbstractInsnNode insn, BasicValue value, BasicValue
                                      expected)
 {
     if (!IsSubTypeOf(value, expected))
     {
         throw new AnalyzerException(insn, "Incompatible return type", expected, value);
     }
 }
Example #2
0
        public override BasicValue Merge(BasicValue value1, BasicValue value2)
        {
            if (!value1.Equals(value2))
            {
                var type1 = value1.GetType();
                var type2 = value2.GetType();
                if (type1 != null && (type1.GetSort() == Type.Object || type1.GetSort() == Type.Array
                                      ) && type2 != null && (type2.GetSort() == Type.Object || type2.GetSort() == Type
                                                             .Array))
                {
                    if (type1.Equals(Null_Type))
                    {
                        return(value2);
                    }
                    if (type2.Equals(Null_Type))
                    {
                        return(value1);
                    }
                    if (IsAssignableFrom(type1, type2))
                    {
                        return(value1);
                    }
                    if (IsAssignableFrom(type2, type1))
                    {
                        return(value2);
                    }
                    var numDimensions = 0;
                    if (type1.GetSort() == Type.Array && type2.GetSort() == Type.Array && type1.GetDimensions
                            () == type2.GetDimensions() && type1.GetElementType().GetSort() == Type.Object &&
                        type2.GetElementType().GetSort() == Type.Object)
                    {
                        numDimensions = type1.GetDimensions();
                        type1         = type1.GetElementType();
                        type2         = type2.GetElementType();
                    }

                    while (true)
                    {
                        if (type1 == null || IsInterface(type1))
                        {
                            return(NewArrayValue(Type.GetObjectType("java/lang/Object"), numDimensions));
                        }
                        type1 = GetSuperClass(type1);
                        if (IsAssignableFrom(type1, type2))
                        {
                            return(NewArrayValue(type1, numDimensions));
                        }
                    }
                }

                return(BasicValue.Uninitialized_Value);
            }

            return(value1);
        }
Example #3
0
        protected internal override bool IsSubTypeOf(BasicValue value, BasicValue expected
                                                     )
        {
            var expectedType = expected.GetType();
            var type         = value.GetType();

            switch (expectedType.GetSort())
            {
            case Type.Int:
            case Type.Float:
            case Type.Long:
            case Type.Double:
            {
                return(type.Equals(expectedType));
            }

            case Type.Array:
            case Type.Object:
            {
                if (type.Equals(Null_Type))
                {
                    return(true);
                }

                if (type.GetSort() == Type.Object || type.GetSort() == Type.Array)
                {
                    if (IsAssignableFrom(expectedType, type))
                    {
                        return(true);
                    }
                    if (GetClass(expectedType).IsInterface)
                    {
                        // The merge of class or interface types can only yield class types (because it is not
                        // possible in general to find an unambiguous common super interface, due to multiple
                        // inheritance). Because of this limitation, we need to relax the subtyping check here
                        // if 'value' is an interface.
                        return(Runtime.IsAssignableFrom(typeof(object), GetClass(type)));
                    }
                    return(false);
                }

                return(false);
            }

            default:
            {
                throw new AssertionError();
            }
            }
        }
Example #4
0
        public override BasicValue NewValue(Type type)
        {
            if (type == null)
            {
                return(BasicValue.Uninitialized_Value);
            }
            var isArray = type.GetSort() == Type.Array;

            if (isArray)
            {
                switch (type.GetElementType().GetSort())
                {
                case Type.Boolean:
                case Type.Char:
                case Type.Byte:
                case Type.Short:
                {
                    return(new BasicValue(type));
                }
                }
            }

            var value = base.NewValue(type);

            if (BasicValue.Reference_Value.Equals(value))
            {
                if (isArray)
                {
                    value = NewValue(type.GetElementType());
                    var descriptor = new StringBuilder();
                    for (var i = 0; i < type.GetDimensions(); ++i)
                    {
                        descriptor.Append('[');
                    }
                    descriptor.Append(value.GetType().GetDescriptor());
                    value = new BasicValue(Type.GetType(descriptor.ToString()));
                }
                else
                {
                    value = new BasicValue(type);
                }
            }

            return(value);
        }
Example #5
0
        /// <exception cref="AnalyzerException" />
        protected internal override BasicValue GetElementValue(BasicValue objectArrayValue
                                                               )
        {
            var arrayType = objectArrayValue.GetType();

            if (arrayType != null)
            {
                if (arrayType.GetSort() == Type.Array)
                {
                    return(NewValue(Type.GetType(Runtime.Substring(arrayType.GetDescriptor(),
                                                                   1))));
                }
                if (arrayType.Equals(Null_Type))
                {
                    return(objectArrayValue);
                }
            }

            throw new AssertionError();
        }
Example #6
0
        protected internal override bool IsArrayValue(BasicValue value)
        {
            var type = value.GetType();

            return(type != null && (type.GetSort() == Type.Array || type.Equals(Null_Type)));
        }
Example #7
0
        /// <exception cref="AnalyzerException" />
        public override BasicValue CopyOperation(AbstractInsnNode insn, BasicValue value)
        {
            Value expected;

            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Iload:
            case OpcodesConstants.Istore:
            {
                expected = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Fload:
            case OpcodesConstants.Fstore:
            {
                expected = BasicValue.Float_Value;
                break;
            }

            case OpcodesConstants.Lload:
            case OpcodesConstants.Lstore:
            {
                expected = BasicValue.Long_Value;
                break;
            }

            case OpcodesConstants.Dload:
            case OpcodesConstants.Dstore:
            {
                expected = BasicValue.Double_Value;
                break;
            }

            case OpcodesConstants.Aload:
            {
                if (!value.IsReference())
                {
                    throw new AnalyzerException(insn, null, "an object reference", value);
                }
                return(value);
            }

            case OpcodesConstants.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);
        }
Example #8
0
 /// <summary>
 ///     Returns whether the type corresponding to the first argument is a subtype of the type
 ///     corresponding to the second argument.
 /// </summary>
 /// <param name="value">a value.</param>
 /// <param name="expected">another value.</param>
 /// <returns>
 ///     whether the type corresponding to 'value' is a subtype of the type corresponding to
 ///     'expected'.
 /// </returns>
 protected internal virtual bool IsSubTypeOf(BasicValue value, BasicValue expected
                                             )
 {
     return(value.Equals(expected));
 }
Example #9
0
 /// <summary>
 ///     Returns the value corresponding to the type of the elements of the given array reference value.
 /// </summary>
 /// <param name="objectArrayValue">
 ///     a value corresponding to array of object (or array) references.
 /// </param>
 /// <returns>
 ///     the value corresponding to the type of the elements of 'objectArrayValue'.
 /// </returns>
 /// <exception cref="AnalyzerException">
 ///     if objectArrayValue does not correspond to an array type.
 /// </exception>
 /// <exception cref="AnalyzerException" />
 protected internal virtual BasicValue GetElementValue(BasicValue objectArrayValue
                                                       )
 {
     return(BasicValue.Reference_Value);
 }
Example #10
0
 /// <summary>Returns whether the given value corresponds to an array reference.</summary>
 /// <param name="value">a value.</param>
 /// <returns>whether 'value' corresponds to an array reference.</returns>
 protected internal virtual bool IsArrayValue(BasicValue value)
 {
     return(value.IsReference());
 }
Example #11
0
        /// <exception cref="AnalyzerException" />
        public override BasicValue TernaryOperation(AbstractInsnNode insn, BasicValue value1
                                                    , BasicValue value2, BasicValue value3)
        {
            BasicValue expected1;
            BasicValue expected3;

            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Iastore:
            {
                expected1 = NewValue(Type.GetType("[I"));
                expected3 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.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 OpcodesConstants.Castore:
            {
                expected1 = NewValue(Type.GetType("[C"));
                expected3 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Sastore:
            {
                expected1 = NewValue(Type.GetType("[S"));
                expected3 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Lastore:
            {
                expected1 = NewValue(Type.GetType("[J"));
                expected3 = BasicValue.Long_Value;
                break;
            }

            case OpcodesConstants.Fastore:
            {
                expected1 = NewValue(Type.GetType("[F"));
                expected3 = BasicValue.Float_Value;
                break;
            }

            case OpcodesConstants.Dastore:
            {
                expected1 = NewValue(Type.GetType("[D"));
                expected3 = BasicValue.Double_Value;
                break;
            }

            case OpcodesConstants.Aastore:
            {
                expected1 = value1;
                expected3 = BasicValue.Reference_Value;
                break;
            }

            default:
            {
                throw new AssertionError();
            }
            }

            if (!IsSubTypeOf(value1, expected1))
            {
                throw new AnalyzerException(insn, "First argument", "a " + expected1 + " array reference"
                                            , value1);
            }
            if (!BasicValue.Int_Value.Equals(value2))
            {
                throw new AnalyzerException(insn, "Second argument", BasicValue.Int_Value, value2
                                            );
            }
            if (!IsSubTypeOf(value3, expected3))
            {
                throw new AnalyzerException(insn, "Third argument", expected3, value3);
            }
            return(null);
        }
Example #12
0
        /// <exception cref="AnalyzerException" />
        public override BasicValue BinaryOperation(AbstractInsnNode insn, BasicValue value1
                                                   , BasicValue value2)
        {
            BasicValue expected1;
            BasicValue expected2;

            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Iaload:
            {
                expected1 = NewValue(Type.GetType("[I"));
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Baload:
            {
                if (IsSubTypeOf(value1, NewValue(Type.GetType("[Z"))))
                {
                    expected1 = NewValue(Type.GetType("[Z"));
                }
                else
                {
                    expected1 = NewValue(Type.GetType("[B"));
                }
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Caload:
            {
                expected1 = NewValue(Type.GetType("[C"));
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Saload:
            {
                expected1 = NewValue(Type.GetType("[S"));
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Laload:
            {
                expected1 = NewValue(Type.GetType("[J"));
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Faload:
            {
                expected1 = NewValue(Type.GetType("[F"));
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Daload:
            {
                expected1 = NewValue(Type.GetType("[D"));
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Aaload:
            {
                expected1 = NewValue(Type.GetType("[Ljava/lang/Object;"));
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Iadd:
            case OpcodesConstants.Isub:
            case OpcodesConstants.Imul:
            case OpcodesConstants.Idiv:
            case OpcodesConstants.Irem:
            case OpcodesConstants.Ishl:
            case OpcodesConstants.Ishr:
            case OpcodesConstants.Iushr:
            case OpcodesConstants.Iand:
            case OpcodesConstants.Ior:
            case OpcodesConstants.Ixor:
            case OpcodesConstants.If_Icmpeq:
            case OpcodesConstants.If_Icmpne:
            case OpcodesConstants.If_Icmplt:
            case OpcodesConstants.If_Icmpge:
            case OpcodesConstants.If_Icmpgt:
            case OpcodesConstants.If_Icmple:
            {
                expected1 = BasicValue.Int_Value;
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Fadd:
            case OpcodesConstants.Fsub:
            case OpcodesConstants.Fmul:
            case OpcodesConstants.Fdiv:
            case OpcodesConstants.Frem:
            case OpcodesConstants.Fcmpl:
            case OpcodesConstants.Fcmpg:
            {
                expected1 = BasicValue.Float_Value;
                expected2 = BasicValue.Float_Value;
                break;
            }

            case OpcodesConstants.Ladd:
            case OpcodesConstants.Lsub:
            case OpcodesConstants.Lmul:
            case OpcodesConstants.Ldiv:
            case OpcodesConstants.Lrem:
            case OpcodesConstants.Land:
            case OpcodesConstants.Lor:
            case OpcodesConstants.Lxor:
            case OpcodesConstants.Lcmp:
            {
                expected1 = BasicValue.Long_Value;
                expected2 = BasicValue.Long_Value;
                break;
            }

            case OpcodesConstants.Lshl:
            case OpcodesConstants.Lshr:
            case OpcodesConstants.Lushr:
            {
                expected1 = BasicValue.Long_Value;
                expected2 = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Dadd:
            case OpcodesConstants.Dsub:
            case OpcodesConstants.Dmul:
            case OpcodesConstants.Ddiv:
            case OpcodesConstants.Drem:
            case OpcodesConstants.Dcmpl:
            case OpcodesConstants.Dcmpg:
            {
                expected1 = BasicValue.Double_Value;
                expected2 = BasicValue.Double_Value;
                break;
            }

            case OpcodesConstants.If_Acmpeq:
            case OpcodesConstants.If_Acmpne:
            {
                expected1 = BasicValue.Reference_Value;
                expected2 = BasicValue.Reference_Value;
                break;
            }

            case OpcodesConstants.Putfield:
            {
                var fieldInsn = (FieldInsnNode)insn;
                expected1 = NewValue(Type.GetObjectType(fieldInsn.owner));
                expected2 = NewValue(Type.GetType(fieldInsn.desc));
                break;
            }

            default:
            {
                throw new AssertionError();
            }
            }

            if (!IsSubTypeOf(value1, expected1))
            {
                throw new AnalyzerException(insn, "First argument", expected1, value1);
            }
            if (!IsSubTypeOf(value2, expected2))
            {
                throw new AnalyzerException(insn, "Second argument", expected2, value2);
            }
            if (insn.GetOpcode() == OpcodesConstants.Aaload)
            {
                return(GetElementValue(value1));
            }
            return(base.BinaryOperation(insn, value1, value2));
        }
Example #13
0
        /// <exception cref="AnalyzerException" />
        public override BasicValue UnaryOperation(AbstractInsnNode insn, BasicValue value
                                                  )
        {
            BasicValue expected;

            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Ineg:
            case OpcodesConstants.Iinc:
            case OpcodesConstants.I2f:
            case OpcodesConstants.I2l:
            case OpcodesConstants.I2d:
            case OpcodesConstants.I2b:
            case OpcodesConstants.I2c:
            case OpcodesConstants.I2s:
            case OpcodesConstants.Ifeq:
            case OpcodesConstants.Ifne:
            case OpcodesConstants.Iflt:
            case OpcodesConstants.Ifge:
            case OpcodesConstants.Ifgt:
            case OpcodesConstants.Ifle:
            case OpcodesConstants.Tableswitch:
            case OpcodesConstants.Lookupswitch:
            case OpcodesConstants.Ireturn:
            case OpcodesConstants.Newarray:
            case OpcodesConstants.Anewarray:
            {
                expected = BasicValue.Int_Value;
                break;
            }

            case OpcodesConstants.Fneg:
            case OpcodesConstants.F2i:
            case OpcodesConstants.F2l:
            case OpcodesConstants.F2d:
            case OpcodesConstants.Freturn:
            {
                expected = BasicValue.Float_Value;
                break;
            }

            case OpcodesConstants.Lneg:
            case OpcodesConstants.L2i:
            case OpcodesConstants.L2f:
            case OpcodesConstants.L2d:
            case OpcodesConstants.Lreturn:
            {
                expected = BasicValue.Long_Value;
                break;
            }

            case OpcodesConstants.Dneg:
            case OpcodesConstants.D2i:
            case OpcodesConstants.D2f:
            case OpcodesConstants.D2l:
            case OpcodesConstants.Dreturn:
            {
                expected = BasicValue.Double_Value;
                break;
            }

            case OpcodesConstants.Getfield:
            {
                expected = NewValue(Type.GetObjectType(((FieldInsnNode)insn).owner));
                break;
            }

            case OpcodesConstants.Arraylength:
            {
                if (!IsArrayValue(value))
                {
                    throw new AnalyzerException(insn, null, "an array reference", value);
                }
                return(base.UnaryOperation(insn, value));
            }

            case OpcodesConstants.Checkcast:
            case OpcodesConstants.Areturn:
            case OpcodesConstants.Athrow:
            case OpcodesConstants.Instanceof:
            case OpcodesConstants.Monitorenter:
            case OpcodesConstants.Monitorexit:
            case OpcodesConstants.Ifnull:
            case OpcodesConstants.Ifnonnull:
            {
                if (!value.IsReference())
                {
                    throw new AnalyzerException(insn, null, "an object reference", value);
                }
                return(base.UnaryOperation(insn, value));
            }

            case OpcodesConstants.Putstatic:
            {
                expected = NewValue(Type.GetType(((FieldInsnNode)insn).desc));
                break;
            }

            default:
            {
                throw new AssertionError();
            }
            }

            if (!IsSubTypeOf(value, expected))
            {
                throw new AnalyzerException(insn, null, expected, value);
            }
            return(base.UnaryOperation(insn, value));
        }