1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.generic;
18
19 import java.util.StringTokenizer;
20 import org.apache.bcel.Constants;
21 import org.apache.bcel.classfile.Constant;
22 import org.apache.bcel.classfile.ConstantPool;
23
24 /***
25 * Super class for the INVOKExxx family of instructions.
26 *
27 * @version $Id: InvokeInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
28 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
29 */
30 public abstract class InvokeInstruction extends FieldOrMethod implements ExceptionThrower,
31 TypedInstruction, StackConsumer, StackProducer {
32
33 /***
34 * Empty constructor needed for the Class.newInstance() statement in
35 * Instruction.readInstruction(). Not to be used otherwise.
36 */
37 InvokeInstruction() {
38 }
39
40
41 /***
42 * @param index to constant pool
43 */
44 protected InvokeInstruction(short opcode, int index) {
45 super(opcode, index);
46 }
47
48
49 /***
50 * @return mnemonic for instruction with symbolic references resolved
51 */
52 public String toString( ConstantPool cp ) {
53 Constant c = cp.getConstant(index);
54 StringTokenizer tok = new StringTokenizer(cp.constantToString(c));
55 return Constants.OPCODE_NAMES[opcode] + " " + tok.nextToken().replace('.', '/')
56 + tok.nextToken();
57 }
58
59
60 /***
61 * Also works for instructions whose stack effect depends on the
62 * constant pool entry they reference.
63 * @return Number of words consumed from stack by this instruction
64 */
65 public int consumeStack( ConstantPoolGen cpg ) {
66 String signature = getSignature(cpg);
67 Type[] args = Type.getArgumentTypes(signature);
68 int sum;
69 if (opcode == Constants.INVOKESTATIC) {
70 sum = 0;
71 } else {
72 sum = 1;
73 }
74 int n = args.length;
75 for (int i = 0; i < n; i++) {
76 sum += args[i].getSize();
77 }
78 return sum;
79 }
80
81
82 /***
83 * Also works for instructions whose stack effect depends on the
84 * constant pool entry they reference.
85 * @return Number of words produced onto stack by this instruction
86 */
87 public int produceStack( ConstantPoolGen cpg ) {
88 return getReturnType(cpg).getSize();
89 }
90
91
92 /*** @return return type of referenced method.
93 */
94 public Type getType( ConstantPoolGen cpg ) {
95 return getReturnType(cpg);
96 }
97
98
99 /*** @return name of referenced method.
100 */
101 public String getMethodName( ConstantPoolGen cpg ) {
102 return getName(cpg);
103 }
104
105
106 /*** @return return type of referenced method.
107 */
108 public Type getReturnType( ConstantPoolGen cpg ) {
109 return Type.getReturnType(getSignature(cpg));
110 }
111
112
113 /*** @return argument types of referenced method.
114 */
115 public Type[] getArgumentTypes( ConstantPoolGen cpg ) {
116 return Type.getArgumentTypes(getSignature(cpg));
117 }
118 }