예제 #1
0
 public Java.Attributes.Code End(Java.ConstantPool pool)
 {
     Java.Attributes.Code result = new Java.Attributes.Code();
     result.CodeBytes = Link(pool);
     StackSimulator.SimulateStack(pool, result);
     return(result);
 }
예제 #2
0
 public CodeCompiler(IResolver resolver, INamesController namesController, IByRefController byRefController,
                     InterMethod method, Java.ConstantPool constsPool)
 {
     this.resolver        = resolver;
     this.namesController = namesController;
     this.byRefController = byRefController;
     this.thisMethod      = method;
     this.constsPool      = constsPool;
 }
예제 #3
0
 public override void Write(System.IO.BinaryWriter Writer, ConstantPool Pool)
 {
     base.Write(Writer, Pool);
     Writer.WriteBE(Pool.AddConstant(new Java.Constants.Integer(Value)));
 }
예제 #4
0
 public new static BooleanElementValue Read(BinaryReader Reader, ConstantPool Pool)
 {
     return(new BooleanElementValue(((Constants.Integer)Pool[Reader.ReadUInt16BE()]).Value == 1));
 }
예제 #5
0
 public static new AnnotationElementValue Read(BinaryReader Reader, ConstantPool Pool)
 {
     return(new AnnotationElementValue(Annotation.Read(Reader, Pool)));
 }
예제 #6
0
 public new static ClassElementValue Read(BinaryReader Reader, ConstantPool Pool)
 {
     return(new ClassElementValue(((Constants.Utf8)Pool[Reader.ReadUInt16BE()]).Value));
 }
예제 #7
0
 public override void Write(System.IO.BinaryWriter Writer, ConstantPool Pool)
 {
     base.Write(Writer, Pool);
     Writer.WriteBE(Pool.AddConstant(new Java.Constants.Utf8(Class)));
 }
예제 #8
0
 protected abstract void Read(uint Length, BinaryReader Reader, ConstantPool Pool);
예제 #9
0
 public new static FloatElementValue Read(BinaryReader Reader, ConstantPool Pool)
 {
     return(new FloatElementValue(((Constants.Float)Pool[Reader.ReadUInt16BE()]).Value));
 }
예제 #10
0
 public new static LongElementValue Read(BinaryReader Reader, ConstantPool Pool)
 {
     return(new LongElementValue(((Constants.Long)Pool[Reader.ReadUInt16BE()]).Value));
 }
예제 #11
0
 public virtual void Write(BinaryWriter Writer, ConstantPool Pool)
 {
     Writer.Write((byte)Tag);
 }
예제 #12
0
        public static Attribute ReadAttribute(BinaryReader Reader, ConstantPool Pool)
        {
            string Name   = ((Constants.Utf8)Pool[Reader.ReadUInt16BE()]).Value;
            uint   Length = Reader.ReadUInt32BE();
            long   Next   = (long)Reader.BaseStream.Position - (long)(Length - 6);

            Attribute Result = null;

            if (Name == "AnnotationDefault")
            {
                Result = new Attributes.AnnotationDefault();
            }
            else if (Name == "Code")
            {
                Result = new Attributes.Code();
            }
            else if (Name == "ConstantValue")
            {
                Result = new Attributes.ConstantValue();
            }
            else if (Name == "Deprecated")
            {
                Result = new Attributes.Deprecated();
            }
            else if (Name == "Exceptions")
            {
                Result = new Attributes.Exceptions();
            }
            else if (Name == "InnerClasses")
            {
                Result = new Attributes.InnerClasses();
            }
            else if (Name == "LineNumberTable")
            {
                Result = new Attributes.LineNumberTable();
            }
            else if (Name == "LocalVariableTable")
            {
                Result = new Attributes.LocalVariableTable();
            }
            else if (Name == "RuntimeVisibleAnnotations")
            {
                Result = new Attributes.RuntimeVisibleAnnotations();
            }
            else if (Name == "RuntimeInvisibleAnnotations")
            {
                Result = new Attributes.RuntimeInvisibleAnnotations();
            }
            else if (Name == "RuntimeVisibleParameterAnnotations")
            {
                Result = new Attributes.RuntimeVisibleParameterAnnotations(Reader.ReadByte());
            }
            else if (Name == "RuntimeInvisibleParameterAnnotations")
            {
                Result = new Attributes.RuntimeInvisibleParameterAnnotations(Reader.ReadByte());
            }
            else if (Name == "Signature")
            {
                Result = new Attributes.Signature();
            }
            else if (Name == "SourceFile")
            {
                Result = new Attributes.SourceFile();
            }
            else if (Name == "Synthetic")
            {
                Result = new Attributes.Synthetic();
            }
            else
            {
                Result      = new Attributes.RawAttribute();
                Result.Name = Name;
            }

            Result.Read(Length, Reader, Pool);
            return(Result);
        }
예제 #13
0
 public virtual void Write(BinaryWriter Writer, ConstantPool Pool)
 {
     Writer.WriteBE(Pool.AddConstant(new Constants.Utf8(Name)));
 }
예제 #14
0
        private void LinkPass1(Java.ConstantPool pool)
        {
            int offset = StartOffset;

            bool lastWide = false;

            for (int i = 0; i < outputCode.Count; i++)
            {
                JavaInstruction instr = outputCode[i];
                outputCodeOffsets.Add(instr, offset);

                object lastOperand = instr.Operand;
                if (instr.Operand is Java.Constant)
                {
                    instr.Operand = pool.AddConstant((Java.Constant)instr.Operand);
                }
                else if (instr.Operand is MultianewarrayOperand)
                {
                    MultianewarrayOperand operand = (MultianewarrayOperand)instr.Operand;
                    instr.Operand = pool.AddConstant(operand.ClassOperand) | (operand.DimensionsOperand << 16);
                }

                if (instr.Opcode == Java.OpCodes.ldc)
                {
                    if (((ushort)instr.Operand) > byte.MaxValue)
                    {
                        instr.Opcode = Java.OpCodes.ldc_w;
                    }
                }

                if (instr.Opcode == Java.OpCodes.invokeinterface)
                {
                    if (lastOperand is Java.Constants.MethodRef)
                    {
                        Java.Constants.MethodRef m = (Java.Constants.MethodRef)lastOperand;

                        lastOperand = new Java.Constants.InterfaceMethodRef(m.Class, m.Name, m.Descriptor);
                    }

                    byte   argsCount  = CalculateInterfaceCallArgsCount(((Java.Constants.InterfaceMethodRef)lastOperand).Descriptor);
                    ushort constIndex = (ushort)instr.Operand;
                    instr.Operand = (uint)(constIndex | ((argsCount + 1) << 24));
                }

                int size = Java.ByteCode.JavaInstructions[instr.Opcode].Size;
                if ((size == -1) && (instr.Opcode == Java.OpCodes.lookupswitch))
                {
                    LookupswitchOperand op = (LookupswitchOperand)lastOperand;
                    instr.Operand = op;

                    int paddingLendth = (4 - ((offset + 1) % 4)) % 4;

                    size = 1                      //opcode
                           + paddingLendth        //padding
                           + 4                    //default
                           + 4                    //npairs
                           + op.Pairs.Length * 8; //pairs count * pairs size (8 = 4 + 4)
                }

                if (lastWide)
                {
                    size     = (size - 1) * 2 + 1;
                    lastWide = false;
                }

                offset += size;

                if (instr.Opcode == Java.OpCodes.wide)
                {
                    lastWide = true;
                }
            }
        }
예제 #15
0
 public new static DoubleElementValue Read(BinaryReader Reader, ConstantPool Pool)
 {
     return(new DoubleElementValue(((Constants.Double)Pool[Reader.ReadUInt16BE()]).Value));
 }
예제 #16
0
 public byte[] Link(Java.ConstantPool pool)
 {
     LinkPass1(pool);
     return(LinkPass2());
 }
예제 #17
0
 public new static ByteElementValue Read(BinaryReader Reader, ConstantPool Pool)
 {
     return(new ByteElementValue((sbyte)(((Constants.Integer)Pool[Reader.ReadUInt16BE()]).Value)));
 }
예제 #18
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;
        }
예제 #19
0
        private static void Disasm(Attributes.Code codeAttr, ConstantPool pool, CountingStreamWriter writer, string[] sourceFile)
        {
            byte[] code = codeAttr.CodeBytes;

            int  i        = 0;
            bool lastWide = false;

            Attributes.LineNumberTable lnt    = codeAttr.Attributes.Where(A => A is Attributes.LineNumberTable).FirstOrDefault() as Attributes.LineNumberTable;
            Attributes.LineNumberTable newLnt = new Attributes.LineNumberTable();
            int lastLine = 0;

            while (i < code.Length)
            {
                if ((lnt != null) && (sourceFile != null))
                {
                    try
                    {
                        var lns = lnt.Table.Where(ln => ln.StartPC <= i);
                        if (lns.Count() > 0)
                        {
                            int currLine = lns.Aggregate((i1, i2) => i1.StartPC > i2.StartPC ? i1 : i2).LineNumberInFile;

                            if (lastLine != currLine)
                            {
                                writer.WriteLine("              ## {0}", sourceFile[currLine]);
                            }
                            lastLine = currLine;
                        }
                    }
                    catch (Exception)
                    {
                    }
                }

                newLnt.Table.Add(new Attributes.LineNumberTable.LineNumber((ushort)i, (ushort)writer.CurrLine));

                OpCodes op = (OpCodes)code[i];

                if (!lastWide)
                {
                    writer.Write("              {0,4:X} : ", i);
                }

                if (op == OpCodes.wide)
                {
                    writer.Write("wide ");
                    i++;
                    lastWide = true;
                    continue;
                }

                string opStr      = op.ToString();
                string operandStr = "";

                if (opStr[0] == '_')
                {
                    opStr = opStr.Substring(1);
                }

                writer.Write(opStr);

                ByteCode.JavaInstructionDescption descr = ByteCode.JavaInstructions[op];
                int operandSize = descr.Size - 1;

                if (lastWide)
                {
                    operandSize *= 2;
                    lastWide     = false;
                }

                switch (descr.OpType)
                {
                case ByteCode.JavaOperandType.ConstPool:
                    ushort index = (ushort)BitConverterBE.ReadAsInt32(code, i + 1, operandSize);
                    operandStr = pool[index].ToString();
                    break;

                case ByteCode.JavaOperandType.ConstValue:
                case ByteCode.JavaOperandType.LocalVar:
                    operandStr = BitConverterBE.ReadAsInt32(code, i + 1, operandSize).ToString();
                    break;

                case ByteCode.JavaOperandType.Offset:
                    short offset = (short)BitConverterBE.ReadAsInt32(code, i + 1, operandSize);
                    operandStr = String.Format("{0,4:X}", (i + offset));
                    break;

                case ByteCode.JavaOperandType.Special:
                    switch (op)
                    {
                    case OpCodes.iinc:
                        int op1 = BitConverterBE.ReadAsInt32(code, i + 1, operandSize / 2);
                        int op2 = BitConverterBE.ReadAsInt32(code, i + 1 + operandSize / 2, operandSize / 2);
                        operandStr = String.Format("{0}, {1}", op1, op2);
                        break;

                    case OpCodes.lookupswitch:
                        int paddingLength = (4 - ((i + 1) % 4)) % 4;
                        int _default      = BitConverterBE.ReadAsInt32(code, i + paddingLength + 1, 4);
                        int npairs        = BitConverterBE.ReadAsInt32(code, i + paddingLength + 5, 4);
                        int pairsStart    = i + paddingLength + 9;
                        operandSize = npairs * 8 + 8 + paddingLength;

                        writer.WriteLine(" default: {0,4:X}, npairs: {1}", _default, npairs);

                        for (int pair = 0; pair < npairs; pair++)
                        {
                            int pairValue  = BitConverterBE.ReadAsInt32(code, pairsStart + (pair * 8), 4);
                            int pairOffset = BitConverterBE.ReadAsInt32(code, pairsStart + (pair * 8) + 4, 4);

                            writer.WriteLine("                     {0,4:X} : {1}", pairOffset, pairValue);
                        }
                        break;

                    case OpCodes.tableswitch:
                        paddingLength = (4 - ((i + 1) % 4)) % 4;
                        _default      = BitConverterBE.ReadAsInt32(code, i + paddingLength + 1, 4);
                        int low   = BitConverterBE.ReadAsInt32(code, i + paddingLength + 5, 4);
                        int hight = BitConverterBE.ReadAsInt32(code, i + paddingLength + 9, 4);

                        writer.WriteLine(" default: {0,4:X}, low: {1}, hight: {2}", _default, low, hight);
                        int jmpCount = hight - low + 1;
                        int jmpStart = i + paddingLength + 13;
                        operandSize = jmpCount * 4 + 13 + paddingLength;

                        for (int jmp = 0; jmp < jmpCount; jmp++)
                        {
                            writer.WriteLine("                     {0,4:X} : {1}", BitConverterBE.ReadAsInt32(code, jmpStart + jmp * 4, 4), low + jmp);
                        }
                        break;

                    case OpCodes.invokeinterface:
                    case OpCodes.invokedynamic:
                        index      = (ushort)BitConverterBE.ReadAsInt32(code, i + 1, 2);
                        operandStr = pool[index].ToString();
                        break;

                    case OpCodes.newarray:
                        operandStr = ArrayTypes[code[i + 1]];
                        break;

                    case OpCodes.multianewarray:
                        index = (ushort)BitConverterBE.ReadAsInt32(code, i + 1, 2);
                        byte dismensions = code[i + 3];
                        operandStr = String.Format("{0}, {1}", dismensions, pool[index].ToString());
                        break;
                    }
                    ;
                    break;
                }

                writer.WriteLine(" {0}", operandStr);
                i += 1 + operandSize;
            }

            if (Program.DebugBytecode)
            {
                if (lnt != null)
                {
                    codeAttr.Attributes.Remove(lnt);
                }
                codeAttr.Attributes.Add(newLnt);
            }
        }