1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 5b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.evaluation; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.CodeAttribute; 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.*; 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.visitor.ConstantVisitor; 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.instruction.*; 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.*; 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.MemberVisitor; 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.evaluation.value.*; 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This InvocationUnit sets up the variables for entering a method, 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * and it updates the stack for the invocation of a class member, 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * using simple values. 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class BasicInvocationUnit 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoextends SimplifiedVisitor 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimplements InvocationUnit, 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConstantVisitor, 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato MemberVisitor 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected final ValueFactory valueFactory; 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Fields acting as parameters between the visitor methods. 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private boolean isStatic; 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private boolean isLoad; 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Stack stack; 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Clazz returnTypeClass; 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new BasicInvocationUnit with the given value factory. 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public BasicInvocationUnit(ValueFactory valueFactory) 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.valueFactory = valueFactory; 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for InvocationUnit. 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void enterMethod(Clazz clazz, Method method, Variables variables) 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor = method.getDescriptor(clazz); 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Initialize the parameters. 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean isStatic = 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0; 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Count the number of parameters, taking into account their categories. 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int parameterSize = ClassUtil.internalMethodParameterSize(descriptor, isStatic); 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Reuse the existing parameters object, ensuring the right size. 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato variables.reset(parameterSize); 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Go over the parameters again. 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato InternalTypeEnumeration internalTypeEnumeration = 81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new InternalTypeEnumeration(descriptor); 82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int parameterIndex = 0; 84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int variableIndex = 0; 85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Put the 'this' reference in variable 0. 87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (!isStatic) 88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Get the reference value. 90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Value value = getMethodParameterValue(clazz, 91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato method, 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato parameterIndex++, 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassUtil.internalTypeFromClassName(clazz.getName()), 94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz); 95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Store the value in variable 0. 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato variables.store(variableIndex++, value); 98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Clazz[] referencedClasses = ((ProgramMethod)method).referencedClasses; 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int referencedClassIndex = 0; 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Set up the variables corresponding to the parameter types and values. 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato while (internalTypeEnumeration.hasMoreTypes()) 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String type = internalTypeEnumeration.nextType(); 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Clazz referencedClass = referencedClasses != null && 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassUtil.isInternalClassType(type) ? 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato referencedClasses[referencedClassIndex++] : 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato null; 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Get the parameter value. 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Value value = getMethodParameterValue(clazz, 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato method, 116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato parameterIndex++, 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato type, 118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato referencedClass); 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Store the value in the corresponding variable. 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato variables.store(variableIndex++, value); 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Increment the variable index again for Category 2 values. 124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (value.isCategory2()) 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato variableIndex++; 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void exitMethod(Clazz clazz, Method method, Value returnValue) 133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato setMethodReturnValue(clazz, method, returnValue); 135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void invokeMember(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction, Stack stack) 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int constantIndex = constantInstruction.constantIndex; 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato switch (constantInstruction.opcode) 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato case InstructionConstants.OP_GETSTATIC: 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isStatic = true; 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isLoad = true; 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato break; 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato case InstructionConstants.OP_PUTSTATIC: 150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isStatic = true; 151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isLoad = false; 152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato break; 153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato case InstructionConstants.OP_GETFIELD: 155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isStatic = false; 156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isLoad = true; 157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato break; 158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato case InstructionConstants.OP_PUTFIELD: 160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isStatic = false; 161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isLoad = false; 162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato break; 163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato case InstructionConstants.OP_INVOKESTATIC: 165b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang case InstructionConstants.OP_INVOKEDYNAMIC: 166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isStatic = true; 167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato break; 168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato case InstructionConstants.OP_INVOKEVIRTUAL: 170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato case InstructionConstants.OP_INVOKESPECIAL: 171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato case InstructionConstants.OP_INVOKEINTERFACE: 172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato isStatic = false; 173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato break; 174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Pop the parameters and push the return value. 177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.stack = stack; 178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz.constantPoolEntryAccept(constantIndex, this); 179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.stack = null; 180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for ConstantVisitor. 184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) 186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Pop the field value, if applicable. 188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (!isLoad) 189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato setFieldValue(clazz, fieldrefConstant, stack.pop()); 191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Pop the reference value, if applicable. 194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (!isStatic) 195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato setFieldClassValue(clazz, fieldrefConstant, stack.apop()); 197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Push the field value, if applicable. 200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (isLoad) 201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String type = fieldrefConstant.getType(clazz); 203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato stack.push(getFieldValue(clazz, fieldrefConstant, type)); 205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitAnyMethodrefConstant(Clazz clazz, RefConstant methodrefConstant) 210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String type = methodrefConstant.getType(clazz); 212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Count the number of parameters. 214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int parameterCount = ClassUtil.internalMethodParameterCount(type); 215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (!isStatic) 216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato parameterCount++; 218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Pop the parameters and the class reference, in reverse order. 221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int parameterIndex = parameterCount-1; parameterIndex >= 0; parameterIndex--) 222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato setMethodParameterValue(clazz, methodrefConstant, parameterIndex, stack.pop()); 224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Push the return value, if applicable. 227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String returnType = ClassUtil.internalMethodReturnType(type); 228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (returnType.charAt(0) != ClassConstants.INTERNAL_TYPE_VOID) 229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato stack.push(getMethodReturnValue(clazz, methodrefConstant, returnType)); 231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 234b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) 235b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 236b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang String type = invokeDynamicConstant.getType(clazz); 237b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 238b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Count the number of parameters. 239b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang int parameterCount = ClassUtil.internalMethodParameterCount(type); 240b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (!isStatic) 241b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 242b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang parameterCount++; 243b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 244b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 245b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Pop the parameters and the class reference, in reverse order. 246b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang for (int parameterIndex = parameterCount-1; parameterIndex >= 0; parameterIndex--) 247b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 248b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang stack.pop(); 249b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 250b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 251b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Push the return value, if applicable. 252b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang String returnType = ClassUtil.internalMethodReturnType(type); 253b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (returnType.charAt(0) != ClassConstants.INTERNAL_TYPE_VOID) 254b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 255b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang stack.push(getMethodReturnValue(clazz, invokeDynamicConstant, returnType)); 256b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 257b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 258b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Sets the class through which the specified field is accessed. 262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected void setFieldClassValue(Clazz clazz, 264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato RefConstant refConstant, 265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ReferenceValue value) 266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // We don't care about the new value. 268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns the class though which the specified field is accessed. 273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected Value getFieldClassValue(Clazz clazz, 275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato RefConstant refConstant, 276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String type) 277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Try to figure out the class of the return type. 279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass = null; 280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato refConstant.referencedMemberAccept(this); 281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return valueFactory.createValue(type, 283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass, 284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato true); 285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Sets the value of the specified field. 290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected void setFieldValue(Clazz clazz, 292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato RefConstant refConstant, 293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Value value) 294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // We don't care about the new field value. 296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns the value of the specified field. 301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected Value getFieldValue(Clazz clazz, 303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato RefConstant refConstant, 304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String type) 305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Try to figure out the class of the return type. 307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass = null; 308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato refConstant.referencedMemberAccept(this); 309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return valueFactory.createValue(type, 311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass, 312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato true); 313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Sets the value of the specified method parameter. 318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected void setMethodParameterValue(Clazz clazz, 320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato RefConstant refConstant, 321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int parameterIndex, 322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Value value) 323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // We don't care about the parameter value. 325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns the value of the specified method parameter. 330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected Value getMethodParameterValue(Clazz clazz, 332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Method method, 333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int parameterIndex, 334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String type, 335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Clazz referencedClass) 336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return valueFactory.createValue(type, referencedClass, true); 338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 342b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Sets the return value of the specified method. 343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected void setMethodReturnValue(Clazz clazz, 345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Method method, 346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Value value) 347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // We don't care about the return value. 349b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 350b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 351b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 352b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 353b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns the return value of the specified method. 354b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 355b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected Value getMethodReturnValue(Clazz clazz, 356b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato RefConstant refConstant, 357b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String type) 358b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 359b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Try to figure out the class of the return type. 360b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass = null; 361b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato refConstant.referencedMemberAccept(this); 362b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 363b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return valueFactory.createValue(type, 364b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass, 365b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato true); 366b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 367b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 368b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 369b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang /** 370b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Returns the return value of the specified method. 371b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */ 372b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang protected Value getMethodReturnValue(Clazz clazz, 373b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang InvokeDynamicConstant invokeDynamicConstant, 374b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang String type) 375b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 376b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Try to figure out the class of the return type. 377b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang Clazz[] referencedClasses = invokeDynamicConstant.referencedClasses; 378b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 379b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang Clazz returnTypeClass = referencedClasses == null ? null : 380b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang referencedClasses[referencedClasses.length - 1]; 381b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 382b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return valueFactory.createValue(type, 383b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang returnTypeClass, 384b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang true); 385b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 386b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 387b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 388b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for MemberVisitor. 389b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 390b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitProgramField(ProgramClass programClass, ProgramField programField) 391b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 392b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass = programField.referencedClass; 393b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 394b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 395b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 396b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) 397b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 398b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Clazz[] referencedClasses = programMethod.referencedClasses; 399b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (referencedClasses != null) 400b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 401b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass = referencedClasses[referencedClasses.length - 1]; 402b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 403b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 404b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 405b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 406b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitLibraryField(LibraryClass programClass, LibraryField programField) 407b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 408b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass = programField.referencedClass; 409b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 410b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 411b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 412b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitLibraryMethod(LibraryClass programClass, LibraryMethod programMethod) 413b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 414b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Clazz[] referencedClasses = programMethod.referencedClasses; 415b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (referencedClasses != null) 416b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 417b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato returnTypeClass = referencedClasses[referencedClasses.length - 1]; 418b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 419b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 420b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 421b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 422b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember) 423b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// { 424b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// } 425b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 426