1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Licensed to the Apache Software Foundation (ASF) under one or more
7  * contributor license agreements.  See the NOTICE file distributed with
8  * this work for additional information regarding copyright ownership.
9  * The ASF licenses this file to You under the Apache License, Version 2.0
10  * (the "License"); you may not use this file except in compliance with
11  * the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 package com.sun.org.apache.bcel.internal.generic;
23 
24 import java.util.StringTokenizer;
25 
26 import com.sun.org.apache.bcel.internal.Const;
27 import com.sun.org.apache.bcel.internal.classfile.Constant;
28 import com.sun.org.apache.bcel.internal.classfile.ConstantCP;
29 import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
30 
31 /**
32  * Super class for the INVOKExxx family of instructions.
33  *
34  * @version $Id: InvokeInstruction.java 1752106 2016-07-10 20:02:39Z britter $
35  */
36 public abstract class InvokeInstruction extends FieldOrMethod implements ExceptionThrower,
37         StackConsumer, StackProducer {
38 
39     /**
40      * Empty constructor needed for the Class.newInstance() statement in
41      * Instruction.readInstruction(). Not to be used otherwise.
42      */
InvokeInstruction()43     InvokeInstruction() {
44     }
45 
46 
47     /**
48      * @param index to constant pool
49      */
InvokeInstruction(final short opcode, final int index)50     protected InvokeInstruction(final short opcode, final int index) {
51         super(opcode, index);
52     }
53 
54 
55     /**
56      * @return mnemonic for instruction with symbolic references resolved
57      */
58     @Override
toString( final ConstantPool cp )59     public String toString( final ConstantPool cp ) {
60         final Constant c = cp.getConstant(super.getIndex());
61         final StringTokenizer tok = new StringTokenizer(cp.constantToString(c));
62         return Const.getOpcodeName(super.getOpcode()) + " " + tok.nextToken().replace('.', '/')
63                 + tok.nextToken();
64     }
65 
66 
67     /**
68      * Also works for instructions whose stack effect depends on the
69      * constant pool entry they reference.
70      * @return Number of words consumed from stack by this instruction
71      */
72     @Override
consumeStack( final ConstantPoolGen cpg )73     public int consumeStack( final ConstantPoolGen cpg ) {
74         int sum;
75         if ((super.getOpcode() == Const.INVOKESTATIC) || (super.getOpcode() == Const.INVOKEDYNAMIC)) {
76             sum = 0;
77         } else {
78             sum = 1; // this reference
79         }
80 
81         final String signature = getSignature(cpg);
82         sum += Type.getArgumentTypesSize(signature);
83         return sum;
84     }
85 
86 
87     /**
88      * Also works for instructions whose stack effect depends on the
89      * constant pool entry they reference.
90      * @return Number of words produced onto stack by this instruction
91      */
92     @Override
produceStack( final ConstantPoolGen cpg )93     public int produceStack( final ConstantPoolGen cpg ) {
94         final String signature = getSignature(cpg);
95         return Type.getReturnTypeSize(signature);
96     }
97 
98     /**
99      * This overrides the deprecated version as we know here that the referenced class
100      * may legally be an array.
101      *
102      * @deprecated in FieldOrMethod
103      *
104      * @return name of the referenced class/interface
105      * @throws IllegalArgumentException if the referenced class is an array (this should not happen)
106      */
107     @Override
108     @Deprecated
getClassName( final ConstantPoolGen cpg )109     public String getClassName( final ConstantPoolGen cpg ) {
110         final ConstantPool cp = cpg.getConstantPool();
111         final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex());
112         final String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class);
113         return className.replace('/', '.');
114     }
115 
116     /** @return return type of referenced method.
117      */
118     @Override
getType( final ConstantPoolGen cpg )119     public Type getType( final ConstantPoolGen cpg ) {
120         return getReturnType(cpg);
121     }
122 
123 
124     /** @return name of referenced method.
125      */
getMethodName( final ConstantPoolGen cpg )126     public String getMethodName( final ConstantPoolGen cpg ) {
127         return getName(cpg);
128     }
129 
130 
131     /** @return return type of referenced method.
132      */
getReturnType( final ConstantPoolGen cpg )133     public Type getReturnType( final ConstantPoolGen cpg ) {
134         return Type.getReturnType(getSignature(cpg));
135     }
136 
137 
138     /** @return argument types of referenced method.
139      */
getArgumentTypes( final ConstantPoolGen cpg )140     public Type[] getArgumentTypes( final ConstantPoolGen cpg ) {
141         return Type.getArgumentTypes(getSignature(cpg));
142     }
143 
144 }
145