private static BuilderExceptionHandler buildHandler(int codeAddress, VirtualClass exceptionType) { BuilderExceptionHandler handler = mock(BuilderExceptionHandler.class); String name = exceptionType.getName(); when(handler.getExceptionType()).thenReturn(name); when(handler.getHandlerCodeAddress()).thenReturn(codeAddress); return handler; }
private static Set<Integer> getExceptionHandlerAddresses(ExecutionGraphManipulator manipulator) { int[] allAddresses = manipulator.getAddresses(); Arrays.sort(allAddresses); int highestAddress = allAddresses[allAddresses.length - 1]; Set<Integer> handlerAddresses = new HashSet<>(); List<BuilderTryBlock> tryBlocks = manipulator.getTryBlocks(); for (BuilderTryBlock tryBlock : tryBlocks) { List<? extends BuilderExceptionHandler> handlers = tryBlock.getExceptionHandlers(); for (BuilderExceptionHandler handler : handlers) { int address = handler.getHandlerCodeAddress(); BuilderInstruction instruction = manipulator.getInstruction(address); while (address < highestAddress) { // Add all instructions until return, goto, etc. handlerAddresses.add(address); address += instruction.getCodeUnits(); instruction = manipulator.getInstruction(address); if (!instruction.getOpcode().canContinue()) { break; } } } } return handlerAddresses; }
@Test public void testNewLabelByAddress() { MethodImplementationBuilder builder = new MethodImplementationBuilder(10); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction32x(Opcode.MOVE_16, 0, 0)); MutableMethodImplementation mutableMethodImplementation = new MutableMethodImplementation(builder.getMethodImplementation()); mutableMethodImplementation.addCatch( mutableMethodImplementation.newLabelForAddress(0), mutableMethodImplementation.newLabelForAddress(8), mutableMethodImplementation.newLabelForAddress(1)); Assert.assertEquals(0, mutableMethodImplementation.getTryBlocks().get(0).getStartCodeAddress()); Assert.assertEquals(8, mutableMethodImplementation.getTryBlocks().get(0).getCodeUnitCount()); Assert.assertEquals(1, mutableMethodImplementation.getTryBlocks().get(0).getExceptionHandlers().get(0) .getHandlerCodeAddress()); }
@Test public void testNewLabelByIndex() { MethodImplementationBuilder builder = new MethodImplementationBuilder(10); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction10x(Opcode.NOP)); builder.addInstruction(new BuilderInstruction32x(Opcode.MOVE_16, 0, 0)); MutableMethodImplementation mutableMethodImplementation = new MutableMethodImplementation(builder.getMethodImplementation()); mutableMethodImplementation.addCatch( mutableMethodImplementation.newLabelForIndex(0), mutableMethodImplementation.newLabelForIndex(6), mutableMethodImplementation.newLabelForIndex(1)); Assert.assertEquals(0, mutableMethodImplementation.getTryBlocks().get(0).getStartCodeAddress()); Assert.assertEquals(8, mutableMethodImplementation.getTryBlocks().get(0).getCodeUnitCount()); Assert.assertEquals(1, mutableMethodImplementation.getTryBlocks().get(0).getExceptionHandlers().get(0) .getHandlerCodeAddress()); } }