Exemple #1
0
 internal void LoadStage3()
 {
     Console.WriteLine("================================================== Stage 3: {0} ==================================================", File.ReferenceName);
     for (int methodIndex = 0; methodIndex < Methods.Count; ++methodIndex)
     {
         Methods[methodIndex].ConvertInstructions(File.MethodDefTable[methodIndex]);
         Methods[methodIndex].ControlFlowGraph = IRControlFlowGraph.Build(Methods[methodIndex]);
         Methods[methodIndex].LinearizeInstructions(File.MethodDefTable[methodIndex]);
         Methods[methodIndex].TransformInstructions(File.MethodDefTable[methodIndex]);
     }
 }
Exemple #2
0
        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>();

            foreach (IRInstruction instruction in pMethod.Instructions)
            {
                switch (instruction.Opcode)
                {
                case IROpcode.Branch:
                {
                    IRBranchInstruction branchInstruction = (IRBranchInstruction)instruction;
                    if (!sourceNodeBreaks.Contains(instruction))
                    {
                        sourceNodeBreaks.Add(instruction);
                    }
                    if (!destinationNodeBreaks.Contains(branchInstruction.TargetIRInstruction))
                    {
                        destinationNodeBreaks.Add(branchInstruction.TargetIRInstruction);
                    }
                    break;
                }

                case IROpcode.Switch:
                {
                    IRSwitchInstruction switchInstruction = (IRSwitchInstruction)instruction;
                    if (!sourceNodeBreaks.Contains(instruction))
                    {
                        sourceNodeBreaks.Add(instruction);
                    }
                    foreach (IRInstruction targetIRInstruction in switchInstruction.TargetIRInstructions)
                    {
                        if (!destinationNodeBreaks.Contains(targetIRInstruction))
                        {
                            destinationNodeBreaks.Add(targetIRInstruction);
                        }
                    }
                    break;
                }

                case IROpcode.Leave:
                {
                    IRLeaveInstruction leaveInstruction = (IRLeaveInstruction)instruction;
                    if (!sourceNodeBreaks.Contains(instruction))
                    {
                        sourceNodeBreaks.Add(instruction);
                    }
                    if (!destinationNodeBreaks.Contains(leaveInstruction.TargetIRInstruction))
                    {
                        destinationNodeBreaks.Add(leaveInstruction.TargetIRInstruction);
                    }
                    break;
                }

                default: break;
                }
            }

            IRControlFlowGraph cfg = new IRControlFlowGraph();
            Node currentNode       = new Node(0);

            cfg.Nodes.Add(currentNode);
            foreach (IRInstruction instruction in pMethod.Instructions)
            {
                bool lastInstruction      = instruction == pMethod.Instructions[pMethod.Instructions.Count - 1];
                bool startFromSource      = sourceNodeBreaks.Contains(instruction);
                bool startFromDestination = destinationNodeBreaks.Contains(instruction);
                if (startFromSource && startFromDestination)
                {
                    if (currentNode.Instructions.Count > 0)
                    {
                        currentNode = new Node((uint)cfg.Nodes.Count);
                        cfg.Nodes.Add(currentNode);
                    }
                    currentNode.Instructions.Add(instruction);
                    currentNode = new Node((uint)cfg.Nodes.Count);
                    cfg.Nodes.Add(currentNode);
                }
                else if (startFromSource)
                {
                    currentNode.Instructions.Add(instruction);
                    currentNode = new Node((uint)cfg.Nodes.Count);
                    cfg.Nodes.Add(currentNode);
                }
                else if (startFromDestination)
                {
                    if (currentNode.Instructions.Count > 0)
                    {
                        currentNode = new Node((uint)cfg.Nodes.Count);
                        cfg.Nodes.Add(currentNode);
                    }
                    currentNode.Instructions.Add(instruction);
                }
                else
                {
                    currentNode.Instructions.Add(instruction);
                }
            }

            for (int nodeIndex = 0; nodeIndex < cfg.Nodes.Count; ++nodeIndex)
            {
                Node          node        = cfg.Nodes[nodeIndex];
                IRInstruction instruction = node.Instructions[node.Instructions.Count - 1];
                switch (instruction.Opcode)
                {
                case IROpcode.Branch:
                {
                    IRBranchInstruction branchInstruction = (IRBranchInstruction)instruction;
                    Node 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[nodeIndex + 1]);
                    }
                    node.LinkTo(childNode);
                    break;
                }

                case IROpcode.Switch:
                {
                    IRSwitchInstruction switchInstruction = (IRSwitchInstruction)instruction;
                    node.LinkTo(cfg.Nodes[nodeIndex + 1]);
                    foreach (IRInstruction targetInstruction in switchInstruction.TargetIRInstructions)
                    {
                        Node 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;
                    Node 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.Return: continue;

                default: node.LinkTo(cfg.Nodes[nodeIndex + 1]); break;
                }
            }
            return(cfg);
        }
        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>();
            foreach (IRInstruction instruction in pMethod.Instructions)
            {
                switch (instruction.Opcode)
                {
                    case IROpcode.Branch:
                        {
                            IRBranchInstruction branchInstruction = (IRBranchInstruction)instruction;
                            if (!sourceNodeBreaks.Contains(instruction)) sourceNodeBreaks.Add(instruction);
                            if (!destinationNodeBreaks.Contains(branchInstruction.TargetIRInstruction)) destinationNodeBreaks.Add(branchInstruction.TargetIRInstruction);
                            break;
                        }
                    case IROpcode.Switch:
                        {
                            IRSwitchInstruction switchInstruction = (IRSwitchInstruction)instruction;
                            if (!sourceNodeBreaks.Contains(instruction)) sourceNodeBreaks.Add(instruction);
                            foreach (IRInstruction targetIRInstruction in switchInstruction.TargetIRInstructions)
                            {
                                if (!destinationNodeBreaks.Contains(targetIRInstruction))
                                {
                                    destinationNodeBreaks.Add(targetIRInstruction);
                                }
                            }
                            break;
                        }
                    case IROpcode.Leave:
                        {
                            IRLeaveInstruction leaveInstruction = (IRLeaveInstruction)instruction;
                            if (!sourceNodeBreaks.Contains(instruction)) sourceNodeBreaks.Add(instruction);
                            if (!destinationNodeBreaks.Contains(leaveInstruction.TargetIRInstruction)) destinationNodeBreaks.Add(leaveInstruction.TargetIRInstruction);
                            break;
                        }
                    default: break;
                }
            }

            IRControlFlowGraph cfg = new IRControlFlowGraph();
            Node currentNode = new Node(0);
            cfg.Nodes.Add(currentNode);
            foreach (IRInstruction instruction in pMethod.Instructions)
            {
                bool lastInstruction = instruction == pMethod.Instructions[pMethod.Instructions.Count - 1];
                bool startFromSource = sourceNodeBreaks.Contains(instruction);
                bool startFromDestination = destinationNodeBreaks.Contains(instruction);
                if (startFromSource && startFromDestination)
                {
                    if (currentNode.Instructions.Count > 0)
                    {
                        currentNode = new Node((uint)cfg.Nodes.Count);
                        cfg.Nodes.Add(currentNode);
                    }
                    currentNode.Instructions.Add(instruction);
                    currentNode = new Node((uint)cfg.Nodes.Count);
                    cfg.Nodes.Add(currentNode);
                }
                else if (startFromSource)
                {
                    currentNode.Instructions.Add(instruction);
                    currentNode = new Node((uint)cfg.Nodes.Count);
                    cfg.Nodes.Add(currentNode);
                }
                else if (startFromDestination)
                {
                    if (currentNode.Instructions.Count > 0)
                    {
                        currentNode = new Node((uint)cfg.Nodes.Count);
                        cfg.Nodes.Add(currentNode);
                    }
                    currentNode.Instructions.Add(instruction);
                }
                else currentNode.Instructions.Add(instruction);
            }

            for (int nodeIndex = 0; nodeIndex < cfg.Nodes.Count; ++nodeIndex)
            {
                Node node = cfg.Nodes[nodeIndex];
                IRInstruction instruction = node.Instructions[node.Instructions.Count - 1];
                switch (instruction.Opcode)
                {
                    case IROpcode.Branch:
                        {
                            IRBranchInstruction branchInstruction = (IRBranchInstruction)instruction;
                            Node 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[nodeIndex + 1]);
                            node.LinkTo(childNode);
                            break;
                        }
                    case IROpcode.Switch:
                        {
                            IRSwitchInstruction switchInstruction = (IRSwitchInstruction)instruction;
                            node.LinkTo(cfg.Nodes[nodeIndex + 1]);
                            foreach (IRInstruction targetInstruction in switchInstruction.TargetIRInstructions)
                            {
                                Node 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;
                            Node 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.Return: continue;
                    default: node.LinkTo(cfg.Nodes[nodeIndex + 1]); break;
                }
            }
            return cfg;
        }