BytecodeInvoke.java revision 12278:8c2f220c759c
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
25package sun.jvm.hotspot.interpreter;
26
27import sun.jvm.hotspot.oops.*;
28import sun.jvm.hotspot.runtime.*;
29import sun.jvm.hotspot.utilities.*;
30
31public class BytecodeInvoke extends BytecodeWithCPIndex {
32  BytecodeInvoke(Method method, int bci) {
33    super(method, bci);
34  }
35
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 */
45  public static BytecodeInvoke atCheck(Method method, int bci) {
46    BytecodeInvoke b = new BytecodeInvoke(method, bci);
47    return (b.isValid() ? b : null);
48  }
49
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
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
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
72  public Method getInvokedMethod() {
73    return method().getConstants().getMethodRefAt(index());
74  }
75
76  // returns the result type (see BasicType.java) of the invoke
77  public int resultType() {
78    ResultTypeFinder rts = new ResultTypeFinder(signature());
79    rts.iterate();
80    return rts.type();
81  }
82
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
92  public boolean isInvokeinterface() { return adjustedInvokeCode() == Bytecodes._invokeinterface; }
93  public boolean isInvokevirtual()   { return adjustedInvokeCode() == Bytecodes._invokevirtual;   }
94  public boolean isInvokestatic()    { return adjustedInvokeCode() == Bytecodes._invokestatic;    }
95  public boolean isInvokespecial()   { return adjustedInvokeCode() == Bytecodes._invokespecial;   }
96  public boolean isInvokedynamic()   { return adjustedInvokeCode() == Bytecodes._invokedynamic; }
97
98  public boolean isValid()           { return isInvokeinterface() ||
99                                              isInvokevirtual()   ||
100                                              isInvokestatic()    ||
101                                              isInvokespecial(); }
102  public void verify() {
103    if (Assert.ASSERTS_ENABLED) {
104      Assert.that(isValid(), "check invoke");
105    }
106  }
107
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