1/* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21package proguard.optimize.evaluation; 22 23import proguard.classfile.*; 24import proguard.classfile.constant.RefConstant; 25import proguard.evaluation.BasicInvocationUnit; 26import proguard.evaluation.value.*; 27 28/** 29 * This InvocationUbit loads parameter values and return values that were 30 * previously stored with the methods that are invoked. 31 * 32 * @see StoringInvocationUnit 33 * @author Eric Lafortune 34 */ 35public class LoadingInvocationUnit 36extends BasicInvocationUnit 37{ 38 private boolean loadFieldValues; 39 private boolean loadMethodParameterValues; 40 private boolean loadMethodReturnValues; 41 42 43 /** 44 * Creates a new LoadingInvocationUnit with the given value factory. 45 */ 46 public LoadingInvocationUnit(ValueFactory valueFactory) 47 { 48 this(valueFactory, false, false, false); 49 } 50 51 52 /** 53 * Creates a new LoadingInvocationUnit with the given value factory, for 54 * loading the specified values. 55 */ 56 public LoadingInvocationUnit(ValueFactory valueFactory, 57 boolean loadFieldValues, 58 boolean loadMethodParameterValues, 59 boolean loadMethodReturnValues) 60 { 61 super(valueFactory); 62 63 this.loadFieldValues = loadFieldValues; 64 this.loadMethodParameterValues = loadMethodParameterValues; 65 this.loadMethodReturnValues = loadMethodReturnValues; 66 } 67 68 69 // Implementations for BasicInvocationUnit. 70 71 protected Value getFieldClassValue(Clazz clazz, 72 RefConstant refConstant, 73 String type) 74 { 75 if (loadFieldValues) 76 { 77 // Do we know this field? 78 Member referencedMember = refConstant.referencedMember; 79 if (referencedMember != null) 80 { 81 // Retrieve the stored field class value. 82 ReferenceValue value = StoringInvocationUnit.getFieldClassValue((Field)referencedMember); 83 if (value != null && 84 value.isParticular()) 85 { 86 return value; 87// // Make sure the value is refreshed. 88// return refresh(value); 89 } 90 } 91 } 92 93 return super.getFieldClassValue(clazz, refConstant, type); 94 } 95 96 97 protected Value getFieldValue(Clazz clazz, 98 RefConstant refConstant, 99 String type) 100 { 101 if (loadFieldValues) 102 { 103 // Do we know this field? 104 Member referencedMember = refConstant.referencedMember; 105 if (referencedMember != null) 106 { 107 // Retrieve the stored field value. 108 Value value = StoringInvocationUnit.getFieldValue((Field)referencedMember); 109 if (value != null && 110 value.isParticular()) 111 { 112 return value; 113// // Make sure the value is refreshed. 114// return refresh(value); 115 } 116 } 117 } 118 119 return super.getFieldValue(clazz, refConstant, type); 120 } 121 122 123 protected Value getMethodParameterValue(Clazz clazz, 124 Method method, 125 int parameterIndex, 126 String type, 127 Clazz referencedClass) 128 { 129 if (loadMethodParameterValues) 130 { 131 // Retrieve the stored method parameter value. 132 Value value = StoringInvocationUnit.getMethodParameterValue(method, parameterIndex); 133 if (value != null && 134 value.isParticular()) 135 { 136 return value; 137// // Make sure the value is refreshed. 138// return refresh(value); 139 } 140 } 141 142 return super.getMethodParameterValue(clazz, 143 method, 144 parameterIndex, 145 type, 146 referencedClass); 147 } 148 149 150 protected Value getMethodReturnValue(Clazz clazz, 151 RefConstant refConstant, 152 String type) 153 { 154 if (loadMethodReturnValues) 155 { 156 // Do we know this method? 157 Member referencedMember = refConstant.referencedMember; 158 if (referencedMember != null) 159 { 160 // Retrieve the stored method return value. 161 Value value = StoringInvocationUnit.getMethodReturnValue((Method)referencedMember); 162 if (value != null && 163 value.isParticular()) 164 { 165 return value; 166// // Make sure the value is refreshed. 167// return refresh(value); 168 } 169 } 170 } 171 172 return super.getMethodReturnValue(clazz, 173 refConstant, 174 type); 175 } 176// 177// 178// // Small utility methods. 179// 180// private Value refresh(Value value) 181// { 182// if (value.isParticular()) 183// { 184// return value; 185// } 186// 187// switch (value.computationalType()) 188// { 189// case Value.TYPE_INTEGER: return valueFactory.createIntegerValue(); 190// case Value.TYPE_LONG: return valueFactory.createLongValue(); 191// case Value.TYPE_FLOAT: return valueFactory.createFloatValue(); 192// case Value.TYPE_DOUBLE: return valueFactory.createDoubleValue(); 193// default: 194// { 195// ReferenceValue referenceValue = value.referenceValue(); 196// 197// return valueFactory.createReferenceValue(referenceValue.getType(), 198// referenceValue.getReferencedClass(), 199// referenceValue.isNull() != Value.NEVER); 200// } 201// } 202// } 203} 204