/*
* Copyright(C) 2001 Mika Riekkinen, Joni Suominen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or(at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package alt.jiapi.reflect.instruction;
import alt.jiapi.reflect.SignatureUtil;
import alt.jiapi.reflect.Signature;
import alt.jiapi.file.ConstantPool;
/**
* This class represents a method invocation instruction.
*
* @author Mika Riekkinen
* @author Joni Suominen
* @version $Revision: 1.16 $ $Date: 2004/04/11 14:22:58 $
*/
public class Invocation extends ReferencingInstruction {
public Invocation(byte[] bytes, ConstantPool cp) {
super(bytes, cp);
}
/**
* Get the name of the target method.
*/
public String getMethodName() {
return super.getName();
}
/**
* Gets the return type.
*/
public String getReturnType() {
Signature s = new Signature(getDescriptor());
return s.getReturnType();
}
/**
* Gets names of each parameter types.
*/
public String[] getParameterTypes() {
Signature s = new Signature(getDescriptor());
return s.getParameters();
}
/**
* Get the stack consumption of this Invocation.
*
* @return Stack consumption
*/
public short stackConsumption() {
short consumption = 0;//(short)getParameterTypes().length;
String[] paramTypes = getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if ("long".equals(paramTypes[i]) ||
"double".equals(paramTypes[i])) {
consumption += 2;
}
else {
consumption++;
}
}
if (getOpcode() != Opcodes.INVOKESTATIC) {
consumption++; // 'this' parameter
}
return consumption;
}
/**
* Count stack usage of this invocation.
*/
public short stackUsage() {
int usage = 0;
String[] paramTypes = getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if ("long".equals(paramTypes[i]) ||
"double".equals(paramTypes[i])) {
usage -= 2;
}
else {
usage--;
}
}
// short usage = (short)-getParameterTypes().length;
if (getOpcode() != Opcodes.INVOKESTATIC) {
usage--; // 'this' parameter
}
if (!"void".equals(getReturnType())) {
usage++;
}
if ("long".equals(getReturnType()) ||
"double".equals(getReturnType())) {
usage++;
}
return (short)usage;
}
public String toString() {
StringBuffer sb =
new StringBuffer(Opcodes.opcodeStrings[0xff & getOpcode()]);
byte[] bytes = getBytes();
for (int i = 1; i < bytes.length; i++) {
sb.append(" ");
sb.append(0xff & bytes[i]);
}
sb.append(" ; ");
sb.append(getClassName());
sb.append(".");
sb.append(getMethodName());
sb.append(getDescriptor());
return sb.toString();
}
}