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