/**
   * Find the blocks protected by each ExceptionHandler. Add "exception edges" in the control flow
   * graph. Add a basic block before the block which catch the exception. This last block store the
   * exception in a variable.
   *
   * <p>Modification 02/04/2002 : add an exception edge between the blocks before the first block
   * protected and the catch block.
   *
   * @param numBlocks an array containing the number of basic block for each instruction.
   * @param insts the instructions
   * @param bbs the basic blocks
   */
  private void findExceptionBlocks(short[] numBlocks, Instruction[] insts, BasicBlock[] bbs) {
    // shows if we had ever add a block for the catch block
    boolean[] marqued = new boolean[bbs.length];
    for (int i = 0; i < exceptionHandlers.length; ++i) {
      ExceptionHandler handle = exceptionHandlers[i];
      int numBlock = numBlocks[handle.getHandle()];
      BasicBlock catchBlock = bbs[numBlock];
      if (!marqued[numBlock]) {
        // add a new block

        // if the first instruction is the saving of the
        // exception put this instruction in the
        // new block else this saving will be added during
        // the 3-adress code generation
        BasicBlock newBlock;
        Instruction first = insts[catchBlock.getStart()];
        if (first instanceof LocalVarInstruction && ((LocalVarInstruction) first).isStore()) {
          int instructionLine = catchBlock.getStart();
          newBlock = new BasicBlock(instructionLine, instructionLine, graph);
          // remove this instruction from the next block
          catchBlock.setStart(instructionLine + 1);
        } else {
          newBlock = new BasicBlock(graph);
        }
        newBlock.setCatchBlock(true);
        catchBlock.insertBefore(newBlock);
        newBlock.addDefaultNextBlock(catchBlock);
        bbs[numBlock] = newBlock;
        catchBlock = newBlock;
        marqued[numBlock] = true;
      }
      handle.setHandlerBlock(catchBlock);
    }
    for (int i = 0; i < exceptionHandlers.length; ++i) {
      ExceptionHandler handle = exceptionHandlers[i];
      BasicBlock catchBlock = handle.getHandlerBlock();
      int numInst = handle.getStart();
      int instEnd = handle.getEnd();
      int numBlock = -1;

      // MODIFICATION 02/04/2002
      if (numInst <= instEnd) {
        BasicBlock first = bbs[numBlocks[numInst]];
        if (catchBlock != first) { // this is possible !
          Iterator preds = first.getPredecessors();
          while (preds.hasNext()) {
            BasicBlock pred = (BasicBlock) preds.next();
            pred.addExceptionNextBlock(catchBlock);
          }
        }
      }
      // END MODIFICATION 02/04/2002

      numBlock = -1;
      for (; numInst <= instEnd; ++numInst) {
        if (numBlocks[numInst] != numBlock) {
          numBlock = numBlocks[numInst];
          // add blocks in exception handler.
          BasicBlock bb = bbs[numBlock];
          handle.addProtectedBlock(bb);
          // add exception edges
          bb.addExceptionNextBlock(catchBlock);

          // if it's a catch block add also the next block
          if (marqued[numBlock]) {
            BasicBlock next = bb.getNext();
            handle.addProtectedBlock(next);
            next.addExceptionNextBlock(catchBlock);
          }
        }
      }
    }
  }