001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This library is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This library is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
015: * for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this library; if not, write to the Free Software Foundation,
019: * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.optimize;
022:
023: import proguard.classfile.*;
024: import proguard.classfile.attribute.CodeAttribute;
025: import proguard.classfile.constant.*;
026: import proguard.classfile.constant.visitor.ConstantVisitor;
027: import proguard.classfile.instruction.ConstantInstruction;
028: import proguard.classfile.util.SimplifiedVisitor;
029: import proguard.classfile.visitor.MemberVisitor;
030: import proguard.evaluation.*;
031: import proguard.evaluation.value.Value;
032: import proguard.optimize.info.ParameterUsageMarker;
033:
034: /**
035: * This InvocationUnit removes unused parameters from the stack before invoking
036: * a method, and then delegates to another given InvocationUnit.
037: *
038: * @see ParameterUsageMarker
039: * @author Eric Lafortune
040: */
041: public class UnusedParameterInvocationUnit extends SimplifiedVisitor
042: implements InvocationUnit, ConstantVisitor, MemberVisitor {
043: private static final boolean DEBUG = false;
044:
045: private final InvocationUnit invocationUnit;
046:
047: private Stack stack;
048:
049: public UnusedParameterInvocationUnit(InvocationUnit invocationUnit) {
050: this .invocationUnit = invocationUnit;
051: }
052:
053: // Implementations for InvocationUnit.
054:
055: public void enterMethod(Clazz clazz, Method method,
056: Variables variables) {
057: invocationUnit.enterMethod(clazz, method, variables);
058: }
059:
060: public void exitMethod(Clazz clazz, Method method, Value returnValue) {
061: invocationUnit.exitMethod(clazz, method, returnValue);
062: }
063:
064: public void invokeMember(Clazz clazz, Method method,
065: CodeAttribute codeAttribute, int offset,
066: ConstantInstruction constantInstruction, Stack stack) {
067: // Fix the stack if this is a method invocation of which some
068: // parameters are marked as unused.
069: this .stack = stack;
070: clazz.constantPoolEntryAccept(
071: constantInstruction.constantIndex, this );
072:
073: invocationUnit.invokeMember(clazz, method, codeAttribute,
074: offset, constantInstruction, stack);
075: }
076:
077: // Implementations for ConstantVisitor.
078:
079: public void visitAnyConstant(Clazz clazz, Constant constant) {
080: }
081:
082: public void visitAnyMethodrefConstant(Clazz clazz,
083: RefConstant refConstant) {
084: refConstant.referencedMemberAccept(this );
085: }
086:
087: // Implementations for MemberVisitor.
088:
089: public void visitProgramMethod(ProgramClass programClass,
090: ProgramMethod programMethod) {
091: if (DEBUG) {
092: System.out.println("UnusedParameterInvocationUnit: "
093: + programMethod.getName(programClass)
094: + programMethod.getDescriptor(programClass));
095: }
096:
097: // Get the total size of the parameters.
098: int parameterSize = ParameterUsageMarker
099: .getParameterSize(programMethod);
100:
101: // Remove unused parameters.
102: for (int index = 0; index < parameterSize; index++) {
103: if (!ParameterUsageMarker.isParameterUsed(programMethod,
104: index)) {
105: if (DEBUG) {
106: System.out.println(" removing stack entry #"
107: + (parameterSize - index - 1) + " ("
108: + stack.getTop(parameterSize - index - 1)
109: + ")");
110: }
111:
112: stack.removeTop(parameterSize - index - 1);
113: }
114: }
115: }
116:
117: public void visitLibraryMethod(LibraryClass libraryClass,
118: LibraryMethod libraryMethod) {
119: }
120: }
|