Ejemplo n.º 1
0
 /// <summary>
 ///     Constructs a new
 ///     <see cref="Subroutine" />
 ///     .
 /// </summary>
 /// <param name="start">the start of this subroutine.</param>
 /// <param name="maxLocals">
 ///     the local variables that are read or written by this subroutine.
 /// </param>
 /// <param name="caller">a JSR instruction that jump to this subroutine.</param>
 internal Subroutine(LabelNode start, int maxLocals, JumpInsnNode caller)
 {
     this.start = start;
     localsUsed = new bool[maxLocals];
     callers    = new List <JumpInsnNode>();
     callers.Add(caller);
 }
Ejemplo n.º 2
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);
            }
Ejemplo n.º 3
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();
                        }
                    }
                }
            }
Ejemplo n.º 4
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;
                                }
                            }
                        }
                    }
                }
            }