private void markAssignment(Variable var) { Deque<BasicBlock> worklist = new ArrayDeque<>(); worklist.push(currentBlock); if (variableDefined[var.getIndex()]) { for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) { placePhi(tryCatch.getHandler().getIndex(), var, currentBlock, worklist); } } else { variableDefined[var.getIndex()] = true; } while (!worklist.isEmpty()) { BasicBlock block = worklist.pop(); int[] frontiers = domFrontiers[block.getIndex()]; if (frontiers != null) { for (int frontier : frontiers) { placePhi(frontier, var, block, worklist); } } } }
private void fillExceptionHandlers(Program program) { exceptionHandlers = new boolean[program.basicBlockCount()]; for (int i = 0; i < exceptionHandlers.length; ++i) { BasicBlock block = program.basicBlockAt(i); for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { exceptionHandlers[tryCatch.getHandler().getIndex()] = true; } } }
private BitSet getUsedVarsInBlock(LivenessAnalyzer liveness, BasicBlock block) { BitSet usedVars = new BitSet(); TransitionExtractor transitionExtractor = new TransitionExtractor(); block.getLastInstruction().acceptVisitor(transitionExtractor); for (BasicBlock successor : transitionExtractor.getTargets()) { usedVars.or(liveness.liveIn(successor.getIndex())); } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { usedVars.or(liveness.liveIn(tryCatch.getHandler().getIndex())); } return usedVars; }
private void parseCatch() throws IOException, ListingParseException { TryCatchBlock tryCatch = new TryCatchBlock(); if (lexer.getToken() == ListingToken.IDENTIFIER && !lexer.getTokenValue().equals("goto")) { tryCatch.setExceptionType((String) lexer.getTokenValue()); lexer.nextToken(); } expectKeyword("goto"); tryCatch.setHandler(expectBlock()); currentBlock.getTryCatchBlocks().add(tryCatch); }
public void fixProgram() { if (mappings == null) { return; } for (BasicBlock block : program.getBasicBlocks()) { Map<BasicBlock, List<Incoming>> incomingsBySource = new LinkedHashMap<>(); for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { if (mappings[incoming.getSource().getIndex()] == incoming.getSource().getIndex()) { continue; } incomingsBySource.computeIfAbsent(incoming.getSource(), b -> new ArrayList<>()).add(incoming); } } for (BasicBlock source : incomingsBySource.keySet()) { boolean isExceptionHandler = source.getTryCatchBlocks().stream() .anyMatch(tryCatch -> tryCatch.getHandler() == block); if (isExceptionHandler) { fixIncomingsInExceptionHandler(source, incomingsBySource.get(source)); } else { BasicBlock newSource = program.basicBlockAt(mappings[source.getIndex()]); for (Incoming incoming : incomingsBySource.get(source)) { incoming.setSource(newSource); } } } } RedundantJumpElimination.optimize(program); }
for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (int j = 0; j < block.getTryCatchBlocks().size(); ++j) { TryCatchBlock tryCatch = block.getTryCatchBlocks().get(j); if (tryCatch.getHandler() == block) { block.getTryCatchBlocks().remove(j--); program.createVariable(); program.basicBlockAt(0).getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches( program.basicBlockAt(1), program)); return program;
? basicBlock.getExceptionVariable().getIndex() : -1); data.writeShort(basicBlock.getPhis().size()); data.writeShort(basicBlock.getTryCatchBlocks().size()); for (Phi phi : basicBlock.getPhis()) { data.writeShort(phi.getReceiver().getIndex()); for (TryCatchBlock tryCatch : basicBlock.getTryCatchBlocks()) { data.writeInt(tryCatch.getExceptionType() != null ? symbolTable.lookup( tryCatch.getExceptionType()) : -1);
public void processMethod(MethodReference method, Program program) { this.methodRef = method; this.program = program; boolean wasModified = false; for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); instructionsToAdd.clear(); boolean missing = false; for (Instruction insn : block) { insn.acceptVisitor(instructionProcessor); if (!instructionsToAdd.isEmpty()) { wasModified = true; truncateBlock(insn); missing = true; break; } } if (!missing) { for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { checkClass(null, tryCatch.getExceptionType()); } } } if (wasModified) { new UnreachableBasicBlockEliminator().optimize(program); } }
public void rename(Program program) { for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock basicBlock = program.basicBlockAt(i); for (Instruction insn : basicBlock) { insn.acceptVisitor(this); } for (TryCatchBlock tryCatch : basicBlock.getTryCatchBlocks()) { if (tryCatch.getExceptionType() != null) { tryCatch.setExceptionType(classNameMapper.map(tryCatch.getExceptionType())); } } } }
public static void copyBasicBlock(BasicBlockReader block, BasicBlock target) { Program targetProgram = target.getProgram(); if (block.getExceptionVariable() != null) { target.setExceptionVariable(targetProgram.variableAt(block.getExceptionVariable().getIndex())); } InstructionCopyReader copyReader = new InstructionCopyReader(targetProgram); for (InstructionIterator iterator = block.iterateInstructions(); iterator.hasNext();) { iterator.next(); iterator.read(copyReader); target.add(copyReader.getCopy()); } target.getPhis().addAll(copyPhis(block, targetProgram)); target.getTryCatchBlocks().addAll(copyTryCatches(block, targetProgram)); }
private void fixOutgoingPhis(BasicBlock block, BasicBlock newBlock, int[] currentJointSources, IntSet outgoingVariablesToRemove, IntSet variablesDefinedHere) { for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { for (Phi phi : tryCatch.getHandler().getPhis()) { int value = currentJointSources[phi.getReceiver().getIndex()];
public void transform(BasicBlock block) { Instruction lastInsn = block.getLastInstruction(); if (lastInsn != null) { lastInsn.acceptVisitor(this); } for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { incoming.setSource(map(incoming.getSource())); } } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { tryCatch.setHandler(map(tryCatch.getHandler())); } }
for (int i = 0; i < blockCount; ++i) { BasicBlock block = program.basicBlockAt(i); for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { exceptionHandlers.add(tryCatch.getHandler());
private void propagateException(String thrownTypeName, BasicBlock block) { for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { String expectedType = tryCatch.getExceptionType(); if (expectedType == null || hierarchy.isSuperType(expectedType, thrownTypeName, false)) { if (tryCatch.getHandler().getExceptionVariable() == null) { break; } int exceptionNode = packNodeAndDegree(tryCatch.getHandler().getExceptionVariable().getIndex(), 0); exceptionNode = nodeMapping[exceptionNode]; int thrownType = getTypeByName(thrownTypeName); if (getNodeTypes(exceptionNode).add(thrownType)) { nodeChanged[exceptionNode] = true; changed = true; } break; } } }
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { ExceptionHandlerDescriptor handler = new ExceptionHandlerDescriptor(++nextHandlerId, tryCatch.getExceptionType());
public BasicBlock split(BasicBlock block, Instruction afterInstruction) { initIfNecessary(); if (afterInstruction.getBasicBlock() != block) { throw new IllegalArgumentException(); } if (isLastInSequence.get(block.getIndex()) == 0) { throw new IllegalArgumentException(); } BasicBlock splitBlock = program.createBasicBlock(); while (previousPtr.size() < splitBlock.getIndex()) { previousPtr.add(previousPtr.size()); firstPtr.add(firstPtr.size()); isLastInSequence.add((byte) 1); } isLastInSequence.set(block.getIndex(), (byte) 0); previousPtr.add(block.getIndex()); firstPtr.add(firstPtr.get(block.getIndex())); mappings[firstPtr.get(block.getIndex())] = splitBlock.getIndex(); isLastInSequence.add((byte) 1); splitBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(block, program)); while (afterInstruction.getNext() != null) { Instruction nextInstruction = afterInstruction.getNext(); nextInstruction.delete(); splitBlock.add(nextInstruction); } return splitBlock; }
public static Graph buildControlFlowGraph(Program program) { GraphBuilder graphBuilder = new GraphBuilder(program.basicBlockCount()); TransitionExtractor transitionExtractor = new TransitionExtractor(); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); Instruction insn = block.getLastInstruction(); if (insn != null) { insn.acceptVisitor(transitionExtractor); if (transitionExtractor.getTargets() != null) { for (BasicBlock successor : transitionExtractor.getTargets()) { graphBuilder.addEdge(i, successor.getIndex()); } } } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { graphBuilder.addEdge(i, tryCatch.getHandler().getIndex()); } } return graphBuilder.build(); }
for (TryCatchBlock tryCatch : sourceBlock.getTryCatchBlocks()) { TryCatchBlock tryCatchCopy = new TryCatchBlock(); int handler = tryCatch.getHandler().getIndex(); tryCatchCopy.setExceptionType(tryCatch.getExceptionType()); tryCatchCopy.setHandler(program.basicBlockAt(copiedNodes.getOrDefault(handler, handler))); targetBlock.getTryCatchBlocks().add(tryCatchCopy);
continueBlock.add(toMove); continueBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(block, program));
private Program generateLaunchProgram(MethodHolder method, ClassHierarchy hierarchy) { ProgramEmitter pe = ProgramEmitter.create(method, hierarchy); pe.getField(TestEntryPoint.class, "testCase", Object.class) .cast(ValueType.object(testMethod.getClassName())) .invokeSpecial(testMethod); MethodReader testMethodReader = hierarchy.getClassSource().resolve(testMethod); AnnotationReader testAnnotation = testMethodReader.getAnnotations().get(JUNIT4_TEST); AnnotationValue throwsValue = testAnnotation != null ? testAnnotation.getValue("expected") : null; if (throwsValue != null) { BasicBlock handler = pe.getProgram().createBasicBlock(); TryCatchBlock tryCatch = new TryCatchBlock(); tryCatch.setExceptionType(((ValueType.Object) throwsValue.getJavaClass()).getClassName()); tryCatch.setHandler(handler); pe.getBlock().getTryCatchBlocks().add(tryCatch); BasicBlock nextBlock = pe.getProgram().createBasicBlock(); pe.jump(nextBlock); pe.enter(nextBlock); pe.construct(AssertionError.class, pe.constant("Expected exception not thrown")).raise(); pe.enter(handler); pe.exit(); } else { pe.exit(); } return pe.getProgram(); } }