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; }
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; }
/// <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; }
/// <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; }
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); } } } }
public MethodMetadataEmittableDataItem(IRMethod m) { #warning Need to get the required data here this.MethodName = m.ToString(); }
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; }
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); }