Esempio n. 1
0
            public Tracker(TypedInstructionCollection instructions)
            {
                DBC.Pre(instructions != null, "instructions is null");

                m_instructions = instructions;
                m_initialState = DoGetInitialState(m_instructions);
            }
Esempio n. 2
0
            public Lattice(TypedInstructionCollection instructions, State state)
            {
                DBC.Pre(instructions != null, "instructions is null");

                m_instructions = instructions;
                m_state        = state;
            }
Esempio n. 3
0
            public Tracker(TypedInstructionCollection instructions)
            {
                var graph        = new ControlFlowGraph(instructions);
                var initialState = new Lattice(instructions, new State(0));

                var data = new DataFlow <Lattice>(instructions, graph.Roots);
                Dictionary <BasicBlock, Lattice> lattices = data.Analyze(new Lattice.Functions(), initialState);

                m_states = new State[instructions.Length];
                foreach (var entry in lattices)
                {
                    BasicBlock block = entry.Key;
                    if (block.Length > 0)
                    {
                        Lattice lattice = entry.Value;

                        for (int index = block.First.Index; index <= block.Last.Index; ++index)                         // it'd be nice to assert that every index was set, but methods often have dead code so it's a little difficult
                        {
                            m_states[index] = lattice.State;
                            lattice         = lattice.Transform(index);
                        }
                    }
                }

                for (int index = 0; index < instructions.Length; ++index)
                {
                    Log.DebugLine(this, "{0:X2}: {1}", instructions[index].Untyped.Offset, m_states[index]);
                }
            }
Esempio n. 4
0
			public Tracker(TypedInstructionCollection instructions)
			{
				DBC.Pre(instructions != null, "instructions is null");

				m_instructions = instructions;
				m_initialState = DoGetInitialState(m_instructions);
			}
Esempio n. 5
0
            // This is another case where the lattice meet and transform paradigm
            // doesn't work so well. What we want to do is set locals and arguments
            // based on the result of null pointer comparisons. Doing this in meet
            // would be really ugly and would break commutativity so we handle it
            // by splicing in a special block to each edge leading out from the branch.
            private void DoSpliceNullCheck(TypedInstructionCollection instructions, BasicBlock block, List <BasicBlock> visited)
            {
                if (visited.IndexOf(block) < 0)
                {
                    visited.Add(block);

                    if (block.Next.Length == 2)
                    {
                        DoTrySpliceNull(instructions, block);
                    }

                    for (int i = 0; i < block.Next.Length; ++i)
                    {
                        DoSpliceNullCheck(instructions, block.Next[i], visited);
                    }

                    if (block.Finally != null)
                    {
                        DoSpliceNullCheck(instructions, block.Finally, visited);
                    }
                    else if (block.Fault != null)
                    {
                        DoSpliceNullCheck(instructions, block.Fault, visited);
                    }
                }
            }
Esempio n. 6
0
 internal TryCatchCollection(TypedInstructionCollection instructions)
 {
     if (instructions.Method.Body != null)
     {
         DoGetTryCatches(instructions);
     }
 }
Esempio n. 7
0
        private static string DoGetMissedOffsets(TypedInstructionCollection instructions, List <BasicBlock> reachable, List <BasicBlock> deadBlocks)
        {
            // Get a list of all the offsets in the method.
            List <int> offsets = new List <int>(instructions.Length);

            foreach (TypedInstruction instruction in instructions)
            {
                offsets.Add(instruction.Untyped.Offset);
            }

            // Remove the visited instructions.
            foreach (BasicBlock block in reachable)
            {
                DoRemoveOffsets(instructions, offsets, block);
            }

            // Remove the dead code.
            foreach (BasicBlock block in deadBlocks)
            {
                DoRemoveOffsets(instructions, offsets, block);
            }

            // Anything left is code we should have visited but didn't.
            return(ListExtensions.Accumulate(offsets, string.Empty, (s, e) => s + e.ToString("X2") + " "));
        }
Esempio n. 8
0
        private List <int> DoGetLeaders(TypedInstructionCollection instructions)
        {
            // The leaders will be:
            List <int> leaders = new List <int>();

            // 1) the first instruction in the method,
            leaders.Add(0);

            for (int index = 0; index < instructions.Length; ++index)
            {
                TypedInstruction instruction = instructions[index];

                // 2) the targets of branches,
                Branch branch = instruction as Branch;
                if (branch != null)
                {
                    m_branchTargets.Add(branch.Target.Index);
                }
                else
                {
                    Switch swtch = instruction as Switch;
                    if (swtch != null)
                    {
                        foreach (TypedInstruction i in swtch.Targets)
                        {
                            m_branchTargets.Add(i.Index);
                        }
                    }
                }

                if (index > 0)
                {
                    // 3) and instructions starting try, catch or finally blocks,
                    TryCatch tc = instructions.TryCatchCollection.HandlerStartsAt(index);
                    if (tc != null)
                    {
                        leaders.Add(index);
                    }

                    // 4) the instructions following branches or end instructions.
                    else if (instructions[index - 1] is Branch || instructions[index - 1] is Switch || instructions[index - 1] is End)
                    {
                        leaders.Add(index);
                    }
                }
            }

            foreach (int target in m_branchTargets)
            {
                if (leaders.IndexOf(target) < 0)
                {
                    leaders.Add(target);
                }
            }

            return(leaders);
        }
Esempio n. 9
0
 private static void DoRemoveOffsets(TypedInstructionCollection instructions, List <int> offsets, BasicBlock block)
 {
     if (block.Length > 0)
     {
         for (int i = block.First.Index; i <= block.Last.Index; ++i)
         {
             Unused.Value = offsets.Remove(instructions[i].Untyped.Offset);
         }
     }
 }
Esempio n. 10
0
        private static Block DoGetBlock(TypedInstructionCollection instructions, int startOffset, int endOffset)
        {
            int startIndex = instructions.OffsetToIndex(startOffset);
            int endIndex   = instructions.OffsetToIndex(endOffset);

            Block block = new Block();

            block.Index  = startIndex;
            block.Length = endIndex - startIndex;

            return(block);
        }
Esempio n. 11
0
            private static void DoSpliceEq(TypedInstructionCollection instructions, BasicBlock block)
            {
                int index = block.Last.Index;

                // ldloc.0 V_0
                // ldnull
                // beq     2F
                LoadArg   arg   = null;
                LoadLocal local = null;

                if (instructions[index - 1].Untyped.OpCode.Code == Code.Ldnull)
                {
                    arg   = instructions[block.Last.Index - 2] as LoadArg;
                    local = instructions[block.Last.Index - 2] as LoadLocal;
                }
                else if (instructions[index - 2].Untyped.OpCode.Code == Code.Ldnull)
                {
                    arg   = instructions[block.Last.Index - 1] as LoadArg;
                    local = instructions[block.Last.Index - 1] as LoadLocal;
                }

                if (arg != null || local != null)
                {
                    TypedInstruction instruction = instructions[block.Last.Index];
                    Code             code        = instruction.Untyped.OpCode.Code;

                    if (code == Code.Bne_Un || code == Code.Bne_Un_S)
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNullArgBlockLen - arg.Arg, FirstNonNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNullLocalBlockLen - local.Variable, FirstNonNullLocalBlockLen - local.Variable);
                        }
                    }
                    else
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNonNullArgBlockLen - arg.Arg, FirstNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNonNullLocalBlockLen - local.Variable, FirstNullLocalBlockLen - local.Variable);
                        }
                    }
                }
            }
Esempio n. 12
0
        private int DoGetIndex(TypedInstructionCollection instructions, string text)
        {
            foreach (LoadString load in instructions.Match <LoadString>())
            {
                if (load.Value.Contains(text))
                {
                    return(load.Index);
                }
            }

            DBC.Fail("Couldn't find {0}", text);
            return(-1);
        }
Esempio n. 13
0
        private Dictionary <int, BasicBlock> DoGetWiredBlocks(TypedInstructionCollection instructions)
        {
            DBC.Pre(instructions.Length > 0, "Can't get a root if there are no instructions");

            m_branchTargets = new List <int>();
            Dictionary <int, BasicBlock> blocks = DoGetUnwiredBlocks(instructions);             // index -> block

            foreach (KeyValuePair <int, BasicBlock> entry in blocks)
            {
                DoWireBlock(instructions, blocks, entry.Value);
            }

            return(blocks);
        }
Esempio n. 14
0
            private static void DoTrySpliceNull(TypedInstructionCollection instructions, BasicBlock block)
            {
                TypedInstruction instruction = instructions[block.Last.Index];
                Code             code        = instruction.Untyped.OpCode.Code;

                if (code == Code.Brtrue || code == Code.Brtrue_S || code == Code.Brfalse || code == Code.Brfalse_S)
                {
                    DoSpliceTrue(instructions, block);
                }
                else if (code == Code.Beq || code == Code.Beq_S || code == Code.Bne_Un || code == Code.Bne_Un_S)
                {
                    DoSpliceEq(instructions, block);
                }
            }
Esempio n. 15
0
        public void ZNestedFinally()
        {
            TypeDefinition   type   = DoGetType("Cases");
            MethodDefinition method = type.Methods.GetMethod("NestedFinally")[0];

            TypedInstructionCollection instructions = new TypedInstructionCollection(new SymbolTable(), method);

            Log.DebugLine((ControlFlowGraph)null, "-----------------------------------");
            Log.DebugLine((ControlFlowGraph)null, "{0:F}", instructions);

            ControlFlowGraph graph = new ControlFlowGraph(instructions);

            Assert.AreEqual(2, graph.Roots.Length);
        }
Esempio n. 16
0
        private void DoInit(string methodName)
        {
            string             loc      = Assembly.GetExecutingAssembly().Location;
            AssemblyDefinition assembly = AssemblyFactory.GetAssembly(loc);

            string         fullName = string.Format("{0}/{1}", GetType().FullName, "Cases");
            TypeDefinition type     = assembly.MainModule.Types[fullName];

            MethodDefinition method = type.Methods.GetMethod(methodName)[0];

            m_instructions = new TypedInstructionCollection(new SymbolTable(), method);
            m_tracker      = new Tracker(m_instructions);
            m_tracker.Analyze();
        }
Esempio n. 17
0
        // Before leaving a try or catch block we need to transfer control to
        // the finally block (if present).
        private static void DoAddFinally(TypedInstructionCollection instructions, List <BasicBlock> nextBlocks, Dictionary <int, BasicBlock> blocks, BasicBlock block)
        {
            TryCatch candidate = null;

            for (int i = 0; i < instructions.TryCatchCollection.Length; ++i)
            {
                TryCatch tc = instructions.TryCatchCollection[i];
                if (tc.Finally.Length > 0)
                {
                    if (block.First.Index >= tc.Try.Index && block.Last.Index < tc.Try.Index + tc.Try.Length)
                    {
                        if (candidate == null || tc.Try.Length < candidate.Try.Length)
                        {
                            candidate = tc;
                        }
                    }
                    else
                    {
                        for (int j = 0; j < tc.Catchers.Count; ++j)
                        {
                            if (block.First.Index >= tc.Catchers[j].Index && block.Last.Index < tc.Catchers[j].Index + tc.Catchers[j].Length)
                            {
                                if (candidate == null || tc.Try.Length < candidate.Try.Length)
                                {
                                    candidate = tc;
                                }
                            }
                        }
                    }
                }
                else if (tc.Fault.Length > 0)
                {
                    for (int j = 0; j < tc.Catchers.Count; ++j)
                    {
                        if (block.First.Index >= tc.Catchers[j].Index && block.Last.Index < tc.Catchers[j].Index + tc.Catchers[j].Length)
                        {
                            block.Fault = blocks[tc.Fault.Index];
                            DoWireCatches(instructions, nextBlocks, blocks, tc.Fault.Index);
                            return;
                        }
                    }
                }
            }

            if (candidate != null)
            {
                block.Finally = blocks[candidate.Finally.Index];
                DoWireCatches(instructions, nextBlocks, blocks, candidate.Finally.Index);
            }
        }
Esempio n. 18
0
        public void Linear()
        {
            TypeDefinition   type   = DoGetType("Cases");
            MethodDefinition method = type.Methods.GetMethod("Linear")[0];

            var instructions = new TypedInstructionCollection(new SymbolTable(), method);
            var tracker      = new V0.Tracker(instructions);

            int index = DoGetIndex(instructions, "first");

            Assert.AreEqual(0, tracker.State(index).Value);

            index = DoGetIndex(instructions, "second");
            Assert.AreEqual(3, tracker.State(index).Value);
        }
Esempio n. 19
0
        public void TrashStackTrace()
        {
            TypeDefinition   type   = DoGetType("Cases");
            MethodDefinition method = type.Methods.GetMethod("TrashStackTrace")[0];

            TypedInstructionCollection instructions = new TypedInstructionCollection(new SymbolTable(), method);

            Log.DebugLine((ControlFlowGraph)null, "-----------------------------------");
            Log.DebugLine((ControlFlowGraph)null, "{0:F}", instructions);

            ControlFlowGraph graph = new ControlFlowGraph(instructions);

            Assert.AreEqual(2, graph.Roots.Length);
            Log.DebugLine((ControlFlowGraph)null, "Root 1:\n{0:T}", graph.Roots[0]);
            Log.DebugLine((ControlFlowGraph)null, "Root 2:\n{0:T}", graph.Roots[1]);
        }
Esempio n. 20
0
            public static readonly int LastNonNullLocalBlockLen  = -4999;               // A_999

            #region Private Methods -------------------------------------------
            // Catch and finally blocks require special handling to reset their stacks
            // on entry. We can't really do this in meet without breaking commutativity
            // and transform is too late. So what we do is splice in a special zero
            // length block right before the handler and when it is transformed reset
            // the stack.
            private void DoSpliceHandlers(TypedInstructionCollection instructions, BasicBlock block, List <BasicBlock> visited)
            {
                if (visited.IndexOf(block) < 0)
                {
                    visited.Add(block);

                    for (int i = 0; i < block.Next.Length; ++i)
                    {
                        BasicBlock next = block.Next[i];

                        if (next.Length > 0)
                        {
                            TryCatch tc = instructions.TryCatchCollection.HandlerStartsAt(next.First.Index);
                            if (tc != null && tc.Try.Index != next.First.Index)
                            {
                                BasicBlock splice = null;
                                if (tc.Finally.Length > 0 && tc.Finally.Index == next.First.Index)
                                {
                                    splice = new BasicBlock(FinallyBlockLen, new BasicBlock[1]);
                                }
                                else if (tc.Fault.Length > 0 && tc.Fault.Index == next.First.Index)
                                {
                                    splice = new BasicBlock(FinallyBlockLen, new BasicBlock[1]);
                                }
                                else
                                {
                                    splice = new BasicBlock(CatchBlockLen, new BasicBlock[1]);
                                }
                                splice.Next[0] = next;

                                block.Next[i] = splice;
                            }
                        }

                        DoSpliceHandlers(instructions, next, visited);
                    }

                    if (block.Finally != null)
                    {
                        DoSpliceHandlers(instructions, block.Finally, visited);
                    }
                    else if (block.Fault != null)
                    {
                        DoSpliceHandlers(instructions, block.Fault, visited);
                    }
                }
            }
Esempio n. 21
0
        private List <BasicBlock> DoGetDeadBlocks(TypedInstructionCollection instructions, Dictionary <int, BasicBlock> blocks, List <BasicBlock> reachable)
        {
            List <BasicBlock> deadBlocks = new List <BasicBlock>();

            // If the block isn't the target of a branch and it's preceded by an end
            // instruction it's dead code. This can happen if a catch block throws.
            foreach (KeyValuePair <int, BasicBlock> entry in blocks)
            {
                BasicBlock b = entry.Value;
                int        i = b.First.Index;

                if (m_branchTargets.IndexOf(i) < 0)
                {
                    if (instructions.TryCatchCollection.HandlerStartsAt(i) == null)
                    {
                        if (i > 0 && (instructions[i - 1] is End || instructions[i - 1] is UnconditionalBranch))
                        {
                            deadBlocks.Add(b);
                        }
                    }
                }
            }

            // If a leave is dead code then its target is dead as well.
            List <BasicBlock> deaderBlocks = new List <BasicBlock>();

            foreach (BasicBlock b in deadBlocks)
            {
                if (b.Length > 0)
                {
                    for (int i = b.First.Index; i <= b.Last.Index; ++i)
                    {
                        if (instructions[i].Untyped.OpCode.Code == Code.Leave || instructions[i].Untyped.OpCode.Code == Code.Leave_S)
                        {
                            UnconditionalBranch branch = (UnconditionalBranch)instructions[i];
                            if (reachable.IndexOf(blocks[branch.Target.Index]) < 0 && deaderBlocks.IndexOf(blocks[branch.Target.Index]) < 0)
                            {
                                deaderBlocks.Add(blocks[branch.Target.Index]);
                            }
                        }
                    }
                }
            }
            deadBlocks.AddRange(deaderBlocks);

            return(deadBlocks);
        }
Esempio n. 22
0
        public ControlFlowGraph(TypedInstructionCollection instructions)
        {
            DBC.Pre(instructions != null, "instructions is null");
            Profile.Start("ControlFlowGraph ctor");

            // If we have instructions then,
            if (instructions.Length > 0)
            {
                // get all of the wired up basic blocks,
                Dictionary <int, BasicBlock> blocks = DoGetWiredBlocks(instructions);
                m_numBlocks = blocks.Count;

                // if the very first instruction is a try block then we'll have
                // mutiple roots,
                foreach (TryCatch tc in instructions.TryCatchCollection)
                {
                    if (tc.Try.Index == 0)
                    {
                        m_roots    = new BasicBlock[tc.Catchers.Count + 1];
                        m_roots[0] = blocks[0];

                        for (int i = 0; i < tc.Catchers.Count; ++i)
                        {
                            CatchBlock cb = tc.Catchers[i];
                            m_roots[i + 1] = blocks[cb.Index];
                        }
                    }
                }

                // otherwise the first instruction is our root.
                if (m_roots == null)
                {
                    m_roots = new BasicBlock[] { blocks[0] }
                }
                ;

                DoInvariantRoots(instructions, blocks, m_roots);
            }
            else
            {
                m_roots = new BasicBlock[0];
            }

            Profile.Stop("ControlFlowGraph ctor");
        }
Esempio n. 23
0
        public void Catch1()
        {
            TypeDefinition   type   = DoGetType("Cases");
            MethodDefinition method = type.Methods.GetMethod("Catch1")[0];

            var instructions = new TypedInstructionCollection(new SymbolTable(), method);
            var tracker      = new V0.Tracker(instructions);

            int index = DoGetIndex(instructions, "first");

            Assert.AreEqual(2, tracker.State(index).Value);

            index = DoGetIndex(instructions, "catch");
            Assert.AreEqual(0, tracker.State(index).Value);

            index = DoGetIndex(instructions, "last");
            Assert.IsFalse(tracker.State(index).HasValue);
        }
Esempio n. 24
0
        private static void DoWireCatches(TypedInstructionCollection instructions, List <BasicBlock> nextBlocks, Dictionary <int, BasicBlock> blocks, int targetIndex)
        {
            foreach (TryCatch tc in instructions.TryCatchCollection)
            {
                if (tc.Try.Index == targetIndex)
                {
                    foreach (CatchBlock cb in tc.Catchers)
                    {
                        nextBlocks.Add(blocks[cb.Index]);
                    }

                    if (tc.Fault.Length > 0 && tc.Catchers.Count == 0)
                    {
                        nextBlocks.Add(blocks[tc.Fault.Index]);
                    }
                }
            }
        }
Esempio n. 25
0
        public void Linear()
        {
            TypeDefinition   type   = DoGetType("Cases");
            MethodDefinition method = type.Methods.GetMethod("Linear")[0];

            TypedInstructionCollection instructions = new TypedInstructionCollection(new SymbolTable(), method);

            Log.DebugLine((ControlFlowGraph)null, "-----------------------------------");
            Log.DebugLine((ControlFlowGraph)null, "{0:F}", instructions);

            ControlFlowGraph graph = new ControlFlowGraph(instructions);

            Assert.AreEqual(1, graph.Roots.Length);
            Log.DebugLine((ControlFlowGraph)null, "\n{0:T}", graph.Roots[0]);
            Assert.AreEqual(1, graph.Length);

            Assert.AreEqual(0, graph.Roots[0].First.Index);
            Assert.AreEqual(instructions.Length - 1, graph.Roots[0].Last.Index);
        }
Esempio n. 26
0
        private static string DoTargetsToString(TypedInstructionCollection instructions, List <int> targets)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append('[');
            for (int i = 0; i < targets.Count; ++i)
            {
                int index = targets[i];
                TypedInstruction instruction = instructions[index];

                builder.Append(instruction.Untyped.Offset.ToString("X2"));
                if (i + 1 < targets.Count)
                {
                    builder.Append(", ");
                }
            }
            builder.Append(']');

            return(builder.ToString());
        }
Esempio n. 27
0
		public ControlFlowGraph(TypedInstructionCollection instructions)
		{		
			DBC.Pre(instructions != null, "instructions is null");
			Profile.Start("ControlFlowGraph ctor");
			
			// If we have instructions then,
			if (instructions.Length > 0)
			{
				// get all of the wired up basic blocks,
				Dictionary<int, BasicBlock> blocks = DoGetWiredBlocks(instructions);
				m_numBlocks = blocks.Count;
					
				// if the very first instruction is a try block then we'll have 
				// mutiple roots,
				foreach (TryCatch tc in instructions.TryCatchCollection)
				{
					if (tc.Try.Index == 0)
					{
						m_roots = new BasicBlock[tc.Catchers.Count + 1];
						m_roots[0] = blocks[0];
	
						for (int i = 0; i < tc.Catchers.Count; ++i)
						{
							CatchBlock cb = tc.Catchers[i];
							m_roots[i + 1] = blocks[cb.Index];
						}					
					}
				}
				
				// otherwise the first instruction is our root.
				if (m_roots == null)
					m_roots = new BasicBlock[]{blocks[0]};
				
				DoInvariantRoots(instructions, blocks, m_roots);
			}
			else
				m_roots = new BasicBlock[0];			
			
			Profile.Stop("ControlFlowGraph ctor");
		}
Esempio n. 28
0
            private static void DoSpliceTrue(TypedInstructionCollection instructions, BasicBlock block)
            {
                int index = block.Last.Index;

                // ldarg.1 a1
                // brtrue  10	(not taken is the first branch)
                LoadArg   arg   = instructions[index - 1] as LoadArg;
                LoadLocal local = instructions[index - 1] as LoadLocal;

                if (arg != null || local != null)
                {
                    TypedInstruction instruction = instructions[index];
                    Code             code        = instruction.Untyped.OpCode.Code;

                    if (code == Code.Brtrue || code == Code.Brtrue_S)
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNullArgBlockLen - arg.Arg, FirstNonNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNullLocalBlockLen - local.Variable, FirstNonNullLocalBlockLen - local.Variable);
                        }
                    }
                    else
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNonNullArgBlockLen - arg.Arg, FirstNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNonNullLocalBlockLen - local.Variable, FirstNullLocalBlockLen - local.Variable);
                        }
                    }
                }
            }
Esempio n. 29
0
        public DataFlow(TypedInstructionCollection instructions, BasicBlock[] roots)
        {
            DBC.Pre(instructions != null, "instructions is null");
            DBC.Pre(roots.Length > 0, "no roots");
            Log.DebugLine(this, "{0:F}", instructions);

            if (instructions.Method.Body.Variables.Count < 256)
            {
                if (roots.Length == 1)
                {
                    m_entry = roots[0];
                }
                else
                {
                    m_entry = new BasicBlock(0, roots);
                }

                DoAddReachableToWorkList(m_entry);
                DoAddPredecessors(null, m_entry);

                // The algorithm is much faster if predecessor blocks appear first.
                m_workList.Sort(delegate(BasicBlock lhs, BasicBlock rhs)
                {
                    return(lhs.SafeIndex.CompareTo(rhs.SafeIndex));
                });

#if LOG_BLOCKS
                DoLogWorkList();
                DoLogPredecessors();
#endif
            }
            else
            {
                // Methods with a very large number of local variables can cause dataflow
                // to take a very long time so we skip them.
                m_skipped = true;
                Log.InfoLine(this, "skipping DataFlow for {0} (it has {1} locals)", instructions.Method, instructions.Method.Body.Variables.Count);
            }
        }
Esempio n. 30
0
            private static Lattice DoGetInitialState(TypedInstructionCollection instructions)
            {
                // Get the arguments.
                int numArgs = instructions.Method.Parameters.Count + 1;

                long?[] args = new long?[numArgs];
                for (int i = 0; i < numArgs; ++i)
                {
                    if (instructions.Method.HasThis && i == 0)
                    {
                        args[i] = 1;
                    }
                    else
                    {
                        args[i] = null;
                    }
                }

                // Get the locals.
                int  numLocals = instructions.Method.Body.Variables.Count;
                long?value     = 0;

                if (!instructions.Method.Body.InitLocals)
                {
                    value = null;
                }

                long?[] locals = new long?[numLocals];
                for (int i = 0; i < numLocals; ++i)
                {
                    locals[i] = value;
                }

                // Get the stack.
                List <StackEntry> stack = new List <StackEntry>();

                return(new Lattice(instructions, new State(args, locals, stack)));
            }
Esempio n. 31
0
        private Dictionary <int, BasicBlock> DoGetUnwiredBlocks(TypedInstructionCollection instructions)
        {
            // First get a list of all the instructions which start a block.
            List <int> leaders = DoGetLeaders(instructions);

            // Sort them so we can efficiently pop them off the list.
            leaders.Sort();
            Log.TraceLine(this, "Leaders: {0}", DoTargetsToString(instructions, leaders));
            leaders.Reverse();

            // And form the basic blocks by starting at the first leader and
            // accumulating instructions until we hit another leader.
            Dictionary <int, BasicBlock> blocks = new Dictionary <int, BasicBlock>();

            while (leaders.Count > 0)
            {
                int first = leaders[leaders.Count - 1];
                leaders.RemoveAt(leaders.Count - 1);

                BasicBlock block;
                if (leaders.Count > 0)
                {
                    int last = leaders[leaders.Count - 1];
                    DBC.Assert(first < last, "Leader {0} should be before {1}", first, last);

                    block = new BasicBlock(instructions[first], instructions[last - 1]);
                }
                else
                {
                    block = new BasicBlock(instructions[first], instructions[instructions.Length - 1]);
                }

                blocks.Add(first, block);
                Log.DebugLine(this, "Added block: {0}", block);
            }

            return(blocks);
        }
Esempio n. 32
0
		private int DoCheckCatch(TypedInstructionCollection instructions, CatchBlock cb, int varIndex)
		{
			int offset = -1;
			
			// Loop through all of the instructions in the catch block,
			for (int index = cb.Index; index < cb.Index + cb.Length && offset < 0; ++index)
			{
				TypedInstruction instruction = instructions[index];
				
				// if we find a throw instruction,
				if (instruction.Untyped.OpCode.Code == Code.Throw)
				{
					// and it's preceded by a load from varIndex then we have a problem.
					LoadLocal load = instructions[index - 1] as LoadLocal;
					if (load != null && load.Variable == varIndex)
					{
						offset = instruction.Untyped.Offset;
						Log.DebugLine(this, "bad throw at {0:X2}", offset); 
					}
				}
			}
			
			return offset;
		}
Esempio n. 33
0
        public void TwoIfs()
        {
            TypeDefinition   type   = DoGetType("Cases");
            MethodDefinition method = type.Methods.GetMethod("TwoIfs")[0];

            var instructions = new TypedInstructionCollection(new SymbolTable(), method);
            var tracker      = new V0.Tracker(instructions);

            int index = DoGetIndex(instructions, "second");

            Assert.AreEqual(2, tracker.State(index).Value);

            index = DoGetIndex(instructions, "third");
            Assert.AreEqual(3, tracker.State(index).Value);

            index = DoGetIndex(instructions, "fourth");
            Assert.IsFalse(tracker.State(index).HasValue);

            index = DoGetIndex(instructions, "fifth");
            Assert.AreEqual(5, tracker.State(index).Value);

            index = DoGetIndex(instructions, "last");
            Assert.IsFalse(tracker.State(index).HasValue);
        }
Esempio n. 34
0
		private Dictionary<int, BasicBlock> DoGetWiredBlocks(TypedInstructionCollection instructions)
		{
			DBC.Pre(instructions.Length > 0, "Can't get a root if there are no instructions");

			m_branchTargets = new List<int>();
			Dictionary<int, BasicBlock> blocks = DoGetUnwiredBlocks(instructions);	// index -> block
			
			foreach (KeyValuePair<int, BasicBlock> entry in blocks)
				DoWireBlock(instructions, blocks, entry.Value);
				
			return blocks;
		}
Esempio n. 35
0
		private static string DoTargetsToString(TypedInstructionCollection instructions, List<int> targets)
		{
			StringBuilder builder = new StringBuilder();
			
			builder.Append('[');
			for (int i = 0; i < targets.Count; ++i)
			{
				int index = targets[i];
				TypedInstruction instruction = instructions[index];
				
				builder.Append(instruction.Untyped.Offset.ToString("X2"));
				if (i + 1 < targets.Count)
					builder.Append(", ");
			}
			builder.Append(']');
			
			return builder.ToString();
		}
Esempio n. 36
0
			private static void DoSpliceEq(TypedInstructionCollection instructions, BasicBlock block)
			{				
				int index = block.Last.Index;
				
                // ldloc.0 V_0
				// ldnull     
                // beq     2F
				LoadArg arg = null;
				LoadLocal local = null;
				if (instructions[index - 1].Untyped.OpCode.Code == Code.Ldnull)
				{
					arg = instructions[block.Last.Index - 2] as LoadArg;
					local = instructions[block.Last.Index - 2] as LoadLocal;
				}
				else if (instructions[index - 2].Untyped.OpCode.Code == Code.Ldnull)
				{
					arg = instructions[block.Last.Index - 1] as LoadArg;
					local = instructions[block.Last.Index - 1] as LoadLocal;
				}

				if (arg != null || local != null)
				{
					TypedInstruction instruction = instructions[block.Last.Index];
					Code code = instruction.Untyped.OpCode.Code;
					
					if (code == Code.Bne_Un || code == Code.Bne_Un_S)
					{
						if (arg != null)
							DoSpliceNull(block, FirstNullArgBlockLen - arg.Arg, FirstNonNullArgBlockLen - arg.Arg);
	
						else 
							DoSpliceNull(block, FirstNullLocalBlockLen - local.Variable, FirstNonNullLocalBlockLen - local.Variable);
					}
					else
					{
						if (arg != null)
							DoSpliceNull(block, FirstNonNullArgBlockLen - arg.Arg, FirstNullArgBlockLen - arg.Arg);
	
						else 
							DoSpliceNull(block, FirstNonNullLocalBlockLen - local.Variable, FirstNullLocalBlockLen - local.Variable);
					}
				}
			}
Esempio n. 37
0
		public void TrashStackTrace()	
		{
			TypeDefinition type = DoGetType("Cases");
			MethodDefinition method = type.Methods.GetMethod("TrashStackTrace")[0];

			TypedInstructionCollection instructions = new TypedInstructionCollection(new SymbolTable(), method);			
			Log.DebugLine((ControlFlowGraph) null, "-----------------------------------"); 
			Log.DebugLine((ControlFlowGraph) null, "{0:F}", instructions);
			
			ControlFlowGraph graph = new ControlFlowGraph(instructions);
			Assert.AreEqual(2, graph.Roots.Length);
			Log.DebugLine((ControlFlowGraph) null, "Root 1:\n{0:T}", graph.Roots[0]);
			Log.DebugLine((ControlFlowGraph) null, "Root 2:\n{0:T}", graph.Roots[1]);
		}	
Esempio n. 38
0
		public void ZFinally()	
		{
			TypeDefinition type = DoGetType("Cases");
			MethodDefinition method = type.Methods.GetMethod("Finally")[0];

			var instructions = new TypedInstructionCollection(new SymbolTable(), method);	
			var tracker = new V0.Tracker(instructions);
						
			int index = DoGetIndex(instructions, "first");
			Assert.AreEqual(2, tracker.State(index).Value);
			
			index = DoGetIndex(instructions, "catch");
			Assert.AreEqual(3, tracker.State(index).Value);
						
			index = DoGetIndex(instructions, "finally");
			Assert.AreEqual(2, tracker.State(index).Value);
			
			index = DoGetIndex(instructions, "last");
			Assert.AreEqual(2, tracker.State(index).Value);
		}
Esempio n. 39
0
		public void Linear()	
		{
			TypeDefinition type = DoGetType("Cases");
			MethodDefinition method = type.Methods.GetMethod("Linear")[0];

			TypedInstructionCollection instructions = new TypedInstructionCollection(new SymbolTable(), method);			
			Log.DebugLine((ControlFlowGraph) null, "-----------------------------------"); 
			Log.DebugLine((ControlFlowGraph) null, "{0:F}", instructions);
			
			ControlFlowGraph graph = new ControlFlowGraph(instructions);
			Assert.AreEqual(1, graph.Roots.Length);
			Log.DebugLine((ControlFlowGraph) null, "\n{0:T}", graph.Roots[0]);
			Assert.AreEqual(1, graph.Length);

			Assert.AreEqual(0, graph.Roots[0].First.Index);
			Assert.AreEqual(instructions.Length - 1, graph.Roots[0].Last.Index);
		}
Esempio n. 40
0
			private static Lattice DoGetInitialState(TypedInstructionCollection instructions)
			{
				// Get the arguments.
				int numArgs = instructions.Method.Parameters.Count + 1;
	
				long?[] args = new long?[numArgs];
				for (int i = 0; i < numArgs; ++i)
					if (instructions.Method.HasThis && i == 0)
						args[i] = 1;
					else
						args[i] = null;
					
				// Get the locals.
				int numLocals = instructions.Method.Body.Variables.Count;
				long? value = 0;
				if (!instructions.Method.Body.InitLocals)
					value = null;

				long?[] locals = new long?[numLocals];
				for (int i = 0; i < numLocals; ++i)
					locals[i] = value;

				// Get the stack.
				List<StackEntry> stack = new List<StackEntry>();

				return new Lattice(instructions, new State(args, locals, stack));
			}
Esempio n. 41
0
		// Before leaving a try or catch block we need to transfer control to 
		// the finally block (if present).
		private static void DoAddFinally(TypedInstructionCollection instructions, List<BasicBlock> nextBlocks, Dictionary<int, BasicBlock> blocks, BasicBlock block)
		{
			TryCatch candidate = null;
			
			for (int i = 0; i < instructions.TryCatchCollection.Length; ++i)
			{
				TryCatch tc = instructions.TryCatchCollection[i];
				if (tc.Finally.Length > 0)
				{
					if (block.First.Index >= tc.Try.Index && block.Last.Index < tc.Try.Index + tc.Try.Length)
					{
						if (candidate == null || tc.Try.Length < candidate.Try.Length)
							candidate = tc;
					}
					else
					{
						for (int j = 0; j < tc.Catchers.Count; ++j)
						{
							if (block.First.Index >= tc.Catchers[j].Index && block.Last.Index < tc.Catchers[j].Index + tc.Catchers[j].Length)
							{
								if (candidate == null || tc.Try.Length < candidate.Try.Length)
									candidate = tc;
							}
						}
					}
				}
				else if (tc.Fault.Length > 0)
				{
					for (int j = 0; j < tc.Catchers.Count; ++j)
					{
						if (block.First.Index >= tc.Catchers[j].Index && block.Last.Index < tc.Catchers[j].Index + tc.Catchers[j].Length)
						{					
							block.Fault = blocks[tc.Fault.Index];
							DoWireCatches(instructions, nextBlocks, blocks, tc.Fault.Index);
							return;
						}
					}
				}
			}	
			
			if (candidate != null)
			{
				block.Finally = blocks[candidate.Finally.Index];
				DoWireCatches(instructions, nextBlocks, blocks, candidate.Finally.Index);
			}
		}
Esempio n. 42
0
		private List<int> DoGetLeaders(TypedInstructionCollection instructions)
		{
			// The leaders will be:   
			List<int> leaders = new List<int>();
			
			// 1) the first instruction in the method,
			leaders.Add(0);
			
			for (int index = 0; index < instructions.Length; ++index)
			{
				TypedInstruction instruction = instructions[index];

				// 2) the targets of branches,
				Branch branch = instruction as Branch;
				if (branch != null)
				{
					m_branchTargets.Add(branch.Target.Index);
				}
				else
				{
					Switch swtch = instruction as Switch;
					if (swtch != null)
					{
						foreach (TypedInstruction i in swtch.Targets)
							m_branchTargets.Add(i.Index);
					}
				}
				
				if (index > 0)
				{
					// 3) and instructions starting try, catch or finally blocks,
					TryCatch tc = instructions.TryCatchCollection.HandlerStartsAt(index);
					if (tc != null)
						leaders.Add(index);

					// 4) the instructions following branches or end instructions.
					else if (instructions[index - 1] is Branch || instructions[index - 1] is Switch || instructions[index - 1] is End)
						leaders.Add(index);
				}
			}
			
			foreach (int target in m_branchTargets)
			{
				if (leaders.IndexOf(target) < 0)
					leaders.Add(target);					
			}
			
			return leaders;
		}
Esempio n. 43
0
		private static void DoWireCatches(TypedInstructionCollection instructions, List<BasicBlock> nextBlocks, Dictionary<int, BasicBlock> blocks, int targetIndex)
		{
			foreach (TryCatch tc in instructions.TryCatchCollection)
			{
				if (tc.Try.Index == targetIndex)
				{
					foreach (CatchBlock cb in tc.Catchers)
						nextBlocks.Add(blocks[cb.Index]);

					if (tc.Fault.Length > 0 && tc.Catchers.Count == 0)
						nextBlocks.Add(blocks[tc.Fault.Index]);
				}
			}
		}
Esempio n. 44
0
		private Dictionary<int, BasicBlock> DoGetUnwiredBlocks(TypedInstructionCollection instructions)
		{
			// First get a list of all the instructions which start a block.
			List<int> leaders = DoGetLeaders(instructions);
			
			// Sort them so we can efficiently pop them off the list.
			leaders.Sort();
			Log.TraceLine(this, "Leaders: {0}", DoTargetsToString(instructions, leaders));
			leaders.Reverse();
			
			// And form the basic blocks by starting at the first leader and
			// accumulating instructions until we hit another leader.
			Dictionary<int, BasicBlock> blocks = new Dictionary<int, BasicBlock>();

			while (leaders.Count > 0)
			{
				int first = leaders[leaders.Count - 1];
				leaders.RemoveAt(leaders.Count - 1);
				
				BasicBlock block;
				if (leaders.Count > 0)
				{
					int last = leaders[leaders.Count - 1];
					DBC.Assert(first < last, "Leader {0} should be before {1}", first, last);
					
					block = new BasicBlock(instructions[first], instructions[last - 1]);
				}
				else
				{
					block = new BasicBlock(instructions[first], instructions[instructions.Length - 1]);
				}

				blocks.Add(first, block);
				Log.DebugLine(this, "Added block: {0}", block);
			}
			
			return blocks;
		}
Esempio n. 45
0
			private static void DoSpliceTrue(TypedInstructionCollection instructions, BasicBlock block)
			{				
				int index = block.Last.Index;
	
				// ldarg.1 a1
				// brtrue  10	(not taken is the first branch)
				LoadArg arg = instructions[index - 1] as LoadArg;
				LoadLocal local = instructions[index - 1] as LoadLocal;

				if (arg != null || local != null)
				{
					TypedInstruction instruction = instructions[index];
					Code code = instruction.Untyped.OpCode.Code;
	
					if (code == Code.Brtrue || code == Code.Brtrue_S)
					{
						if (arg != null)
							DoSpliceNull(block, FirstNullArgBlockLen - arg.Arg, FirstNonNullArgBlockLen - arg.Arg);
	
						else 
							DoSpliceNull(block, FirstNullLocalBlockLen - local.Variable, FirstNonNullLocalBlockLen - local.Variable);
					}
					else 
					{
						if (arg != null)
							DoSpliceNull(block, FirstNonNullArgBlockLen - arg.Arg, FirstNullArgBlockLen - arg.Arg);
	
						else 
							DoSpliceNull(block, FirstNonNullLocalBlockLen - local.Variable, FirstNullLocalBlockLen - local.Variable);
					}
				}
			}
Esempio n. 46
0
            // This is another case where the lattice meet and transform paradigm 
            // doesn't work so well. What we want to do is set locals and arguments
            // based on the result of null pointer comparisons. Doing this in meet 
            // would be really ugly and would break commutativity so we handle it
            // by splicing in a special block to each edge leading out from the branch.
			private void DoSpliceNullCheck(TypedInstructionCollection instructions, BasicBlock block, List<BasicBlock> visited)
			{
				if (visited.IndexOf(block) < 0)
				{
					visited.Add(block);
					
					if (block.Next.Length == 2)
						DoTrySpliceNull(instructions, block);
					
					for (int i = 0; i < block.Next.Length; ++i)
						DoSpliceNullCheck(instructions, block.Next[i], visited);
					
					if (block.Finally != null)
						DoSpliceNullCheck(instructions, block.Finally, visited);
					else if (block.Fault != null)
						DoSpliceNullCheck(instructions, block.Fault, visited);
				}
			}
Esempio n. 47
0
		private int DoGetIndex(TypedInstructionCollection instructions, string text)
		{
			foreach (LoadString load in instructions.Match<LoadString>())
			{
				if (load.Value.Contains(text))
					return load.Index;
			}
			
			DBC.Fail("Couldn't find {0}", text);
			return -1;
		}
Esempio n. 48
0
		private void DoInvariantRoots(TypedInstructionCollection instructions, Dictionary<int, BasicBlock> blocks, BasicBlock[] roots)
		{	
			List<BasicBlock> deadBlocks = null, reachable = null;
			
			try
			{
				// Get all of the blocks reachable from roots,
				reachable = new List<BasicBlock>();
				foreach (BasicBlock b in roots)
					DoGetReachableBlocks(reachable, b);
				
				int sum = 0;
				for (int i = 0; i < reachable.Count; ++i)
				{
					BasicBlock b1 = reachable[i];
					Log.TraceLine(this, "reachable{0} = {1}", i, b1);
					sum += b1.Last.Index - b1.First.Index + 1;
					
					// they should be sane,
					DBC.Assert(b1.First.Index <= b1.Last.Index, "block {0} has bad indexes", b1);
					DBC.Assert(b1.Next != null, "block {0} has no next blocks array", b1);				
					
					// and they should all be disjoint.
					for (int j = i + 1; j < reachable.Count; ++j)
					{
						BasicBlock b2 = reachable[j];
						DBC.Assert(b1.First.Index < b2.First.Index || b1.First.Index > b2.Last.Index, "block {0} intersects block {1}", b1, b2);
						DBC.Assert(b1.Last.Index < b2.First.Index || b1.Last.Index > b2.Last.Index, "block {0} intersects block {1}", b1, b2);
					}
				}
				
				// And the total number of instructions in them should equal the number of
				// instructions in instructions plus any dead blocks.
				deadBlocks = DoGetDeadBlocks(instructions, blocks, reachable);
				
				int deadCount = 0;
				foreach (BasicBlock b in deadBlocks)
				{
					deadCount += b.Last.Index - b.First.Index + 1;
					Log.TraceLine(this, "Block {0} is dead code", b);
				}
				
				DBC.Assert(sum + deadCount == instructions.Length, "blocks cover {0} instructions, but there are {1} instructions", sum, instructions.Length);
			}
			catch (AssertException e)
			{
				Log.ErrorLine(this, "Assert: {0}", e.Message);
				if (reachable != null && deadBlocks != null)
					Log.ErrorLine(this, "Missed: {0}", DoGetMissedOffsets(instructions, reachable, deadBlocks));
				Log.ErrorLine(this, "Instructions:");
				Log.ErrorLine(this, "{0:F}", instructions);
				Log.ErrorLine(this, "Blocks are:");
				foreach (BasicBlock b in blocks.Values)
				{
					Log.ErrorLine(this, "{0}", b);
					Log.ErrorLine(this);
				}
				throw;
			}
		}
Esempio n. 49
0
		public void DoWhile()	
		{
			TypeDefinition type = DoGetType("Cases");
			MethodDefinition method = type.Methods.GetMethod("DoWhile")[0];

			var instructions = new TypedInstructionCollection(new SymbolTable(), method);	
			var tracker = new V0.Tracker(instructions);
						
			int index = DoGetIndex(instructions, "first");
			Assert.IsFalse(tracker.State(index).HasValue);
			
			index = DoGetIndex(instructions, "second");
			Assert.AreEqual(2, tracker.State(index).Value);
						
			index = DoGetIndex(instructions, "last");
			Assert.IsFalse(tracker.State(index).HasValue);
		}
Esempio n. 50
0
		internal MethodInfo(TypeDefinition type, MethodDefinition method)
		{
			Type = type;
			Method = method;
			Instructions = new TypedInstructionCollection(new SymbolTable(), Method);
		}
Esempio n. 51
0
			public static readonly int LastNonNullLocalBlockLen  = -4999;	// A_999
			
			#region Private Methods -------------------------------------------
			// Catch and finally blocks require special handling to reset their stacks
			// on entry. We can't really do this in meet without breaking commutativity
			// and transform is too late. So what we do is splice in a special zero
			// length block right before the handler and when it is transformed reset
			// the stack.
			private void DoSpliceHandlers(TypedInstructionCollection instructions, BasicBlock block, List<BasicBlock> visited)
			{
				if (visited.IndexOf(block) < 0)
				{
					visited.Add(block);
					
					for (int i = 0; i < block.Next.Length; ++i)
					{
						BasicBlock next = block.Next[i];
						
						if (next.Length > 0)
						{
							TryCatch tc = instructions.TryCatchCollection.HandlerStartsAt(next.First.Index);
							if (tc != null && tc.Try.Index != next.First.Index)
							{
								BasicBlock splice = null;
								if (tc.Finally.Length > 0 && tc.Finally.Index == next.First.Index)
									splice = new BasicBlock(FinallyBlockLen, new BasicBlock[1]);
								else if (tc.Fault.Length > 0 && tc.Fault.Index == next.First.Index)
									splice = new BasicBlock(FinallyBlockLen, new BasicBlock[1]);
								else
									splice = new BasicBlock(CatchBlockLen, new BasicBlock[1]);
								splice.Next[0] = next;
								
								block.Next[i] = splice;
							}
						}
						
						DoSpliceHandlers(instructions, next, visited);
					}
					
					if (block.Finally != null)
						DoSpliceHandlers(instructions, block.Finally, visited);
					else if (block.Fault != null)
						DoSpliceHandlers(instructions, block.Fault, visited);
				}
			}
Esempio n. 52
0
		private static string DoGetMissedOffsets(TypedInstructionCollection instructions, List<BasicBlock> reachable, List<BasicBlock> deadBlocks)
		{
			// Get a list of all the offsets in the method.
			List<int> offsets = new List<int>(instructions.Length);
			
			foreach (TypedInstruction instruction in instructions)
				offsets.Add(instruction.Untyped.Offset);
				
			// Remove the visited instructions.
			foreach (BasicBlock block in reachable)
				DoRemoveOffsets(instructions, offsets, block);
				
			// Remove the dead code.
			foreach (BasicBlock block in deadBlocks)
				DoRemoveOffsets(instructions, offsets, block);
				
			// Anything left is code we should have visited but didn't.
			return ListExtensions.Accumulate(offsets, string.Empty, (s, e) => s + e.ToString("X2") + " ");
		}
Esempio n. 53
0
        private void DoInit(string methodName)
        {
            string loc = Assembly.GetExecutingAssembly().Location;
            AssemblyDefinition assembly = AssemblyFactory.GetAssembly(loc);

            string fullName = string.Format("{0}/{1}", GetType().FullName, "Cases");
            TypeDefinition type = assembly.MainModule.Types[fullName];

            MethodDefinition method = type.Methods.GetMethod(methodName)[0];

            m_instructions = new TypedInstructionCollection(new SymbolTable(), method);
            m_tracker = new Tracker(m_instructions);
            m_tracker.Analyze();
        }
Esempio n. 54
0
		private static void DoRemoveOffsets(TypedInstructionCollection instructions, List<int> offsets, BasicBlock block)
		{
			if (block.Length > 0)
			{
				for (int i = block.First.Index; i <= block.Last.Index; ++i)
				{
					Unused.Value = offsets.Remove(instructions[i].Untyped.Offset);
				}
			}
		}
Esempio n. 55
0
		public void ZNestedFinally()	
		{
			TypeDefinition type = DoGetType("Cases");
			MethodDefinition method = type.Methods.GetMethod("NestedFinally")[0];

			TypedInstructionCollection instructions = new TypedInstructionCollection(new SymbolTable(), method);			
			Log.DebugLine((ControlFlowGraph) null, "-----------------------------------"); 
			Log.DebugLine((ControlFlowGraph) null, "{0:F}", instructions);
			
			ControlFlowGraph graph = new ControlFlowGraph(instructions);
			Assert.AreEqual(2, graph.Roots.Length);
		}
Esempio n. 56
0
		private List<BasicBlock> DoGetDeadBlocks(TypedInstructionCollection instructions, Dictionary<int, BasicBlock> blocks, List<BasicBlock> reachable)
		{
			List<BasicBlock> deadBlocks = new List<BasicBlock>();
			
			// If the block isn't the target of a branch and it's preceded by an end
			// instruction it's dead code. This can happen if a catch block throws.
			foreach (KeyValuePair<int, BasicBlock> entry in blocks)
			{
				BasicBlock b = entry.Value;
				int i = b.First.Index;
				
				if (m_branchTargets.IndexOf(i) < 0)
				{
					if (instructions.TryCatchCollection.HandlerStartsAt(i) == null)
						if (i > 0 && (instructions[i - 1] is End || instructions[i - 1] is UnconditionalBranch))
							deadBlocks.Add(b);
				}
			}
			
			// If a leave is dead code then its target is dead as well. 
			List<BasicBlock> deaderBlocks = new List<BasicBlock>();
			foreach (BasicBlock b in deadBlocks)
			{
				if (b.Length > 0)
				{
					for (int i = b.First.Index; i <= b.Last.Index; ++i)
					{
						if (instructions[i].Untyped.OpCode.Code == Code.Leave || instructions[i].Untyped.OpCode.Code == Code.Leave_S)
						{
							UnconditionalBranch branch = (UnconditionalBranch) instructions[i];
							if (reachable.IndexOf(blocks[branch.Target.Index]) < 0 && deaderBlocks.IndexOf(blocks[branch.Target.Index]) < 0)
								deaderBlocks.Add(blocks[branch.Target.Index]);
						}
					}
				}
			}
			deadBlocks.AddRange(deaderBlocks);
			
			return deadBlocks;
		}
Esempio n. 57
0
		private void DoWireBlock(TypedInstructionCollection instructions, Dictionary<int, BasicBlock> blocks, BasicBlock block)
		{
			var nextBlocks = new List<BasicBlock>();
			
			if (block.First.Index == 0)
				DoWireCatches(instructions, nextBlocks, blocks, 0);

			do
			{
				ConditionalBranch conditional = block.Last as ConditionalBranch;
				if (conditional != null)
				{
					nextBlocks.Add(blocks[conditional.Index + 1]);
					nextBlocks.Add(blocks[conditional.Target.Index]);
					
					DoWireCatches(instructions, nextBlocks, blocks, conditional.Index + 1);
					DoWireCatches(instructions, nextBlocks, blocks, conditional.Target.Index);
					break;
				}

				UnconditionalBranch unconditional = block.Last as UnconditionalBranch;
				if (unconditional != null)
				{
					nextBlocks.Add(blocks[unconditional.Target.Index]);
					DoWireCatches(instructions, nextBlocks, blocks, unconditional.Target.Index);
					
					if (block.Last.Untyped.OpCode.Code == Code.Leave || block.Last.Untyped.OpCode.Code == Code.Leave_S)
						DoAddFinally(instructions, nextBlocks, blocks, block);
					break;
				}

				Switch swtch = block.Last as Switch;
				if (swtch != null)
				{
					foreach (TypedInstruction t in swtch.Targets)
					{
						nextBlocks.Add(blocks[t.Index]);
						DoWireCatches(instructions, nextBlocks, blocks, t.Index);
					}
					nextBlocks.Add(blocks[swtch.Index + 1]);
					DoWireCatches(instructions, nextBlocks, blocks, swtch.Index + 1);
					break;
				}

				End end = block.Last as End;
				if (end != null)
				{
					DoAddFinally(instructions, nextBlocks, blocks, block);
					break;
				}
				
				DoWireCatches(instructions, nextBlocks, blocks, block.Last.Index + 1);
				nextBlocks.Add(blocks[block.Last.Index + 1]);
			} 
			while (false);
							
			block.Next = nextBlocks.ToArray();
			Log.DebugLine(this, "Wired block: {0}", block);
		}
Esempio n. 58
0
			private static void DoTrySpliceNull(TypedInstructionCollection instructions, BasicBlock block)
			{
				TypedInstruction instruction = instructions[block.Last.Index];
				Code code = instruction.Untyped.OpCode.Code;
				
				if (code == Code.Brtrue || code == Code.Brtrue_S || code == Code.Brfalse || code == Code.Brfalse_S)
				{
					DoSpliceTrue(instructions, block);
				}
				else if (code == Code.Beq || code == Code.Beq_S || code == Code.Bne_Un || code == Code.Bne_Un_S)
				{
					DoSpliceEq(instructions, block);
				}
			}