Esempio n. 1
0
        /// <exception cref="AnalyzerException" />
        private bool ExecuteDupX2(AbstractInsnNode insn, V value1, Interpreter <V> interpreter
                                  )
        {
            var value2 = Pop();

            if (value2.GetSize() == 1)
            {
                var value3 = Pop();
                if (value3.GetSize() == 1)
                {
                    Push(interpreter.CopyOperation(insn, value1));
                    Push(value3);
                    Push(value2);
                    Push(value1);
                    return(true);
                }
            }
            else
            {
                Push(interpreter.CopyOperation(insn, value1));
                Push(value2);
                Push(value1);
                return(true);
            }

            return(false);
        }
Esempio n. 2
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. 3
0
 /// <summary>
 /// Remove the dead code - or unreachable code - from a method.
 /// </summary>
 /// <param name="method">  the method to be updated </param>
 internal virtual void removeDeadCode(MethodNode method)
 {
     try
     {
         // Analyze the method using the BasicInterpreter.
         // As a result, the computed frames are null for instructions
         // that cannot be reached.
         Analyzer analyzer = new Analyzer(new BasicInterpreter());
         analyzer.analyze(specializedClassName, method);
         Frame[]            frames = analyzer.Frames;
         AbstractInsnNode[] insns  = method.instructions.toArray();
         for (int i = 0; i < frames.Length; i++)
         {
             AbstractInsnNode insn = insns[i];
             if (frames[i] == null && insn.Type != AbstractInsnNode.LABEL)
             {
                 // This instruction was not reached by the analyzer
                 method.instructions.remove(insn);
                 insns[i] = null;
             }
         }
     }
     catch (AnalyzerException)
     {
         // Ignore error
     }
 }
Esempio n. 4
0
 /// <summary>
 ///     Constructs a new
 ///     <see cref="AnalyzerException" />
 ///     .
 /// </summary>
 /// <param name="insn">the bytecode instruction where the analysis failed.</param>
 /// <param name="message">the reason why the analysis failed.</param>
 /// <param name="expected">an expected value.</param>
 /// <param name="actual">the actual value, different from the expected one.</param>
 public AnalyzerException(AbstractInsnNode insn, string message, object expected,
                          Value actual)
     : base((message == null ? "Expected " : message + ": expected ") + expected + ", but found "
            + actual)
 {
     node = insn;
 }
Esempio n. 5
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);
     }
 }
Esempio n. 6
0
            internal virtual AbstractInsnNode getConstantInsn(object value)
            {
                AbstractInsnNode constantInsn = null;

                if (isIntValue(value))
                {
                    int n = getIntValue(value);
                    // Find the optimum opcode to represent this integer value
                    switch (n)
                    {
                    case -1:
                        constantInsn = new InsnNode(Opcodes.ICONST_M1);
                        break;

                    case 0:
                        constantInsn = new InsnNode(Opcodes.ICONST_0);
                        break;

                    case 1:
                        constantInsn = new InsnNode(Opcodes.ICONST_1);
                        break;

                    case 2:
                        constantInsn = new InsnNode(Opcodes.ICONST_2);
                        break;

                    case 3:
                        constantInsn = new InsnNode(Opcodes.ICONST_3);
                        break;

                    case 4:
                        constantInsn = new InsnNode(Opcodes.ICONST_4);
                        break;

                    case 5:
                        constantInsn = new InsnNode(Opcodes.ICONST_5);
                        break;

                    default:
                        if (sbyte.MinValue <= n && n < sbyte.MaxValue)
                        {
                            constantInsn = new IntInsnNode(Opcodes.BIPUSH, n);
                        }
                        else if (short.MinValue <= n && n < short.MaxValue)
                        {
                            constantInsn = new IntInsnNode(Opcodes.SIPUSH, n);
                        }
                        else
                        {
                            constantInsn = new LdcInsnNode(new int?(n));
                        }
                        break;
                    }
                }

                return(constantInsn);
            }
Esempio n. 7
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. 8
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. 9
0
            /// <summary>
            /// Remove unused line numbers, i.e. line numbers where there is no code.
            /// </summary>
            /// <param name="method">  the method to be updated </param>
            internal virtual void removeUselessLineNumbers(MethodNode method)
            {
                // Remove all the line numbers being immediately followed by another line number.
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: for (java.util.ListIterator<?> lit = method.instructions.iterator(); lit.hasNext();)
                for (IEnumerator <object> lit = method.instructions.GetEnumerator(); lit.MoveNext();)
                {
                    AbstractInsnNode insn = (AbstractInsnNode)lit.Current;
                    if (insn.Type == LINE)
                    {
                        AbstractInsnNode nextInsn = insn.Next;
                        if (nextInsn != null && nextInsn.Type == LINE)
                        {
//JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only:
                            lit.remove();
                        }
                    }
                }
            }
Esempio n. 10
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. 11
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. 12
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. 13
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. 14
0
            /// <summary>
            /// Remove unused labels, i.e. labels that are not referenced.
            /// </summary>
            /// <param name="method">  the method to be updated </param>
            internal virtual void removeUnusedLabels(MethodNode method)
            {
                // Scan for all the used labels
                ISet <LabelNode> usedLabels = new HashSet <LabelNode>();

//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: for (java.util.ListIterator<?> lit = method.instructions.iterator(); lit.hasNext();)
                for (IEnumerator <object> lit = method.instructions.GetEnumerator(); lit.MoveNext();)
                {
                    AbstractInsnNode insn = (AbstractInsnNode)lit.Current;
                    if (insn.Type == JUMP_INSN)
                    {
                        JumpInsnNode jumpInsn = (JumpInsnNode)insn;
                        usedLabels.Add(jumpInsn.label);
                    }
                    else if (insn.Type == TABLESWITCH_INSN)
                    {
                        TableSwitchInsnNode tableSwitchInsn = (TableSwitchInsnNode)insn;
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: for (java.util.Iterator<?> it = tableSwitchInsn.labels.iterator(); it.hasNext();)
                        for (IEnumerator <object> it = tableSwitchInsn.labels.GetEnumerator(); it.MoveNext();)
                        {
                            LabelNode labelNode = (LabelNode)it.Current;
                            if (labelNode != null)
                            {
                                usedLabels.Add(labelNode);
                            }
                        }
                    }
                    else if (insn.Type == LOOKUPSWITCH_INSN)
                    {
                        LookupSwitchInsnNode loopupSwitchInsn = (LookupSwitchInsnNode)insn;
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: for (java.util.Iterator<?> it = loopupSwitchInsn.labels.iterator(); it.hasNext();)
                        for (IEnumerator <object> it = loopupSwitchInsn.labels.GetEnumerator(); it.MoveNext();)
                        {
                            LabelNode labelNode = (LabelNode)it.Current;
                            if (labelNode != null)
                            {
                                usedLabels.Add(labelNode);
                            }
                        }
                    }
                }

                // Remove all the label instructions not being identified in the scan
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: for (java.util.ListIterator<?> lit = method.instructions.iterator(); lit.hasNext();)
                for (IEnumerator <object> lit = method.instructions.GetEnumerator(); lit.MoveNext();)
                {
                    AbstractInsnNode insn = (AbstractInsnNode)lit.Current;
                    if (insn.Type == LABEL)
                    {
                        if (!usedLabels.Contains(insn))
                        {
//JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only:
                            lit.remove();
                        }
                    }
                }
            }
Esempio n. 15
0
 /// <exception cref="AnalyzerException" />
 public override BasicValue CopyOperation(AbstractInsnNode insn, BasicValue value)
 {
     return(value);
 }
Esempio n. 16
0
            /// <summary>
            /// Optimize the jumps from a method:
            /// - jumps to a "GOTO label" instruction
            ///   are replaced with a direct jump to "label";
            /// - a GOTO to the next instruction is deleted;
            /// - a GOTO to a RETURN or ATHROW instruction
            ///   is replaced with this RETURN or ATHROW instruction.
            /// </summary>
            /// <param name="method">  the method to be optimized </param>
            internal virtual void optimizeJumps(MethodNode method)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: for (java.util.ListIterator<?> lit = method.instructions.iterator(); lit.hasNext();)
                for (IEnumerator <object> lit = method.instructions.GetEnumerator(); lit.MoveNext();)
                {
                    AbstractInsnNode insn = (AbstractInsnNode)lit.Current;
                    if (insn.Type == JUMP_INSN)
                    {
                        JumpInsnNode     jumpInsn = (JumpInsnNode)insn;
                        LabelNode        label    = jumpInsn.label;
                        AbstractInsnNode target;
                        // while target == goto l, replace label with l
                        while (true)
                        {
                            target = label;
                            while (target != null && target.Opcode < 0)
                            {
                                target = target.Next;
                            }
                            if (target != null && target.Opcode == Opcodes.GOTO)
                            {
                                label = ((JumpInsnNode)target).label;
                            }
                            else
                            {
                                break;
                            }
                        }

                        // update target
                        jumpInsn.label = label;

                        bool removeJump = false;
                        if (jumpInsn.Opcode == Opcodes.GOTO)
                        {
                            // Delete a GOTO to the next instruction
                            AbstractInsnNode next = jumpInsn.Next;
                            while (next != null)
                            {
                                if (next == label)
                                {
                                    removeJump = true;
                                    break;
                                }
                                else if (next.Opcode >= 0)
                                {
                                    break;
                                }
                                next = next.Next;
                            }
                        }

                        if (removeJump)
                        {
//JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only:
                            lit.remove();
                        }
                        else
                        {
                            // if possible, replace jump with target instruction
                            if (jumpInsn.Opcode == Opcodes.GOTO && target != null)
                            {
                                switch (target.Opcode)
                                {
                                case Opcodes.IRETURN:
                                case Opcodes.LRETURN:
                                case Opcodes.FRETURN:
                                case Opcodes.DRETURN:
                                case Opcodes.ARETURN:
                                case Opcodes.RETURN:
                                case Opcodes.ATHROW:
                                    // replace instruction with clone of target
                                    method.instructions.set(insn, target.clone(null));
                                    break;
                                }
                            }
                        }
                    }
                }
            }
Esempio n. 17
0
            internal virtual void visitMethod(MethodNode method)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'sealed override':
//ORIGINAL LINE: sealed override bool isConstructor = "<init>".equals(method.name);
                bool isConstructor = "<init>".Equals(method.name);

                deleteUpToInsn = null;
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: for (java.util.ListIterator<?> lit = method.instructions.iterator(); lit.hasNext();)
                for (IEnumerator <object> lit = method.instructions.GetEnumerator(); lit.MoveNext();)
                {
                    AbstractInsnNode insn = (AbstractInsnNode)lit.Current;

                    if (deleteUpToInsn != null)
                    {
                        if (insn == deleteUpToInsn)
                        {
                            deleteUpToInsn = null;
                        }
                        else
                        {
                            // Do not delete labels, they could be used as a target from a previous jump.
                            // Also keep line numbers for easier debugging.
                            if (insn.Type != LABEL && insn.Type != LINE)
                            {
//JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only:
                                lit.remove();
                            }
                            continue;
                        }
                    }

                    if (insn.Type == AbstractInsnNode.FRAME)
                    {
                        // Remove all the FRAME information, they will be calculated
                        // anew after the class specialization.
                        lit.remove();
                    }
                    else if (insn.Opcode == Opcodes.GETSTATIC)
                    {
                        FieldInsnNode fieldInsn = (FieldInsnNode)insn;
                        if (variables.ContainsKey(fieldInsn.name))
                        {
                            bool processed = false;
                            value = variables[fieldInsn.name];
                            AbstractInsnNode nextInsn = insn.Next;
                            if (analyseIfTestInt(method, insn))
                            {
                                processed = true;
                            }
                            else if (nextInsn != null && nextInsn.Type == TABLESWITCH_INSN)
                            {
                                TableSwitchInsnNode switchInsn = (TableSwitchInsnNode)nextInsn;
                                LabelNode           label      = null;
                                if (isIntValue(value))
                                {
                                    int n = getIntValue(value);
                                    if (n >= switchInsn.min && n <= switchInsn.max)
                                    {
                                        int i = n - switchInsn.min;
                                        if (i < switchInsn.labels.size())
                                        {
                                            label = (LabelNode)switchInsn.labels.get(i);
                                        }
                                    }
                                }
                                if (label == null)
                                {
                                    label = switchInsn.dflt;
                                }
                                if (label != null)
                                {
                                    // Replace the table switch instruction by a GOTO to the switch label
                                    method.instructions.set(insn, new JumpInsnNode(Opcodes.GOTO, label));
                                    processed = true;
                                }
                            }
                            else if (nextInsn != null && nextInsn.Type == LOOKUPSWITCH_INSN)
                            {
                                LookupSwitchInsnNode switchInsn = (LookupSwitchInsnNode)nextInsn;
                                LabelNode            label      = null;
                                if (isIntValue(value))
                                {
                                    int n = getIntValue(value);
                                    int i = 0;
                                    foreach (object value in switchInsn.keys)
                                    {
                                        if (value is int?)
                                        {
                                            if (((int?)value).Value == n)
                                            {
                                                label = (LabelNode)switchInsn.labels.get(i);
                                                break;
                                            }
                                        }
                                        i++;
                                    }
                                }
                                if (label == null)
                                {
                                    label = switchInsn.dflt;
                                }
                                if (label != null)
                                {
                                    // Replace the table switch instruction by a GOTO to the switch label
                                    method.instructions.set(insn, new JumpInsnNode(Opcodes.GOTO, label));
                                    processed = true;
                                }
                            }
                            else if (nextInsn != null && nextInsn.Type == AbstractInsnNode.INSN)
                            {
                                int   opcode          = nextInsn.Opcode;
                                int   n               = 0;
                                float f               = 0f;
                                bool  isIntConstant   = false;
                                bool  isFloatConstant = false;
                                switch (opcode)
                                {
                                case Opcodes.ICONST_M1:
                                    n             = -1;
                                    isIntConstant = true;
                                    break;

                                case Opcodes.ICONST_0:
                                    n             = 0;
                                    isIntConstant = true;
                                    break;

                                case Opcodes.ICONST_1:
                                    n             = 1;
                                    isIntConstant = true;
                                    break;

                                case Opcodes.ICONST_2:
                                    n             = 2;
                                    isIntConstant = true;
                                    break;

                                case Opcodes.ICONST_3:
                                    n             = 3;
                                    isIntConstant = true;
                                    break;

                                case Opcodes.ICONST_4:
                                    n             = 4;
                                    isIntConstant = true;
                                    break;

                                case Opcodes.ICONST_5:
                                    n             = 5;
                                    isIntConstant = true;
                                    break;

                                case Opcodes.FCONST_0:
                                    f = 0f;
                                    isFloatConstant = true;
                                    break;

                                case Opcodes.FCONST_1:
                                    f = 1f;
                                    isFloatConstant = true;
                                    break;

                                case Opcodes.FCONST_2:
                                    f = 2f;
                                    isFloatConstant = true;
                                    break;
                                }
                                if (isIntConstant)
                                {
                                    if (analyseIfTestInt(method, insn, nextInsn, n))
                                    {
                                        processed = true;
                                    }
                                }
                                else if (isFloatConstant)
                                {
                                    if (analyseIfTestFloat(method, insn, nextInsn, f))
                                    {
                                        processed = true;
                                    }
                                }
                            }
                            else if (nextInsn != null && nextInsn.Type == AbstractInsnNode.INT_INSN)
                            {
                                IntInsnNode intInsn = (IntInsnNode)nextInsn;
                                if (analyseIfTestInt(method, insn, nextInsn, intInsn.operand))
                                {
                                    processed = true;
                                }
                            }
                            else if (nextInsn != null && nextInsn.Type == AbstractInsnNode.LDC_INSN)
                            {
                                LdcInsnNode ldcInsn = (LdcInsnNode)nextInsn;
                                if (isIntValue(ldcInsn.cst))
                                {
                                    if (analyseIfTestInt(method, insn, nextInsn, getIntValue(ldcInsn.cst)))
                                    {
                                        processed = true;
                                    }
                                }
                                else if (isFloatValue(ldcInsn.cst))
                                {
                                    if (analyseIfTestFloat(method, insn, nextInsn, getFloatValue(ldcInsn.cst)))
                                    {
                                        processed = true;
                                    }
                                }
                            }

                            if (!processed)
                            {
                                // Replace the FieldInfo access by its constant value
                                AbstractInsnNode constantInsn = getConstantInsn(value);
                                if (constantInsn != null)
                                {
                                    method.instructions.set(insn, constantInsn);
                                }
                            }
                        }
                        else
                        {
                            if (fieldInsn.owner.Equals(className))
                            {
                                // Replace the class name by the specialized class name
                                fieldInsn.owner = specializedClassName;
                            }
                        }
                    }
                    else if (insn.Opcode == Opcodes.PUTSTATIC)
                    {
                        FieldInsnNode fieldInsn = (FieldInsnNode)insn;
                        if (!variables.ContainsKey(fieldInsn.name))
                        {
                            if (fieldInsn.owner.Equals(className))
                            {
                                // Replace the class name by the specialized class name
                                fieldInsn.owner = specializedClassName;
                            }
                        }
                    }
                    else if (insn.Type == AbstractInsnNode.METHOD_INSN)
                    {
                        MethodInsnNode methodInsn = (MethodInsnNode)insn;
                        if (methodInsn.owner.Equals(className))
                        {
                            // Replace the class name by the specialized class name
                            methodInsn.owner = specializedClassName;
                        }
                        else if (isConstructor && methodInsn.owner.Equals(superClassName))
                        {
                            // Update the call to the constructor of the parent class
                            methodInsn.owner = className;
                        }
                    }
                }

                // Delete all the information about local variables, they are no longer correct
                // (the class loader would complain).
                method.localVariables.clear();

                optimizeJumps(method);
                removeDeadCode(method);
                optimizeJumps(method);
                removeUnusedLabels(method);
                removeUselessLineNumbers(method);
            }
Esempio n. 18
0
 /// <exception cref="AnalyzerException" />
 public override BasicValue TernaryOperation(AbstractInsnNode insn, BasicValue value1
                                             , BasicValue value2, BasicValue value3)
 {
     return(null);
 }
Esempio n. 19
0
 /// <summary>
 ///     Constructs a new
 ///     <see cref="AnalyzerException" />
 ///     .
 /// </summary>
 /// <param name="insn">the bytecode instruction where the analysis failed.</param>
 /// <param name="message">the reason why the analysis failed.</param>
 /// <param name="cause">the cause of the failure.</param>
 public AnalyzerException(AbstractInsnNode insn, string message, Exception cause)
     : base(message, cause)
 {
     node = insn;
 }
Esempio n. 20
0
            internal virtual bool analyseIfTestFloat(MethodNode method, AbstractInsnNode insn, AbstractInsnNode valueInsn, float testValue)
            {
                bool eliminateJump = false;

                AbstractInsnNode nextInsn = valueInsn.Next;

                if (nextInsn != null && (nextInsn.Opcode == Opcodes.FCMPL || nextInsn.Opcode == Opcodes.FCMPG))
                {
                    AbstractInsnNode nextNextInsn = nextInsn.Next;
                    if (nextNextInsn != null && nextNextInsn.Type == JUMP_INSN)
                    {
                        JumpInsnNode jumpInsn = (JumpInsnNode)nextNextInsn;
                        bool         doJump   = false;
                        switch (jumpInsn.Opcode)
                        {
                        case Opcodes.IFEQ:
                            if (isFloatValue(value))
                            {
                                doJump        = getFloatValue(value) == testValue;
                                eliminateJump = true;
                            }
                            break;

                        case Opcodes.IFNE:
                            if (isFloatValue(value))
                            {
                                doJump        = getFloatValue(value) != testValue;
                                eliminateJump = true;
                            }
                            break;

                        case Opcodes.IFLT:
                            if (isFloatValue(value))
                            {
                                doJump        = getFloatValue(value) < testValue;
                                eliminateJump = true;
                            }
                            break;

                        case Opcodes.IFGE:
                            if (isFloatValue(value))
                            {
                                doJump        = getFloatValue(value) >= testValue;
                                eliminateJump = true;
                            }
                            break;

                        case Opcodes.IFGT:
                            if (isFloatValue(value))
                            {
                                doJump        = getFloatValue(value) > testValue;
                                eliminateJump = true;
                            }
                            break;

                        case Opcodes.IFLE:
                            if (isFloatValue(value))
                            {
                                doJump        = getFloatValue(value) <= testValue;
                                eliminateJump = true;
                            }
                            break;
                        }

                        if (eliminateJump)
                        {
                            if (doJump)
                            {
                                // Replace the expression test by a fixed GOTO.
                                // The skipped instructions will be eliminated by dead code analysis.
                                method.instructions.set(insn, new JumpInsnNode(Opcodes.GOTO, jumpInsn.label));
                            }
                            else
                            {
                                method.instructions.remove(insn);
                            }
                            deleteUpToInsn = jumpInsn.Next;
                        }
                    }
                }

                return(eliminateJump);
            }
Esempio n. 21
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. 22
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. 23
0
 public override void ReturnOperation(AbstractInsnNode insn, SourceValue value, SourceValue
                                      expected)
 {
 }
Esempio n. 24
0
 public override SourceValue TernaryOperation(AbstractInsnNode insn, SourceValue value1
                                              , SourceValue value2, SourceValue value3)
 {
     return(new SourceValue(1, insn));
 }
Esempio n. 25
0
 internal virtual bool analyseIfTestInt(MethodNode method, AbstractInsnNode insn)
 {
     return(analyseIfTestInt(method, insn, insn, null));
 }
Esempio n. 26
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. 27
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. 28
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. 29
0
        private static string DetailedMessage(string errorMessage, MethodNode method, Frame[] frames, AbstractInsnNode errorLocation)
        {
            StringWriter message = new StringWriter();

            using (PrintWriter @out = new PrintWriter(message))
            {
                IList <int> localLengths = new List <int>();
                IList <int> stackLengths = new List <int>();
                foreach (Frame frame in frames)
                {
                    if (frame != null)
                    {
                        for (int i = 0; i < frame.Locals; i++)
                        {
                            Insert(i, frame.getLocal(i), localLengths);
                        }
                        for (int i = 0; i < frame.StackSize; i++)
                        {
                            Insert(i, frame.getStack(i), stackLengths);
                        }
                    }
                }
                Textifier          formatted = new Textifier();
                TraceMethodVisitor mv        = new TraceMethodVisitor(formatted);

                @out.println(errorMessage);
                @out.append("\t\tin ").append(method.name).append(method.desc).println();
                for (int i = 0; i < method.instructions.size(); i++)
                {
                    AbstractInsnNode insn = method.instructions.get(i);
                    insn.accept(mv);
                    Frame frame = frames[i];
                    @out.append("\t\t");
                    @out.append(insn == errorLocation ? ">>> " : "    ");
                    @out.format("%05d [", i);
                    if (frame == null)
                    {
//JAVA TO C# CONVERTER WARNING: Unlike Java's ListIterator, enumerators in .NET do not allow altering the collection:
                        Padding(@out, localLengths.GetEnumerator(), '?');
                        @out.append(" : ");
//JAVA TO C# CONVERTER WARNING: Unlike Java's ListIterator, enumerators in .NET do not allow altering the collection:
                        Padding(@out, stackLengths.GetEnumerator(), '?');
                    }
                    else
                    {
                        Emit(@out, localLengths, frame.getLocal, frame.Locals);
                        Padding(@out, localLengths.listIterator(frame.Locals), '-');
                        @out.append(" : ");
                        Emit(@out, stackLengths, frame.getStack, frame.StackSize);
                        Padding(@out, stackLengths.listIterator(frame.StackSize), ' ');
                    }
                    @out.print("] : ");
                    @out.print(formatted.text.get(formatted.text.size() - 1));
                }
                for (int j = 0; j < method.tryCatchBlocks.size(); j++)
                {
                    method.tryCatchBlocks.get(j).accept(mv);
                    @out.print(" " + formatted.text.get(formatted.text.size() - 1));
                }
            }
            return(message.ToString());
        }
Esempio n. 30
0
 public override SourceValue CopyOperation(AbstractInsnNode insn, SourceValue value
                                           )
 {
     return(new SourceValue(value.GetSize(), insn));
 }