Esempio n. 1
0
 // 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));
 }
Esempio n. 2
0
      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);
          }
        }

      }
Esempio n. 3
0
    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));
    }