aboutsummaryrefslogtreecommitdiffstats
path: root/src/proguard/classfile/editor
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/classfile/editor')
-rw-r--r--src/proguard/classfile/editor/AccessFixer.java28
-rw-r--r--src/proguard/classfile/editor/AnnotationAdder.java2
-rw-r--r--src/proguard/classfile/editor/AnnotationsAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/AttributeAdder.java4
-rw-r--r--src/proguard/classfile/editor/AttributeSorter.java2
-rw-r--r--src/proguard/classfile/editor/AttributesEditor.java2
-rw-r--r--src/proguard/classfile/editor/BridgeMethodFixer.java117
-rw-r--r--src/proguard/classfile/editor/ClassEditor.java2
-rw-r--r--src/proguard/classfile/editor/ClassElementSorter.java2
-rw-r--r--src/proguard/classfile/editor/ClassMemberSorter.java2
-rw-r--r--src/proguard/classfile/editor/ClassReferenceFixer.java2
-rw-r--r--src/proguard/classfile/editor/CodeAttributeComposer.java48
-rw-r--r--src/proguard/classfile/editor/CodeAttributeEditor.java161
-rw-r--r--src/proguard/classfile/editor/CodeAttributeEditorResetter.java2
-rw-r--r--src/proguard/classfile/editor/ComparableConstant.java83
-rw-r--r--src/proguard/classfile/editor/ConstantAdder.java47
-rw-r--r--src/proguard/classfile/editor/ConstantPoolEditor.java119
-rw-r--r--src/proguard/classfile/editor/ConstantPoolRemapper.java105
-rw-r--r--src/proguard/classfile/editor/ConstantPoolShrinker.java578
-rw-r--r--src/proguard/classfile/editor/ConstantPoolSorter.java7
-rw-r--r--src/proguard/classfile/editor/ElementValueAdder.java2
-rw-r--r--src/proguard/classfile/editor/ElementValuesEditor.java2
-rw-r--r--src/proguard/classfile/editor/ExceptionAdder.java2
-rw-r--r--src/proguard/classfile/editor/ExceptionInfoAdder.java2
-rw-r--r--src/proguard/classfile/editor/ExceptionsAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/InnerClassesAccessFixer.java83
-rw-r--r--src/proguard/classfile/editor/InstructionAdder.java2
-rw-r--r--src/proguard/classfile/editor/InstructionWriter.java2
-rw-r--r--src/proguard/classfile/editor/InterfaceAdder.java2
-rw-r--r--src/proguard/classfile/editor/InterfaceSorter.java119
-rw-r--r--src/proguard/classfile/editor/InterfacesEditor.java2
-rw-r--r--src/proguard/classfile/editor/LineNumberInfoAdder.java2
-rw-r--r--src/proguard/classfile/editor/LineNumberTableAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/LocalVariableInfoAdder.java2
-rw-r--r--src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java2
-rw-r--r--src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/MemberAdder.java49
-rw-r--r--src/proguard/classfile/editor/MemberReferenceFixer.java37
-rw-r--r--src/proguard/classfile/editor/MethodInvocationFixer.java57
-rw-r--r--src/proguard/classfile/editor/NameAndTypeShrinker.java188
-rw-r--r--src/proguard/classfile/editor/NamedAttributeDeleter.java2
-rw-r--r--src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java2
-rw-r--r--src/proguard/classfile/editor/StackSizeUpdater.java2
-rw-r--r--src/proguard/classfile/editor/SubclassAdder.java2
-rw-r--r--src/proguard/classfile/editor/SubclassToAdder.java2
-rw-r--r--src/proguard/classfile/editor/Utf8Shrinker.java455
-rw-r--r--src/proguard/classfile/editor/VariableCleaner.java204
-rw-r--r--src/proguard/classfile/editor/VariableEditor.java11
-rw-r--r--src/proguard/classfile/editor/VariableRemapper.java75
-rw-r--r--src/proguard/classfile/editor/VariableSizeUpdater.java13
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));
}
}
}