示例#1
0
        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;
        }
示例#2
0
        public void Append(Instruction instruction)
        {
            if (instruction == null)
            {
                throw new ArgumentNullException("instruction");
            }

            instructions.Add(instruction);
        }
示例#3
0
        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);
        }
示例#4
0
        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;
        }
示例#5
0
		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;
                }
            }
        }
示例#7
0
        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);
            }
        }
示例#8
0
        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;
        }
示例#9
0
        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;
        }
示例#10
0
        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;
        }