Ejemplo n.º 1
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);
            }
Ejemplo n.º 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);
            }