public void visitExceptionInfo( Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) { int startPC = Math.max(exceptionInfo.u2startPC, clipStart); int endPC = Math.min(exceptionInfo.u2endPC, clipEnd); int handlerPC = exceptionInfo.u2handlerPC; int catchType = exceptionInfo.u2catchType; // Exclude any subroutine invocations that jump out of the try block, // by adding a try block before (and later on, after) each invocation. for (int offset = startPC; offset < endPC; offset++) { if (branchTargetFinder.isSubroutineInvocation(offset)) { Instruction instruction = InstructionFactory.create(codeAttribute.code, offset); int instructionLength = instruction.length(offset); // Is it a subroutine invocation? if (!exceptionInfo.isApplicable(offset + ((BranchInstruction) instruction).branchOffset)) { if (DEBUG) { System.out.println( " Appending extra exception [" + startPC + " -> " + offset + "] -> " + handlerPC); } // Append a try block that ends before the subroutine invocation. codeAttributeComposer.appendException( new ExceptionInfo(startPC, offset, handlerPC, catchType)); // The next try block will start after the subroutine invocation. startPC = offset + instructionLength; } } } if (DEBUG) { System.out.println( " Appending exception [" + startPC + " -> " + endPC + "] -> " + handlerPC); } // Append the exception. Note that exceptions with empty try blocks // are automatically ignored. codeAttributeComposer.appendException(new ExceptionInfo(startPC, endPC, handlerPC, catchType)); }
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) { // Update the descriptor if it has any unused parameters. String descriptor = programMethod.getDescriptor(programClass); String newDescriptor = shrinkDescriptor(programMethod, descriptor); if (!descriptor.equals(newDescriptor)) { // Shrink the signature and parameter annotations. programMethod.attributesAccept(programClass, this); String name = programMethod.getName(programClass); String newName = name; // Append a code, if the method isn't a class instance initializer. if (!name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)) { newName += ClassConstants.SPECIAL_MEMBER_SEPARATOR + Long.toHexString(Math.abs((descriptor).hashCode())); } if (DEBUG) { System.out.println("MethodDescriptorShrinker:"); System.out.println(" Class file = " + programClass.getName()); System.out.println(" Method name = " + name); System.out.println(" -> " + newName); System.out.println(" Method descriptor = " + descriptor); System.out.println(" -> " + newDescriptor); } ConstantPoolEditor constantPoolEditor = new ConstantPoolEditor(programClass); // Update the name, if necessary. if (!newName.equals(name)) { programMethod.u2nameIndex = constantPoolEditor.addUtf8Constant(newName); } // Update the referenced classes. programMethod.referencedClasses = shrinkReferencedClasses(programMethod, descriptor, programMethod.referencedClasses); // Finally, update the descriptor itself. programMethod.u2descriptorIndex = constantPoolEditor.addUtf8Constant(newDescriptor); // Visit the method, if required. if (extraMemberVisitor != null) { extraMemberVisitor.visitProgramMethod(programClass, programMethod); } } }