示例#1
0
        private void CompileLogicNot(ILExpression e, ExpectType expect)
        {
            CompileExpression(e.Arguments[0], ExpectType.Primitive);

            //  push exp
            //  ifeq zero
            //  iconst_0
            //  goto exit
            //zero:
            //  iconst_1
            //exit

            string labelSufixes = rnd.Next().ToString();
            string zeroLabel    = "zero" + labelSufixes;
            string exitLabel    = "exit" + labelSufixes;

            Java.OpCodes branch = Java.OpCodes.ifeq;
            TranslateToBool(e.Arguments[0].InferredType, ref branch, e);

            codeGenerator
            .Add(branch, zeroLabel, e)
            .Add(Java.OpCodes.iconst_0, null, e)
            .Add(Java.OpCodes._goto, exitLabel, e)
            .Label(zeroLabel)
            .Add(Java.OpCodes.iconst_1)
            .Label(exitLabel);
        }
示例#2
0
        private void CompileLogicAnd(ILExpression e, ExpectType expect)
        {
            string labelsSufix = rnd.Next().ToString();

            string falseLabel = "false" + labelsSufix;
            string exitLabel  = "exit" + labelsSufix;

            Java.OpCodes branch = Java.OpCodes.ifeq;

            CompileExpression(e.Arguments[0], ExpectType.Primitive);
            TranslateToBool(e.Arguments[0].InferredType, ref branch, e);

            codeGenerator.Add(branch, falseLabel, e);
            CompileExpression(e.Arguments[1], ExpectType.Primitive);
            TranslateToBool(e.Arguments[1].InferredType, ref branch, e);


            branch = Java.OpCodes.ifeq;
            codeGenerator
            .Add(branch, falseLabel, e)
            .Add(Java.OpCodes.iconst_1, null, e)
            .Add(Java.OpCodes._goto, exitLabel, e)
            .Label(falseLabel)
            .Add(Java.OpCodes.iconst_0, null, e)
            .Label(exitLabel);
        }
示例#3
0
        public JavaBytecodeWriter AddArrayLoad(JavaArrayType arrType, object tag)
        {
            Java.OpCodes opcode = Java.OpCodes.aaload;

            switch (arrType)
            {
            case JavaArrayType.Boolean: opcode = Java.OpCodes.baload; break;

            case JavaArrayType.Byte: opcode = Java.OpCodes.baload; break;

            case JavaArrayType.Char: opcode = Java.OpCodes.caload; break;

            case JavaArrayType.Double: opcode = Java.OpCodes.daload; break;

            case JavaArrayType.Float: opcode = Java.OpCodes.faload; break;

            case JavaArrayType.Int: opcode = Java.OpCodes.iaload; break;

            case JavaArrayType.Long: opcode = Java.OpCodes.laload; break;

            case JavaArrayType.Short: opcode = Java.OpCodes.saload; break;
            }

            return(Add(opcode, null, tag));
        }
示例#4
0
        public JavaBytecodeWriter AddReturn(JavaPrimitiveType jp, object tag)
        {
            Java.OpCodes opcode = Java.OpCodes.areturn;
            switch (jp)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Int:
            case JavaPrimitiveType.Short:
                opcode = Java.OpCodes.ireturn;
                break;

            case JavaPrimitiveType.Long: opcode = Java.OpCodes.lreturn; break;

            case JavaPrimitiveType.Float: opcode = Java.OpCodes.freturn; break;

            case JavaPrimitiveType.Double: opcode = Java.OpCodes.dreturn; break;

            case JavaPrimitiveType.Void: opcode = Java.OpCodes._return; break;
            }

            AddInstruction(new JavaInstruction(opcode, null, tag));

            return(this);
        }
示例#5
0
        public JavaBytecodeWriter AddDefaultValue(JavaPrimitiveType jp, object tag)
        {
            Java.OpCodes opcode = Java.OpCodes.aconst_null;

            switch (jp)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Int:
            case JavaPrimitiveType.Short:
                opcode = Java.OpCodes.iconst_0;
                break;

            case JavaPrimitiveType.Long:
                opcode = Java.OpCodes.lconst_0;
                break;

            case JavaPrimitiveType.Float:
                opcode = Java.OpCodes.fconst_0;
                break;

            case JavaPrimitiveType.Double:
                opcode = Java.OpCodes.dconst_0;
                break;
            }

            AddInstruction(new JavaInstruction(opcode, null, tag));

            return(this);
        }
示例#6
0
        private void AddLocalVarStore(JavaPrimitiveType varType, int varIndex, object tag)
        {
            Java.OpCodes shortOpcode = Java.OpCodes.astore_0;
            Java.OpCodes longOpcode  = Java.OpCodes.astore;

            switch (varType)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Short:
            case JavaPrimitiveType.Int:
                shortOpcode = Java.OpCodes.istore_0;
                longOpcode  = Java.OpCodes.istore;
                break;

            case JavaPrimitiveType.Long:
                shortOpcode = Java.OpCodes.lstore_0;
                longOpcode  = Java.OpCodes.lstore;
                break;

            case JavaPrimitiveType.Float:
                shortOpcode = Java.OpCodes.fstore_0;
                longOpcode  = Java.OpCodes.fstore;
                break;

            case JavaPrimitiveType.Double:
                shortOpcode = Java.OpCodes.dstore_0;
                longOpcode  = Java.OpCodes.dstore;
                break;
            }
            AddLocalVarInstruction(shortOpcode, longOpcode, varIndex, tag);
        }
示例#7
0
        private void TranslateToBool(TypeReference inferredType, ref Java.OpCodes cmpOp, object tag)
        {
            JavaPrimitiveType gettedType = JavaHelpers.InterTypeToJavaPrimitive(resolver.Resolve(
                                                                                    inferredType, thisMethod.FullGenericArguments));

            switch (gettedType)
            {
            case JavaPrimitiveType.Double: codeGenerator.Add(Java.OpCodes.d2i, null, tag); break;

            case JavaPrimitiveType.Float: codeGenerator.Add(Java.OpCodes.f2i, null, tag); break;

            case JavaPrimitiveType.Long: codeGenerator.Add(Java.OpCodes.l2i, null, tag); break;

            case JavaPrimitiveType.Ref: cmpOp = (cmpOp == Java.OpCodes.ifne ? Java.OpCodes.ifnonnull : Java.OpCodes.ifnull); break;
            }
        }
示例#8
0
 private void AddLocalVarInstruction(Java.OpCodes shortOpcode, Java.OpCodes longOpcode, int varIndex, object tag)
 {
     if (varIndex < 4)
     {
         AddInstruction(new JavaInstruction((Java.OpCodes)(((int)shortOpcode) + varIndex), null, tag));
     }
     else if (varIndex < byte.MaxValue)
     {
         AddInstruction(new JavaInstruction(longOpcode, (byte)varIndex, tag));
     }
     else
     {
         AddInstruction(new JavaInstruction(Java.OpCodes.wide, null, tag));
         AddInstruction(new JavaInstruction(longOpcode, (ushort)varIndex, tag));
     }
 }
示例#9
0
        public static void SimulateStack(Java.ConstantPool Pool, Java.Attributes.Code resultCode)
        {
            List <int>            SimulatedInstructions = new List <int>();
            Dictionary <int, int> Branches = new Dictionary <int, int>();
            StackImitator         Stack    = new StackImitator();

            Branches.Add(0, 0);
            foreach (Java.Attributes.Code.Exception E in resultCode.ExceptionTable)
            {
                Branches.Add(E.HandlerPC, 1);
            }

            byte[] Code          = resultCode.CodeBytes;
            int    CodeLength    = Code.Length;
            bool   LastWide      = false;
            int    LocalVarCount = 0;

            while (Branches.Count > 0)
            {
                KeyValuePair <int, int> Branch = Branches.First();
                Branches.Remove(Branch.Key);

                Stack.Value = Branch.Value;
                int Position = Branch.Key;

                while (Position < CodeLength)
                {
                    if (SimulatedInstructions.Contains(Position))
                    {
                        break;
                    }
                    SimulatedInstructions.Add(Position);

                    Java.OpCodes OpCode = (Java.OpCodes)Code[Position];
                    if (OpCode == Java.OpCodes.wide)
                    {
                        LastWide = true;
                        Position++;
                        continue;
                    }

                    ByteCode.JavaInstructionDescption Desc = ByteCode.JavaInstructions[OpCode];
                    int Size = Desc.Size;

                    if (LastWide)
                    {
                        Size     = (Size - 1) * 2 + 1;
                        LastWide = false;
                    }

                    int Operand = 0;
                    if ((Desc.OpType != ByteCode.JavaOperandType.None) && (Desc.OpType != ByteCode.JavaOperandType.Special))
                    {
                        Operand = BitConverterBE.ReadAsInt32(Code, Position + 1, Size - 1);
                    }

                    if (OpCodeToVarIndex.ContainsKey(OpCode))
                    {
                        int varIndex = OpCodeToVarIndex[OpCode];

                        if (varIndex < 0)
                        {
                            varIndex = Operand;
                        }

                        if (Array.IndexOf(DoubleSizeVars, OpCode) >= 0)
                        {
                            varIndex++;
                        }

                        LocalVarCount = Math.Max(LocalVarCount, varIndex + 1);
                    }

                    if (Desc.OpType == ByteCode.JavaOperandType.Special)
                    {
                        if (OpCode == Java.OpCodes.invokeinterface)
                        {
                            Operand = BitConverterBE.ReadAsInt32(Code, Position + 1, Size - 1);
                            uint tmp = ((uint)((Operand & 0xffff0000) >> 16) | (uint)((Operand & 0xffff) << 16));
                            Operand = unchecked ((int)tmp);
                        }
                    }

                    if (Desc.PopAction != null)
                    {
                        Stack.Pop(Desc.PopAction(Operand, Pool));
                    }
                    if (Desc.PushAction != null)
                    {
                        Stack.Push(Desc.PushAction(Operand, Pool));
                    }

                    if (Desc.BranchType == ByteCode.JavaBranchType.Break)
                    {
                        break;
                    }
                    else if (Desc.BranchType == ByteCode.JavaBranchType.Conditional)
                    {
                        if ((OpCode == Java.OpCodes.jsr) || (OpCode == Java.OpCodes.jsr_w))
                        {
                            Stack.Push(1);
                        }

                        int NextPosition = Position + Operand;

                        if (!Branches.ContainsKey(NextPosition))
                        {
                            Branches.Add(NextPosition, Stack.Value);
                        }

                        if ((OpCode == Java.OpCodes.jsr) || (OpCode == Java.OpCodes.jsr_w))
                        {
                            Stack.Pop(0);
                        }

                        Position += Size;
                    }
                    else if (Desc.BranchType == ByteCode.JavaBranchType.Switch)
                    {
                        int PaddingLength    = (4 - ((Position + 1) % 4)) % 4;
                        int SwitchArrayStart = Position + PaddingLength + 1;
                        int NextPosition     = BitConverterBE.ReadAsInt32(Code, SwitchArrayStart, 4);

                        if (OpCode == Java.OpCodes.lookupswitch)
                        {
                            int Count = BitConverterBE.ReadAsInt32(Code, SwitchArrayStart + 4, 4);
                            for (int i = 0; i < Count; i++)
                            {
                                int Offset  = BitConverterBE.ReadAsInt32(Code, SwitchArrayStart + 8 + (i * 8) + 4, 4);
                                int NextPos = Position + Offset;
                                if (!Branches.ContainsKey(NextPos))
                                {
                                    Branches.Add(Position + Offset, Stack.Value);
                                }
                            }
                        }
                        else if (OpCode == Java.OpCodes.tableswitch)
                        {
                            int low   = BitConverterBE.ReadAsInt32(Code, SwitchArrayStart + 4, 4);
                            int hight = BitConverterBE.ReadAsInt32(Code, SwitchArrayStart + 8, 4);

                            for (int i = 0; i < hight - low + 1; i++)
                            {
                                int Offset  = BitConverterBE.ReadAsInt32(Code, SwitchArrayStart + 12 + (i * 4), 4);
                                int NextPos = Position + Offset;
                                if (!Branches.ContainsKey(NextPos))
                                {
                                    Branches.Add(Position + Offset, Stack.Value);
                                }
                            }
                        }

                        Position += NextPosition;
                    }
                    else if (Desc.BranchType == ByteCode.JavaBranchType.Goto)
                    {
                        Position += Operand;
                    }
                    else if (Desc.BranchType == ByteCode.JavaBranchType.Next)
                    {
                        Position += Size;
                    }
                }
            }

            resultCode.MaxStack  = (ushort)Stack.MaxValue;
            resultCode.MaxLocals = (ushort)LocalVarCount;
        }
示例#10
0
        private void CompileFlowC(ILExpression e, Java.OpCodes IntCmp, Java.OpCodes RefCmp, Java.OpCodes OtherCmp, bool unsigned = false)
        {
            unsigned = unsigned && Program.Unsigned;

            JavaPrimitiveType jpt = JavaHelpers.InterTypeToJavaPrimitive(
                resolver.Resolve(e.Arguments[0].InferredType, thisMethod.FullGenericArguments));

            Action modifOp = () => { };

            if (unsigned)
            {
                //From http://habrahabr.ru/post/225901 (author: @elw00d)
                switch (jpt)
                {
                case JavaPrimitiveType.Bool:
                case JavaPrimitiveType.Byte:
                    modifOp = () => codeGenerator.AddIntConst(0x80, e).Add(OpCodes.ixor, null, e);
                    break;

                case JavaPrimitiveType.Short:
                    modifOp = () => codeGenerator.AddIntConst(0x8000, e).Add(OpCodes.ixor, null, e);
                    break;

                case JavaPrimitiveType.Int:
                    modifOp = () => codeGenerator.AddIntConst((unchecked ((int)0x80000000)), e).Add(OpCodes.ixor, null, e);
                    break;

                case JavaPrimitiveType.Long:
                    modifOp = () => codeGenerator.AddLongConst((unchecked ((long)0x8000000000000000)), e).Add(OpCodes.lxor, null, e);
                    break;
                }
            }

            CompileExpression(e.Arguments[0], ExpectType.Any);
            modifOp();
            CompileExpression(e.Arguments[1], ExpectType.Any);
            modifOp();

            //  if OtherCmp - dcmpg or fcmpg or lcmp
            //  *Cmp true
            //  iconst_0
            //  goto end
            //:true
            //  iconst_1
            //:end

            string labelPrefix = rnd.Next().ToString();
            string trueLabel   = labelPrefix + "true";
            string endLabel    = labelPrefix + "end";

            switch (jpt)
            {
            case JavaPrimitiveType.Bool:
            case JavaPrimitiveType.Byte:
            case JavaPrimitiveType.Char:
            case JavaPrimitiveType.Short:
            case JavaPrimitiveType.Int:
                codeGenerator.Add(IntCmp, trueLabel, e);
                break;

            case JavaPrimitiveType.Ref: codeGenerator.Add(RefCmp, trueLabel, e); break;

            case JavaPrimitiveType.Long: codeGenerator.Add(Java.OpCodes.lcmp, null, e).Add(OtherCmp, trueLabel, e); break;

            case JavaPrimitiveType.Float: codeGenerator.Add(Java.OpCodes.fcmpg, null, e).Add(OtherCmp, trueLabel, e); break;

            case JavaPrimitiveType.Double: codeGenerator.Add(Java.OpCodes.dcmpg, null, e).Add(OtherCmp, trueLabel, e); break;
            }

            codeGenerator
            .Add(Java.OpCodes.iconst_0, null, e)
            .Add(Java.OpCodes._goto, endLabel, e)
            .Label(trueLabel)
            .Add(Java.OpCodes.iconst_1, null, e)
            .Label(endLabel);
        }
示例#11
0
 public JavaBytecodeWriter Add(Java.OpCodes op, object operand, object tag)
 {
     return(AddInstruction(new JavaInstruction(op, operand, tag)));
 }
示例#12
0
 public JavaBytecodeWriter Add(Java.OpCodes op)
 {
     return(AddInstruction(new JavaInstruction(op, null, null)));
 }
示例#13
0
 public JavaInstruction(Java.OpCodes opcode, object operand, object tag)
 {
     this.Opcode  = opcode;
     this.Operand = operand;
     this.Tag     = tag;
 }
示例#14
0
 public JavaInstruction(Java.OpCodes opcode, object operand)
 {
     this.Opcode  = opcode;
     this.Operand = operand;
     this.Tag     = null;
 }
示例#15
0
 public JavaInstruction(Java.OpCodes opcode)
 {
     this.Opcode  = opcode;
     this.Operand = null;
     this.Tag     = null;
 }