diff options
author | Ying Wang <wangying@google.com> | 2012-02-27 18:34:24 -0800 |
---|---|---|
committer | Ying Wang <wangying@google.com> | 2012-02-27 18:34:24 -0800 |
commit | 9f606f95f03a75961498803e24bee6799a7c0885 (patch) | |
tree | a45f4d74feda9b76277a0c9ced55ad15d82248a1 /src/proguard/classfile/editor | |
parent | cfead78069f3dc32998dc118ee08cab3867acea2 (diff) | |
download | android_external_proguard-9f606f95f03a75961498803e24bee6799a7c0885.tar.gz android_external_proguard-9f606f95f03a75961498803e24bee6799a7c0885.tar.bz2 android_external_proguard-9f606f95f03a75961498803e24bee6799a7c0885.zip |
Revert "Upgrade from Progaurd 4.4 to 4.7."cm-10.1.3-RC2cm-10.1.3-RC1cm-10.1.3cm-10.1.2cm-10.1.1cm-10.1.0-RC5cm-10.1.0-RC4cm-10.1.0-RC3cm-10.1.0-RC2cm-10.1.0-RC1cm-10.1.0cm-10.1-M3cm-10.1-M2cm-10.1-M1mr1.1-stagingjellybean-stablejellybeancm-10.1
This reverts commit cfead78069f3dc32998dc118ee08cab3867acea2.
Bug: 6079915
Diffstat (limited to 'src/proguard/classfile/editor')
51 files changed, 411 insertions, 2235 deletions
diff --git a/src/proguard/classfile/editor/AccessFixer.java b/src/proguard/classfile/editor/AccessFixer.java index 8ff08f3..7d6274e 100644 --- a/src/proguard/classfile/editor/AccessFixer.java +++ b/src/proguard/classfile/editor/AccessFixer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -21,8 +21,6 @@ package proguard.classfile.editor; import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.visitor.*; import proguard.classfile.constant.*; import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.util.*; @@ -63,26 +61,12 @@ implements ConstantVisitor, } - public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) - { - // Check the bootstrap method. - invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this); - } - - - public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) - { - // Check the method reference. - clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this); - } - - public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { referencingClass = clazz; // Remember the specified class, since it might be different from - // the referenced class that actually contains the class member. + // the referenced class that acutally contains the class member. clazz.constantPoolEntryAccept(refConstant.u2classIndex, referencedClassFinder); // Make sure the access flags of the referenced class member are @@ -107,8 +91,8 @@ implements ConstantVisitor, public void visitProgramClass(ProgramClass programClass) { - int currentAccessFlags = programClass.getAccessFlags(); - int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags); + int currentAccessFlags = programClass.getAccessFlags(); + int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags); // Compute the required access level. Clazz referencingClass = this.referencingClass; @@ -133,8 +117,8 @@ implements ConstantVisitor, public void visitProgramMember(ProgramClass programClass, ProgramMember programMember) { - int currentAccessFlags = programMember.getAccessFlags(); - int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags); + int currentAccessFlags = programMember.getAccessFlags(); + int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags); // Compute the required access level. int requiredAccessLevel = diff --git a/src/proguard/classfile/editor/AnnotationAdder.java b/src/proguard/classfile/editor/AnnotationAdder.java index 3c35608..359164a 100644 --- a/src/proguard/classfile/editor/AnnotationAdder.java +++ b/src/proguard/classfile/editor/AnnotationAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/AnnotationsAttributeEditor.java b/src/proguard/classfile/editor/AnnotationsAttributeEditor.java index 5537f5e..bf8852c 100644 --- a/src/proguard/classfile/editor/AnnotationsAttributeEditor.java +++ b/src/proguard/classfile/editor/AnnotationsAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/AttributeAdder.java b/src/proguard/classfile/editor/AttributeAdder.java index a7f8dc3..2b610b7 100644 --- a/src/proguard/classfile/editor/AttributeAdder.java +++ b/src/proguard/classfile/editor/AttributeAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -256,7 +256,7 @@ implements AttributeVisitor CodeAttributeComposer codeAttributeComposer = new CodeAttributeComposer(); - codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength + 32); + codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength); // Add the instructions. codeAttribute.instructionsAccept(clazz, diff --git a/src/proguard/classfile/editor/AttributeSorter.java b/src/proguard/classfile/editor/AttributeSorter.java index dcae85e..d8e3367 100644 --- a/src/proguard/classfile/editor/AttributeSorter.java +++ b/src/proguard/classfile/editor/AttributeSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/AttributesEditor.java b/src/proguard/classfile/editor/AttributesEditor.java index 91c0080..10846cc 100644 --- a/src/proguard/classfile/editor/AttributesEditor.java +++ b/src/proguard/classfile/editor/AttributesEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/BridgeMethodFixer.java b/src/proguard/classfile/editor/BridgeMethodFixer.java deleted file mode 100644 index 010c8a2..0000000 --- a/src/proguard/classfile/editor/BridgeMethodFixer.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard.classfile.editor; - -import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.visitor.AttributeVisitor; -import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.instruction.*; -import proguard.classfile.instruction.visitor.InstructionVisitor; -import proguard.classfile.util.*; -import proguard.classfile.visitor.*; - -/** - * This MemberVisitor fixes all inappropriate bridge access flags of the - * program methods that it visits, checking whether the methods to which they - * bridge have the same name. Some compilers, like in Eclipse and in later - * versions of JDK 1.6, complain if they can't find the method with the same - * name. - * - * @author Eric Lafortune - */ -public class BridgeMethodFixer -extends SimplifiedVisitor -implements MemberVisitor, - AttributeVisitor, - InstructionVisitor, - ConstantVisitor -{ - private static final boolean DEBUG = false; - - - // Return values for the visitor methods. - private String bridgedMethodName; - - - // Implementations for MemberVisitor. - - public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) - { - if ((programMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_BRIDGE) != 0) - { - programMethod.attributesAccept(programClass, this); - } - } - - - // Implementations for AttributeVisitor. - - public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} - - - public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) - { - // Go over the instructions of the bridge method. - codeAttribute.instructionsAccept(clazz, method, this); - } - - - // Implementations for InstructionVisitor. - - public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} - - - public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) - { - switch (constantInstruction.opcode) - { - case InstructionConstants.OP_INVOKEVIRTUAL: - case InstructionConstants.OP_INVOKESPECIAL: - case InstructionConstants.OP_INVOKESTATIC: - case InstructionConstants.OP_INVOKEINTERFACE: - // Get the name of the bridged method. - clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); - - // Check if the name is different. - if (!method.getName(clazz).equals(bridgedMethodName)) - { - if (DEBUG) - { - System.out.println("BridgeMethodFixer: ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"] does not bridge to ["+bridgedMethodName+"]"); - } - - // Clear the bridge flag. - ((ProgramMethod)method).u2accessFlags &= ~ClassConstants.INTERNAL_ACC_BRIDGE; - } - break; - } - } - - - // Implementations for ConstantVisitor. - - public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) - { - bridgedMethodName = refConstant.getName(clazz); - } -}
\ No newline at end of file diff --git a/src/proguard/classfile/editor/ClassEditor.java b/src/proguard/classfile/editor/ClassEditor.java index f51ae45..e503ea3 100644 --- a/src/proguard/classfile/editor/ClassEditor.java +++ b/src/proguard/classfile/editor/ClassEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ClassElementSorter.java b/src/proguard/classfile/editor/ClassElementSorter.java index c5eb366..3256c88 100644 --- a/src/proguard/classfile/editor/ClassElementSorter.java +++ b/src/proguard/classfile/editor/ClassElementSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ClassMemberSorter.java b/src/proguard/classfile/editor/ClassMemberSorter.java index 61d69b2..f31fcd0 100644 --- a/src/proguard/classfile/editor/ClassMemberSorter.java +++ b/src/proguard/classfile/editor/ClassMemberSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ClassReferenceFixer.java b/src/proguard/classfile/editor/ClassReferenceFixer.java index 808d339..9857903 100644 --- a/src/proguard/classfile/editor/ClassReferenceFixer.java +++ b/src/proguard/classfile/editor/ClassReferenceFixer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/CodeAttributeComposer.java b/src/proguard/classfile/editor/CodeAttributeComposer.java index a645f57..e783203 100644 --- a/src/proguard/classfile/editor/CodeAttributeComposer.java +++ b/src/proguard/classfile/editor/CodeAttributeComposer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -29,8 +29,6 @@ import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; -import java.util.Arrays; - /** * This AttributeVisitor accumulates instructions and exceptions, and then * copies them into code attributes that it visits. @@ -51,7 +49,7 @@ implements AttributeVisitor, //* private static final boolean DEBUG = false; /*/ - public static boolean DEBUG = false; + public static boolean DEBUG = true; //*/ @@ -315,7 +313,7 @@ implements AttributeVisitor, int handlerPC = -exceptionInfo.u2handlerPC; if (handlerPC > 0) { - if (remappableExceptionHandler(handlerPC)) + if (remappableInstructionOffset(handlerPC)) { exceptionInfo.u2handlerPC = remapInstructionOffset(handlerPC); } @@ -492,7 +490,7 @@ implements AttributeVisitor, int handlerPC = exceptionInfo.u2handlerPC; exceptionInfo.u2handlerPC = !allowExternalExceptionHandlers || - remappableExceptionHandler(handlerPC) ? + remappableInstructionOffset(handlerPC) ? remapInstructionOffset(handlerPC) : -handlerPC; } @@ -676,21 +674,13 @@ implements AttributeVisitor, /** - * Returns whether the given old exception handler can be remapped in the - * current code fragment. + * Returns whether the given old instruction offset can be remapped at the */ - private boolean remappableExceptionHandler(int oldInstructionOffset) + private boolean remappableInstructionOffset(int oldInstructionOffset) { - if (oldInstructionOffset > codeFragmentLengths[level]) - { - return false; - } - - int newInstructionOffset = - instructionOffsetMap[level][oldInstructionOffset]; - - return newInstructionOffset > INVALID && - newInstructionOffset < codeLength; + return + oldInstructionOffset <= codeFragmentLengths[level] && + instructionOffsetMap[level][oldInstructionOffset] > INVALID; } @@ -713,7 +703,10 @@ implements AttributeVisitor, } // Clear the unused array entries. - Arrays.fill(exceptionInfos, newIndex, exceptionInfoCount, null); + for (int index = newIndex; index < exceptionInfoCount; index++) + { + exceptionInfos[index] = null; + } return newIndex; } @@ -741,7 +734,10 @@ implements AttributeVisitor, } // Clear the unused array entries. - Arrays.fill(lineNumberInfos, newIndex, lineNumberInfoCount, null); + for (int index = newIndex; index < lineNumberInfoCount; index++) + { + lineNumberInfos[index] = null; + } return newIndex; } @@ -768,7 +764,10 @@ implements AttributeVisitor, } // Clear the unused array entries. - Arrays.fill(localVariableInfos, newIndex, localVariableInfoCount, null); + for (int index = newIndex; index < localVariableInfoCount; index++) + { + localVariableInfos[index] = null; + } return newIndex; } @@ -795,7 +794,10 @@ implements AttributeVisitor, } // Clear the unused array entries. - Arrays.fill(localVariableTypeInfos, newIndex, localVariableTypeInfoCount, null); + for (int index = newIndex; index < localVariableTypeInfoCount; index++) + { + localVariableTypeInfos[index] = null; + } return newIndex; } diff --git a/src/proguard/classfile/editor/CodeAttributeEditor.java b/src/proguard/classfile/editor/CodeAttributeEditor.java index 82ed29e..9658c98 100644 --- a/src/proguard/classfile/editor/CodeAttributeEditor.java +++ b/src/proguard/classfile/editor/CodeAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -28,8 +28,7 @@ import proguard.classfile.attribute.visitor.*; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; - -import java.util.Arrays; +import proguard.classfile.visitor.ClassPrinter; /** * This AttributeVisitor accumulates specified changes to code, and then applies @@ -106,10 +105,13 @@ implements AttributeVisitor, } else { - Arrays.fill(preInsertions, 0, codeLength, null); - Arrays.fill(replacements, 0, codeLength, null); - Arrays.fill(postInsertions, 0, codeLength, null); - Arrays.fill(deleted, 0, codeLength, false); + for (int index = 0; index < codeLength; index++) + { + preInsertions[index] = null; + replacements[index] = null; + postInsertions[index] = null; + deleted[index] = false; + } } modified = false; @@ -326,51 +328,52 @@ implements AttributeVisitor, { if (DEBUG) { - System.out.println("CodeAttributeEditor: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)); + System.out.println("CodeAttributeEditor: ["+clazz.getName()+"."+method.getName(clazz)+"]"); } - // Do we have to update the code? - if (modified) + // Avoid doing any work if nothing is changing anyway. + if (!modified) { - // Can we perform a faster simple replacement of instructions? - if (canPerformSimpleReplacements(codeAttribute)) - { - if (DEBUG) - { - System.out.println(" Simple editing"); - } + return; + } - // Simply overwrite the instructions. - performSimpleReplacements(codeAttribute); - } - else - { - if (DEBUG) - { - System.out.println(" Full editing"); - } + // Check if we can perform a faster simple replacement of instructions. + if (canPerformSimpleReplacements(codeAttribute)) + { + // Simply overwrite the instructions. + performSimpleReplacements(codeAttribute); - // Move and remap the instructions. - codeAttribute.u4codeLength = - updateInstructions(clazz, method, codeAttribute); + // Update the maximum stack size and local variable frame size. + updateFrameSizes(clazz, method, codeAttribute); + } + else + { + // Move and remap the instructions. + codeAttribute.u4codeLength = + updateInstructions(clazz, method, codeAttribute); - // Remap the exception table. - codeAttribute.exceptionsAccept(clazz, method, this); + // Remap the exception table. + codeAttribute.exceptionsAccept(clazz, method, this); - // Remove exceptions with empty code blocks. - codeAttribute.u2exceptionTableLength = - removeEmptyExceptions(codeAttribute.exceptionTable, - codeAttribute.u2exceptionTableLength); + // Remove exceptions with empty code blocks. + codeAttribute.u2exceptionTableLength = + removeEmptyExceptions(codeAttribute.exceptionTable, + codeAttribute.u2exceptionTableLength); - // Remap the line number table and the local variable tables. - codeAttribute.attributesAccept(clazz, method, this); - } + // Update the maximum stack size and local variable frame size. + updateFrameSizes(clazz, method, codeAttribute); + + // Remap the line number table and the local variable table. + codeAttribute.attributesAccept(clazz, method, this); // Make sure instructions are widened if necessary. instructionWriter.visitCodeAttribute(clazz, method, codeAttribute); } + } - // Update the maximum stack size and local variable frame size. + + private void updateFrameSizes(Clazz clazz, Method method, CodeAttribute codeAttribute) + { if (updateFrameSizes) { stackSizeUpdater.visitCodeAttribute(clazz, method, codeAttribute); @@ -412,6 +415,12 @@ implements AttributeVisitor, { // Remap all local variable table entries. localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + + // Remove local variables with empty code blocks. + localVariableTableAttribute.u2localVariableTableLength = + removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable, + localVariableTableAttribute.u2localVariableTableLength, + codeAttribute.u2maxLocals); } @@ -419,6 +428,12 @@ implements AttributeVisitor, { // Remap all local variable table entries. localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + + // Remove local variables with empty code blocks. + localVariableTypeTableAttribute.u2localVariableTypeTableLength = + removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, + localVariableTypeTableAttribute.u2localVariableTypeTableLength, + codeAttribute.u2maxLocals); } @@ -897,12 +912,10 @@ implements AttributeVisitor, public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) { // Remap the code offset and length. - int newStartPC = remapInstructionOffset(localVariableInfo.u2startPC); - int newEndPC = remapInstructionOffset(localVariableInfo.u2startPC + - localVariableInfo.u2length); - - localVariableInfo.u2length = newEndPC - newStartPC; - localVariableInfo.u2startPC = newStartPC; + // TODO: The local variable frame might not be strictly preserved. + localVariableInfo.u2length = remapBranchOffset(localVariableInfo.u2startPC, + localVariableInfo.u2length); + localVariableInfo.u2startPC = remapInstructionOffset(localVariableInfo.u2startPC); } @@ -911,12 +924,10 @@ implements AttributeVisitor, public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) { // Remap the code offset and length. - int newStartPC = remapInstructionOffset(localVariableTypeInfo.u2startPC); - int newEndPC = remapInstructionOffset(localVariableTypeInfo.u2startPC + - localVariableTypeInfo.u2length); - - localVariableTypeInfo.u2length = newEndPC - newStartPC; - localVariableTypeInfo.u2startPC = newStartPC; + // TODO: The local variable frame might not be strictly preserved. + localVariableTypeInfo.u2length = remapBranchOffset(localVariableTypeInfo.u2startPC, + localVariableTypeInfo.u2length); + localVariableTypeInfo.u2startPC = remapInstructionOffset(localVariableTypeInfo.u2startPC); } @@ -1006,6 +1017,54 @@ implements AttributeVisitor, } + /** + * Returns the given list of local variables, without the ones that have empty + * code blocks or that exceed the actual number of local variables. + */ + private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos, + int localVariableInfoCount, + int maxLocals) + { + // Overwrite all empty local variable entries. + int newIndex = 0; + for (int index = 0; index < localVariableInfoCount; index++) + { + LocalVariableInfo localVariableInfo = localVariableInfos[index]; + if (localVariableInfo.u2length > 0 && + localVariableInfo.u2index < maxLocals) + { + localVariableInfos[newIndex++] = localVariableInfo; + } + } + + return newIndex; + } + + + /** + * Returns the given list of local variable types, without the ones that + * have empty code blocks or that exceed the actual number of local variables. + */ + private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, + int localVariableTypeInfoCount, + int maxLocals) + { + // Overwrite all empty local variable type entries. + int newIndex = 0; + for (int index = 0; index < localVariableTypeInfoCount; index++) + { + LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; + if (localVariableTypeInfo.u2length > 0 && + localVariableTypeInfo.u2index < maxLocals) + { + localVariableTypeInfos[newIndex++] = localVariableTypeInfo; + } + } + + return newIndex; + } + + private class CompositeInstruction extends Instruction { diff --git a/src/proguard/classfile/editor/CodeAttributeEditorResetter.java b/src/proguard/classfile/editor/CodeAttributeEditorResetter.java index eedc045..9962ea5 100644 --- a/src/proguard/classfile/editor/CodeAttributeEditorResetter.java +++ b/src/proguard/classfile/editor/CodeAttributeEditorResetter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ComparableConstant.java b/src/proguard/classfile/editor/ComparableConstant.java index ba5f3b1..bb81221 100644 --- a/src/proguard/classfile/editor/ComparableConstant.java +++ b/src/proguard/classfile/editor/ComparableConstant.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -39,7 +39,7 @@ class ComparableConstant extends SimplifiedVisitor implements Comparable, ConstantVisitor { - private static final int[] PRIORITIES = new int[19]; + private static final int[] PRIORITIES = new int[13]; static { PRIORITIES[ClassConstants.CONSTANT_Integer] = 0; // Possibly byte index (ldc). @@ -47,15 +47,12 @@ implements Comparable, ConstantVisitor PRIORITIES[ClassConstants.CONSTANT_String] = 2; PRIORITIES[ClassConstants.CONSTANT_Class] = 3; PRIORITIES[ClassConstants.CONSTANT_Long] = 4; // Always wide index (ldc2_w). - PRIORITIES[ClassConstants.CONSTANT_Double] = 5; // Always wide index (ldc2_w). - PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index (getfield,...). - PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7; // Always wide index (invokespecial,...). - PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8; // Always wide index (invokeinterface). - PRIORITIES[ClassConstants.CONSTANT_InvokeDynamic] = 9; // Always wide index (invokedynamic). - PRIORITIES[ClassConstants.CONSTANT_MethodHandle] = 10; - PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 11; - PRIORITIES[ClassConstants.CONSTANT_MethodType] = 12; - PRIORITIES[ClassConstants.CONSTANT_Utf8] = 13; + PRIORITIES[ClassConstants.CONSTANT_Double] = 5; + PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index. + PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7; + PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8; + PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 9; + PRIORITIES[ClassConstants.CONSTANT_Utf8] = 10; } private final Clazz clazz; @@ -125,32 +122,26 @@ implements Comparable, ConstantVisitor public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) { - int value = integerConstant.getValue(); - int otherValue = ((IntegerConstant)otherConstant).getValue(); - result = value < otherValue ? -1 : - value == otherValue ? 0 : - 1; + // In JDK 1.4, we can use Integer.compare(a,b). + result = new Integer(integerConstant.getValue()).compareTo(new Integer(((IntegerConstant)otherConstant).getValue())); } public void visitLongConstant(Clazz clazz, LongConstant longConstant) { - long value = longConstant.getValue(); - long otherValue = ((LongConstant)otherConstant).getValue(); - result = value < otherValue ? -1 : - value == otherValue ? 0 : - 1; + // In JDK 1.4, we can use Long.compare(a,b). + result = new Long(longConstant.getValue()).compareTo(new Long(((LongConstant)otherConstant).getValue())); } public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) { - result = Float.compare(floatConstant.getValue(), - ((FloatConstant)otherConstant).getValue()); + // In JDK 1.4, we can use Float.compare(a,b). + result = new Float(floatConstant.getValue()).compareTo(new Float(((FloatConstant)otherConstant).getValue())); } public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) - { - result = Double.compare(doubleConstant.getValue(), - ((DoubleConstant)otherConstant).getValue()); + { + // In JDK 1.4, we can use Double.compare(a,b). + result = new Double(doubleConstant.getValue()).compareTo(new Double(((DoubleConstant)otherConstant).getValue())); } public void visitStringConstant(Clazz clazz, StringConstant stringConstant) @@ -163,38 +154,6 @@ implements Comparable, ConstantVisitor result = utf8Constant.getString().compareTo(((Utf8Constant)otherConstant).getString()); } - public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) - { - InvokeDynamicConstant otherInvokeDynamicConstant = (InvokeDynamicConstant)otherConstant; - - int index = invokeDynamicConstant.getBootstrapMethodAttributeIndex(); - int otherIndex = otherInvokeDynamicConstant.getBootstrapMethodAttributeIndex(); - - result = index < otherIndex ? -1 : - index > otherIndex ? 1 : - (invokeDynamicConstant.getName(clazz) + ' ' + - invokeDynamicConstant.getType(clazz)) - .compareTo - (otherInvokeDynamicConstant.getName(clazz) + ' ' + - otherInvokeDynamicConstant.getType(clazz)); - } - - public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) - { - MethodHandleConstant otherMethodHandleConstant = (MethodHandleConstant)otherConstant; - - int kind = methodHandleConstant.getReferenceKind(); - int otherKind = methodHandleConstant.getReferenceKind(); - - result = kind < otherKind ? -1 : - kind > otherKind ? 1 : - (methodHandleConstant.getName(clazz) + ' ' + - methodHandleConstant.getType(clazz)) - .compareTo - (otherMethodHandleConstant.getName(clazz) + ' ' + - otherMethodHandleConstant.getType(clazz)); - } - public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { RefConstant otherRefConstant = (RefConstant)otherConstant; @@ -212,14 +171,6 @@ implements Comparable, ConstantVisitor result = classConstant.getName(clazz).compareTo(((ClassConstant)otherConstant).getName(clazz)); } - public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant MethodTypeConstant) - { - MethodTypeConstant otherMethodTypeConstant = (MethodTypeConstant)otherConstant; - result = MethodTypeConstant.getType(clazz) - .compareTo - (otherMethodTypeConstant.getType(clazz)); - } - public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { NameAndTypeConstant otherNameAndTypeConstant = (NameAndTypeConstant)otherConstant; diff --git a/src/proguard/classfile/editor/ConstantAdder.java b/src/proguard/classfile/editor/ConstantAdder.java index 14edbce..2b74f5f 100644 --- a/src/proguard/classfile/editor/ConstantAdder.java +++ b/src/proguard/classfile/editor/ConstantAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -23,7 +23,6 @@ package proguard.classfile.editor; import proguard.classfile.*; import proguard.classfile.constant.*; import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.util.ListUtil; /** * This ConstantVisitor adds all constants that it visits to the constant pool @@ -129,43 +128,6 @@ implements ConstantVisitor } - public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) - { - // First add the name and type constant. - clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this); - - // Copy the referenced classes. - Clazz[] referencedClasses = invokeDynamicConstant.referencedClasses; - Clazz[] referencedClassesCopy = null; - if (referencedClasses != null) - { - referencedClassesCopy = new Clazz[referencedClasses.length]; - System.arraycopy(referencedClasses, 0, - referencedClassesCopy, 0, - referencedClasses.length); - } - - // Then add the actual invoke dynamic constant. - constantIndex = - constantPoolEditor.addInvokeDynamicConstant(invokeDynamicConstant.getBootstrapMethodAttributeIndex(), - constantIndex, - referencedClassesCopy); - } - - - public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) - { - // First add the field ref, interface method ref, or method ref - // constant. - clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this); - - // Then add the actual method handle constant. - constantIndex = - constantPoolEditor.addMethodHandleConstant(methodHandleConstant.getReferenceKind(), - constantIndex); - } - - public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) { // First add the referenced class constant, with its own referenced class. @@ -223,13 +185,6 @@ implements ConstantVisitor } - public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) - { - constantIndex = - constantPoolEditor.addMethodTypeConstant(methodTypeConstant.getType(clazz)); - } - - public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { constantIndex = diff --git a/src/proguard/classfile/editor/ConstantPoolEditor.java b/src/proguard/classfile/editor/ConstantPoolEditor.java index 6ba4857..8663dee 100644 --- a/src/proguard/classfile/editor/ConstantPoolEditor.java +++ b/src/proguard/classfile/editor/ConstantPoolEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -199,93 +199,6 @@ public class ConstantPoolEditor /** - * Finds or creates a InvokeDynamicConstant constant pool entry with the - * given bootstrap method constant pool entry index, method name, and - * descriptor. - * @return the constant pool index of the InvokeDynamicConstant. - */ - public int addInvokeDynamicConstant(int bootstrapMethodIndex, - String name, - String descriptor, - Clazz[] referencedClasses) - { - return addInvokeDynamicConstant(bootstrapMethodIndex, - addNameAndTypeConstant(name, descriptor), - referencedClasses); - } - - - /** - * Finds or creates a InvokeDynamicConstant constant pool entry with the given - * class constant pool entry index and name and type constant pool entry - * index. - * @return the constant pool index of the InvokeDynamicConstant. - */ - public int addInvokeDynamicConstant(int bootstrapMethodIndex, - int nameAndTypeIndex, - Clazz[] referencedClasses) - { - int constantPoolCount = targetClass.u2constantPoolCount; - Constant[] constantPool = targetClass.constantPool; - - // Check if the entry already exists. - for (int index = 1; index < constantPoolCount; index++) - { - Constant constant = constantPool[index]; - - if (constant != null && - constant.getTag() == ClassConstants.CONSTANT_InvokeDynamic) - { - InvokeDynamicConstant invokeDynamicConstant = (InvokeDynamicConstant)constant; - if (invokeDynamicConstant.u2bootstrapMethodAttributeIndex == bootstrapMethodIndex && - invokeDynamicConstant.u2nameAndTypeIndex == nameAndTypeIndex) - { - return index; - } - } - } - - return addConstant(new InvokeDynamicConstant(bootstrapMethodIndex, - nameAndTypeIndex, - referencedClasses)); - } - - - /** - * Finds or creates a MethodHandleConstant constant pool entry of the - * specified kind and with the given field ref, interface method ref, - * or method ref constant pool entry index. - * @return the constant pool index of the MethodHandleConstant. - */ - public int addMethodHandleConstant(int referenceKind, - int referenceIndex) - { - int constantPoolCount = targetClass.u2constantPoolCount; - Constant[] constantPool = targetClass.constantPool; - - // Check if the entry already exists. - for (int index = 1; index < constantPoolCount; index++) - { - Constant constant = constantPool[index]; - - if (constant != null && - constant.getTag() == ClassConstants.CONSTANT_MethodHandle) - { - MethodHandleConstant methodHandleConstant = (MethodHandleConstant)constant; - if (methodHandleConstant.u1referenceKind == referenceKind && - methodHandleConstant.u2referenceIndex == referenceIndex) - { - return index; - } - } - } - - return addConstant(new MethodHandleConstant(referenceKind, - referenceIndex)); - } - - - /** * Finds or creates a FieldrefConstant constant pool entry for the given * class and field. * @return the constant pool index of the FieldrefConstant. @@ -650,36 +563,6 @@ public class ConstantPoolEditor /** - * Finds or creates a MethodTypeConstant constant pool entry with the given - * type. - * @return the constant pool index of the MethodTypeConstant. - */ - public int addMethodTypeConstant(String type) - { - int constantPoolCount = targetClass.u2constantPoolCount; - Constant[] constantPool = targetClass.constantPool; - - // Check if the entry already exists. - for (int index = 1; index < constantPoolCount; index++) - { - Constant constant = constantPool[index]; - - if (constant != null && - constant.getTag() == ClassConstants.CONSTANT_MethodType) - { - MethodTypeConstant methodTypeConstant = (MethodTypeConstant)constant; - if (methodTypeConstant.getType(targetClass).equals(type)) - { - return index; - } - } - } - - return addConstant(new MethodTypeConstant(addUtf8Constant(type))); - } - - - /** * Finds or creates a NameAndTypeConstant constant pool entry with the given * name and type. * @return the constant pool index of the NameAndTypeConstant. diff --git a/src/proguard/classfile/editor/ConstantPoolRemapper.java b/src/proguard/classfile/editor/ConstantPoolRemapper.java index 7677218..7430d3d 100644 --- a/src/proguard/classfile/editor/ConstantPoolRemapper.java +++ b/src/proguard/classfile/editor/ConstantPoolRemapper.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -47,10 +47,9 @@ implements ClassVisitor, ConstantVisitor, MemberVisitor, AttributeVisitor, - BootstrapMethodInfoVisitor, + InstructionVisitor, InnerClassesInfoVisitor, ExceptionInfoVisitor, - InstructionVisitor, StackMapFrameVisitor, VerificationTypeVisitor, LocalVariableInfoVisitor, @@ -58,7 +57,7 @@ implements ClassVisitor, AnnotationVisitor, ElementValueVisitor { - private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false); + private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); private int[] constantIndexMap; @@ -101,21 +100,10 @@ implements ClassVisitor, // Implementations for ConstantVisitor. - public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) - { - // Nothing to do. - } - - - public void visitLongConstant(Clazz clazz, LongConstant longConstant) - { - // Nothing to do. - } - - - public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { - // Nothing to do. + classConstant.u2nameIndex = + remapConstantIndex(classConstant.u2nameIndex); } @@ -125,39 +113,24 @@ implements ClassVisitor, } - public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) { - stringConstant.u2stringIndex = - remapConstantIndex(stringConstant.u2stringIndex); + fieldrefConstant.u2classIndex = + remapConstantIndex(fieldrefConstant.u2classIndex); + fieldrefConstant.u2nameAndTypeIndex = + remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex); } - public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) + public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) { // Nothing to do. } - public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) - { - invokeDynamicConstant.u2nameAndTypeIndex = - remapConstantIndex(invokeDynamicConstant.u2nameAndTypeIndex); - } - - - public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) - { - methodHandleConstant.u2referenceIndex = - remapConstantIndex(methodHandleConstant.u2referenceIndex); - } - - - public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) + public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) { - fieldrefConstant.u2classIndex = - remapConstantIndex(fieldrefConstant.u2classIndex); - fieldrefConstant.u2nameAndTypeIndex = - remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex); + // Nothing to do. } @@ -170,6 +143,12 @@ implements ClassVisitor, } + public void visitLongConstant(Clazz clazz, LongConstant longConstant) + { + // Nothing to do. + } + + public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) { methodrefConstant.u2classIndex = @@ -179,26 +158,25 @@ implements ClassVisitor, } - public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { - classConstant.u2nameIndex = - remapConstantIndex(classConstant.u2nameIndex); + nameAndTypeConstant.u2nameIndex = + remapConstantIndex(nameAndTypeConstant.u2nameIndex); + nameAndTypeConstant.u2descriptorIndex = + remapConstantIndex(nameAndTypeConstant.u2descriptorIndex); } - public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) { - methodTypeConstant.u2descriptorIndex = - remapConstantIndex(methodTypeConstant.u2descriptorIndex); + stringConstant.u2stringIndex = + remapConstantIndex(stringConstant.u2stringIndex); } - public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) + public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) { - nameAndTypeConstant.u2nameIndex = - remapConstantIndex(nameAndTypeConstant.u2nameIndex); - nameAndTypeConstant.u2descriptorIndex = - remapConstantIndex(nameAndTypeConstant.u2descriptorIndex); + // Nothing to do. } @@ -252,16 +230,6 @@ implements ClassVisitor, } - public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) - { - bootstrapMethodsAttribute.u2attributeNameIndex = - remapConstantIndex(bootstrapMethodsAttribute.u2attributeNameIndex); - - // Remap the constant pool references of the bootstrap method entries. - bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); - } - - public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { sourceFileAttribute.u2attributeNameIndex = @@ -442,19 +410,6 @@ implements ClassVisitor, } - // Implementations for BootstrapMethodInfoVisitor. - - public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) - { - bootstrapMethodInfo.u2methodHandleIndex = - remapConstantIndex(bootstrapMethodInfo.u2methodHandleIndex); - - // Remap the constant pool references of the bootstrap methods.. - remapConstantIndexArray(bootstrapMethodInfo.u2methodArguments, - bootstrapMethodInfo.u2methodArgumentCount); - } - - // Implementations for InnerClassesInfoVisitor. public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) diff --git a/src/proguard/classfile/editor/ConstantPoolShrinker.java b/src/proguard/classfile/editor/ConstantPoolShrinker.java deleted file mode 100644 index 8c8e5d6..0000000 --- a/src/proguard/classfile/editor/ConstantPoolShrinker.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard.classfile.editor; - -import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.annotation.*; -import proguard.classfile.attribute.annotation.visitor.*; -import proguard.classfile.attribute.preverification.*; -import proguard.classfile.attribute.preverification.visitor.*; -import proguard.classfile.attribute.visitor.*; -import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.instruction.*; -import proguard.classfile.instruction.visitor.InstructionVisitor; -import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.*; - -import java.util.Arrays; - -/** - * This ClassVisitor removes all unused entries from the constant pool. - * - * @author Eric Lafortune - */ -public class ConstantPoolShrinker -extends SimplifiedVisitor -implements ClassVisitor, - MemberVisitor, - ConstantVisitor, - AttributeVisitor, - BootstrapMethodInfoVisitor, - InnerClassesInfoVisitor, - ExceptionInfoVisitor, - StackMapFrameVisitor, - VerificationTypeVisitor, - LocalVariableInfoVisitor, - LocalVariableTypeInfoVisitor, - AnnotationVisitor, - ElementValueVisitor, - InstructionVisitor -{ - // A visitor info flag to indicate the constant is being used. - private static final Object USED = new Object(); - - private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE]; - private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper(); - - - // Implementations for ClassVisitor. - - public void visitProgramClass(ProgramClass programClass) - { - // Mark this class's name. - markConstant(programClass, programClass.u2thisClass); - - // Mark the superclass class constant. - programClass.superClassConstantAccept(this); - - // Mark the interface class constants. - programClass.interfaceConstantsAccept(this); - - // Mark the constants referenced by the class members. - programClass.fieldsAccept(this); - programClass.methodsAccept(this); - - // Mark the attributes. - programClass.attributesAccept(this); - - // Shift the used constant pool entries together, filling out the - // index map. - int newConstantPoolCount = - shrinkConstantPool(programClass.constantPool, - programClass.u2constantPoolCount); - - // Remap the references to the constant pool if it has shrunk. - if (newConstantPoolCount < programClass.u2constantPoolCount) - { - programClass.u2constantPoolCount = newConstantPoolCount; - - // Remap all constant pool references. - constantPoolRemapper.setConstantIndexMap(constantIndexMap); - constantPoolRemapper.visitProgramClass(programClass); - } - } - - - // Implementations for MemberVisitor. - - public void visitProgramMember(ProgramClass programClass, ProgramMember programMember) - { - // Mark the name and descriptor. - markConstant(programClass, programMember.u2nameIndex); - markConstant(programClass, programMember.u2descriptorIndex); - - // Mark the attributes. - programMember.attributesAccept(programClass, this); - } - - - // Implementations for ConstantVisitor. - - public void visitAnyConstant(Clazz clazz, Constant constant) - { - markAsUsed(constant); - } - - - public void visitStringConstant(Clazz clazz, StringConstant stringConstant) - { - markAsUsed(stringConstant); - - markConstant(clazz, stringConstant.u2stringIndex); - } - - - public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) - { - markAsUsed(invokeDynamicConstant); - - markConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex); - - // Mark the bootstrap methods attribute. - clazz.attributesAccept(this); - } - - - public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) - { - markAsUsed(methodHandleConstant); - - markConstant(clazz, methodHandleConstant.u2referenceIndex); - } - - - public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) - { - markAsUsed(refConstant); - - markConstant(clazz, refConstant.u2classIndex); - markConstant(clazz, refConstant.u2nameAndTypeIndex); - } - - - public void visitClassConstant(Clazz clazz, ClassConstant classConstant) - { - markAsUsed(classConstant); - - markConstant(clazz, classConstant.u2nameIndex); - } - - - public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) - { - markAsUsed(methodTypeConstant); - - markConstant(clazz, methodTypeConstant.u2descriptorIndex); - } - - - public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) - { - markAsUsed(nameAndTypeConstant); - - markConstant(clazz, nameAndTypeConstant.u2nameIndex); - markConstant(clazz, nameAndTypeConstant.u2descriptorIndex); - } - - - // Implementations for AttributeVisitor. - - public void visitAnyAttribute(Clazz clazz, Attribute attribute) - { - markConstant(clazz, attribute.u2attributeNameIndex); - } - - - public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) - { - markConstant(clazz, bootstrapMethodsAttribute.u2attributeNameIndex); - - // Mark the bootstrap method entries. - bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); - } - - - public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) - { - markConstant(clazz, sourceFileAttribute.u2attributeNameIndex); - markConstant(clazz, sourceFileAttribute.u2sourceFileIndex); - } - - - public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) - { - markConstant(clazz, sourceDirAttribute.u2attributeNameIndex); - markConstant(clazz, sourceDirAttribute.u2sourceDirIndex); - } - - - public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) - { - markConstant(clazz, innerClassesAttribute.u2attributeNameIndex); - - // Mark the outer class entries. - innerClassesAttribute.innerClassEntriesAccept(clazz, this); - } - - - public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) - { - markConstant(clazz, enclosingMethodAttribute.u2attributeNameIndex); - markConstant(clazz, enclosingMethodAttribute.u2classIndex); - - if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) - { - markConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex); - } - } - - - public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) - { - markConstant(clazz, signatureAttribute.u2attributeNameIndex); - markConstant(clazz, signatureAttribute.u2signatureIndex); - } - - - public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) - { - markConstant(clazz, constantValueAttribute.u2attributeNameIndex); - markConstant(clazz, constantValueAttribute.u2constantValueIndex); - } - - - public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) - { - markConstant(clazz, exceptionsAttribute.u2attributeNameIndex); - - // Mark the constant pool entries referenced by the exceptions. - exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this); - } - - - public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) - { - markConstant(clazz, codeAttribute.u2attributeNameIndex); - - // Mark the constant pool entries referenced by the instructions, - // by the exceptions, and by the attributes. - codeAttribute.instructionsAccept(clazz, method, this); - codeAttribute.exceptionsAccept(clazz, method, this); - codeAttribute.attributesAccept(clazz, method, this); - } - - - public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) - { - markConstant(clazz, stackMapAttribute.u2attributeNameIndex); - - // Mark the constant pool entries referenced by the stack map frames. - stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); - } - - - public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) - { - markConstant(clazz, stackMapTableAttribute.u2attributeNameIndex); - - // Mark the constant pool entries referenced by the stack map frames. - stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); - } - - - public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) - { - markConstant(clazz, localVariableTableAttribute.u2attributeNameIndex); - - // Mark the constant pool entries referenced by the local variables. - localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - } - - - public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) - { - markConstant(clazz, localVariableTypeTableAttribute.u2attributeNameIndex); - - // Mark the constant pool entries referenced by the local variable types. - localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - } - - - public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) - { - markConstant(clazz, annotationsAttribute.u2attributeNameIndex); - - // Mark the constant pool entries referenced by the annotations. - annotationsAttribute.annotationsAccept(clazz, this); - } - - - public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) - { - markConstant(clazz, parameterAnnotationsAttribute.u2attributeNameIndex); - - // Mark the constant pool entries referenced by the annotations. - parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); - } - - - public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) - { - markConstant(clazz, annotationDefaultAttribute.u2attributeNameIndex); - - // Mark the constant pool entries referenced by the element value. - annotationDefaultAttribute.defaultValueAccept(clazz, this); - } - - - // Implementations for BootstrapMethodInfoVisitor. - - public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) - { - markConstant(clazz, bootstrapMethodInfo.u2methodHandleIndex); - - // Mark the constant pool entries referenced by the arguments. - bootstrapMethodInfo.methodArgumentsAccept(clazz, this); - } - - - // Implementations for InnerClassesInfoVisitor. - - public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) - { - innerClassesInfo.innerClassConstantAccept(clazz, this); - innerClassesInfo.outerClassConstantAccept(clazz, this); - innerClassesInfo.innerNameConstantAccept(clazz, this); - } - - - // Implementations for ExceptionInfoVisitor. - - public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) - { - if (exceptionInfo.u2catchType != 0) - { - markConstant(clazz, exceptionInfo.u2catchType); - } - } - - - // Implementations for StackMapFrameVisitor. - - public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {} - - - public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame) - { - // Mark the constant pool entries referenced by the verification types. - sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this); - } - - - public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame) - { - // Mark the constant pool entries referenced by the verification types. - moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this); - } - - - public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame) - { - // Mark the constant pool entries referenced by the verification types. - fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this); - fullFrame.stackAccept(clazz, method, codeAttribute, offset, this); - } - - - // Implementations for VerificationTypeVisitor. - - public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {} - - - public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType) - { - markConstant(clazz, objectType.u2classIndex); - } - - - // Implementations for LocalVariableInfoVisitor. - - public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) - { - markConstant(clazz, localVariableInfo.u2nameIndex); - markConstant(clazz, localVariableInfo.u2descriptorIndex); - } - - - // Implementations for LocalVariableTypeInfoVisitor. - - public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) - { - markConstant(clazz, localVariableTypeInfo.u2nameIndex); - markConstant(clazz, localVariableTypeInfo.u2signatureIndex); - } - - - // Implementations for AnnotationVisitor. - - public void visitAnnotation(Clazz clazz, Annotation annotation) - { - markConstant(clazz, annotation.u2typeIndex); - - // Mark the constant pool entries referenced by the element values. - annotation.elementValuesAccept(clazz, this); - } - - - // Implementations for ElementValueVisitor. - - public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) - { - if (constantElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, constantElementValue.u2elementNameIndex); - } - - markConstant(clazz, constantElementValue.u2constantValueIndex); - } - - - public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) - { - if (enumConstantElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, enumConstantElementValue.u2elementNameIndex); - } - - markConstant(clazz, enumConstantElementValue.u2typeNameIndex); - markConstant(clazz, enumConstantElementValue.u2constantNameIndex); - } - - - public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) - { - if (classElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, classElementValue.u2elementNameIndex); - } - - markConstant(clazz, classElementValue.u2classInfoIndex); - } - - - public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) - { - if (annotationElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, annotationElementValue.u2elementNameIndex); - } - - // Mark the constant pool entries referenced by the annotation. - annotationElementValue.annotationAccept(clazz, this); - } - - - public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) - { - if (arrayElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, arrayElementValue.u2elementNameIndex); - } - - // Mark the constant pool entries referenced by the element values. - arrayElementValue.elementValuesAccept(clazz, annotation, this); - } - - - // Implementations for InstructionVisitor. - - public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} - - - public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) - { - markConstant(clazz, constantInstruction.constantIndex); - } - - - // Small utility methods. - - /** - * Marks the given constant pool entry of the given class. This includes - * visiting any referenced objects. - */ - private void markConstant(Clazz clazz, int index) - { - clazz.constantPoolEntryAccept(index, this); - } - - - /** - * Marks the given visitor accepter as being used. - */ - private void markAsUsed(Constant constant) - { - constant.setVisitorInfo(USED); - } - - - /** - * Returns whether the given visitor accepter has been marked as being used. - */ - private boolean isUsed(VisitorAccepter visitorAccepter) - { - return visitorAccepter.getVisitorInfo() == USED; - } - - - /** - * Removes all constants that are not marked as being used from the given - * constant pool. - * @return the new number of entries. - */ - private int shrinkConstantPool(Constant[] constantPool, int length) - { - // Create a new index map, if necessary. - if (constantIndexMap.length < length) - { - constantIndexMap = new int[length]; - } - - int counter = 1; - boolean isUsed = false; - - // Shift the used constant pool entries together. - for (int index = 1; index < length; index++) - { - constantIndexMap[index] = counter; - - Constant constant = constantPool[index]; - - // Don't update the flag if this is the second half of a long entry. - if (constant != null) - { - isUsed = isUsed(constant); - } - - if (isUsed) - { - constantPool[counter++] = constant; - } - } - - // Clear the remaining constant pool elements. - Arrays.fill(constantPool, counter, length, null); - - return counter; - } -} diff --git a/src/proguard/classfile/editor/ConstantPoolSorter.java b/src/proguard/classfile/editor/ConstantPoolSorter.java index 8e18865..faae318 100644 --- a/src/proguard/classfile/editor/ConstantPoolSorter.java +++ b/src/proguard/classfile/editor/ConstantPoolSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -112,7 +112,10 @@ implements ClassVisitor System.arraycopy(newConstantPool, 0, programClass.constantPool, 0, newLength); // Clear any remaining entries. - Arrays.fill(programClass.constantPool, newLength, constantPoolCount, null); + for (int index = newLength; index < constantPoolCount; index++) + { + programClass.constantPool[index] = null; + } programClass.u2constantPoolCount = newLength; diff --git a/src/proguard/classfile/editor/ElementValueAdder.java b/src/proguard/classfile/editor/ElementValueAdder.java index 895fd68..8cbd11d 100644 --- a/src/proguard/classfile/editor/ElementValueAdder.java +++ b/src/proguard/classfile/editor/ElementValueAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ElementValuesEditor.java b/src/proguard/classfile/editor/ElementValuesEditor.java index ce9352a..bfc4e9f 100644 --- a/src/proguard/classfile/editor/ElementValuesEditor.java +++ b/src/proguard/classfile/editor/ElementValuesEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ExceptionAdder.java b/src/proguard/classfile/editor/ExceptionAdder.java index ee0fb52..1ccb1a6 100644 --- a/src/proguard/classfile/editor/ExceptionAdder.java +++ b/src/proguard/classfile/editor/ExceptionAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ExceptionInfoAdder.java b/src/proguard/classfile/editor/ExceptionInfoAdder.java index 5fd98a8..e0cc9c5 100644 --- a/src/proguard/classfile/editor/ExceptionInfoAdder.java +++ b/src/proguard/classfile/editor/ExceptionInfoAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ExceptionsAttributeEditor.java b/src/proguard/classfile/editor/ExceptionsAttributeEditor.java index d49658a..4509a9a 100644 --- a/src/proguard/classfile/editor/ExceptionsAttributeEditor.java +++ b/src/proguard/classfile/editor/ExceptionsAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/InnerClassesAccessFixer.java b/src/proguard/classfile/editor/InnerClassesAccessFixer.java deleted file mode 100644 index 1d991df..0000000 --- a/src/proguard/classfile/editor/InnerClassesAccessFixer.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard.classfile.editor; - -import proguard.classfile.*; -import proguard.classfile.attribute.visitor.InnerClassesInfoVisitor; -import proguard.classfile.attribute.InnerClassesInfo; -import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.util.*; -import proguard.classfile.visitor.*; - -/** - * This InnerClassesInfoVisitor fixes the inner class access flags of the - * inner classes information that it visits. - * - * @author Eric Lafortune - */ -public class InnerClassesAccessFixer -extends SimplifiedVisitor -implements InnerClassesInfoVisitor, - ConstantVisitor, - ClassVisitor -{ - private int innerClassAccessFlags; - - - // Implementations for InnerClassesInfoVisitor. - - public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) - { - // The current access flags are the default. - innerClassAccessFlags = innerClassesInfo.u2innerClassAccessFlags; - - // See if we can find new access flags. - innerClassesInfo.innerClassConstantAccept(clazz, this); - - // Update the access flags. - innerClassesInfo.u2innerClassAccessFlags = innerClassAccessFlags; - } - - - // Implementations for ConstantVisitor. - - public void visitAnyConstant(Clazz clazz, Constant constant) {} - - - public void visitClassConstant(Clazz clazz, ClassConstant classConstant) - { - classConstant.referencedClassAccept(this); - } - - - // Implementations for ClassVisitor. - - public void visitLibraryClass(LibraryClass libraryClass) {} - - - public void visitProgramClass(ProgramClass programClass) - { - innerClassAccessFlags = - AccessUtil.replaceAccessFlags(innerClassAccessFlags, - programClass.u2accessFlags); - } -}
\ No newline at end of file diff --git a/src/proguard/classfile/editor/InstructionAdder.java b/src/proguard/classfile/editor/InstructionAdder.java index 34fb63b..60fde6d 100644 --- a/src/proguard/classfile/editor/InstructionAdder.java +++ b/src/proguard/classfile/editor/InstructionAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/InstructionWriter.java b/src/proguard/classfile/editor/InstructionWriter.java index b7da62f..d842358 100644 --- a/src/proguard/classfile/editor/InstructionWriter.java +++ b/src/proguard/classfile/editor/InstructionWriter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/InterfaceAdder.java b/src/proguard/classfile/editor/InterfaceAdder.java index 9c11d97..e095af6 100644 --- a/src/proguard/classfile/editor/InterfaceAdder.java +++ b/src/proguard/classfile/editor/InterfaceAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/InterfaceSorter.java b/src/proguard/classfile/editor/InterfaceSorter.java index 176e13e..6521369 100644 --- a/src/proguard/classfile/editor/InterfaceSorter.java +++ b/src/proguard/classfile/editor/InterfaceSorter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -21,14 +21,10 @@ package proguard.classfile.editor; import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.visitor.AttributeVisitor; -import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.util.*; +import proguard.classfile.util.SimplifiedVisitor; import proguard.classfile.visitor.ClassVisitor; -import java.util.*; +import java.util.Arrays; /** * This ClassVisitor sorts the interfaces of the program classes that it visits. @@ -37,8 +33,7 @@ import java.util.*; */ public class InterfaceSorter extends SimplifiedVisitor -implements ClassVisitor, - AttributeVisitor +implements ClassVisitor { // Implementations for ClassVisitor. @@ -47,106 +42,26 @@ implements ClassVisitor, int[] interfaces = programClass.u2interfaces; int interfacesCount = programClass.u2interfacesCount; - if (interfacesCount > 1) - { - // Sort the interfaces. - Arrays.sort(interfaces, 0, interfacesCount); - - // Remove any duplicate entries. - int newInterfacesCount = 0; - int previousInterfaceIndex = 0; - for (int index = 0; index < interfacesCount; index++) - { - int interfaceIndex = interfaces[index]; - - // Isn't this a duplicate of the previous interface? - if (interfaceIndex != previousInterfaceIndex) - { - interfaces[newInterfacesCount++] = interfaceIndex; - - // Remember the interface. - previousInterfaceIndex = interfaceIndex; - } - } - - programClass.u2interfacesCount = newInterfacesCount; - - // Update the signature, if any - programClass.attributesAccept(this); - } - } - - - // Implementations for AttributeVisitor. - - public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} - - - public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) - { - // Process the generic definitions, superclass, and implemented - // interfaces. - String signature = clazz.getString(signatureAttribute.u2signatureIndex); - - // Count the signature types. - InternalTypeEnumeration internalTypeEnumeration = - new InternalTypeEnumeration(signature); + // Sort the interfaces. + Arrays.sort(interfaces, 0, interfacesCount); - int count = 0; - int interfacesCount = -1; - while (internalTypeEnumeration.hasMoreTypes()) + // Remove any duplicate entries. + int newInterfacesCount = 0; + int previousInterfaceIndex = 0; + for (int index = 0; index < interfacesCount; index++) { - String internalType = internalTypeEnumeration.nextType(); + int interfaceIndex = interfaces[index]; - count++; - - if (ClassUtil.isInternalClassType(internalType)) + // Isn't this a duplicate of the previous interface? + if (interfaceIndex != previousInterfaceIndex) { - interfacesCount++; - } - } - - // Put the signature types in an array. - internalTypeEnumeration = - new InternalTypeEnumeration(signature); - - String[] internalTypes = new String[count]; - - for (int index = 0; index < count; index++) - { - String internalType = internalTypeEnumeration.nextType(); - - internalTypes[index] = internalType; - } + interfaces[newInterfacesCount++] = interfaceIndex; - // Sort the interface types in the array. - Arrays.sort(internalTypes, count - interfacesCount, count); - - // Recompose the signature types in a string. - StringBuffer newSignatureBuffer = new StringBuffer(); - - for (int index = 0; index < count; index++) - { - // Is this not an interface type, or an interface type that isn't - // a duplicate of the previous interface type? - if (index < count - interfacesCount || - !internalTypes[index].equals(internalTypes[index-1])) - { - newSignatureBuffer.append(internalTypes[index]); + // Remember the interface. + previousInterfaceIndex = interfaceIndex; } } - String newSignature = newSignatureBuffer.toString(); - - // Did the signature change? - if (!newSignature.equals(signature)) - { - // Update the signature. - ((Utf8Constant)((ProgramClass)clazz).constantPool[signatureAttribute.u2signatureIndex]).setString(newSignatureBuffer.toString()); - - // Clear the referenced classes. - // TODO: Properly update the referenced classes. - signatureAttribute.referencedClasses = null; - } + programClass.u2interfacesCount = newInterfacesCount; } } diff --git a/src/proguard/classfile/editor/InterfacesEditor.java b/src/proguard/classfile/editor/InterfacesEditor.java index 59cdd6a..d3170e1 100644 --- a/src/proguard/classfile/editor/InterfacesEditor.java +++ b/src/proguard/classfile/editor/InterfacesEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LineNumberInfoAdder.java b/src/proguard/classfile/editor/LineNumberInfoAdder.java index b0db7fb..aa8c0c4 100644 --- a/src/proguard/classfile/editor/LineNumberInfoAdder.java +++ b/src/proguard/classfile/editor/LineNumberInfoAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java b/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java index 7497458..ab96b38 100644 --- a/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java +++ b/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LocalVariableInfoAdder.java b/src/proguard/classfile/editor/LocalVariableInfoAdder.java index 0f47933..f285e4f 100644 --- a/src/proguard/classfile/editor/LocalVariableInfoAdder.java +++ b/src/proguard/classfile/editor/LocalVariableInfoAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java index 8bb051d..053b628 100644 --- a/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java +++ b/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java b/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java index a1c1379..ca50f3f 100644 --- a/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java +++ b/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java index 9b1ebd5..fe5a64d 100644 --- a/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java +++ b/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/MemberAdder.java b/src/proguard/classfile/editor/MemberAdder.java index 7791e3b..5f939bb 100644 --- a/src/proguard/classfile/editor/MemberAdder.java +++ b/src/proguard/classfile/editor/MemberAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -26,9 +26,8 @@ import proguard.classfile.util.SimplifiedVisitor; import proguard.classfile.visitor.MemberVisitor; /** - * This MemberVisitor copies all class members that it visits to the given - * target class. Their visitor info is set to the class members from which they - * were copied. + * This ConstantVisitor adds all class members that it visits to the given + * target class. * * @author Eric Lafortune */ @@ -46,9 +45,8 @@ implements MemberVisitor private static final Attribute[] EMPTY_ATTRIBUTES = new Attribute[0]; - private final ProgramClass targetClass; -// private final boolean addFields; - private final MemberVisitor extraMemberVisitor; + private final ProgramClass targetClass; +// private final boolean addFields; private final ConstantAdder constantAdder; private final ClassEditor classEditor; @@ -61,30 +59,13 @@ implements MemberVisitor * @param targetClass the class to which all visited class members will be * added. */ - public MemberAdder(ProgramClass targetClass) - { - this(targetClass, null); - } - - - /** - * Creates a new MemberAdder that will copy methods into the given target - * class. - * @param targetClass the class to which all visited class members - * will be added. - * @param extraMemberVisitor an optional member visitor that visits each - * new member right after it has been added. This - * allows changing the visitor info, for instance. - */ // * @param addFields specifies whether fields should be added, or fused // * with the present fields. - public MemberAdder(ProgramClass targetClass, -// boolean addFields, - MemberVisitor extraMemberVisitor) + public MemberAdder(ProgramClass targetClass)//), +// boolean addFields) { - this.targetClass = targetClass; -// this.addFields = addFields; - this.extraMemberVisitor = extraMemberVisitor; + this.targetClass = targetClass; +// this.addFields = addFields; constantAdder = new ConstantAdder(targetClass); classEditor = new ClassEditor(targetClass); @@ -169,12 +150,6 @@ implements MemberVisitor // Add the completed field. classEditor.addField(newProgramField); - - // Visit the newly added field, if necessary. - if (extraMemberVisitor != null) - { - extraMemberVisitor.visitProgramField(targetClass, newProgramField); - } } @@ -265,12 +240,6 @@ implements MemberVisitor // Add the completed method. classEditor.addMethod(newProgramMethod); - - // Visit the newly added method, if necessary. - if (extraMemberVisitor != null) - { - extraMemberVisitor.visitProgramMethod(targetClass, newProgramMethod); - } } diff --git a/src/proguard/classfile/editor/MemberReferenceFixer.java b/src/proguard/classfile/editor/MemberReferenceFixer.java index 6d665c1..4bd8af5 100644 --- a/src/proguard/classfile/editor/MemberReferenceFixer.java +++ b/src/proguard/classfile/editor/MemberReferenceFixer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -298,17 +298,22 @@ implements ClassVisitor, { Clazz referencedClass = enclosingMethodAttribute.referencedClass; - // Does it have a new name or type? - String newName = referencedMember.getName(referencedClass); - String newType = referencedMember.getDescriptor(referencedClass); + // Does it have a new class? + if (!enclosingMethodAttribute.getClassName(clazz).equals(referencedClass.getName())) + { + // Update the class index. + enclosingMethodAttribute.u2classIndex = + new ConstantPoolEditor((ProgramClass)clazz).addClassConstant(referencedClass); + } - if (!enclosingMethodAttribute.getName(clazz).equals(newName) || - !enclosingMethodAttribute.getType(clazz).equals(newType)) + // Does it have a new name or type? + if (!enclosingMethodAttribute.getName(clazz).equals(referencedMember.getName(referencedClass)) || + !enclosingMethodAttribute.getType(clazz).equals(referencedMember.getDescriptor(referencedClass))) { // Update the name and type index. enclosingMethodAttribute.u2nameAndTypeIndex = - new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(newName, - newType); + new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(referencedMember.getName(referencedClass), + referencedMember.getDescriptor(referencedClass)); } } } @@ -428,9 +433,10 @@ implements ClassVisitor, Member referencedMember) { System.out.println("MemberReferenceFixer:"); - System.out.println(" ["+clazz.getName()+"]: String ["+ - stringConstant.getString(clazz)+"] -> ["+ - referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]"); + System.out.println(" Class file = "+clazz.getName()); + System.out.println(" Ref class = "+referencedClass.getName()); + System.out.println(" Ref member name = "+stringConstant.getString(clazz)); + System.out.println(" -> "+referencedMember.getName(referencedClass)); } @@ -440,8 +446,11 @@ implements ClassVisitor, Member referencedMember) { System.out.println("MemberReferenceFixer:"); - System.out.println(" ["+clazz.getName()+"]: ["+ - refConstant.getClassName(clazz)+"."+refConstant.getName(clazz)+" "+refConstant.getType(clazz)+"] -> ["+ - referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]"); + System.out.println(" Class file = "+clazz.getName()); + System.out.println(" Ref class = "+referencedClass.getName()); + System.out.println(" Ref member name = "+refConstant.getName(clazz)); + System.out.println(" -> "+referencedMember.getName(referencedClass)); + System.out.println(" Ref descriptor = "+refConstant.getType(clazz)); + System.out.println(" -> "+referencedMember.getDescriptor(referencedClass)); } } diff --git a/src/proguard/classfile/editor/MethodInvocationFixer.java b/src/proguard/classfile/editor/MethodInvocationFixer.java index f33ef1d..ef76012 100644 --- a/src/proguard/classfile/editor/MethodInvocationFixer.java +++ b/src/proguard/classfile/editor/MethodInvocationFixer.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -28,6 +28,7 @@ import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.*; +import proguard.classfile.visitor.*; /** * This AttributeVisitor fixes all inappropriate special/virtual/static/interface @@ -39,7 +40,9 @@ public class MethodInvocationFixer extends SimplifiedVisitor implements AttributeVisitor, InstructionVisitor, - ConstantVisitor + ConstantVisitor, + ClassVisitor, + MemberVisitor { private static final boolean DEBUG = false; @@ -85,8 +88,7 @@ implements AttributeVisitor, clazz.constantPoolEntryAccept(constantIndex, this); // Did we find the called class and method? - if (referencedClass != null && - referencedMethod != null) + if (referencedMethod != null) { // Do we need to update the opcode? byte opcode = constantInstruction.opcode; @@ -166,7 +168,6 @@ implements AttributeVisitor, // but not a super call)? if (opcode != InstructionConstants.OP_INVOKEVIRTUAL && (opcode != InstructionConstants.OP_INVOKESPECIAL || - clazz.equals(referencedClass) || !clazz.extends_(referencedClass))) { // Replace the invocation by an invokevirtual instruction. @@ -193,30 +194,40 @@ implements AttributeVisitor, public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) { - // Remember the referenced class. Note that we're interested in the - // class of the method reference, not in the class in which the - // method was actually found, unless it is an array type. - // - if (ClassUtil.isInternalArrayType(refConstant.getClassName(clazz))) - { - // For an array type, the class will be java.lang.Object. - referencedClass = refConstant.referencedClass; - } - else - { - clazz.constantPoolEntryAccept(refConstant.u2classIndex, this); - } - - // Remember the referenced method. - referencedMethodClass = refConstant.referencedClass; - referencedMethod = refConstant.referencedMember; + // Check if this is an interface method. Note that we're interested in + // the class of the method reference, not in the class in which the + // method was actually found. + //refConstant.referencedClassAccept(this); + clazz.constantPoolEntryAccept(refConstant.u2classIndex, this); + + // Get the referenced access flags and names. + refConstant.referencedMemberAccept(this); } public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { + // Check if this is an interface class. + classConstant.referencedClassAccept(this); + } + + + // Implementations for ClassVisitor. + + public void visitAnyClass(Clazz clazz) + { // Remember the referenced class. - referencedClass = classConstant.referencedClass; + referencedClass = clazz; + } + + + // Implementations for MemberVisitor. + + public void visitAnyMember(Clazz clazz, Member member) + { + // Remember the referenced method. + referencedMethodClass = clazz; + referencedMethod = member; } diff --git a/src/proguard/classfile/editor/NameAndTypeShrinker.java b/src/proguard/classfile/editor/NameAndTypeShrinker.java deleted file mode 100644 index f316884..0000000 --- a/src/proguard/classfile/editor/NameAndTypeShrinker.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard.classfile.editor; - -import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.visitor.AttributeVisitor; -import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.editor.ConstantPoolRemapper; -import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.ClassVisitor; - -import java.util.Arrays; - - -/** - * This ClassVisitor removes NameAndType constant pool entries that are not - * used. - * - * @author Eric Lafortune - */ -public class NameAndTypeShrinker -extends SimplifiedVisitor -implements ClassVisitor, - ConstantVisitor, - AttributeVisitor -{ - // A visitor info flag to indicate the NameAndType constant pool entry is being used. - private static final Object USED = new Object(); - - private int[] constantIndexMap; - private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper(); - - - // Implementations for ClassVisitor. - - public void visitProgramClass(ProgramClass programClass) - { - // Mark the NameAndType entries referenced by all other constant pool - // entries. - programClass.constantPoolEntriesAccept(this); - - // Mark the NameAndType entries referenced by all EnclosingMethod - // attributes. - programClass.attributesAccept(this); - - // Shift the used constant pool entries together, filling out the - // index map. - int newConstantPoolCount = - shrinkConstantPool(programClass.constantPool, - programClass.u2constantPoolCount); - - // Remap the references to the constant pool if it has shrunk. - if (newConstantPoolCount < programClass.u2constantPoolCount) - { - programClass.u2constantPoolCount = newConstantPoolCount; - - // Remap all constant pool references. - constantPoolRemapper.setConstantIndexMap(constantIndexMap); - constantPoolRemapper.visitProgramClass(programClass); - } - } - - - // Implementations for ConstantVisitor. - - public void visitAnyConstant(Clazz clazz, Constant constant) {} - - - public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) - { - markNameAndTypeConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex); - } - - - public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) - { - markNameAndTypeConstant(clazz, refConstant.u2nameAndTypeIndex); - } - - - // Implementations for AttributeVisitor. - - public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} - - - public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) - { - if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) - { - markNameAndTypeConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex); - } - } - - - // Small utility methods. - - /** - * Marks the given UTF-8 constant pool entry of the given class. - */ - private void markNameAndTypeConstant(Clazz clazz, int index) - { - markAsUsed((NameAndTypeConstant)((ProgramClass)clazz).getConstant(index)); - } - - - /** - * Marks the given VisitorAccepter as being used. - * In this context, the VisitorAccepter will be a NameAndTypeConstant object. - */ - private void markAsUsed(VisitorAccepter visitorAccepter) - { - visitorAccepter.setVisitorInfo(USED); - } - - - /** - * Returns whether the given VisitorAccepter has been marked as being used. - * In this context, the VisitorAccepter will be a NameAndTypeConstant object. - */ - private boolean isUsed(VisitorAccepter visitorAccepter) - { - return visitorAccepter.getVisitorInfo() == USED; - } - - - /** - * Removes all NameAndType entries that are not marked as being used - * from the given constant pool. - * @return the new number of entries. - */ - private int shrinkConstantPool(Constant[] constantPool, int length) - { - // Create a new index map, if necessary. - if (constantIndexMap == null || - constantIndexMap.length < length) - { - constantIndexMap = new int[length]; - } - - int counter = 1; - boolean isUsed = false; - - // Shift the used constant pool entries together. - for (int index = 1; index < length; index++) - { - constantIndexMap[index] = counter; - - Constant constant = constantPool[index]; - - // Don't update the flag if this is the second half of a long entry. - if (constant != null) - { - isUsed = constant.getTag() != ClassConstants.CONSTANT_NameAndType || - isUsed(constant); - } - - if (isUsed) - { - constantPool[counter++] = constant; - } - } - - // Clear the remaining constant pool elements. - Arrays.fill(constantPool, counter, length, null); - - return counter; - } -} diff --git a/src/proguard/classfile/editor/NamedAttributeDeleter.java b/src/proguard/classfile/editor/NamedAttributeDeleter.java index 5ae950d..0c4d339 100644 --- a/src/proguard/classfile/editor/NamedAttributeDeleter.java +++ b/src/proguard/classfile/editor/NamedAttributeDeleter.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java b/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java index c97e2c8..4cad6b8 100644 --- a/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java +++ b/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/StackSizeUpdater.java b/src/proguard/classfile/editor/StackSizeUpdater.java index cc743b1..94e0519 100644 --- a/src/proguard/classfile/editor/StackSizeUpdater.java +++ b/src/proguard/classfile/editor/StackSizeUpdater.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/SubclassAdder.java b/src/proguard/classfile/editor/SubclassAdder.java index f944ef8..6b9fd64 100644 --- a/src/proguard/classfile/editor/SubclassAdder.java +++ b/src/proguard/classfile/editor/SubclassAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/SubclassToAdder.java b/src/proguard/classfile/editor/SubclassToAdder.java index f4cdd70..deb242f 100644 --- a/src/proguard/classfile/editor/SubclassToAdder.java +++ b/src/proguard/classfile/editor/SubclassToAdder.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/proguard/classfile/editor/Utf8Shrinker.java b/src/proguard/classfile/editor/Utf8Shrinker.java deleted file mode 100644 index b9dac44..0000000 --- a/src/proguard/classfile/editor/Utf8Shrinker.java +++ /dev/null @@ -1,455 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard.classfile.editor; - -import proguard.classfile.*; -import proguard.classfile.attribute.*; -import proguard.classfile.attribute.annotation.*; -import proguard.classfile.attribute.annotation.visitor.*; -import proguard.classfile.attribute.preverification.*; -import proguard.classfile.attribute.visitor.*; -import proguard.classfile.constant.*; -import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.editor.ConstantPoolRemapper; -import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.*; - -import java.util.Arrays; - - -/** - * This ClassVisitor removes UTF-8 constant pool entries that are not used. - * - * @author Eric Lafortune - */ -public class Utf8Shrinker -extends SimplifiedVisitor -implements ClassVisitor, - MemberVisitor, - ConstantVisitor, - AttributeVisitor, - InnerClassesInfoVisitor, - LocalVariableInfoVisitor, - LocalVariableTypeInfoVisitor, - AnnotationVisitor, - ElementValueVisitor -{ - // A visitor info flag to indicate the UTF-8 constant pool entry is being used. - private static final Object USED = new Object(); - - private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE]; - private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper(); - - - // Implementations for ClassVisitor. - - public void visitProgramClass(ProgramClass programClass) - { - // Mark the UTF-8 entries referenced by the other constant pool entries. - programClass.constantPoolEntriesAccept(this); - - // Mark the UTF-8 entries referenced by the fields and methods. - programClass.fieldsAccept(this); - programClass.methodsAccept(this); - - // Mark the UTF-8 entries referenced by the attributes. - programClass.attributesAccept(this); - - // Shift the used constant pool entries together, filling out the - // index map. - int newConstantPoolCount = - shrinkConstantPool(programClass.constantPool, - programClass.u2constantPoolCount); - - // Remap the references to the constant pool if it has shrunk. - if (newConstantPoolCount < programClass.u2constantPoolCount) - { - programClass.u2constantPoolCount = newConstantPoolCount; - - // Remap all constant pool references. - constantPoolRemapper.setConstantIndexMap(constantIndexMap); - constantPoolRemapper.visitProgramClass(programClass); - } - } - - - // Implementations for MemberVisitor. - - public void visitProgramMember(ProgramClass programClass, ProgramMember programMember) - { - // Mark the name and descriptor UTF-8 entries. - markCpUtf8Entry(programClass, programMember.u2nameIndex); - markCpUtf8Entry(programClass, programMember.u2descriptorIndex); - - // Mark the UTF-8 entries referenced by the attributes. - programMember.attributesAccept(programClass, this); - } - - - // Implementations for ConstantVisitor. - - public void visitAnyConstant(Clazz clazz, Constant constant) {} - - - public void visitStringConstant(Clazz clazz, StringConstant stringConstant) - { - markCpUtf8Entry(clazz, stringConstant.u2stringIndex); - } - - - public void visitClassConstant(Clazz clazz, ClassConstant classConstant) - { - markCpUtf8Entry(clazz, classConstant.u2nameIndex); - } - - - public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) - { - markCpUtf8Entry(clazz, nameAndTypeConstant.u2nameIndex); - markCpUtf8Entry(clazz, nameAndTypeConstant.u2descriptorIndex); - } - - - // Implementations for AttributeVisitor. - - public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute) - { - // This is the best we can do for unknown attributes. - markCpUtf8Entry(clazz, unknownAttribute.u2attributeNameIndex); - } - - - public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) - { - markCpUtf8Entry(clazz, sourceFileAttribute.u2attributeNameIndex); - - markCpUtf8Entry(clazz, sourceFileAttribute.u2sourceFileIndex); - } - - - public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) - { - markCpUtf8Entry(clazz, sourceDirAttribute.u2attributeNameIndex); - - markCpUtf8Entry(clazz, sourceDirAttribute.u2sourceDirIndex); - } - - - public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) - { - markCpUtf8Entry(clazz, innerClassesAttribute.u2attributeNameIndex); - - // Mark the UTF-8 entries referenced by the inner classes. - innerClassesAttribute.innerClassEntriesAccept(clazz, this); - } - - - public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) - { - markCpUtf8Entry(clazz, enclosingMethodAttribute.u2attributeNameIndex); - - // These entries have already been marked in the constant pool. - //clazz.constantPoolEntryAccept(this, enclosingMethodAttribute.u2classIndex); - //clazz.constantPoolEntryAccept(this, enclosingMethodAttribute.u2nameAndTypeIndex); - } - - - public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) - { - markCpUtf8Entry(clazz, deprecatedAttribute.u2attributeNameIndex); - } - - - public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute) - { - markCpUtf8Entry(clazz, syntheticAttribute.u2attributeNameIndex); - } - - - public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) - { - markCpUtf8Entry(clazz, signatureAttribute.u2attributeNameIndex); - - markCpUtf8Entry(clazz, signatureAttribute.u2signatureIndex); - } - - - public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) - { - markCpUtf8Entry(clazz, constantValueAttribute.u2attributeNameIndex); - } - - - public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) - { - markCpUtf8Entry(clazz, exceptionsAttribute.u2attributeNameIndex); - } - - - public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) - { - markCpUtf8Entry(clazz, codeAttribute.u2attributeNameIndex); - - // Mark the UTF-8 entries referenced by the attributes. - codeAttribute.attributesAccept(clazz, method, this); - } - - - public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) - { - markCpUtf8Entry(clazz, stackMapAttribute.u2attributeNameIndex); - } - - - public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) - { - markCpUtf8Entry(clazz, stackMapTableAttribute.u2attributeNameIndex); - } - - - public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) - { - markCpUtf8Entry(clazz, lineNumberTableAttribute.u2attributeNameIndex); - } - - - public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) - { - markCpUtf8Entry(clazz, localVariableTableAttribute.u2attributeNameIndex); - - // Mark the UTF-8 entries referenced by the local variables. - localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - } - - - public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) - { - markCpUtf8Entry(clazz, localVariableTypeTableAttribute.u2attributeNameIndex); - - // Mark the UTF-8 entries referenced by the local variable types. - localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); - } - - - public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) - { - markCpUtf8Entry(clazz, annotationsAttribute.u2attributeNameIndex); - - // Mark the UTF-8 entries referenced by the annotations. - annotationsAttribute.annotationsAccept(clazz, this); - } - - - public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) - { - markCpUtf8Entry(clazz, parameterAnnotationsAttribute.u2attributeNameIndex); - - // Mark the UTF-8 entries referenced by the annotations. - parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); - } - - - public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) - { - markCpUtf8Entry(clazz, annotationDefaultAttribute.u2attributeNameIndex); - - // Mark the UTF-8 entries referenced by the element value. - annotationDefaultAttribute.defaultValueAccept(clazz, this); - } - - - // Implementations for InnerClassesInfoVisitor. - - public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) - { - if (innerClassesInfo.u2innerNameIndex != 0) - { - markCpUtf8Entry(clazz, innerClassesInfo.u2innerNameIndex); - } - } - - - // Implementations for LocalVariableInfoVisitor. - - public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) - { - markCpUtf8Entry(clazz, localVariableInfo.u2nameIndex); - markCpUtf8Entry(clazz, localVariableInfo.u2descriptorIndex); - } - - - // Implementations for LocalVariableTypeInfoVisitor. - - public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) - { - markCpUtf8Entry(clazz, localVariableTypeInfo.u2nameIndex); - markCpUtf8Entry(clazz, localVariableTypeInfo.u2signatureIndex); - } - - - // Implementations for AnnotationVisitor. - - public void visitAnnotation(Clazz clazz, Annotation annotation) - { - markCpUtf8Entry(clazz, annotation.u2typeIndex); - - // Mark the UTF-8 entries referenced by the element values. - annotation.elementValuesAccept(clazz, this); - } - - - // Implementations for ElementValueVisitor. - - public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) - { - if (constantElementValue.u2elementNameIndex != 0) - { - markCpUtf8Entry(clazz, constantElementValue.u2elementNameIndex); - } - - // Only the string constant element value refers to a UTF-8 entry. - if (constantElementValue.u1tag == ClassConstants.ELEMENT_VALUE_STRING_CONSTANT) - { - markCpUtf8Entry(clazz, constantElementValue.u2constantValueIndex); - } - } - - - public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) - { - if (enumConstantElementValue.u2elementNameIndex != 0) - { - markCpUtf8Entry(clazz, enumConstantElementValue.u2elementNameIndex); - } - - markCpUtf8Entry(clazz, enumConstantElementValue.u2typeNameIndex); - markCpUtf8Entry(clazz, enumConstantElementValue.u2constantNameIndex); - } - - - public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) - { - if (classElementValue.u2elementNameIndex != 0) - { - markCpUtf8Entry(clazz, classElementValue.u2elementNameIndex); - } - - markCpUtf8Entry(clazz, classElementValue.u2classInfoIndex); - } - - - public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) - { - if (annotationElementValue.u2elementNameIndex != 0) - { - markCpUtf8Entry(clazz, annotationElementValue.u2elementNameIndex); - } - - // Mark the UTF-8 entries referenced by the annotation. - annotationElementValue.annotationAccept(clazz, this); - } - - - public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) - { - if (arrayElementValue.u2elementNameIndex != 0) - { - markCpUtf8Entry(clazz, arrayElementValue.u2elementNameIndex); - } - - // Mark the UTF-8 entries referenced by the element values. - arrayElementValue.elementValuesAccept(clazz, annotation, this); - } - - - // Small utility methods. - - /** - * Marks the given UTF-8 constant pool entry of the given class. - */ - private void markCpUtf8Entry(Clazz clazz, int index) - { - markAsUsed((Utf8Constant)((ProgramClass)clazz).getConstant(index)); - } - - - /** - * Marks the given VisitorAccepter as being used. - * In this context, the VisitorAccepter will be a Utf8Constant object. - */ - private void markAsUsed(VisitorAccepter visitorAccepter) - { - visitorAccepter.setVisitorInfo(USED); - } - - - /** - * Returns whether the given VisitorAccepter has been marked as being used. - * In this context, the VisitorAccepter will be a Utf8Constant object. - */ - private boolean isUsed(VisitorAccepter visitorAccepter) - { - return visitorAccepter.getVisitorInfo() == USED; - } - - - /** - * Removes all UTF-8 entries that are not marked as being used - * from the given constant pool. - * @return the new number of entries. - */ - private int shrinkConstantPool(Constant[] constantPool, int length) - { - // Create a new index map, if necessary. - if (constantIndexMap.length < length) - { - constantIndexMap = new int[length]; - } - - int counter = 1; - boolean isUsed = false; - - // Shift the used constant pool entries together. - for (int index = 1; index < length; index++) - { - constantIndexMap[index] = counter; - - Constant constant = constantPool[index]; - - // Don't update the flag if this is the second half of a long entry. - if (constant != null) - { - isUsed = constant.getTag() != ClassConstants.CONSTANT_Utf8 || - isUsed(constant); - } - - if (isUsed) - { - constantPool[counter++] = constant; - } - } - - // Clear the remaining constant pool elements. - Arrays.fill(constantPool, counter, length, null); - - return counter; - } -} diff --git a/src/proguard/classfile/editor/VariableCleaner.java b/src/proguard/classfile/editor/VariableCleaner.java index af51403..1e93c15 100644 --- a/src/proguard/classfile/editor/VariableCleaner.java +++ b/src/proguard/classfile/editor/VariableCleaner.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -22,15 +22,15 @@ package proguard.classfile.editor; import proguard.classfile.*; import proguard.classfile.attribute.*; -import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.SimplifiedVisitor; - -import java.util.Arrays; +import proguard.optimize.info.VariableUsageMarker; /** - * This AttributeVisitor cleans up variable tables in all code attributes that - * it visits. It trims overlapping local variables. It removes empty local - * variables and empty local variable tables. + * This AttributeVisitor cleans up unused variables in all attributes that it + * visits. * * @author Eric Lafortune */ @@ -38,8 +38,7 @@ public class VariableCleaner extends SimplifiedVisitor implements AttributeVisitor { - private boolean deleteLocalVariableTableAttribute; - private boolean deleteLocalVariableTypeTableAttribute; + private final VariableUsageMarker variableUsageMarker = new VariableUsageMarker(); // Implementations for AttributeVisitor. @@ -49,35 +48,11 @@ implements AttributeVisitor public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { - deleteLocalVariableTableAttribute = false; - deleteLocalVariableTypeTableAttribute = false; + // Figure out the local variables that are used by the code. + variableUsageMarker.visitCodeAttribute(clazz, method, codeAttribute); - // Trim the local variable table and the local variable type table. + // Clean up the variables of the attributes. codeAttribute.attributesAccept(clazz, method, this); - - // Delete the local variable table if it ended up empty. - if (deleteLocalVariableTableAttribute) - { - AttributesEditor editor = - new AttributesEditor((ProgramClass)clazz, - (ProgramMember)method, - codeAttribute, - true); - - editor.deleteAttribute(ClassConstants.ATTR_LocalVariableTable); - } - - // Delete the local variable type table if it ended up empty. - if (deleteLocalVariableTypeTableAttribute) - { - AttributesEditor editor = - new AttributesEditor((ProgramClass)clazz, - (ProgramMember)method, - codeAttribute, - true); - - editor.deleteAttribute(ClassConstants.ATTR_LocalVariableTypeTable); - } } @@ -85,20 +60,9 @@ implements AttributeVisitor { // Clean up local variables that aren't used. localVariableTableAttribute.u2localVariableTableLength = - removeUnusedLocalVariables(localVariableTableAttribute.localVariableTable, - localVariableTableAttribute.u2localVariableTableLength, - codeAttribute.u2maxLocals); - - // Trim the code blocks of the local variables. - trimLocalVariables(localVariableTableAttribute.localVariableTable, - localVariableTableAttribute.u2localVariableTableLength, - codeAttribute.u2maxLocals); - - // Delete the attribute in a moment, if it is empty. - if (localVariableTableAttribute.u2localVariableTableLength == 0) - { - deleteLocalVariableTableAttribute = true; - } + removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable, + localVariableTableAttribute.u2localVariableTableLength, + codeAttribute.u2maxLocals); } @@ -106,20 +70,9 @@ implements AttributeVisitor { // Clean up local variables that aren't used. localVariableTypeTableAttribute.u2localVariableTypeTableLength = - removeUnusedLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, - localVariableTypeTableAttribute.u2localVariableTypeTableLength, - codeAttribute.u2maxLocals); - - // Trim the code blocks of the local variables. - trimLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, - localVariableTypeTableAttribute.u2localVariableTypeTableLength, - codeAttribute.u2maxLocals); - - // Delete the attribute in a moment, if it is empty. - if (localVariableTypeTableAttribute.u2localVariableTypeTableLength == 0) - { - deleteLocalVariableTypeTableAttribute = true; - } + removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, + localVariableTypeTableAttribute.u2localVariableTypeTableLength, + codeAttribute.u2maxLocals); } @@ -127,28 +80,27 @@ implements AttributeVisitor /** * Returns the given list of local variables, without the ones that aren't - * used. + * used */ - private int removeUnusedLocalVariables(LocalVariableInfo[] localVariableInfos, - int localVariableInfoCount, - int maxLocals) + private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos, + int localVariableInfoCount, + int maxLocals) { // Overwrite all empty local variable entries. int newIndex = 0; - for (int index = 0; index < localVariableInfoCount; index++) + for (int index = 0; index < localVariableInfoCount && index < maxLocals; index++) { - LocalVariableInfo localVariableInfo = localVariableInfos[index]; - - if (localVariableInfo.u2index >= 0 && - localVariableInfo.u2index < maxLocals && - localVariableInfo.u2length > 0) + if (variableUsageMarker.isVariableUsed(index)) { localVariableInfos[newIndex++] = localVariableInfos[index]; } } // Clean up any remaining array elements. - Arrays.fill(localVariableInfos, newIndex, localVariableInfoCount, null); + for (int index = newIndex; index < localVariableInfoCount; index++) + { + localVariableInfos[index] = null; + } return newIndex; } @@ -156,112 +108,28 @@ implements AttributeVisitor /** * Returns the given list of local variable types, without the ones that - * aren't used. + * aren't used */ - private int removeUnusedLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, - int localVariableTypeInfoCount, - int maxLocals) + private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, + int localVariableTypeInfoCount, + int maxLocals) { // Overwrite all empty local variable type entries. int newIndex = 0; - for (int index = 0; index < localVariableTypeInfoCount; index++) + for (int index = 0; index < localVariableTypeInfoCount && index < maxLocals; index++) { - LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; - - if (localVariableTypeInfo.u2index >= 0 && - localVariableTypeInfo.u2index < maxLocals && - localVariableTypeInfo.u2length > 0) + if (variableUsageMarker.isVariableUsed(index)) { localVariableTypeInfos[newIndex++] = localVariableTypeInfos[index]; } } // Clean up any remaining array elements. - Arrays.fill(localVariableTypeInfos, newIndex, localVariableTypeInfoCount, null); - - return newIndex; - } - - - /** - * Sorts the given list of local variables and trims their code blocks - * when necessary. The block is trimmed at the end, which is a bit - * arbitrary. - */ - private void trimLocalVariables(LocalVariableInfo[] localVariableInfos, - int localVariableInfoCount, - int maxLocals) - { - // Sort the local variable entries. - Arrays.sort(localVariableInfos, 0, localVariableInfoCount); - - int[] startPCs = createMaxArray(maxLocals); - - // Trim the local variable entries, starting at the last one. - for (int index = localVariableInfoCount-1; index >= 0; index--) + for (int index = newIndex; index < localVariableTypeInfoCount; index++) { - LocalVariableInfo localVariableInfo = localVariableInfos[index]; - - // Make sure the variable's code block doesn't overlap with the - // next one for the same variable. - int maxLength = startPCs[localVariableInfo.u2index] - - localVariableInfo.u2startPC; - - if (localVariableInfo.u2length > maxLength) - { - localVariableInfo.u2length = maxLength; - } - - startPCs[localVariableInfo.u2index] = localVariableInfo.u2startPC; + localVariableTypeInfos[index] = null; } - } - - - /** - * Sorts the given list of local variable types and trims their code blocks - * when necessary. The block is trimmed at the end, which is a bit - * arbitrary. - */ - private void trimLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, - int localVariableTypeInfoCount, - int maxLocals) - { - // Sort the local variable entries. - Arrays.sort(localVariableTypeInfos, 0, localVariableTypeInfoCount); - - int[] startPCs = createMaxArray(maxLocals); - - // Trim the local variable entries, starting at the last one. - for (int index = localVariableTypeInfoCount-1; index >= 0; index--) - { - LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; - // Make sure the variable's code block doesn't overlap with the - // next one for the same variable. - int maxLength = startPCs[localVariableTypeInfo.u2index] - - localVariableTypeInfo.u2startPC; - - if (localVariableTypeInfo.u2length > maxLength) - { - localVariableTypeInfo.u2length = maxLength; - } - - startPCs[localVariableTypeInfo.u2index] = localVariableTypeInfo.u2startPC; - } - } - - - /** - * Creates an integer array of the given length, initialized with - * Integer.MAX_VALUE. - */ - private int[] createMaxArray(int length) - { - int[] startPCs = new int[length]; - for (int index = 0; index < length; index++) - { - startPCs[index] = Integer.MAX_VALUE; - } - return startPCs; + return newIndex; } }
\ No newline at end of file diff --git a/src/proguard/classfile/editor/VariableEditor.java b/src/proguard/classfile/editor/VariableEditor.java index 8c99ff8..a583b49 100644 --- a/src/proguard/classfile/editor/VariableEditor.java +++ b/src/proguard/classfile/editor/VariableEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -25,8 +25,6 @@ import proguard.classfile.attribute.*; import proguard.classfile.attribute.visitor.AttributeVisitor; import proguard.classfile.util.SimplifiedVisitor; -import java.util.Arrays; - /** * This AttributeVisitor accumulates specified changes to local variables, and * then applies these accumulated changes to the code attributes that it visits. @@ -55,13 +53,14 @@ implements AttributeVisitor // Try to reuse the previous array. if (deleted.length < maxLocals) { - // Create a new array. deleted = new boolean[maxLocals]; } else { - // Reset the array. - Arrays.fill(deleted, 0, maxLocals, false); + for (int index = 0; index < maxLocals; index++) + { + deleted[index] = false; + } } modified = false; diff --git a/src/proguard/classfile/editor/VariableRemapper.java b/src/proguard/classfile/editor/VariableRemapper.java index df26534..590cd4e 100644 --- a/src/proguard/classfile/editor/VariableRemapper.java +++ b/src/proguard/classfile/editor/VariableRemapper.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -40,9 +40,6 @@ implements AttributeVisitor, LocalVariableInfoVisitor, LocalVariableTypeInfoVisitor { - private static final boolean DEBUG = false; - - private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); private int[] variableMap; @@ -65,19 +62,6 @@ implements AttributeVisitor, public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { - if (DEBUG) - { - System.out.println("VariableRemapper: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)); - for (int index= 0; index < codeAttribute.u2maxLocals; index++) - { - System.out.println(" v"+index+" -> "+variableMap[index]); - } - } - - // Remap the variables of the attributes, before editing the code and - // cleaning up its local variable frame. - codeAttribute.attributesAccept(clazz, method, this); - // Initially, the code attribute editor doesn't contain any changes. codeAttributeEditor.reset(codeAttribute.u4codeLength); @@ -86,6 +70,9 @@ implements AttributeVisitor, // Apply the code atribute editor. codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + + // Remap the variables of the attributes. + codeAttribute.attributesAccept(clazz, method, this); } @@ -93,6 +80,11 @@ implements AttributeVisitor, { // Remap the variable references of the local variables. localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + + // Remove local variables that haven't been mapped. + localVariableTableAttribute.u2localVariableTableLength = + removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable, + localVariableTableAttribute.u2localVariableTableLength); } @@ -100,6 +92,11 @@ implements AttributeVisitor, { // Remap the variable references of the local variables. localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + + // Remove local variables that haven't been mapped. + localVariableTypeTableAttribute.u2localVariableTypeTableLength = + removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, + localVariableTypeTableAttribute.u2localVariableTypeTableLength); } @@ -153,4 +150,48 @@ implements AttributeVisitor, { return variableMap[variableIndex]; } + + + /** + * Returns the given list of local variables, without the ones that have + * been removed. + */ + private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos, + int localVariableInfoCount) + { + // Overwrite all empty local variable entries. + int newIndex = 0; + for (int index = 0; index < localVariableInfoCount; index++) + { + LocalVariableInfo localVariableInfo = localVariableInfos[index]; + if (localVariableInfo.u2index >= 0) + { + localVariableInfos[newIndex++] = localVariableInfo; + } + } + + return newIndex; + } + + + /** + * Returns the given list of local variable types, without the ones that + * have been removed. + */ + private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, + int localVariableTypeInfoCount) + { + // Overwrite all empty local variable type entries. + int newIndex = 0; + for (int index = 0; index < localVariableTypeInfoCount; index++) + { + LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; + if (localVariableTypeInfo.u2index >= 0) + { + localVariableTypeInfos[newIndex++] = localVariableTypeInfo; + } + } + + return newIndex; + } } diff --git a/src/proguard/classfile/editor/VariableSizeUpdater.java b/src/proguard/classfile/editor/VariableSizeUpdater.java index bb87151..18958c5 100644 --- a/src/proguard/classfile/editor/VariableSizeUpdater.java +++ b/src/proguard/classfile/editor/VariableSizeUpdater.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -29,8 +29,7 @@ import proguard.classfile.util.*; /** * This AttributeVisitor computes and updates the maximum local variable frame - * size of the code attributes that it visits. It also cleans up the local - * variable tables. + * size of the code attributes that it visits. * * @author Eric Lafortune */ @@ -46,9 +45,6 @@ implements AttributeVisitor, //*/ - private VariableCleaner variableCleaner = new VariableCleaner(); - - // Implementations for AttributeVisitor. public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} @@ -73,9 +69,6 @@ implements AttributeVisitor, // Go over all instructions. codeAttribute.instructionsAccept(clazz, method, this); - - // Remove the unused variables of the attributes. - variableCleaner.visitCodeAttribute(clazz, method, codeAttribute); } @@ -98,7 +91,7 @@ implements AttributeVisitor, if (DEBUG) { - System.out.println(" Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset)); + System.out.println("Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset)); } } } |