Esempio n. 1
0
        public override SourceValue UnaryOperation(AbstractInsnNode insn, SourceValue value
                                                   )
        {
            int size;

            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Lneg:
            case OpcodesConstants.Dneg:
            case OpcodesConstants.I2l:
            case OpcodesConstants.I2d:
            case OpcodesConstants.L2d:
            case OpcodesConstants.F2l:
            case OpcodesConstants.F2d:
            case OpcodesConstants.D2l:
            {
                size = 2;
                break;
            }

            case OpcodesConstants.Getfield:
            {
                size = Type.GetType(((FieldInsnNode)insn).desc).GetSize();
                break;
            }

            default:
            {
                size = 1;
                break;
            }
            }

            return(new SourceValue(size, insn));
        }
Esempio n. 2
0
        /// <exception cref="AnalyzerException" />
        private void ExecuteInvokeInsn(AbstractInsnNode insn, string methodDescriptor, Interpreter
                                       <V> interpreter)
        {
            var valueList = new List <V>();

            for (var i = Type.GetArgumentTypes(methodDescriptor).Length; i > 0; --i)
            {
                valueList.Add(0, Pop());
            }
            if (insn.GetOpcode() != OpcodesConstants.Invokestatic && insn.GetOpcode() != OpcodesConstants
                .Invokedynamic)
            {
                valueList.Add(0, Pop());
            }
            if (Type.GetReturnType(methodDescriptor) == Type.Void_Type)
            {
                interpreter.NaryOperation(insn, valueList);
            }
            else
            {
                Push(interpreter.NaryOperation(insn, valueList));
            }
        }
Esempio n. 3
0
        /// <exception cref="AnalyzerException" />
        public override BasicValue NaryOperation <_T0>(AbstractInsnNode insn, IList <_T0> values
                                                       )
        {
            var opcode = insn.GetOpcode();

            if (opcode == OpcodesConstants.Multianewarray)
            {
                return(NewValue(Type.GetType(((MultiANewArrayInsnNode)insn).desc)));
            }
            if (opcode == OpcodesConstants.Invokedynamic)
            {
                return(NewValue(Type.GetReturnType(((InvokeDynamicInsnNode)insn).desc)));
            }
            return(NewValue(Type.GetReturnType(((MethodInsnNode)insn).desc)));
        }
Esempio n. 4
0
        /// <exception cref="AnalyzerException" />
        public override BasicValue NaryOperation <_T0>(AbstractInsnNode insn, IList <_T0> values
                                                       )
        {
            var opcode = insn.GetOpcode();

            if (opcode == OpcodesConstants.Multianewarray)
            {
                foreach (var value in values)
                {
                    if (!BasicValue.Int_Value.Equals(value))
                    {
                        throw new AnalyzerException(insn, null, BasicValue.Int_Value, value);
                    }
                }
            }
            else
            {
                var i = 0;
                var j = 0;
                if (opcode != OpcodesConstants.Invokestatic && opcode != OpcodesConstants.Invokedynamic)
                {
                    var owner = Type.GetObjectType(((MethodInsnNode)insn).owner);
                    if (!IsSubTypeOf(values[i++], NewValue(owner)))
                    {
                        throw new AnalyzerException(insn, "Method owner", NewValue(owner), values[0]);
                    }
                }

                var methodDescriptor = opcode == OpcodesConstants.Invokedynamic
                    ? ((InvokeDynamicInsnNode
                        )insn).desc
                    : ((MethodInsnNode)insn).desc;
                var args = Type.GetArgumentTypes(methodDescriptor);
                while (i < values.Count)
                {
                    var expected = NewValue(args[j++]);
                    var actual   = values[i++];
                    if (!IsSubTypeOf(actual, expected))
                    {
                        throw new AnalyzerException(insn, "Argument " + j, expected, actual);
                    }
                }
            }

            return(base.NaryOperation(insn, values));
        }
Esempio n. 5
0
        public override SourceValue NaryOperation <_T0>(AbstractInsnNode insn, IList <_T0>
                                                        values)
        {
            int size;
            var opcode = insn.GetOpcode();

            if (opcode == OpcodesConstants.Multianewarray)
            {
                size = 1;
            }
            else if (opcode == OpcodesConstants.Invokedynamic)
            {
                size = Type.GetReturnType(((InvokeDynamicInsnNode)insn).desc).GetSize();
            }
            else
            {
                size = Type.GetReturnType(((MethodInsnNode)insn).desc).GetSize();
            }
            return(new SourceValue(size, insn));
        }
Esempio n. 6
0
        public override SourceValue BinaryOperation(AbstractInsnNode insn, SourceValue value1
                                                    , SourceValue value2)
        {
            int size;

            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Laload:
            case OpcodesConstants.Daload:
            case OpcodesConstants.Ladd:
            case OpcodesConstants.Dadd:
            case OpcodesConstants.Lsub:
            case OpcodesConstants.Dsub:
            case OpcodesConstants.Lmul:
            case OpcodesConstants.Dmul:
            case OpcodesConstants.Ldiv:
            case OpcodesConstants.Ddiv:
            case OpcodesConstants.Lrem:
            case OpcodesConstants.Drem:
            case OpcodesConstants.Lshl:
            case OpcodesConstants.Lshr:
            case OpcodesConstants.Lushr:
            case OpcodesConstants.Land:
            case OpcodesConstants.Lor:
            case OpcodesConstants.Lxor:
            {
                size = 2;
                break;
            }

            default:
            {
                size = 1;
                break;
            }
            }

            return(new SourceValue(size, insn));
        }
Esempio n. 7
0
        public override SourceValue NewOperation(AbstractInsnNode insn)
        {
            int size;

            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Lconst_0:
            case OpcodesConstants.Lconst_1:
            case OpcodesConstants.Dconst_0:
            case OpcodesConstants.Dconst_1:
            {
                size = 2;
                break;
            }

            case OpcodesConstants.Ldc:
            {
                var value = ((LdcInsnNode)insn).cst;
                size = value is long || value is double? 2 : 1;
                break;
            }

            case OpcodesConstants.Getstatic:
            {
                size = Type.GetType(((FieldInsnNode)insn).desc).GetSize();
                break;
            }

            default:
            {
                size = 1;
                break;
            }
            }

            return(new SourceValue(size, insn));
        }
Esempio n. 8
0
        /// <summary>
        ///     Simulates the execution of the given instruction on this execution stack frame.
        /// </summary>
        /// <param name="insn">the instruction to execute.</param>
        /// <param name="interpreter">
        ///     the interpreter to use to compute values from other values.
        /// </param>
        /// <exception cref="AnalyzerException">
        ///     if the instruction cannot be executed on this execution frame (e.g. a
        ///     POP on an empty operand stack).
        /// </exception>
        /// <exception cref="AnalyzerException" />
        public virtual void Execute(AbstractInsnNode insn, Interpreter <V> interpreter)
        {
            V   value1;
            V   value2;
            V   value3;
            V   value4;
            int var;

            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Nop:
            {
                break;
            }

            case OpcodesConstants.Aconst_Null:
            case OpcodesConstants.Iconst_M1:
            case OpcodesConstants.Iconst_0:
            case OpcodesConstants.Iconst_1:
            case OpcodesConstants.Iconst_2:
            case OpcodesConstants.Iconst_3:
            case OpcodesConstants.Iconst_4:
            case OpcodesConstants.Iconst_5:
            case OpcodesConstants.Lconst_0:
            case OpcodesConstants.Lconst_1:
            case OpcodesConstants.Fconst_0:
            case OpcodesConstants.Fconst_1:
            case OpcodesConstants.Fconst_2:
            case OpcodesConstants.Dconst_0:
            case OpcodesConstants.Dconst_1:
            case OpcodesConstants.Bipush:
            case OpcodesConstants.Sipush:
            case OpcodesConstants.Ldc:
            {
                Push(interpreter.NewOperation(insn));
                break;
            }

            case OpcodesConstants.Iload:
            case OpcodesConstants.Lload:
            case OpcodesConstants.Fload:
            case OpcodesConstants.Dload:
            case OpcodesConstants.Aload:
            {
                Push(interpreter.CopyOperation(insn, GetLocal(((VarInsnNode)insn).var)));
                break;
            }

            case OpcodesConstants.Istore:
            case OpcodesConstants.Lstore:
            case OpcodesConstants.Fstore:
            case OpcodesConstants.Dstore:
            case OpcodesConstants.Astore:
            {
                value1 = interpreter.CopyOperation(insn, Pop());
                var    = ((VarInsnNode)insn).var;
                SetLocal(var, value1);
                if (value1.GetSize() == 2)
                {
                    SetLocal(var + 1, interpreter.NewEmptyValue(var + 1));
                }
                if (var > 0)
                {
                    Value local = GetLocal(var - 1);
                    if (local != null && local.GetSize() == 2)
                    {
                        SetLocal(var - 1, interpreter.NewEmptyValue(var - 1));
                    }
                }

                break;
            }

            case OpcodesConstants.Iastore:
            case OpcodesConstants.Lastore:
            case OpcodesConstants.Fastore:
            case OpcodesConstants.Dastore:
            case OpcodesConstants.Aastore:
            case OpcodesConstants.Bastore:
            case OpcodesConstants.Castore:
            case OpcodesConstants.Sastore:
            {
                value3 = Pop();
                value2 = Pop();
                value1 = Pop();
                interpreter.TernaryOperation(insn, value1, value2, value3);
                break;
            }

            case OpcodesConstants.Pop:
            {
                if (Pop().GetSize() == 2)
                {
                    throw new AnalyzerException(insn, "Illegal use of POP");
                }
                break;
            }

            case OpcodesConstants.Pop2:
            {
                if (Pop().GetSize() == 1 && Pop().GetSize() != 1)
                {
                    throw new AnalyzerException(insn, "Illegal use of POP2");
                }
                break;
            }

            case OpcodesConstants.Dup:
            {
                value1 = Pop();
                if (value1.GetSize() != 1)
                {
                    throw new AnalyzerException(insn, "Illegal use of DUP");
                }
                Push(value1);
                Push(interpreter.CopyOperation(insn, value1));
                break;
            }

            case OpcodesConstants.Dup_X1:
            {
                value1 = Pop();
                value2 = Pop();
                if (value1.GetSize() != 1 || value2.GetSize() != 1)
                {
                    throw new AnalyzerException(insn, "Illegal use of DUP_X1");
                }
                Push(interpreter.CopyOperation(insn, value1));
                Push(value2);
                Push(value1);
                break;
            }

            case OpcodesConstants.Dup_X2:
            {
                value1 = Pop();
                if (value1.GetSize() == 1 && ExecuteDupX2(insn, value1, interpreter))
                {
                    break;
                }
                throw new AnalyzerException(insn, "Illegal use of DUP_X2");
            }

            case OpcodesConstants.Dup2:
            {
                value1 = Pop();
                if (value1.GetSize() == 1)
                {
                    value2 = Pop();
                    if (value2.GetSize() == 1)
                    {
                        Push(value2);
                        Push(value1);
                        Push(interpreter.CopyOperation(insn, value2));
                        Push(interpreter.CopyOperation(insn, value1));
                        break;
                    }
                }
                else
                {
                    Push(value1);
                    Push(interpreter.CopyOperation(insn, value1));
                    break;
                }

                throw new AnalyzerException(insn, "Illegal use of DUP2");
            }

            case OpcodesConstants.Dup2_X1:
            {
                value1 = Pop();
                if (value1.GetSize() == 1)
                {
                    value2 = Pop();
                    if (value2.GetSize() == 1)
                    {
                        value3 = Pop();
                        if (value3.GetSize() == 1)
                        {
                            Push(interpreter.CopyOperation(insn, value2));
                            Push(interpreter.CopyOperation(insn, value1));
                            Push(value3);
                            Push(value2);
                            Push(value1);
                            break;
                        }
                    }
                }
                else
                {
                    value2 = Pop();
                    if (value2.GetSize() == 1)
                    {
                        Push(interpreter.CopyOperation(insn, value1));
                        Push(value2);
                        Push(value1);
                        break;
                    }
                }

                throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
            }

            case OpcodesConstants.Dup2_X2:
            {
                value1 = Pop();
                if (value1.GetSize() == 1)
                {
                    value2 = Pop();
                    if (value2.GetSize() == 1)
                    {
                        value3 = Pop();
                        if (value3.GetSize() == 1)
                        {
                            value4 = Pop();
                            if (value4.GetSize() == 1)
                            {
                                Push(interpreter.CopyOperation(insn, value2));
                                Push(interpreter.CopyOperation(insn, value1));
                                Push(value4);
                                Push(value3);
                                Push(value2);
                                Push(value1);
                                break;
                            }
                        }
                        else
                        {
                            Push(interpreter.CopyOperation(insn, value2));
                            Push(interpreter.CopyOperation(insn, value1));
                            Push(value3);
                            Push(value2);
                            Push(value1);
                            break;
                        }
                    }
                }
                else if (ExecuteDupX2(insn, value1, interpreter))
                {
                    break;
                }

                throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
            }

            case OpcodesConstants.Swap:
            {
                value2 = Pop();
                value1 = Pop();
                if (value1.GetSize() != 1 || value2.GetSize() != 1)
                {
                    throw new AnalyzerException(insn, "Illegal use of SWAP");
                }
                Push(interpreter.CopyOperation(insn, value2));
                Push(interpreter.CopyOperation(insn, value1));
                break;
            }

            case OpcodesConstants.Iaload:
            case OpcodesConstants.Laload:
            case OpcodesConstants.Faload:
            case OpcodesConstants.Daload:
            case OpcodesConstants.Aaload:
            case OpcodesConstants.Baload:
            case OpcodesConstants.Caload:
            case OpcodesConstants.Saload:
            case OpcodesConstants.Iadd:
            case OpcodesConstants.Ladd:
            case OpcodesConstants.Fadd:
            case OpcodesConstants.Dadd:
            case OpcodesConstants.Isub:
            case OpcodesConstants.Lsub:
            case OpcodesConstants.Fsub:
            case OpcodesConstants.Dsub:
            case OpcodesConstants.Imul:
            case OpcodesConstants.Lmul:
            case OpcodesConstants.Fmul:
            case OpcodesConstants.Dmul:
            case OpcodesConstants.Idiv:
            case OpcodesConstants.Ldiv:
            case OpcodesConstants.Fdiv:
            case OpcodesConstants.Ddiv:
            case OpcodesConstants.Irem:
            case OpcodesConstants.Lrem:
            case OpcodesConstants.Frem:
            case OpcodesConstants.Drem:
            case OpcodesConstants.Ishl:
            case OpcodesConstants.Lshl:
            case OpcodesConstants.Ishr:
            case OpcodesConstants.Lshr:
            case OpcodesConstants.Iushr:
            case OpcodesConstants.Lushr:
            case OpcodesConstants.Iand:
            case OpcodesConstants.Land:
            case OpcodesConstants.Ior:
            case OpcodesConstants.Lor:
            case OpcodesConstants.Ixor:
            case OpcodesConstants.Lxor:
            case OpcodesConstants.Lcmp:
            case OpcodesConstants.Fcmpl:
            case OpcodesConstants.Fcmpg:
            case OpcodesConstants.Dcmpl:
            case OpcodesConstants.Dcmpg:
            {
                value2 = Pop();
                value1 = Pop();
                Push(interpreter.BinaryOperation(insn, value1, value2));
                break;
            }

            case OpcodesConstants.Ineg:
            case OpcodesConstants.Lneg:
            case OpcodesConstants.Fneg:
            case OpcodesConstants.Dneg:
            {
                Push(interpreter.UnaryOperation(insn, Pop()));
                break;
            }

            case OpcodesConstants.Iinc:
            {
                var = ((IincInsnNode)insn).var;
                SetLocal(var, interpreter.UnaryOperation(insn, GetLocal(var)));
                break;
            }

            case OpcodesConstants.I2l:
            case OpcodesConstants.I2f:
            case OpcodesConstants.I2d:
            case OpcodesConstants.L2i:
            case OpcodesConstants.L2f:
            case OpcodesConstants.L2d:
            case OpcodesConstants.F2i:
            case OpcodesConstants.F2l:
            case OpcodesConstants.F2d:
            case OpcodesConstants.D2i:
            case OpcodesConstants.D2l:
            case OpcodesConstants.D2f:
            case OpcodesConstants.I2b:
            case OpcodesConstants.I2c:
            case OpcodesConstants.I2s:
            {
                Push(interpreter.UnaryOperation(insn, Pop()));
                break;
            }

            case OpcodesConstants.Ifeq:
            case OpcodesConstants.Ifne:
            case OpcodesConstants.Iflt:
            case OpcodesConstants.Ifge:
            case OpcodesConstants.Ifgt:
            case OpcodesConstants.Ifle:
            {
                interpreter.UnaryOperation(insn, Pop());
                break;
            }

            case OpcodesConstants.If_Icmpeq:
            case OpcodesConstants.If_Icmpne:
            case OpcodesConstants.If_Icmplt:
            case OpcodesConstants.If_Icmpge:
            case OpcodesConstants.If_Icmpgt:
            case OpcodesConstants.If_Icmple:
            case OpcodesConstants.If_Acmpeq:
            case OpcodesConstants.If_Acmpne:
            case OpcodesConstants.Putfield:
            {
                value2 = Pop();
                value1 = Pop();
                interpreter.BinaryOperation(insn, value1, value2);
                break;
            }

            case OpcodesConstants.Goto:
            {
                break;
            }

            case OpcodesConstants.Jsr:
            {
                Push(interpreter.NewOperation(insn));
                break;
            }

            case OpcodesConstants.Ret:
            {
                break;
            }

            case OpcodesConstants.Tableswitch:
            case OpcodesConstants.Lookupswitch:
            {
                interpreter.UnaryOperation(insn, Pop());
                break;
            }

            case OpcodesConstants.Ireturn:
            case OpcodesConstants.Lreturn:
            case OpcodesConstants.Freturn:
            case OpcodesConstants.Dreturn:
            case OpcodesConstants.Areturn:
            {
                value1 = Pop();
                interpreter.UnaryOperation(insn, value1);
                interpreter.ReturnOperation(insn, value1, returnValue);
                break;
            }

            case OpcodesConstants.Return:
            {
                if (returnValue != null)
                {
                    throw new AnalyzerException(insn, "Incompatible return type");
                }
                break;
            }

            case OpcodesConstants.Getstatic:
            {
                Push(interpreter.NewOperation(insn));
                break;
            }

            case OpcodesConstants.Putstatic:
            {
                interpreter.UnaryOperation(insn, Pop());
                break;
            }

            case OpcodesConstants.Getfield:
            {
                Push(interpreter.UnaryOperation(insn, Pop()));
                break;
            }

            case OpcodesConstants.Invokevirtual:
            case OpcodesConstants.Invokespecial:
            case OpcodesConstants.Invokestatic:
            case OpcodesConstants.Invokeinterface:
            {
                ExecuteInvokeInsn(insn, ((MethodInsnNode)insn).desc, interpreter);
                break;
            }

            case OpcodesConstants.Invokedynamic:
            {
                ExecuteInvokeInsn(insn, ((InvokeDynamicInsnNode)insn).desc, interpreter);
                break;
            }

            case OpcodesConstants.New:
            {
                Push(interpreter.NewOperation(insn));
                break;
            }

            case OpcodesConstants.Newarray:
            case OpcodesConstants.Anewarray:
            case OpcodesConstants.Arraylength:
            {
                Push(interpreter.UnaryOperation(insn, Pop()));
                break;
            }

            case OpcodesConstants.Athrow:
            {
                interpreter.UnaryOperation(insn, Pop());
                break;
            }

            case OpcodesConstants.Checkcast:
            case OpcodesConstants.Instanceof:
            {
                Push(interpreter.UnaryOperation(insn, Pop()));
                break;
            }

            case OpcodesConstants.Monitorenter:
            case OpcodesConstants.Monitorexit:
            {
                interpreter.UnaryOperation(insn, Pop());
                break;
            }

            case OpcodesConstants.Multianewarray:
            {
                IList <V> valueList = new List <V>();
                for (var i = ((MultiANewArrayInsnNode)insn).dims; i > 0; --i)
                {
                    valueList.Add(0, Pop());
                }
                Push(interpreter.NaryOperation(insn, valueList));
                break;
            }

            case OpcodesConstants.Ifnull:
            case OpcodesConstants.Ifnonnull:
            {
                interpreter.UnaryOperation(insn, Pop());
                break;
            }

            default:
            {
                throw new AnalyzerException(insn, "Illegal opcode " + insn.GetOpcode());
            }
            }
        }
Esempio n. 9
0
        /// <summary>Analyzes the given method.</summary>
        /// <param name="owner">the internal name of the class to which 'method' belongs.</param>
        /// <param name="method">the method to be analyzed.</param>
        /// <returns>
        ///     the symbolic state of the execution stack frame at each bytecode instruction of the
        ///     method. The size of the returned array is equal to the number of instructions (and labels)
        ///     of the method. A given frame is
        ///     <literal>null</literal>
        ///     if and only if the corresponding
        ///     instruction cannot be reached (dead code).
        /// </returns>
        /// <exception cref="AnalyzerException">if a problem occurs during the analysis.</exception>
        /// <exception cref="AnalyzerException" />
        public virtual Frame <V>[] Analyze(string owner, MethodNode method)
        {
            if ((method.access & (AccessFlags.Abstract | AccessFlags.Native
                                  )) != 0)
            {
                frames = new Frame <V> [0];
                return(frames);
            }

            insnList                 = method.instructions;
            insnListSize             = insnList.Size();
            handlers                 = (IList <TryCatchBlockNode>[]) new IList <object> [insnListSize];
            frames                   = new Frame <V> [insnListSize];
            subroutines              = new Subroutine[insnListSize];
            inInstructionsToProcess  = new bool[insnListSize];
            instructionsToProcess    = new int[insnListSize];
            numInstructionsToProcess = 0;
            // For each exception handler, and each instruction within its range, record in 'handlers' the
            // fact that execution can flow from this instruction to the exception handler.
            for (var i = 0; i < method.tryCatchBlocks.Count; ++i)
            {
                var tryCatchBlock = method.tryCatchBlocks[i];
                var startIndex    = insnList.IndexOf(tryCatchBlock.start);
                var endIndex      = insnList.IndexOf(tryCatchBlock.end);
                for (var j = startIndex; j < endIndex; ++j)
                {
                    var insnHandlers = handlers[j];
                    if (insnHandlers == null)
                    {
                        insnHandlers = new List <TryCatchBlockNode>();
                        handlers[j]  = insnHandlers;
                    }

                    insnHandlers.Add(tryCatchBlock);
                }
            }

            // For each instruction, compute the subroutine to which it belongs.
            // Follow the main 'subroutine', and collect the jsr instructions to nested subroutines.
            var main = new Subroutine(null, method.maxLocals, null);
            IList <AbstractInsnNode> jsrInsns = new List <AbstractInsnNode>();

            FindSubroutine(0, main, jsrInsns);
            // Follow the nested subroutines, and collect their own nested subroutines, until all
            // subroutines are found.
            IDictionary <LabelNode, Subroutine> jsrSubroutines = new Dictionary <LabelNode, Subroutine
                                                                                 >();

            while (!(jsrInsns.Count == 0))
            {
                var jsrInsn    = (JumpInsnNode)jsrInsns.RemoveAtReturningValue(0);
                var subroutine = jsrSubroutines.GetOrNull(jsrInsn.label);
                if (subroutine == null)
                {
                    subroutine = new Subroutine(jsrInsn.label, method.maxLocals, jsrInsn);
                    Collections.Put(jsrSubroutines, jsrInsn.label, subroutine);
                    FindSubroutine(insnList.IndexOf(jsrInsn.label), subroutine, jsrInsns);
                }
                else
                {
                    subroutine.callers.Add(jsrInsn);
                }
            }

            // Clear the main 'subroutine', which is not a real subroutine (and was used only as an
            // intermediate step above to find the real ones).
            for (var i = 0; i < insnListSize; ++i)
            {
                if (subroutines[i] != null && subroutines[i].start == null)
                {
                    subroutines[i] = null;
                }
            }
            // Initializes the data structures for the control flow analysis.
            var currentFrame = ComputeInitialFrame(owner, method);

            Merge(0, currentFrame, null);
            Init(owner, method);
            // Control flow analysis.
            while (numInstructionsToProcess > 0)
            {
                // Get and remove one instruction from the list of instructions to process.
                var insnIndex  = instructionsToProcess[--numInstructionsToProcess];
                var oldFrame   = frames[insnIndex];
                var subroutine = subroutines[insnIndex];
                inInstructionsToProcess[insnIndex] = false;
                // Simulate the execution of this instruction.
                AbstractInsnNode insnNode = null;
                try
                {
                    insnNode = method.instructions.Get(insnIndex);
                    var insnOpcode = insnNode.GetOpcode();
                    var insnType   = insnNode.GetType();
                    if (insnType == AbstractInsnNode.Label || insnType == AbstractInsnNode.Line || insnType
                        == AbstractInsnNode.Frame)
                    {
                        Merge(insnIndex + 1, oldFrame, subroutine);
                        NewControlFlowEdge(insnIndex, insnIndex + 1);
                    }
                    else
                    {
                        currentFrame.Init(oldFrame).Execute(insnNode, interpreter);
                        subroutine = subroutine == null ? null : new Subroutine(subroutine);
                        if (insnNode is JumpInsnNode)
                        {
                            var jumpInsn = (JumpInsnNode)insnNode;
                            if (insnOpcode != OpcodesConstants.Goto && insnOpcode != OpcodesConstants.Jsr)
                            {
                                currentFrame.InitJumpTarget(insnOpcode, null);
                                /* target = */
                                Merge(insnIndex + 1, currentFrame, subroutine);
                                NewControlFlowEdge(insnIndex, insnIndex + 1);
                            }

                            var jumpInsnIndex = insnList.IndexOf(jumpInsn.label);
                            currentFrame.InitJumpTarget(insnOpcode, jumpInsn.label);
                            if (insnOpcode == OpcodesConstants.Jsr)
                            {
                                Merge(jumpInsnIndex, currentFrame, new Subroutine(jumpInsn.label, method.maxLocals
                                                                                  , jumpInsn));
                            }
                            else
                            {
                                Merge(jumpInsnIndex, currentFrame, subroutine);
                            }
                            NewControlFlowEdge(insnIndex, jumpInsnIndex);
                        }
                        else if (insnNode is LookupSwitchInsnNode)
                        {
                            var lookupSwitchInsn = (LookupSwitchInsnNode)insnNode;
                            var targetInsnIndex  = insnList.IndexOf(lookupSwitchInsn.dflt);
                            currentFrame.InitJumpTarget(insnOpcode, lookupSwitchInsn.dflt);
                            Merge(targetInsnIndex, currentFrame, subroutine);
                            NewControlFlowEdge(insnIndex, targetInsnIndex);
                            for (var i = 0; i < lookupSwitchInsn.labels.Count; ++i)
                            {
                                var label = lookupSwitchInsn.labels[i];
                                targetInsnIndex = insnList.IndexOf(label);
                                currentFrame.InitJumpTarget(insnOpcode, label);
                                Merge(targetInsnIndex, currentFrame, subroutine);
                                NewControlFlowEdge(insnIndex, targetInsnIndex);
                            }
                        }
                        else if (insnNode is TableSwitchInsnNode)
                        {
                            var tableSwitchInsn = (TableSwitchInsnNode)insnNode;
                            var targetInsnIndex = insnList.IndexOf(tableSwitchInsn.dflt);
                            currentFrame.InitJumpTarget(insnOpcode, tableSwitchInsn.dflt);
                            Merge(targetInsnIndex, currentFrame, subroutine);
                            NewControlFlowEdge(insnIndex, targetInsnIndex);
                            for (var i = 0; i < tableSwitchInsn.labels.Count; ++i)
                            {
                                var label = tableSwitchInsn.labels[i];
                                currentFrame.InitJumpTarget(insnOpcode, label);
                                targetInsnIndex = insnList.IndexOf(label);
                                Merge(targetInsnIndex, currentFrame, subroutine);
                                NewControlFlowEdge(insnIndex, targetInsnIndex);
                            }
                        }
                        else if (insnOpcode == OpcodesConstants.Ret)
                        {
                            if (subroutine == null)
                            {
                                throw new AnalyzerException(insnNode, "RET instruction outside of a subroutine");
                            }
                            for (var i = 0; i < subroutine.callers.Count; ++i)
                            {
                                var caller       = subroutine.callers[i];
                                var jsrInsnIndex = insnList.IndexOf(caller);
                                if (frames[jsrInsnIndex] != null)
                                {
                                    Merge(jsrInsnIndex + 1, frames[jsrInsnIndex], currentFrame, subroutines[jsrInsnIndex
                                          ], subroutine.localsUsed);
                                    NewControlFlowEdge(insnIndex, jsrInsnIndex + 1);
                                }
                            }
                        }
                        else if (insnOpcode != OpcodesConstants.Athrow &&
                                 (insnOpcode < OpcodesConstants.Ireturn || insnOpcode > OpcodesConstants.Return))
                        {
                            if (subroutine != null)
                            {
                                if (insnNode is VarInsnNode)
                                {
                                    var var = ((VarInsnNode)insnNode).var;
                                    subroutine.localsUsed[var] = true;
                                    if (insnOpcode == OpcodesConstants.Lload || insnOpcode == OpcodesConstants.Dload ||
                                        insnOpcode == OpcodesConstants.Lstore ||
                                        insnOpcode == OpcodesConstants.Dstore)
                                    {
                                        subroutine.localsUsed[var + 1] = true;
                                    }
                                }
                                else if (insnNode is IincInsnNode)
                                {
                                    var var = ((IincInsnNode)insnNode).var;
                                    subroutine.localsUsed[var] = true;
                                }
                            }

                            Merge(insnIndex + 1, currentFrame, subroutine);
                            NewControlFlowEdge(insnIndex, insnIndex + 1);
                        }
                    }

                    var insnHandlers = handlers[insnIndex];
                    if (insnHandlers != null)
                    {
                        foreach (var tryCatchBlock in insnHandlers)
                        {
                            Type catchType;
                            if (tryCatchBlock.type == null)
                            {
                                catchType = Type.GetObjectType("java/lang/Throwable");
                            }
                            else
                            {
                                catchType = Type.GetObjectType(tryCatchBlock.type);
                            }
                            if (NewControlFlowExceptionEdge(insnIndex, tryCatchBlock))
                            {
                                var handler = NewFrame(oldFrame);
                                handler.ClearStack();
                                handler.Push(interpreter.NewExceptionValue(tryCatchBlock, handler, catchType));
                                Merge(insnList.IndexOf(tryCatchBlock.handler), handler, subroutine);
                            }
                        }
                    }
                }
                catch (AnalyzerException e)
                {
                    throw new AnalyzerException(e.node, "Error at instruction " + insnIndex + ": " +
                                                e.Message, e);
                }
                catch (Exception e)
                {
                    // DontCheck(IllegalCatch): can't be fixed, for backward compatibility.
                    throw new AnalyzerException(insnNode, "Error at instruction " + insnIndex + ": "
                                                + e.Message, e);
                }
            }

            return(frames);
        }
Esempio n. 10
0
        /// <exception cref="AnalyzerException" />
        public override BasicValue BinaryOperation(AbstractInsnNode insn, BasicValue value1
                                                   , BasicValue value2)
        {
            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Iaload:
            case OpcodesConstants.Baload:
            case OpcodesConstants.Caload:
            case OpcodesConstants.Saload:
            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:
            {
                return(BasicValue.Int_Value);
            }

            case OpcodesConstants.Faload:
            case OpcodesConstants.Fadd:
            case OpcodesConstants.Fsub:
            case OpcodesConstants.Fmul:
            case OpcodesConstants.Fdiv:
            case OpcodesConstants.Frem:
            {
                return(BasicValue.Float_Value);
            }

            case OpcodesConstants.Laload:
            case OpcodesConstants.Ladd:
            case OpcodesConstants.Lsub:
            case OpcodesConstants.Lmul:
            case OpcodesConstants.Ldiv:
            case OpcodesConstants.Lrem:
            case OpcodesConstants.Lshl:
            case OpcodesConstants.Lshr:
            case OpcodesConstants.Lushr:
            case OpcodesConstants.Land:
            case OpcodesConstants.Lor:
            case OpcodesConstants.Lxor:
            {
                return(BasicValue.Long_Value);
            }

            case OpcodesConstants.Daload:
            case OpcodesConstants.Dadd:
            case OpcodesConstants.Dsub:
            case OpcodesConstants.Dmul:
            case OpcodesConstants.Ddiv:
            case OpcodesConstants.Drem:
            {
                return(BasicValue.Double_Value);
            }

            case OpcodesConstants.Aaload:
            {
                return(BasicValue.Reference_Value);
            }

            case OpcodesConstants.Lcmp:
            case OpcodesConstants.Fcmpl:
            case OpcodesConstants.Fcmpg:
            case OpcodesConstants.Dcmpl:
            case OpcodesConstants.Dcmpg:
            {
                return(BasicValue.Int_Value);
            }

            case OpcodesConstants.If_Icmpeq:
            case OpcodesConstants.If_Icmpne:
            case OpcodesConstants.If_Icmplt:
            case OpcodesConstants.If_Icmpge:
            case OpcodesConstants.If_Icmpgt:
            case OpcodesConstants.If_Icmple:
            case OpcodesConstants.If_Acmpeq:
            case OpcodesConstants.If_Acmpne:
            case OpcodesConstants.Putfield:
            {
                return(null);
            }

            default:
            {
                throw new AssertionError();
            }
            }
        }
Esempio n. 11
0
        /// <exception cref="AnalyzerException" />
        public override BasicValue UnaryOperation(AbstractInsnNode insn, BasicValue value
                                                  )
        {
            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Ineg:
            case OpcodesConstants.Iinc:
            case OpcodesConstants.L2i:
            case OpcodesConstants.F2i:
            case OpcodesConstants.D2i:
            case OpcodesConstants.I2b:
            case OpcodesConstants.I2c:
            case OpcodesConstants.I2s:
            {
                return(BasicValue.Int_Value);
            }

            case OpcodesConstants.Fneg:
            case OpcodesConstants.I2f:
            case OpcodesConstants.L2f:
            case OpcodesConstants.D2f:
            {
                return(BasicValue.Float_Value);
            }

            case OpcodesConstants.Lneg:
            case OpcodesConstants.I2l:
            case OpcodesConstants.F2l:
            case OpcodesConstants.D2l:
            {
                return(BasicValue.Long_Value);
            }

            case OpcodesConstants.Dneg:
            case OpcodesConstants.I2d:
            case OpcodesConstants.L2d:
            case OpcodesConstants.F2d:
            {
                return(BasicValue.Double_Value);
            }

            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.Lreturn:
            case OpcodesConstants.Freturn:
            case OpcodesConstants.Dreturn:
            case OpcodesConstants.Areturn:
            case OpcodesConstants.Putstatic:
            {
                return(null);
            }

            case OpcodesConstants.Getfield:
            {
                return(NewValue(Type.GetType(((FieldInsnNode)insn).desc)));
            }

            case OpcodesConstants.Newarray:
            {
                switch (((IntInsnNode)insn).operand)
                {
                case OpcodesConstants.T_Boolean:
                {
                    return(NewValue(Type.GetType("[Z")));
                }

                case OpcodesConstants.T_Char:
                {
                    return(NewValue(Type.GetType("[C")));
                }

                case OpcodesConstants.T_Byte:
                {
                    return(NewValue(Type.GetType("[B")));
                }

                case OpcodesConstants.T_Short:
                {
                    return(NewValue(Type.GetType("[S")));
                }

                case OpcodesConstants.T_Int:
                {
                    return(NewValue(Type.GetType("[I")));
                }

                case OpcodesConstants.T_Float:
                {
                    return(NewValue(Type.GetType("[F")));
                }

                case OpcodesConstants.T_Double:
                {
                    return(NewValue(Type.GetType("[D")));
                }

                case OpcodesConstants.T_Long:
                {
                    return(NewValue(Type.GetType("[J")));
                }
                }

                throw new AnalyzerException(insn, "Invalid array type");
            }

            case OpcodesConstants.Anewarray:
            {
                return(NewValue(Type.GetType("[" + Type.GetObjectType(((TypeInsnNode)insn).desc))
                                ));
            }

            case OpcodesConstants.Arraylength:
            {
                return(BasicValue.Int_Value);
            }

            case OpcodesConstants.Athrow:
            {
                return(null);
            }

            case OpcodesConstants.Checkcast:
            {
                return(NewValue(Type.GetObjectType(((TypeInsnNode)insn).desc)));
            }

            case OpcodesConstants.Instanceof:
            {
                return(BasicValue.Int_Value);
            }

            case OpcodesConstants.Monitorenter:
            case OpcodesConstants.Monitorexit:
            case OpcodesConstants.Ifnull:
            case OpcodesConstants.Ifnonnull:
            {
                return(null);
            }

            default:
            {
                throw new AssertionError();
            }
            }
        }
Esempio n. 12
0
        /// <exception cref="AnalyzerException" />
        public override BasicValue NewOperation(AbstractInsnNode insn)
        {
            switch (insn.GetOpcode())
            {
            case OpcodesConstants.Aconst_Null:
            {
                return(NewValue(Null_Type));
            }

            case OpcodesConstants.Iconst_M1:
            case OpcodesConstants.Iconst_0:
            case OpcodesConstants.Iconst_1:
            case OpcodesConstants.Iconst_2:
            case OpcodesConstants.Iconst_3:
            case OpcodesConstants.Iconst_4:
            case OpcodesConstants.Iconst_5:
            {
                return(BasicValue.Int_Value);
            }

            case OpcodesConstants.Lconst_0:
            case OpcodesConstants.Lconst_1:
            {
                return(BasicValue.Long_Value);
            }

            case OpcodesConstants.Fconst_0:
            case OpcodesConstants.Fconst_1:
            case OpcodesConstants.Fconst_2:
            {
                return(BasicValue.Float_Value);
            }

            case OpcodesConstants.Dconst_0:
            case OpcodesConstants.Dconst_1:
            {
                return(BasicValue.Double_Value);
            }

            case OpcodesConstants.Bipush:
            case OpcodesConstants.Sipush:
            {
                return(BasicValue.Int_Value);
            }

            case OpcodesConstants.Ldc:
            {
                var value = ((LdcInsnNode)insn).cst;
                if (value is int)
                {
                    return(BasicValue.Int_Value);
                }

                if (value is float)
                {
                    return(BasicValue.Float_Value);
                }

                if (value is long)
                {
                    return(BasicValue.Long_Value);
                }

                if (value is double)
                {
                    return(BasicValue.Double_Value);
                }

                if (value is string)
                {
                    return(NewValue(Type.GetObjectType("java/lang/String")));
                }

                if (value is Type)
                {
                    var sort = ((Type)value).GetSort();
                    if (sort == Type.Object || sort == Type.Array)
                    {
                        return(NewValue(Type.GetObjectType("java/lang/Class")));
                    }
                    if (sort == Type.Method)
                    {
                        return(NewValue(Type.GetObjectType("java/lang/invoke/MethodType")));
                    }
                    throw new AnalyzerException(insn, "Illegal LDC value " + value);
                }

                if (value is Handle)
                {
                    return(NewValue(Type.GetObjectType("java/lang/invoke/MethodHandle")));
                }
                if (value is ConstantDynamic)
                {
                    return(NewValue(Type.GetType(((ConstantDynamic)value).GetDescriptor())));
                }
                throw new AnalyzerException(insn, "Illegal LDC value " + value);
                goto case OpcodesConstants.Jsr;
            }

            case OpcodesConstants.Jsr:
            {
                return(BasicValue.Returnaddress_Value);
            }

            case OpcodesConstants.Getstatic:
            {
                return(NewValue(Type.GetType(((FieldInsnNode)insn).desc)));
            }

            case OpcodesConstants.New:
            {
                return(NewValue(Type.GetObjectType(((TypeInsnNode)insn).desc)));
            }

            default:
            {
                throw new AssertionError();
            }
            }
        }
Esempio n. 13
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);
        }
Esempio n. 14
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);
        }
Esempio n. 15
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));
        }
Esempio n. 16
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));
        }