View Javadoc
1   /*
2    * Copyright (c) 2001, 2012, 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 {
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        buf.append('(');
116       buf.append(Integer.toString(index()));
117        buf.append(')');
118     }
119     buf.append(" [Method ");
120     StringBuffer sigBuf = new StringBuffer();
121     new SignatureConverter(signature(), sigBuf).iterateReturntype();
122     buf.append(sigBuf.toString().replace('/', '.'));
123     buf.append(spaces);
124     buf.append(name().asString());
125     buf.append('(');
126     sigBuf = new StringBuffer();
127     new SignatureConverter(signature(), sigBuf).iterateParameters();
128     buf.append(sigBuf.toString().replace('/', '.'));
129     buf.append(')');
130     buf.append(']');
131     if (code() != javaCode()) {
132        buf.append(spaces);
133        buf.append('[');
134        buf.append(getBytecodeName());
135        buf.append(']');
136     }
137     return buf.toString();
138   }
139 }