1 /*
2  * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 package sun.jvm.hotspot.interpreter;
26 
27 import sun.jvm.hotspot.oops.*;
28 import sun.jvm.hotspot.runtime.*;
29 import sun.jvm.hotspot.utilities.*;
30 
31 public class BytecodeInvoke extends BytecodeWithCPIndex {
BytecodeInvoke(Method method, int bci)32   BytecodeInvoke(Method method, int bci) {
33     super(method, bci);
34   }
35 
at(Method method, int bci)36   public static BytecodeInvoke at(Method method, int bci) {
37     BytecodeInvoke b = new BytecodeInvoke(method, bci);
38     if (Assert.ASSERTS_ENABLED) {
39       b.verify();
40     }
41     return b;
42   }
43 
44   /** Like at, but returns null if the BCI is not at an invoke */
atCheck(Method method, int bci)45   public static BytecodeInvoke atCheck(Method method, int bci) {
46     BytecodeInvoke b = new BytecodeInvoke(method, bci);
47     return (b.isValid() ? b : null);
48   }
49 
at(BytecodeStream bcs)50   public static BytecodeInvoke at(BytecodeStream bcs) {
51     return new BytecodeInvoke(bcs.method(), bcs.bci());
52   }
53 
54   // returns the name of the invoked method
name()55   public Symbol name() {
56     ConstantPool cp = method().getConstants();
57     if (isInvokedynamic()) {
58       return cp.uncachedGetNameRefAt(indexForFieldOrMethod());
59     }
60     return cp.getNameRefAt(index());
61   }
62 
63   // returns the signature of the invoked method
signature()64   public Symbol signature() {
65     ConstantPool cp = method().getConstants();
66     if (isInvokedynamic()) {
67       return cp.uncachedGetSignatureRefAt(indexForFieldOrMethod());
68     }
69     return cp.getSignatureRefAt(index());
70   }
71 
getInvokedMethod()72   public Method getInvokedMethod() {
73     return method().getConstants().getMethodRefAt(index());
74   }
75 
76   // returns the result type (see BasicType.java) of the invoke
resultType()77   public int resultType() {
78     ResultTypeFinder rts = new ResultTypeFinder(signature());
79     rts.iterate();
80     return rts.type();
81   }
82 
adjustedInvokeCode()83   public int adjustedInvokeCode() {
84     return javaCode();
85   }
86 
87   // "specified" method   (from constant pool)
88   // FIXME: elided for now
89   // public Method staticTarget();
90 
91   // Testers
isInvokeinterface()92   public boolean isInvokeinterface() { return adjustedInvokeCode() == Bytecodes._invokeinterface; }
isInvokevirtual()93   public boolean isInvokevirtual()   { return adjustedInvokeCode() == Bytecodes._invokevirtual;   }
isInvokestatic()94   public boolean isInvokestatic()    { return adjustedInvokeCode() == Bytecodes._invokestatic;    }
isInvokespecial()95   public boolean isInvokespecial()   { return adjustedInvokeCode() == Bytecodes._invokespecial;   }
isInvokedynamic()96   public boolean isInvokedynamic()   { return adjustedInvokeCode() == Bytecodes._invokedynamic; }
97 
isValid()98   public boolean isValid()           { return isInvokeinterface() ||
99                                               isInvokevirtual()   ||
100                                               isInvokestatic()    ||
101                                               isInvokespecial(); }
verify()102   public void verify() {
103     if (Assert.ASSERTS_ENABLED) {
104       Assert.that(isValid(), "check invoke");
105     }
106   }
107 
toString()108   public String toString() {
109     StringBuffer buf = new StringBuffer();
110     buf.append(getJavaBytecodeName());
111     buf.append(spaces);
112     buf.append('#');
113     buf.append(Integer.toString(indexForFieldOrMethod()));
114     if (isInvokedynamic()) {
115       ConstantPool cp = method.getConstants();
116       buf.append('(');
117       int poolIndex = cp.invokeDynamicNameAndTypeRefIndexAt(indexForFieldOrMethod());
118       buf.append(Integer.toString(poolIndex));
119       buf.append(')');
120       buf.append(" [Name and Type ");
121       buf.append(name().asString());
122       buf.append(":");
123       buf.append(signature().asString().replace('/', '.'));
124     } else {
125       buf.append(" [Method ");
126       StringBuffer sigBuf = new StringBuffer();
127       new SignatureConverter(signature(), sigBuf).iterateReturntype();
128       buf.append(sigBuf.toString().replace('/', '.'));
129       buf.append(spaces);
130       buf.append(name().asString());
131       buf.append('(');
132       sigBuf = new StringBuffer();
133       new SignatureConverter(signature(), sigBuf).iterateParameters();
134       buf.append(sigBuf.toString().replace('/', '.'));
135       buf.append(')');
136     }
137     buf.append(']');
138     if (code() != javaCode()) {
139        buf.append(spaces);
140        buf.append('[');
141        buf.append(getBytecodeName());
142        buf.append(']');
143     }
144     return buf.toString();
145   }
146 }
147