1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
5b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Copyright (c) 2002-2009 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:
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                isStatic = true;
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                break;
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            case InstructionConstants.OP_INVOKEVIRTUAL:
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            case InstructionConstants.OP_INVOKESPECIAL:
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            case InstructionConstants.OP_INVOKEINTERFACE:
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                isStatic = false;
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                break;
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Pop the parameters and push the return value.
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.stack = stack;
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        clazz.constantPoolEntryAccept(constantIndex, this);
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.stack = null;
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for ConstantVisitor.
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Pop the field value, if applicable.
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (!isLoad)
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            setFieldValue(clazz, fieldrefConstant, stack.pop());
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Pop the reference value, if applicable.
193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (!isStatic)
194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            setFieldClassValue(clazz, fieldrefConstant, stack.apop());
196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Push the field value, if applicable.
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (isLoad)
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            String type = fieldrefConstant.getType(clazz);
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            stack.push(getFieldValue(clazz, fieldrefConstant, type));
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyMethodrefConstant(Clazz clazz, RefConstant methodrefConstant)
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String type = methodrefConstant.getType(clazz);
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Count the number of parameters.
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int parameterCount = ClassUtil.internalMethodParameterCount(type);
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (!isStatic)
215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            parameterCount++;
217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Pop the parameters and the class reference, in reverse order.
220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int parameterIndex = parameterCount-1; parameterIndex >= 0; parameterIndex--)
221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            setMethodParameterValue(clazz, methodrefConstant, parameterIndex, stack.pop());
223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Push the return value, if applicable.
226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String returnType = ClassUtil.internalMethodReturnType(type);
227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (returnType.charAt(0) != ClassConstants.INTERNAL_TYPE_VOID)
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            stack.push(getMethodReturnValue(clazz, methodrefConstant, returnType));
230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sets the class through which the specified field is accessed.
236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void setFieldClassValue(Clazz          clazz,
238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                      RefConstant    refConstant,
239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                      ReferenceValue value)
240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // We don't care about the new value.
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the class though which the specified field is accessed.
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected Value getFieldClassValue(Clazz       clazz,
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                       RefConstant refConstant,
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                       String      type)
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Try to figure out the class of the return type.
253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        returnTypeClass = null;
254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        refConstant.referencedMemberAccept(this);
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return valueFactory.createValue(type,
257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        returnTypeClass,
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        true);
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sets the value of the specified field.
264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void setFieldValue(Clazz       clazz,
266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                 RefConstant refConstant,
267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                 Value       value)
268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // We don't care about the new field value.
270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the value of the specified field.
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected Value getFieldValue(Clazz       clazz,
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                  RefConstant refConstant,
278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                  String      type)
279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Try to figure out the class of the return type.
281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        returnTypeClass = null;
282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        refConstant.referencedMemberAccept(this);
283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return valueFactory.createValue(type,
285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        returnTypeClass,
286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        true);
287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sets the value of the specified method parameter.
292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void setMethodParameterValue(Clazz       clazz,
294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           RefConstant refConstant,
295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           int         parameterIndex,
296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                           Value       value)
297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // We don't care about the parameter value.
299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the value of the specified method parameter.
304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected Value getMethodParameterValue(Clazz  clazz,
306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            Method method,
307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            int    parameterIndex,
308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            String type,
309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            Clazz  referencedClass)
310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return valueFactory.createValue(type, referencedClass, true);
312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sets the return value of the specified method.
317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void setMethodReturnValue(Clazz  clazz,
319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        Method method,
320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        Value  value)
321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // We don't care about the return value.
323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the return value of the specified method.
328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected Value getMethodReturnValue(Clazz       clazz,
330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                         RefConstant refConstant,
331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                         String      type)
332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Try to figure out the class of the return type.
334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        returnTypeClass = null;
335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        refConstant.referencedMemberAccept(this);
336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return valueFactory.createValue(type,
338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        returnTypeClass,
339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        true);
340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
342b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for MemberVisitor.
344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramField(ProgramClass programClass, ProgramField programField)
346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        returnTypeClass = programField.referencedClass;
348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
349b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
350b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
351b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
352b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
353b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz[] referencedClasses = programMethod.referencedClasses;
354b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (referencedClasses != null)
355b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
356b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            returnTypeClass = referencedClasses[referencedClasses.length - 1];
357b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
358b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
359b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
360b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
361b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLibraryField(LibraryClass programClass, LibraryField programField)
362b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
363b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        returnTypeClass = programField.referencedClass;
364b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
365b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
366b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
367b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLibraryMethod(LibraryClass programClass, LibraryMethod programMethod)
368b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
369b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz[] referencedClasses = programMethod.referencedClasses;
370b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (referencedClasses != null)
371b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
372b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            returnTypeClass = referencedClasses[referencedClasses.length - 1];
373b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
374b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
375b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
376b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
377b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato//    public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember)
378b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato//    {
379b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato//    }
380b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
381