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.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 =
712270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            (method.getAccessFlags() & ClassConstants.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);
2282270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        if (returnType.charAt(0) != ClassConstants.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);
2532270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        if (returnType.charAt(0) != ClassConstants.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}
421