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