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); }
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"); }
// 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); } } }