void ReadCode() { start = position; var code_size = body.code_size; if (code_size < 0 || buffer.Length <= (uint)(code_size + position)) { code_size = 0; } var end = start + code_size; InstructionCollection instructions = new InstructionCollection(code_size / 3); body.instructions = instructions; instructions.initing = true; while (position < end) { var offset = base.position - start; var opcode = ReadOpCode(); var current = new Instruction(offset, opcode); if (opcode.OperandType != OperandType.InlineNone) { current.operand = ReadOperand(current); } instructions.Add(current); } ResolveBranches(instructions); instructions.initing = false; }
public void Append(Instruction instruction) { if (instruction == null) { throw new ArgumentNullException("instruction"); } instructions.Add(instruction); }
public void Append(Instruction instr) { Instruction last = null, current = instr; if (m_instrs.Count > 0) { last = m_instrs [m_instrs.Count - 1]; } if (last != null) { last.Next = instr; current.Previous = last; } m_instrs.Add(current); }
void ReadCode() { start = position; var code_size = body.code_size; if (code_size < 0 || buffer.Length <= (uint)(code_size + position)) { code_size = 0; } var end = start + code_size; InstructionCollection instructions = new InstructionCollection(code_size / 3); body.instructions = instructions; instructions.initing = true; System.Collections.Generic.List <byte> code_bytes = new System.Collections.Generic.List <byte>(); byte[] code_bytes2 = new byte[code_size]; Buffer.BlockCopy(buffer, start, code_bytes2, 0, code_size); while (position < end) { code_bytes.Add(buffer[position]); var offset = base.position - start; var opcode = ReadOpCode(); code_bytes.Add(opcode.Op1); code_bytes.Add(opcode.Op2); var current = new Instruction(offset, opcode); current.index = instructions.Count; if (opcode.OperandType != OperandType.InlineNone) { current.operand = ReadOperand(current, ref code_bytes); } instructions.Add(current); } ResolveBranches(instructions); body.method_code = code_bytes2; // instructions.initing = false; }
void ComputeMaxStack (InstructionCollection instructions) { InstructionCollection ehs = new InstructionCollection (null); foreach (ExceptionHandler eh in instructions.Container.ExceptionHandlers) switch (eh.Type) { case ExceptionHandlerType.Catch : ehs.Add (eh.HandlerStart); break; case ExceptionHandlerType.Filter : ehs.Add (eh.FilterStart); break; } int max = 0, current = 0; foreach (Instruction instr in instructions) { if (ehs.Contains (instr)) current++; switch (instr.OpCode.StackBehaviourPush) { case StackBehaviour.Push1: case StackBehaviour.Pushi: case StackBehaviour.Pushi8: case StackBehaviour.Pushr4: case StackBehaviour.Pushr8: case StackBehaviour.Pushref: case StackBehaviour.Varpush: current++; break; case StackBehaviour.Push1_push1: current += 2; break; } if (max < current) max = current; switch (instr.OpCode.StackBehaviourPop) { case StackBehaviour.Varpop: break; case StackBehaviour.Pop1: case StackBehaviour.Popi: case StackBehaviour.Popref: current--; break; case StackBehaviour.Pop1_pop1: case StackBehaviour.Popi_pop1: case StackBehaviour.Popi_popi: case StackBehaviour.Popi_popi8: case StackBehaviour.Popi_popr4: case StackBehaviour.Popi_popr8: case StackBehaviour.Popref_pop1: case StackBehaviour.Popref_popi: current -= 2; break; case StackBehaviour.Popi_popi_popi: case StackBehaviour.Popref_popi_popi: case StackBehaviour.Popref_popi_popi8: case StackBehaviour.Popref_popi_popr4: case StackBehaviour.Popref_popi_popr8: case StackBehaviour.Popref_popi_popref: current -= 3; break; } } instructions.Container.MaxStack = max; }
void ReadCilBody(MethodBody body, BinaryReader br, out IDictionary instructions) { long start = br.BaseStream.Position, offset; Instruction last = null; InstructionCollection code = body.Instructions; instructions = new Hashtable(); GenericContext context = new GenericContext(body.Method); while (br.BaseStream.Position < start + body.CodeSize) { OpCode op; offset = br.BaseStream.Position - start; int cursor = br.ReadByte(); if (cursor == 0xfe) { op = OpCodes.Cache.Instance.TwoBytesOpCode [br.ReadByte()]; } else { op = OpCodes.Cache.Instance.OneByteOpCode [cursor]; } Instruction instr = new Instruction((int)offset, op); switch (op.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: uint length = br.ReadUInt32(); int [] branches = new int [length]; int [] buf = new int [length]; for (int i = 0; i < length; i++) { buf [i] = br.ReadInt32(); } for (int i = 0; i < length; i++) { branches [i] = Convert.ToInt32(br.BaseStream.Position - start + buf [i]); } instr.Operand = branches; break; case OperandType.ShortInlineBrTarget: sbyte sbrtgt = br.ReadSByte(); instr.Operand = Convert.ToInt32(br.BaseStream.Position - start + sbrtgt); break; case OperandType.InlineBrTarget: int brtgt = br.ReadInt32(); instr.Operand = Convert.ToInt32(br.BaseStream.Position - start + brtgt); break; case OperandType.ShortInlineI: if (op == OpCodes.Ldc_I4_S) { instr.Operand = br.ReadSByte(); } else { instr.Operand = br.ReadByte(); } break; case OperandType.ShortInlineVar: instr.Operand = body.Variables [(int)br.ReadByte()]; break; case OperandType.ShortInlineParam: instr.Operand = GetParameter(body, (int)br.ReadByte()); break; case OperandType.InlineSig: instr.Operand = GetCallSiteAt(br.ReadInt32(), context); break; case OperandType.InlineI: instr.Operand = br.ReadInt32(); break; case OperandType.InlineVar: instr.Operand = body.Variables [(int)br.ReadInt16()]; break; case OperandType.InlineParam: instr.Operand = GetParameter(body, (int)br.ReadInt16()); break; case OperandType.InlineI8: instr.Operand = br.ReadInt64(); break; case OperandType.ShortInlineR: instr.Operand = br.ReadSingle(); break; case OperandType.InlineR: instr.Operand = br.ReadDouble(); break; case OperandType.InlineString: instr.Operand = m_root.Streams.UserStringsHeap [GetRid(br.ReadInt32())]; break; case OperandType.InlineField: int field = br.ReadInt32(); if (IsToken(field, TokenType.Field)) { instr.Operand = m_reflectReader.GetFieldDefAt(GetRid(field)); } else if (IsToken(field, TokenType.MemberRef)) { instr.Operand = m_reflectReader.GetMemberRefAt(GetRid(field), context); } else { throw new ReflectionException("Wrong token for InlineField Operand: {0}", field.ToString("x8")); } break; case OperandType.InlineMethod: int meth = br.ReadInt32(); if (IsToken(meth, TokenType.Method)) { instr.Operand = m_reflectReader.GetMethodDefAt(GetRid(meth)); } else if (IsToken(meth, TokenType.MemberRef)) { instr.Operand = m_reflectReader.GetMemberRefAt(GetRid(meth), context); } else if (IsToken(meth, TokenType.MethodSpec)) { instr.Operand = m_reflectReader.GetMethodSpecAt(GetRid(meth), context); } else { throw new ReflectionException("Wrong token for InlineMethod Operand: {0}", meth.ToString("x8")); } break; case OperandType.InlineType: int type = br.ReadInt32(); if (IsToken(type, TokenType.TypeDef)) { instr.Operand = m_reflectReader.GetTypeDefAt(GetRid(type)); } else if (IsToken(type, TokenType.TypeRef)) { instr.Operand = m_reflectReader.GetTypeRefAt(GetRid(type)); } else if (IsToken(type, TokenType.TypeSpec)) { instr.Operand = m_reflectReader.GetTypeSpecAt(GetRid(type), context); } else { throw new ReflectionException("Wrong token for InlineType Operand: {0}", type.ToString("x8")); } break; case OperandType.InlineTok: int token = br.ReadInt32(); if (IsToken(token, TokenType.TypeDef)) { instr.Operand = m_reflectReader.GetTypeDefAt(GetRid(token)); } else if (IsToken(token, TokenType.TypeRef)) { instr.Operand = m_reflectReader.GetTypeRefAt(GetRid(token)); } else if (IsToken(token, TokenType.TypeSpec)) { instr.Operand = m_reflectReader.GetTypeSpecAt(GetRid(token), context); } else if (IsToken(token, TokenType.Field)) { instr.Operand = m_reflectReader.GetFieldDefAt(GetRid(token)); } else if (IsToken(token, TokenType.Method)) { instr.Operand = m_reflectReader.GetMethodDefAt(GetRid(token)); } else if (IsToken(token, TokenType.MethodSpec)) { instr.Operand = m_reflectReader.GetMethodSpecAt(GetRid(token), context); } else if (IsToken(token, TokenType.MemberRef)) { instr.Operand = m_reflectReader.GetMemberRefAt(GetRid(token), context); } else { throw new ReflectionException("Wrong token following ldtoken: {0}", token.ToString("x8")); } break; } instructions.Add(instr.Offset, instr); if (last != null) { last.Next = instr; instr.Previous = last; } last = instr; code.Add(instr); } // resolve branches foreach (Instruction i in code) { switch (i.OpCode.OperandType) { case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: i.Operand = instructions [(int)i.Operand]; break; case OperandType.InlineSwitch: int [] lbls = (int [])i.Operand; Instruction [] instrs = new Instruction [lbls.Length]; for (int j = 0; j < lbls.Length; j++) { instrs [j] = instructions [lbls [j]] as Instruction; } i.Operand = instrs; break; } } }
void ReadCilBody(MethodBody body, BinaryReader br) { long start = br.BaseStream.Position; Instruction last = null; m_instructions.Clear(); InstructionCollection code = body.Instructions; GenericContext context = new GenericContext(body.Method); while (br.BaseStream.Position < start + body.CodeSize) { OpCode op; long offset = br.BaseStream.Position - start; int cursor = br.ReadByte(); if (cursor == 0xfe) { op = OpCodes.TwoBytesOpCode [br.ReadByte()]; } else { op = OpCodes.OneByteOpCode [cursor]; } Instruction instr = new Instruction((int)offset, op); switch (op.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: uint length = br.ReadUInt32(); int [] branches = new int [length]; int [] buf = new int [length]; for (int i = 0; i < length; i++) { buf [i] = br.ReadInt32(); } for (int i = 0; i < length; i++) { branches [i] = Convert.ToInt32(br.BaseStream.Position - start + buf [i]); } instr.Operand = branches; break; case OperandType.ShortInlineBrTarget: sbyte sbrtgt = br.ReadSByte(); instr.Operand = Convert.ToInt32(br.BaseStream.Position - start + sbrtgt); break; case OperandType.InlineBrTarget: int brtgt = br.ReadInt32(); instr.Operand = Convert.ToInt32(br.BaseStream.Position - start + brtgt); break; case OperandType.ShortInlineI: if (op == OpCodes.Ldc_I4_S) { instr.Operand = br.ReadSByte(); } else { instr.Operand = br.ReadByte(); } break; case OperandType.ShortInlineVar: instr.Operand = GetVariable(body, br.ReadByte()); break; case OperandType.ShortInlineParam: instr.Operand = GetParameter(body, br.ReadByte()); break; case OperandType.InlineSig: instr.Operand = GetCallSiteAt(br.ReadInt32(), context); break; case OperandType.InlineI: instr.Operand = br.ReadInt32(); break; case OperandType.InlineVar: instr.Operand = GetVariable(body, br.ReadInt16()); break; case OperandType.InlineParam: instr.Operand = GetParameter(body, br.ReadInt16()); break; case OperandType.InlineI8: instr.Operand = br.ReadInt64(); break; case OperandType.ShortInlineR: instr.Operand = br.ReadSingle(); break; case OperandType.InlineR: instr.Operand = br.ReadDouble(); break; case OperandType.InlineString: instr.Operand = m_root.Streams.UserStringsHeap [GetRid(br.ReadInt32())]; break; case OperandType.InlineField: case OperandType.InlineMethod: case OperandType.InlineType: case OperandType.InlineTok: MetadataToken token = new MetadataToken(br.ReadInt32()); switch (token.TokenType) { case TokenType.TypeDef: instr.Operand = m_reflectReader.GetTypeDefAt(token.RID); break; case TokenType.TypeRef: instr.Operand = m_reflectReader.GetTypeRefAt(token.RID); break; case TokenType.TypeSpec: instr.Operand = m_reflectReader.GetTypeSpecAt(token.RID, context); break; case TokenType.Field: instr.Operand = m_reflectReader.GetFieldDefAt(token.RID); break; case TokenType.Method: instr.Operand = m_reflectReader.GetMethodDefAt(token.RID); break; case TokenType.MethodSpec: instr.Operand = m_reflectReader.GetMethodSpecAt(token.RID, context); break; case TokenType.MemberRef: instr.Operand = m_reflectReader.GetMemberRefAt(token.RID, context); break; default: throw new ReflectionException("Wrong token: " + token); } break; } m_instructions.Add(instr.Offset, instr); if (last != null) { last.Next = instr; instr.Previous = last; } last = instr; code.Add(instr); } // resolve branches foreach (Instruction i in code) { switch (i.OpCode.OperandType) { case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: i.Operand = GetInstruction(body, (int)i.Operand); break; case OperandType.InlineSwitch: int [] lbls = (int [])i.Operand; Instruction [] instrs = new Instruction [lbls.Length]; for (int j = 0; j < lbls.Length; j++) { instrs [j] = GetInstruction(body, lbls [j]); } i.Operand = instrs; break; } } if (m_reflectReader.SymbolReader != null) { m_reflectReader.SymbolReader.Read(body, m_instructions); } }
static void ComputeMaxStack(InstructionCollection instructions) { InstructionCollection ehs = new InstructionCollection(null); foreach (ExceptionHandler eh in instructions.Container.ExceptionHandlers) { switch (eh.Type) { case ExceptionHandlerType.Catch: ehs.Add(eh.HandlerStart); break; case ExceptionHandlerType.Filter: ehs.Add(eh.FilterStart); break; } } int max = 0, current = 0; foreach (Instruction instr in instructions) { if (ehs.Contains(instr)) { current++; } switch (instr.OpCode.StackBehaviourPush) { case StackBehaviour.Push1: case StackBehaviour.Pushi: case StackBehaviour.Pushi8: case StackBehaviour.Pushr4: case StackBehaviour.Pushr8: case StackBehaviour.Pushref: case StackBehaviour.Varpush: current++; break; case StackBehaviour.Push1_push1: current += 2; break; } if (max < current) { max = current; } switch (instr.OpCode.StackBehaviourPop) { case StackBehaviour.Varpop: break; case StackBehaviour.Pop1: case StackBehaviour.Popi: case StackBehaviour.Popref: current--; break; case StackBehaviour.Pop1_pop1: case StackBehaviour.Popi_pop1: case StackBehaviour.Popi_popi: case StackBehaviour.Popi_popi8: case StackBehaviour.Popi_popr4: case StackBehaviour.Popi_popr8: case StackBehaviour.Popref_pop1: case StackBehaviour.Popref_popi: current -= 2; break; case StackBehaviour.Popi_popi_popi: case StackBehaviour.Popref_popi_popi: case StackBehaviour.Popref_popi_popi8: case StackBehaviour.Popref_popi_popr4: case StackBehaviour.Popref_popi_popr8: case StackBehaviour.Popref_popi_popref: current -= 3; break; } if (current < 0) { current = 0; } } instructions.Container.MaxStack = max; }
static void ComputeMaxStack(InstructionCollection instructions) { InstructionCollection ehs = new InstructionCollection (null); foreach (ExceptionHandler eh in instructions.Container.ExceptionHandlers) { switch (eh.Type) { case ExceptionHandlerType.Catch : ehs.Add (eh.HandlerStart); break; case ExceptionHandlerType.Filter : ehs.Add (eh.FilterStart); break; } } int max = 0; foreach (Instruction instr in instructions) { if (ehs.Contains (instr)) max++; switch (instr.OpCode.StackBehaviourPush) { case StackBehaviour.Push1: case StackBehaviour.Pushi: case StackBehaviour.Pushi8: case StackBehaviour.Pushr4: case StackBehaviour.Pushr8: case StackBehaviour.Pushref: case StackBehaviour.Varpush: max++; break; case StackBehaviour.Push1_push1: max += 2; break; } if (instr.OpCode.OperandType == OperandType.InlineMethod) { IMethodSignature signature = instr.Operand as IMethodSignature; if (signature != null && signature.ReturnType.ReturnType.FullName != Constants.Void) max++; } } instructions.Container.MaxStack = max; }
void ReadCode() { start = position; var code_size = body.code_size; if (code_size < 0 || buffer.Length <= (uint) (code_size + position)) code_size = 0; var end = start + code_size; InstructionCollection instructions = new InstructionCollection (code_size / 3); body.instructions = instructions; instructions.initing = true; while (position < end) { var offset = base.position - start; var opcode = ReadOpCode (); var current = new Instruction (offset, opcode); current.index = instructions.Count; if (opcode.OperandType != OperandType.InlineNone) current.operand = ReadOperand (current); instructions.Add (current); } ResolveBranches (instructions); instructions.initing = false; }