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 */ 21 package proguard.optimize.evaluation; 22 23 import proguard.classfile.*; 24 import proguard.classfile.constant.RefConstant; 25 import proguard.evaluation.BasicInvocationUnit; 26 import 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 */ 35 public class LoadingInvocationUnit 36 extends 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 */ LoadingInvocationUnit(ValueFactory valueFactory)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 */ LoadingInvocationUnit(ValueFactory valueFactory, boolean loadFieldValues, boolean loadMethodParameterValues, boolean loadMethodReturnValues)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 getFieldClassValue(Clazz clazz, RefConstant refConstant, String type)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 getFieldValue(Clazz clazz, RefConstant refConstant, String type)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 getMethodParameterValue(Clazz clazz, Method method, int parameterIndex, String type, Clazz referencedClass)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 getMethodReturnValue(Clazz clazz, RefConstant refConstant, String type)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