Ejemplo n.º 1
0
		static void CopyBranchStackSize (Instruction instruction, ref Dictionary<Instruction, int> stack_sizes, int stack_size)
		{
			if (stack_size == 0)
				return;

			switch (instruction.opcode.OperandType) {
			case OperandType.ShortInlineBrTarget:
			case OperandType.InlineBrTarget:
				CopyBranchStackSize (ref stack_sizes, (Instruction) instruction.operand, stack_size);
				break;
			case OperandType.InlineSwitch:
				var targets = (Instruction[]) instruction.operand;
				for (int i = 0; i < targets.Length; i++)
					CopyBranchStackSize (ref stack_sizes, targets [i], stack_size);
				break;
			}
		}
Ejemplo n.º 2
0
		static void CopyBranchStackSize (ref Dictionary<Instruction, int> stack_sizes, Instruction target, int stack_size)
		{
			if (stack_sizes == null)
				stack_sizes = new Dictionary<Instruction, int> ();

			int branch_stack_size = stack_size;

			int computed_size;
			if (stack_sizes.TryGetValue (target, out computed_size))
				branch_stack_size = System.Math.Max (branch_stack_size, computed_size);

			stack_sizes [target] = branch_stack_size;
		}
Ejemplo n.º 3
0
		static void AddExceptionStackSize (Instruction handler_start, ref Dictionary<Instruction, int> stack_sizes)
		{
			if (handler_start == null)
				return;

			if (stack_sizes == null)
				stack_sizes = new Dictionary<Instruction, int> ();

			stack_sizes [handler_start] = 1;
		}
Ejemplo n.º 4
0
		static void ComputeStackSize (Instruction instruction, ref Dictionary<Instruction, int> stack_sizes, ref int stack_size, ref int max_stack)
		{
			int computed_size;
			if (stack_sizes != null && stack_sizes.TryGetValue (instruction, out computed_size))
				stack_size = computed_size;

			max_stack = System.Math.Max (max_stack, stack_size);
			ComputeStackDelta (instruction, ref stack_size);
			max_stack = System.Math.Max (max_stack, stack_size);

			CopyBranchStackSize (instruction, ref stack_sizes, stack_size);
			ComputeStackSize (instruction, ref stack_size);
		}
Ejemplo n.º 5
0
		object ReadOperand (Instruction instruction)
		{
			switch (instruction.opcode.OperandType) {
			case OperandType.InlineSwitch:
				var length = ReadInt32 ();
				var base_offset = Offset + (4 * length);
				var branches = new int [length];
				for (int i = 0; i < length; i++)
					branches [i] = base_offset + ReadInt32 ();
				return branches;
			case OperandType.ShortInlineBrTarget:
				return ReadSByte () + Offset;
			case OperandType.InlineBrTarget:
				return ReadInt32 () + Offset;
			case OperandType.ShortInlineI:
				if (instruction.opcode == OpCodes.Ldc_I4_S)
					return ReadSByte ();

				return ReadByte ();
			case OperandType.InlineI:
				return ReadInt32 ();
			case OperandType.ShortInlineR:
				return ReadSingle ();
			case OperandType.InlineR:
				return ReadDouble ();
			case OperandType.InlineI8:
				return ReadInt64 ();
			case OperandType.ShortInlineVar:
				return GetVariable (ReadByte ());
			case OperandType.InlineVar:
				return GetVariable (ReadUInt16 ());
			case OperandType.ShortInlineArg:
				return GetParameter (ReadByte ());
			case OperandType.InlineArg:
				return GetParameter (ReadUInt16 ());
			case OperandType.InlineSig:
				return GetCallSite (ReadToken ());
			case OperandType.InlineString:
				return GetString (ReadToken ());
			case OperandType.InlineTok:
			case OperandType.InlineType:
			case OperandType.InlineMethod:
			case OperandType.InlineField:
				return reader.LookupToken (ReadToken ());
			default:
				throw new NotSupportedException ();
			}
		}
Ejemplo n.º 6
0
		public void Emit (OpCode opcode, Instruction [] targets)
		{
			Append (Create (opcode, targets));
		}
Ejemplo n.º 7
0
		public static Instruction Create (OpCode opcode, Instruction target)
		{
			if (target == null)
				throw new ArgumentNullException ("target");
			if (opcode.OperandType != OperandType.InlineBrTarget &&
				opcode.OperandType != OperandType.ShortInlineBrTarget)
				throw new ArgumentException ("opcode");

			return new Instruction (opcode, target);
		}
Ejemplo n.º 8
0
		static bool IsFatRange (Instruction start, Instruction end)
		{
			if (start == null)
				throw new ArgumentException ();

			if (end == null)
				return true;

			return end.Offset - start.Offset > 255 || start.Offset > 65535;
		}
Ejemplo n.º 9
0
		public void Remove (Instruction instruction)
		{
			if (instruction == null)
				throw new ArgumentNullException ("instruction");

			if (!instructions.Remove (instruction))
				throw new ArgumentOutOfRangeException ("instruction");
		}
Ejemplo n.º 10
0
		static void AppendLabel (StringBuilder builder, Instruction instruction)
		{
			builder.Append ("IL_");
			builder.Append (instruction.offset.ToString ("x4"));
		}
Ejemplo n.º 11
0
		public void Replace (Instruction target, Instruction instruction)
		{
			if (target == null)
				throw new ArgumentNullException ("target");
			if (instruction == null)
				throw new ArgumentNullException ("instruction");

			InsertAfter (target, instruction);
			Remove (target);
		}
Ejemplo n.º 12
0
		public void Append (Instruction instruction)
		{
			if (instruction == null)
				throw new ArgumentNullException ("instruction");

			instructions.Add (instruction);
		}
Ejemplo n.º 13
0
		public void InsertAfter (Instruction target, Instruction instruction)
		{
			if (target == null)
				throw new ArgumentNullException ("target");
			if (instruction == null)
				throw new ArgumentNullException ("instruction");

			var index = instructions.IndexOf (target);
			if (index == -1)
				throw new ArgumentOutOfRangeException ("target");

			instructions.Insert (index + 1, instruction);
		}
Ejemplo n.º 14
0
		static void ComputeStackSize (Instruction instruction, ref int stack_size)
		{
			switch (instruction.opcode.FlowControl) {
			case FlowControl.Branch:
			case FlowControl.Break:
			case FlowControl.Throw:
			case FlowControl.Return:
				stack_size = 0;
				break;
			}
		}
Ejemplo n.º 15
0
		public static Instruction Create (OpCode opcode, Instruction [] targets)
		{
			if (targets == null)
				throw new ArgumentNullException ("targets");
			if (opcode.OperandType != OperandType.InlineSwitch)
				throw new ArgumentException ("opcode");

			return new Instruction (opcode, targets);
		}
Ejemplo n.º 16
0
		static void ComputeStackDelta (Instruction instruction, ref int stack_size)
		{
			switch (instruction.opcode.FlowControl) {
			case FlowControl.Call: {
				var method = (IMethodSignature) instruction.operand;
				// pop 'this' argument
				if (method.HasImplicitThis() && instruction.opcode.Code != Code.Newobj)
					stack_size--;
				// pop normal arguments
				if (method.HasParameters)
					stack_size -= method.Parameters.Count;
				// pop function pointer
				if (instruction.opcode.Code == Code.Calli)
					stack_size--;
				// push return value
				if (method.ReturnType.etype != ElementType.Void || instruction.opcode.Code == Code.Newobj)
					stack_size++;
				break;
			}
			default:
				ComputePopDelta (instruction.opcode.StackBehaviourPop, ref stack_size);
				ComputePushDelta (instruction.opcode.StackBehaviourPush, ref stack_size);
				break;
			}
		}
Ejemplo n.º 17
0
		void WriteOperand (Instruction instruction)
		{
			var opcode = instruction.opcode;
			var operand_type = opcode.OperandType;
			if (operand_type == OperandType.InlineNone)
				return;

			var operand = instruction.operand;
			if (operand == null)
				throw new ArgumentException ();

			switch (operand_type) {
			case OperandType.InlineSwitch: {
				var targets = (Instruction []) operand;
				WriteInt32 (targets.Length);
				var diff = instruction.Offset + opcode.Size + (4 * (targets.Length + 1));
				for (int i = 0; i < targets.Length; i++)
					WriteInt32 (GetTargetOffset (targets [i]) - diff);
				break;
			}
			case OperandType.ShortInlineBrTarget: {
				var target = (Instruction) operand;
				WriteSByte ((sbyte) (GetTargetOffset (target) - (instruction.Offset + opcode.Size + 1)));
				break;
			}
			case OperandType.InlineBrTarget: {
				var target = (Instruction) operand;
				WriteInt32 (GetTargetOffset (target) - (instruction.Offset + opcode.Size + 4));
				break;
			}
			case OperandType.ShortInlineVar:
				WriteByte ((byte) GetVariableIndex ((VariableDefinition) operand));
				break;
			case OperandType.ShortInlineArg:
				WriteByte ((byte) GetParameterIndex ((ParameterDefinition) operand));
				break;
			case OperandType.InlineVar:
				WriteInt16 ((short) GetVariableIndex ((VariableDefinition) operand));
				break;
			case OperandType.InlineArg:
				WriteInt16 ((short) GetParameterIndex ((ParameterDefinition) operand));
				break;
			case OperandType.InlineSig:
				WriteMetadataToken (GetStandAloneSignature ((CallSite) operand));
				break;
			case OperandType.ShortInlineI:
				if (opcode == OpCodes.Ldc_I4_S)
					WriteSByte ((sbyte) operand);
				else
					WriteByte ((byte) operand);
				break;
			case OperandType.InlineI:
				WriteInt32 ((int) operand);
				break;
			case OperandType.InlineI8:
				WriteInt64 ((long) operand);
				break;
			case OperandType.ShortInlineR:
				WriteSingle ((float) operand);
				break;
			case OperandType.InlineR:
				WriteDouble ((double) operand);
				break;
			case OperandType.InlineString:
				WriteMetadataToken (
					new MetadataToken (
						TokenType.String,
						GetUserStringIndex ((string) operand)));
				break;
			case OperandType.InlineType:
			case OperandType.InlineField:
			case OperandType.InlineMethod:
			case OperandType.InlineTok:
				WriteMetadataToken (metadata.LookupToken ((IMetadataTokenProvider) operand));
				break;
			default:
				throw new ArgumentException ();
			}
		}
Ejemplo n.º 18
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;
			var instructions = body.instructions = new InstructionCollection ((code_size + 1) / 2);

			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);
		}
Ejemplo n.º 19
0
		int GetTargetOffset (Instruction instruction)
		{
			if (instruction == null) {
				var last = body.instructions [body.instructions.size - 1];
				return last.offset + last.GetSize ();
			}

			return instruction.offset;
		}
Ejemplo n.º 20
0
		void ResolveBranches (Collection<Instruction> instructions)
		{
			var items = instructions.items;
			var size = instructions.size;

			for (int i = 0; i < size; i++) {
				var instruction = items [i];
				switch (instruction.opcode.OperandType) {
				case OperandType.ShortInlineBrTarget:
				case OperandType.InlineBrTarget:
					instruction.operand = GetInstruction ((int) instruction.operand);
					break;
				case OperandType.InlineSwitch:
					var offsets = (int []) instruction.operand;
					var branches = new Instruction [offsets.Length];
					for (int j = 0; j < offsets.Length; j++)
						branches [j] = GetInstruction (offsets [j]);

					instruction.operand = branches;
					break;
				}
			}
		}
Ejemplo n.º 21
0
		public Instruction Create (OpCode opcode, Instruction [] targets)
		{
			return Instruction.Create (opcode, targets);
		}