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); }
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; }
public override void Write(System.IO.BinaryWriter Writer, ConstantPool Pool) { base.Write(Writer, Pool); Writer.WriteBE(Pool.AddConstant(new Java.Constants.Integer(Value))); }
public new static BooleanElementValue Read(BinaryReader Reader, ConstantPool Pool) { return(new BooleanElementValue(((Constants.Integer)Pool[Reader.ReadUInt16BE()]).Value == 1)); }
public static new AnnotationElementValue Read(BinaryReader Reader, ConstantPool Pool) { return(new AnnotationElementValue(Annotation.Read(Reader, Pool))); }
public new static ClassElementValue Read(BinaryReader Reader, ConstantPool Pool) { return(new ClassElementValue(((Constants.Utf8)Pool[Reader.ReadUInt16BE()]).Value)); }
public override void Write(System.IO.BinaryWriter Writer, ConstantPool Pool) { base.Write(Writer, Pool); Writer.WriteBE(Pool.AddConstant(new Java.Constants.Utf8(Class))); }
protected abstract void Read(uint Length, BinaryReader Reader, ConstantPool Pool);
public new static FloatElementValue Read(BinaryReader Reader, ConstantPool Pool) { return(new FloatElementValue(((Constants.Float)Pool[Reader.ReadUInt16BE()]).Value)); }
public new static LongElementValue Read(BinaryReader Reader, ConstantPool Pool) { return(new LongElementValue(((Constants.Long)Pool[Reader.ReadUInt16BE()]).Value)); }
public virtual void Write(BinaryWriter Writer, ConstantPool Pool) { Writer.Write((byte)Tag); }
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); }
public virtual void Write(BinaryWriter Writer, ConstantPool Pool) { Writer.WriteBE(Pool.AddConstant(new Constants.Utf8(Name))); }
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; } } }
public new static DoubleElementValue Read(BinaryReader Reader, ConstantPool Pool) { return(new DoubleElementValue(((Constants.Double)Pool[Reader.ReadUInt16BE()]).Value)); }
public byte[] Link(Java.ConstantPool pool) { LinkPass1(pool); return(LinkPass2()); }
public new static ByteElementValue Read(BinaryReader Reader, ConstantPool Pool) { return(new ByteElementValue((sbyte)(((Constants.Integer)Pool[Reader.ReadUInt16BE()]).Value))); }
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; }
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); } }