Пример #1
0
        public override bool Equals(object rhsObj)
        {
            if (rhsObj == null)                                    // objects may be null
            {
                return(false);
            }

            if (GetType() != rhsObj.GetType())
            {
                return(false);
            }

            CatchBlock rhs = (CatchBlock)rhsObj;

            return(this == rhs);
        }
Пример #2
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");
        }
Пример #3
0
        // There will be separate handlers for each catch block and for the
        // finally block (if present). Handlers that share the same try block
        // will have equal [TryStart, TryEnd) values. The handler block will
        // be in [HandlerStart, HandlerEnd).
        private void DoGetTryCatches(TypedInstructionCollection instructions)
        {
            if (instructions.Method.Body.ExceptionHandlers.Count == 0)
            {
                return;
            }

            Log.DebugLine(this, "----------------------------------------");
            Log.DebugLine(this, "{0:F}", instructions);
            foreach (ExceptionHandler handler in instructions.Method.Body.ExceptionHandlers)
            {
                Log.DebugLine(this, "handler.TryStart.Offset {0:X2}", handler.TryStart.Offset);
                Log.DebugLine(this, "handler.TryEnd.Offset {0:X2}", handler.TryEnd.Offset);

                if (handler.Type == ExceptionHandlerType.Catch)
                {
                    Log.DebugLine(this, "handler.CatchStart.Offset {0:X2}", handler.HandlerStart.Offset);
                    Log.DebugLine(this, "handler.CatchEnd.Offset {0:X2}", handler.HandlerEnd.Offset);
                }
                else if (handler.Type == ExceptionHandlerType.Finally)
                {
                    Log.DebugLine(this, "handler.FinallyStart.Offset {0:X2}", handler.HandlerStart.Offset);
                    Log.DebugLine(this, "handler.FinallyEnd.Offset {0:X2}", handler.HandlerEnd.Offset);
                }
                else if (handler.Type == ExceptionHandlerType.Fault)
                {
                    Log.DebugLine(this, "handler.FaultStart.Offset {0:X2}", handler.HandlerStart.Offset);
                    Log.DebugLine(this, "handler.FaultEnd.Offset {0:X2}", handler.HandlerEnd.Offset);
                }
            }

            // First add the catch blocks and the try blocks they're associated with.
            var tries = new Dictionary <long, TryCatch>();

            foreach (ExceptionHandler handler in instructions.Method.Body.ExceptionHandlers)
            {
                if (handler.Type == ExceptionHandlerType.Catch)
                {
                    TryCatch tc = new TryCatch();
                    tc.Try      = DoGetBlock(instructions, handler.TryStart.Offset, handler.TryEnd.Offset);
                    tc.Catchers = new List <CatchBlock>();
                    m_trys.Add(tc);

                    Block b = DoGetBlock(instructions, handler.HandlerStart.Offset, handler.HandlerEnd.Offset);
                    tries.Add(10000L * handler.TryStart.Offset + handler.HandlerEnd.Offset, tc);

                    CatchBlock block = new CatchBlock();
                    block.Index     = b.Index;
                    block.Length    = b.Length;
                    block.CatchType = handler.CatchType;

                    tc.Catchers.Add(block);
                }
            }

            // Then add the finally blocks and their try blocks if they weren't added already.
            foreach (ExceptionHandler handler in instructions.Method.Body.ExceptionHandlers)
            {
                if (handler.Type == ExceptionHandlerType.Finally || handler.Type == ExceptionHandlerType.Fault)
                {
                    long key = 10000L * handler.TryStart.Offset + handler.TryEnd.Offset;

                    TryCatch tc;
                    if (!tries.TryGetValue(key, out tc))
                    {
                        tc          = new TryCatch();
                        tc.Try      = DoGetBlock(instructions, handler.TryStart.Offset, handler.TryEnd.Offset);
                        tc.Catchers = new List <CatchBlock>();
                        m_trys.Add(tc);
                    }

                    if (handler.Type == ExceptionHandlerType.Finally)
                    {
                        tc.Finally = DoGetBlock(instructions, handler.HandlerStart.Offset, handler.HandlerEnd.Offset);
                    }
                    else
                    {
                        tc.Fault = DoGetBlock(instructions, handler.HandlerStart.Offset, handler.HandlerEnd.Offset);
                    }
                }
            }

            foreach (TryCatch tc in m_trys)
            {
                Log.DebugLine(this, "try {0:X2} to {1:X2}", instructions[tc.Try.Index].Untyped.Offset, instructions[tc.Try.Index + tc.Try.Length - 1].Untyped.Offset);
                foreach (CatchBlock c in tc.Catchers)
                {
                    Log.DebugLine(this, "   catch {0:X2} to {1:X2}", instructions[c.Index].Untyped.Offset, instructions[c.Index + c.Length - 1].Untyped.Offset);
                }
                if (tc.Finally.Length > 0)
                {
                    Log.DebugLine(this, "   finally {0:X2} to {1:X2}", instructions[tc.Finally.Index].Untyped.Offset, instructions[tc.Finally.Index + tc.Finally.Length - 1].Untyped.Offset);
                }
                else if (tc.Fault.Length > 0)
                {
                    Log.DebugLine(this, "   finally {0:X2} to {1:X2}", instructions[tc.Fault.Index].Untyped.Offset, instructions[tc.Fault.Index + tc.Fault.Length - 1].Untyped.Offset);
                }
            }
        }