/** * Generate handler info for exception with the generated instructions. * * @param insts the generated instructions. * @return handlers of exception for classfile. */ public HandlerInfo[] getHandlerInfos(Instruction[] insts) { HandlerInfo[] handlers = info.getHandlers(); for (int i = 0; i < handlers.length; ++i) { HandlerInfo handler = handlers[i]; ExceptionHandler eh = exceptionHandlers[i]; eh.searchIndex(); handler.setStart(insts[eh.getStart()]); handler.setEnd(insts[eh.getEnd()]); handler.setHandler(insts[eh.getHandle()]); } return handlers; }
/** * 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); } } } } }