// reverse b2e_succ to construct b2e_pred private void BuildHandlerPredecessorMap () { Relation e_pred = new BlockRelation(); foreach(Block block in all_blocks) { Block e_block = ExceptionHandler(block); if (e_block != null) e_pred.Add(e_block, block); } b2e_pred = Relation.Compact(e_pred, typeof(CfgBlock)); }
public void TreatLeaveInstructions () { // The order the leave instructions are treated is important: if block B1 is // protected by a finally handler that contains block B2, then all "leave" // instructions from B1 must be processed AFTER all "leave" instructions from B2. // The following code does exactly this. StatementList blocks = method.Body.Statements; IMutableRelation/*<Block,Block>*/ blockSuccessor = new BlockRelation(); ExceptionHandlerList ehs = method.ExceptionHandlers; for(int i = 0, n = ehs == null ? 0 : ehs.Count; i < n; i++) { ExceptionHandler eh = ehs[i]; if (eh.HandlerType != NodeType.Finally) { continue; } int hdlr_start = (int) b2index[eh.HandlerStartBlock]; int hdlr_end = (int) b2index[eh.BlockAfterHandlerEnd]; int try_start = (int) b2index[eh.TryStartBlock]; int try_end = (int) b2index[eh.BlockAfterTryEnd]; for(int bti = try_start; bti < try_end; bti++) { for(int bhi = hdlr_start; bhi < hdlr_end; bhi++) { blockSuccessor.Add(/*B1*/(Block) blocks[bti], /*B2*/(Block) blocks[bhi]); } } } // gather all original blocks IList/*<Block>*/ originalBlocks = new ArrayList(); originalBlocks.Add(this.cfg.entry_point); originalBlocks.Add(this.cfg.normal_exit_point); originalBlocks.Add(this.cfg.excp_exit_point); originalBlocks.Add(this.cfg.exit_point); for(int i = 0; i < blocks.Count; i++) { originalBlocks.Add((Block) blocks[i]); } IList/*<Block>*/ blocksInOrder = GraphUtil.TopologicallySortGraph(DataStructUtil.NodeSetFactory, originalBlocks, new MapBasedNavigator(blockSuccessor)); // blocksInOrder starts with the blocks b such that blockSuccessor[b] is empty; i.e., they // don't have to wait for any other block foreach (Block block in blocksInOrder) { StatementList stats = block.Statements; for(int i = 0; i < stats.Count; i++) { Branch leave = stats[i] as Branch; if ((leave == null) || ! leave.LeavesExceptionBlock) { continue; } ProcessLeave(block, i, leave); } } }
private void BuildNormalFlow ( CfgBlock[] blocks, NormalFlowBlockNavigator nfbnav, CfgBlock real_entry ) { IMutableRelation/*<Block,Block>*/ n_succ = new BlockRelation(); foreach(Block block in blocks) { if (block is ISpecialBlock) continue; n_succ.AddAll(block, nfbnav.NextNodes(block)); } // common sense rules n_succ.Add(entry_point, real_entry); n_succ.Add(normal_exit_point, exit_point); n_succ.Add(excp_exit_point, exit_point); IRelation/*<Block,Block>*/ n_pred = n_succ.Reverse(); b2n_succ = Relation.Compact(n_succ, typeof(CfgBlock)); b2n_pred = Relation.Compact(n_pred, typeof(CfgBlock)); }