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