Example #1
0
		public IRParameter Clone(IRMethod newMethod)
		{
			IRParameter p = new IRParameter(this.Assembly);
			p.ParentMethod = newMethod;
			p.mParentParameter = this.mType == null ? this : null;
			p.Type = this.mType;
			return p;
		}
Example #2
0
		public IRLocal Clone(IRMethod newMethod)
		{
			IRLocal local = new IRLocal(this.Assembly);
			local.ParentMethod = newMethod;
			local.mType = this.Type;
			local.Index = newMethod.Locals.Count;
			if (SSAData != null) local.SSAData = SSAData.Clone();
			return local;
		}
Example #3
0
		/// <summary>
		/// This does a shallow copy of all of the members of the
		/// abstract IRInstruction class to the specified instruction.
		/// </summary>
		/// <param name="i">The instruction to copy to.</param>
		/// <param name="newMethod">The method this instruction will be added to.</param>
		/// <returns><see cref="i"/></returns>
		protected IRInstruction CopyTo(IRInstruction i, IRMethod newMethod)
		{
			i.ILOffset = this.ILOffset;
			i.IRIndex = this.IRIndex;
			i.Opcode = this.Opcode;
			i.ParentMethod = newMethod;
			if (Destination != null)
			{
				i.Destination = this.Destination.Clone(i);
			}
			foreach (IRLinearizedLocation t in this.Sources)
			{
				i.Sources.Add(t.Clone(i));
			}
			return i;
		}
Example #4
0
		/// <summary>
		/// This creates a shallow clone of this method, but
		/// does a deep clone of it's instructions, parameters, and locals.
		/// </summary>
		/// <param name="newParent">The parent for the new method.</param>
		/// <returns>The clone of this method.</returns>
		public IRMethod Clone(IRType newParent)
		{
			if (newParent == null) throw new Exception();
			IRMethod m = new IRMethod(this.Assembly);

			if (this.PresolvedMethod)
				m.mParentMethod = this.GenericMethod;
			else
				m.mParentMethod = this;
			m.ParentType = newParent;
			m.GenericMethod = this.GenericMethod;
			m.GenericParameters.AddRange(this.GenericParameters);
			if (this.mInstructions.Count != 0 && Assembly.AppDomain.CurrentCompileStage >= 3)
			{
				m.mBoundInstructions = true;
				this.Instructions.ForEach(i => m.mInstructions.Add(i.Clone(m)));
				m.Instructions.FixClonedTargetInstructions();
			}
			if (this.mLocals.Count != 0 && Assembly.AppDomain.CurrentCompileStage >= 3)
			{
				m.mBoundLocals = true;
				this.mLocals.ForEach(l => m.mLocals.Add(l.Clone(m)));
			}
			this.mParameters.ForEach(p => m.mParameters.Add(p.Clone(m)));
			m.MaximumStackDepth = this.MaximumStackDepth;
			m.Name = this.Name;
			m.Flags = this.Flags;
			m.ImplFlags = this.ImplFlags;
			m.ReturnType = this.ReturnType;
			return m;
		}
Example #5
0
		public void Resolve(ref IRMethod selfReference, IRGenericParameterList typeParams, IRGenericParameterList methodParams)
		{
			if (!Resolved || PresolvedMethod || PostsolvedMethod)
			{
				IRType t = ParentType;
				t.Resolve(ref t, typeParams, methodParams);
				if (IsGeneric)
				{
					if (!this.GenericParameters.Resolved)
					{
						if (this.PostsolvedMethod)
						{
							this.GenericParameters.TrySubstitute(typeParams, methodParams);
						}
						else
						{
							if (this.PresolvedMethod)
							{
								selfReference = Assembly.AppDomain.PresolveGenericMethod(this.GenericMethod, methodParams.ToList(), typeParams.ToList());
							}
							else
							{
								selfReference = Assembly.AppDomain.PresolveGenericMethod(this, methodParams.ToList(), typeParams.ToList());
							}
							selfReference.PresolvedMethod = false;
							selfReference.PostsolvedMethod = true;
							selfReference.Resolve(ref selfReference, typeParams, methodParams);
							return;
						}
					}
					if (this.GenericParameters.Resolved)
					{
						IRMethod mth = null;
						if (!t.GenericMethods.TryGetValue(this, out mth))
						{
							IRMethod mth2 = null;
							mth = this.GenericMethod.Clone(t);
							mth.GenericParameters.Substitute(t.GenericParameters, this.GenericParameters);
							if (!t.GenericMethods.TryGetValue(mth, out mth2))
							{
								t.GenericMethods.Add(mth, mth);
								mth.Substitute(this.GenericParameters);
							}
							else
							{
								mth = mth2;
							}
						}
						selfReference = mth;
					}
					else
					{
						// Dia a painful death.
						// This will eventually need to get the instantiation of this method.
					}
				}
				else
				{
					if (t.GenericParameters.Resolved)
					{
						selfReference = t.Methods[selfReference.ParentTypeMethodIndex];
						selfReference.Resolve(ref selfReference, t.GenericParameters, methodParams);
					}
				}
			}
		}
Example #6
0
			public MethodMetadataEmittableDataItem(IRMethod m)
			{
#warning Need to get the required data here
				this.MethodName = m.ToString();
			}
Example #7
0
		public abstract IRInstruction Clone(IRMethod pNewMethod);
		public static IRControlFlowGraph Build(IRMethod pMethod)
		{
			if (pMethod.Instructions.Count == 0) return null;

			HashSet<IRInstruction> sourceNodeBreaks = new HashSet<IRInstruction>();
			HashSet<IRInstruction> destinationNodeBreaks = new HashSet<IRInstruction>();
			int lIRIdx = pMethod.Instructions.Count - 1;
			foreach (IRInstruction instruction in pMethod.Instructions)
			{
				bool lastInstruction = instruction.IRIndex == lIRIdx;
				switch (instruction.Opcode)
				{
					case IROpcode.Branch:
						{
							IRBranchInstruction branchInstruction = (IRBranchInstruction)instruction;
							sourceNodeBreaks.Add(instruction);
							destinationNodeBreaks.Add(branchInstruction.TargetIRInstruction);
							break;
						}
					case IROpcode.Switch:
						{
							IRSwitchInstruction switchInstruction = (IRSwitchInstruction)instruction;
							sourceNodeBreaks.Add(instruction);
							switchInstruction.TargetIRInstructions.ForEach(i => destinationNodeBreaks.Add(i));
							break;
						}
					case IROpcode.Leave:
						{
							IRLeaveInstruction leaveInstruction = (IRLeaveInstruction)instruction;
							sourceNodeBreaks.Add(instruction);
							destinationNodeBreaks.Add(leaveInstruction.TargetIRInstruction);
							break;
						}
					case IROpcode.EndFinally:
						{
							IREndFinallyInstruction endFinallyInstruction = (IREndFinallyInstruction)instruction;
							sourceNodeBreaks.Add(instruction);
							if (!lastInstruction) destinationNodeBreaks.Add(pMethod.Instructions[instruction.IRIndex + 1]);
							break;
						}
					case IROpcode.Throw:
					case IROpcode.Rethrow:
					case IROpcode.Return:
						sourceNodeBreaks.Add(instruction);
						break;
					default: break;
				}
			}

			IRControlFlowGraph cfg = new IRControlFlowGraph();
			IRControlFlowGraphNode currentNode = new IRControlFlowGraphNode(0);
			cfg.Nodes.Add(currentNode);
			foreach (IRInstruction instruction in pMethod.Instructions)
			{
				bool lastInstruction = instruction.IRIndex == lIRIdx;
				bool startFromSource = sourceNodeBreaks.Contains(instruction);
				bool startFromDestination = destinationNodeBreaks.Contains(instruction);
				if (startFromSource && startFromDestination)
				{
					if (currentNode.Instructions.Count > 0)
					{
						currentNode = new IRControlFlowGraphNode(cfg.Nodes.Count);
						cfg.Nodes.Add(currentNode);
					}
					currentNode.Instructions.Add(instruction);
					if (!lastInstruction)
					{
						currentNode = new IRControlFlowGraphNode(cfg.Nodes.Count);
						cfg.Nodes.Add(currentNode);
					}
				}
				else if (startFromSource)
				{
					currentNode.Instructions.Add(instruction);
					if (!lastInstruction)
					{
						currentNode = new IRControlFlowGraphNode(cfg.Nodes.Count);
						cfg.Nodes.Add(currentNode);
					}
				}
				else if (startFromDestination)
				{
					if (currentNode.Instructions.Count > 0)
					{
						currentNode = new IRControlFlowGraphNode(cfg.Nodes.Count);
						cfg.Nodes.Add(currentNode);
					}
					currentNode.Instructions.Add(instruction);
				}
				else currentNode.Instructions.Add(instruction);
			}

			foreach (IRControlFlowGraphNode node in cfg.Nodes)
			{
				IRInstruction instruction = node.Instructions[node.Instructions.Count - 1];
				switch (instruction.Opcode)
				{
					case IROpcode.Branch:
						{
							IRBranchInstruction branchInstruction = (IRBranchInstruction)instruction;
							IRControlFlowGraphNode childNode = cfg.Nodes.Find(n => n.Instructions[0] == branchInstruction.TargetIRInstruction);
							if (childNode == null) throw new NullReferenceException();
							if (branchInstruction.BranchCondition != IRBranchCondition.Always) node.LinkTo(cfg.Nodes[node.Index + 1]);
							node.LinkTo(childNode);
							break;
						}
					case IROpcode.Switch:
						{
							IRSwitchInstruction switchInstruction = (IRSwitchInstruction)instruction;
							node.LinkTo(cfg.Nodes[node.Index + 1]);
							foreach (IRInstruction targetInstruction in switchInstruction.TargetIRInstructions)
							{
								IRControlFlowGraphNode childNode = cfg.Nodes.Find(n => n.Instructions[0] == targetInstruction);
								if (childNode == null) throw new NullReferenceException();
								node.LinkTo(childNode);
							}
							break;
						}
					case IROpcode.Leave:
						{
							IRLeaveInstruction leaveInstruction = (IRLeaveInstruction)instruction;
							IRControlFlowGraphNode childNode = cfg.Nodes.Find(n => n.Instructions[0] == leaveInstruction.TargetIRInstruction);
							if (childNode == null) throw new NullReferenceException();
							node.LinkTo(childNode);
							break;
						}
					case IROpcode.Throw:
					case IROpcode.Rethrow:
					case IROpcode.Return: continue;
					default: if (cfg.Nodes.Count > node.Index + 1) node.LinkTo(cfg.Nodes[node.Index + 1]); break;
				}
			}

			List<IRControlFlowGraphNode> allDeadNodes = new List<IRControlFlowGraphNode>(32);
			List<IRControlFlowGraphNode> deadNodes = null;
			while ((deadNodes = cfg.Nodes.FindAll(n => n.Index > 0 && n.ParentNodes.Count == 0)).Count > 0)
			{
				allDeadNodes.AddRange(deadNodes);
				foreach (IRControlFlowGraphNode deadNode in deadNodes)
				{
					foreach (IRControlFlowGraphNode childNode in deadNode.ChildNodes) childNode.ParentNodes.Remove(deadNode);
					cfg.Nodes.RemoveAt(deadNode.Index);
					for (int nodeIndex = deadNode.Index; nodeIndex < cfg.Nodes.Count; ++nodeIndex)
					{
						IRControlFlowGraphNode node = cfg.Nodes[nodeIndex];
						node.Index -= 1;
					}
				}
			}

			cfg.Nodes.ForEach(n => n.Dominators = new BitVector(cfg.Nodes.Count, true));
			BitVector intersectedParentDominators = new BitVector(cfg.Nodes.Count);
			HashSet<IRControlFlowGraphNode> todoSet = new HashSet<IRControlFlowGraphNode>();
			HashSet<IRControlFlowGraphNode>.Enumerator todoSetEnumerator;
			todoSet.Add(cfg.Nodes[0]);
			while (todoSet.Count > 0)
			{
				todoSetEnumerator = todoSet.GetEnumerator();
				todoSetEnumerator.MoveNext();
				IRControlFlowGraphNode node = todoSetEnumerator.Current;
				todoSet.Remove(node);
				intersectedParentDominators.SetAll(node.ParentNodes.Count > 0);
				node.ParentNodes.ForEach(n => intersectedParentDominators.AndEquals(n.Dominators));
				intersectedParentDominators.Set(node.Index, true);
				if (!intersectedParentDominators.Equals(node.Dominators))
				{
					node.Dominators = new BitVector(intersectedParentDominators);
					node.ChildNodes.ForEach(n => todoSet.Add(n));
				}
			}
			foreach (IRControlFlowGraphNode node in cfg.Nodes)
			{
				for (int index = 0; index < node.Dominators.Count; ++index)
				{
					if (node.Dominators.Get(index))
						node.DominatorsCount++;
				}
			}
			foreach (IRControlFlowGraphNode node in cfg.Nodes)
			{
				int max = -1;
				foreach (IRControlFlowGraphNode innerNode in cfg.Nodes)
				{
					if (node.Dominators.Get(innerNode.Index) && node != innerNode && innerNode.DominatorsCount > max)
					{
						max = innerNode.DominatorsCount;
						node.Dominator = innerNode;
					}
				}
			}
			cfg.Nodes[0].Dominator = cfg.Nodes[0];

			foreach (IRControlFlowGraphNode node in cfg.Nodes)
			{
				if (node.ParentNodes.Count < 2) continue;
				foreach (IRControlFlowGraphNode parentNode in node.ParentNodes)
				{
					IRControlFlowGraphNode treeNode = parentNode;
					while (treeNode != node.Dominator)
					{
						treeNode.Frontiers.Add(node);
						treeNode = treeNode.Dominator;
					}
				}
			}

			return cfg;
		}
Example #9
0
		internal void LoadStage1()
		{
			Console.WriteLine("========== Stage 1: {0,-45} ==========", File.ReferenceName);
			Types = new List<IRType>(File.TypeDefTable.Length);
			Fields = new List<IRField>(File.FieldTable.Length);
			Methods = new List<IRMethod>(File.MethodDefTable.Length);
			foreach (TypeDefData typeDefData in File.TypeDefTable) Types.Add(new IRType(this));
			foreach (FieldData fieldData in File.FieldTable) Fields.Add(new IRField(this));
			foreach (MethodDefData methodDefData in File.MethodDefTable)
			{
				IRMethod method = new IRMethod(this);
				Methods.Add(method);
				var mGenParams = new List<GenericParamData>(methodDefData.GenericParamList);
				for (int i = 0; i < mGenParams.Count; i++)
				{
					method.GenericParameters.Add(IRType.GetMVarPlaceholder(mGenParams[i].Number));
				}
			}

			for (int typeIndex = 0; typeIndex < Types.Count; ++typeIndex)
			{
				IRType type = Types[typeIndex];
				TypeDefData typeDefData = File.TypeDefTable[typeIndex];

				type.Namespace = typeDefData.TypeNamespace;
				type.Name = typeDefData.TypeName;
				type.Flags = typeDefData.Flags;
				var genParams = new List<GenericParamData>(typeDefData.GenericParamList);
				for (int i = 0; i < genParams.Count; i++)
				{
					type.GenericParameters.Add(IRType.GetVarPlaceholder(genParams[i].Number));
				}

				foreach (FieldData fieldData in typeDefData.FieldList)
				{
					IRField field = Fields[fieldData.TableIndex];
					field.Name = fieldData.Name;
					field.Flags = fieldData.Flags;
					field.ParentType = type;
					type.Fields.Add(field);
				}
				foreach (MethodDefData methodDefData in typeDefData.MethodList)
				{
					IRMethod method = Methods[methodDefData.TableIndex];
					method.Name = methodDefData.Name;
					method.Flags = methodDefData.Flags;
					method.ImplFlags = methodDefData.ImplFlags;
					method.ParentType = type;
					type.Methods.Add(method);

					foreach (ParamData paramData in methodDefData.ParamList)
					{
						IRParameter parameter = new IRParameter(this);
						parameter.ParentMethod = method;
						method.Parameters.Add(parameter);
					}

					if (methodDefData.Body != null && methodDefData.Body.ExpandedLocalVarSignature != null)
					{
						method.MaximumStackDepth = methodDefData.Body.MaxStack;
						foreach (SigLocalVar sigLocalVar in methodDefData.Body.ExpandedLocalVarSignature.LocalVars)
						{
							IRLocal local = new IRLocal(this);
							local.ParentMethod = method;
							local.Index = method.Locals.Count;
							method.Locals.Add(local);
						}
					}
				}
			}
			for (int typeIndex = 0; typeIndex < Types.Count; ++typeIndex)
			{
				IRType type = Types[typeIndex];
				TypeDefData typeDefData = File.TypeDefTable[typeIndex];

				foreach (TypeDefData nestedTypeDefData in typeDefData.NestedClassList)
				{
					IRType nestedType = Types[nestedTypeDefData.TableIndex];
					//nestedType.Namespace = type.Namespace + "." + type.Name;
					nestedType.NestedInsideOfType = type;
					type.NestedTypes.Add(nestedType);
				}
			}
			if (CORLibrary) AppDomain.CacheCOR(this);
			else if (RuntimeLibrary) AppDomain.CacheRuntime(this);
		}