Beispiel #1
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();
                        }
                    }
                }
            }
Beispiel #2
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);
            }