1/* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2013 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 final boolean loadFieldValues; 39 private final boolean loadMethodParameterValues; 40 private final 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 } 88 } 89 } 90 91 return super.getFieldClassValue(clazz, refConstant, type); 92 } 93 94 95 protected Value getFieldValue(Clazz clazz, 96 RefConstant refConstant, 97 String type) 98 { 99 if (loadFieldValues) 100 { 101 // Do we know this field? 102 Member referencedMember = refConstant.referencedMember; 103 if (referencedMember != null) 104 { 105 // Retrieve the stored field value. 106 Value value = StoringInvocationUnit.getFieldValue((Field)referencedMember); 107 if (value != null && 108 value.isParticular()) 109 { 110 return value; 111 } 112 } 113 } 114 115 return super.getFieldValue(clazz, refConstant, type); 116 } 117 118 119 protected Value getMethodParameterValue(Clazz clazz, 120 Method method, 121 int parameterIndex, 122 String type, 123 Clazz referencedClass) 124 { 125 if (loadMethodParameterValues) 126 { 127 // Retrieve the stored method parameter value. 128 Value value = StoringInvocationUnit.getMethodParameterValue(method, parameterIndex); 129 if (value != null && 130 value.isParticular()) 131 { 132 return value; 133 } 134 } 135 136 return super.getMethodParameterValue(clazz, 137 method, 138 parameterIndex, 139 type, 140 referencedClass); 141 } 142 143 144 protected Value getMethodReturnValue(Clazz clazz, 145 RefConstant refConstant, 146 String type) 147 { 148 if (loadMethodReturnValues) 149 { 150 // Do we know this method? 151 Member referencedMember = refConstant.referencedMember; 152 if (referencedMember != null) 153 { 154 // Retrieve the stored method return value. 155 Value value = StoringInvocationUnit.getMethodReturnValue((Method)referencedMember); 156 if (value != null && 157 value.isParticular()) 158 { 159 return value; 160 } 161 } 162 } 163 164 return super.getMethodReturnValue(clazz, 165 refConstant, 166 type); 167 } 168 169 170// // Small utility methods. 171// 172// private Value refresh(Value value) 173// { 174// if (value.isParticular()) 175// { 176// return value; 177// } 178// 179// switch (value.computationalType()) 180// { 181// case Value.TYPE_INTEGER: return valueFactory.createIntegerValue(); 182// case Value.TYPE_LONG: return valueFactory.createLongValue(); 183// case Value.TYPE_FLOAT: return valueFactory.createFloatValue(); 184// case Value.TYPE_DOUBLE: return valueFactory.createDoubleValue(); 185// default: 186// { 187// ReferenceValue referenceValue = value.referenceValue(); 188// 189// return valueFactory.createReferenceValue(referenceValue.getType(), 190// referenceValue.getReferencedClass(), 191// referenceValue.isNull() != Value.NEVER); 192// } 193// } 194// } 195} 196