1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 52270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom * Copyright (c) 2002-2014 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.classfile.editor; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.*; 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.visitor.AttributeVisitor; 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.*; 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.visitor.ConstantVisitor; 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.instruction.*; 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.instruction.visitor.InstructionVisitor; 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.*; 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This AttributeVisitor fixes all inappropriate special/virtual/static/interface 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * invocations of the code attributes that it visits. 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class MethodInvocationFixer 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoextends SimplifiedVisitor 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimplements AttributeVisitor, 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato InstructionVisitor, 42b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang ConstantVisitor 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private static final boolean DEBUG = false; 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Return values for the visitor methods. 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Clazz referencedClass; 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Clazz referencedMethodClass; 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Member referencedMethod; 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for AttributeVisitor. 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Reset the code attribute editor. 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor.reset(codeAttribute.u4codeLength); 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Remap the variables of the instructions. 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttribute.instructionsAccept(clazz, method, this); 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Apply the code atribute editor. 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for InstructionVisitor. 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int constantIndex = constantInstruction.constantIndex; 81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Get information on the called class and method, if present. 83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato referencedMethod = null; 84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz.constantPoolEntryAccept(constantIndex, this); 86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Did we find the called class and method? 88b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (referencedClass != null && 89b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang referencedMethod != null) 90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Do we need to update the opcode? 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato byte opcode = constantInstruction.opcode; 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Is the method static? 952270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom if ((referencedMethod.getAccessFlags() & ClassConstants.ACC_STATIC) != 0) 96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // But is it not a static invocation? 98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (opcode != InstructionConstants.OP_INVOKESTATIC) 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Replace the invocation by an invokestatic instruction. 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Instruction replacementInstruction = 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 103b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang constantIndex); 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor.replaceInstruction(offset, replacementInstruction); 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (DEBUG) 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato debug(clazz, method, offset, constantInstruction, replacementInstruction); 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Is the method private, or an instance initializer? 1152270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom else if ((referencedMethod.getAccessFlags() & ClassConstants.ACC_PRIVATE) != 0 || 1162270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom referencedMethod.getName(referencedMethodClass).equals(ClassConstants.METHOD_NAME_INIT)) 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // But is it not a special invocation? 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (opcode != InstructionConstants.OP_INVOKESPECIAL) 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Replace the invocation by an invokespecial instruction. 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Instruction replacementInstruction = 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, 124b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang constantIndex); 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor.replaceInstruction(offset, replacementInstruction); 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (DEBUG) 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato debug(clazz, method, offset, constantInstruction, replacementInstruction); 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Is the method an interface method? 1362270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom else if ((referencedClass.getAccessFlags() & ClassConstants.ACC_INTERFACE) != 0) 137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int invokeinterfaceConstant = 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (ClassUtil.internalMethodParameterSize(referencedMethod.getDescriptor(referencedMethodClass), false)) << 8; 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // But is it not an interface invocation, or is the parameter 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // size incorrect? 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (opcode != InstructionConstants.OP_INVOKEINTERFACE || 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato constantInstruction.constant != invokeinterfaceConstant) 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Fix the parameter size of the interface invocation. 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Instruction replacementInstruction = 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new ConstantInstruction(InstructionConstants.OP_INVOKEINTERFACE, 149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato constantIndex, 150b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang invokeinterfaceConstant); 151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor.replaceInstruction(offset, replacementInstruction); 153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (DEBUG) 155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato debug(clazz, method, offset, constantInstruction, replacementInstruction); 157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // The method is not static, private, an instance initializer, or 162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // an interface method. 163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // But is it not a virtual invocation (or a special invocation, 166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // but not a super call)? 167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (opcode != InstructionConstants.OP_INVOKEVIRTUAL && 168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (opcode != InstructionConstants.OP_INVOKESPECIAL || 169b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang clazz.equals(referencedClass) || 170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato !clazz.extends_(referencedClass))) 171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Replace the invocation by an invokevirtual instruction. 173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Instruction replacementInstruction = 174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 175b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang constantIndex); 176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato codeAttributeEditor.replaceInstruction(offset, replacementInstruction); 178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (DEBUG) 180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato debug(clazz, method, offset, constantInstruction, replacementInstruction); 182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for ConstantVisitor. 190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitAnyConstant(Clazz clazz, Constant constant) {} 192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) 195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 196b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Remember the referenced class. Note that we're interested in the 197b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // class of the method reference, not in the class in which the 198b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // method was actually found, unless it is an array type. 199b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // 200b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (ClassUtil.isInternalArrayType(refConstant.getClassName(clazz))) 201b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 202b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // For an array type, the class will be java.lang.Object. 203b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang referencedClass = refConstant.referencedClass; 204b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 205b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang else 206b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 207b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang clazz.constantPoolEntryAccept(refConstant.u2classIndex, this); 208b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 210b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang // Remember the referenced method. 211b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang referencedMethodClass = refConstant.referencedClass; 212b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang referencedMethod = refConstant.referencedMember; 2139f606f95f03a75961498803e24bee6799a7c0885Ying Wang } 2149f606f95f03a75961498803e24bee6799a7c0885Ying Wang 2159f606f95f03a75961498803e24bee6799a7c0885Ying Wang 216b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang public void visitClassConstant(Clazz clazz, ClassConstant classConstant) 2179f606f95f03a75961498803e24bee6799a7c0885Ying Wang { 218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Remember the referenced class. 219b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang referencedClass = classConstant.referencedClass; 220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Small utility methods. 224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void debug(Clazz clazz, 226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Method method, 227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int offset, 228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConstantInstruction constantInstruction, 229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Instruction replacementInstruction) 230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println("MethodInvocationFixer:"); 232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" Class = "+clazz.getName()); 233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" Method = "+method.getName(clazz)+method.getDescriptor(clazz)); 234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" Instruction = "+constantInstruction.toString(offset)); 235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" -> Class = "+referencedClass); 236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" Method = "+referencedMethod); 2372270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom if ((referencedClass.getAccessFlags() & ClassConstants.ACC_INTERFACE) != 0) 238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" Parameter size = "+(ClassUtil.internalMethodParameterSize(referencedMethod.getDescriptor(referencedMethodClass), false))); 240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato System.out.println(" Replacement instruction = "+replacementInstruction.toString(offset)); 242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 244