1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 package org.apache.bcel.generic; 19 20 import java.io.DataOutputStream; 21 import java.io.IOException; 22 23 import org.apache.bcel.classfile.Constant; 24 import org.apache.bcel.classfile.ConstantClass; 25 import org.apache.bcel.classfile.ConstantPool; 26 import org.apache.bcel.util.ByteSequence; 27 28 /** 29 * Abstract super class for instructions that use an index into the 30 * constant pool such as LDC, INVOKEVIRTUAL, etc. 31 * 32 * @see ConstantPoolGen 33 * @see LDC 34 * @see INVOKEVIRTUAL 35 * 36 * @version $Id$ 37 */ 38 public abstract class CPInstruction extends Instruction implements TypedInstruction, 39 IndexedInstruction { 40 41 /** 42 * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter 43 */ 44 @Deprecated 45 protected int index; // index to constant pool 46 47 48 /** 49 * Empty constructor needed for Instruction.readInstruction. 50 * Not to be used otherwise. 51 */ 52 CPInstruction() { 53 } 54 55 56 /** 57 * @param index to constant pool 58 */ 59 protected CPInstruction(final short opcode, final int index) { 60 super(opcode, (short) 3); 61 setIndex(index); 62 } 63 64 65 /** 66 * Dump instruction as byte code to stream out. 67 * @param out Output stream 68 */ 69 @Override 70 public void dump( final DataOutputStream out ) throws IOException { 71 out.writeByte(super.getOpcode()); 72 out.writeShort(index); 73 } 74 75 76 /** 77 * Long output format: 78 * 79 * <name of opcode> "["<opcode number>"]" 80 * "("<length of instruction>")" "<"< constant pool index>">" 81 * 82 * @param verbose long/short format switch 83 * @return mnemonic for instruction 84 */ 85 @Override 86 public String toString( final boolean verbose ) { 87 return super.toString(verbose) + " " + index; 88 } 89 90 91 /** 92 * @return mnemonic for instruction with symbolic references resolved 93 */ 94 @Override 95 public String toString( final ConstantPool cp ) { 96 final Constant c = cp.getConstant(index); 97 String str = cp.constantToString(c); 98 if (c instanceof ConstantClass) { 99 str = str.replace('.', '/'); 100 } 101 return org.apache.bcel.Const.getOpcodeName(super.getOpcode()) + " " + str; 102 } 103 104 105 /** 106 * Read needed data (i.e., index) from file. 107 * @param bytes input stream 108 * @param wide wide prefix? 109 */ 110 @Override 111 protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { 112 setIndex(bytes.readUnsignedShort()); 113 super.setLength(3); 114 } 115 116 117 /** 118 * @return index in constant pool referred by this instruction. 119 */ 120 @Override 121 public final int getIndex() { 122 return index; 123 } 124 125 126 /** 127 * Set the index to constant pool. 128 * @param index in constant pool. 129 */ 130 @Override 131 public void setIndex( final int index ) { // TODO could be package-protected? 132 if (index < 0) { 133 throw new ClassGenException("Negative index value: " + index); 134 } 135 this.index = index; 136 } 137 138 139 /** @return type related with this instruction. 140 */ 141 @Override 142 public Type getType( final ConstantPoolGen cpg ) { 143 final ConstantPool cp = cpg.getConstantPool(); 144 String name = cp.getConstantString(index, org.apache.bcel.Const.CONSTANT_Class); 145 if (!name.startsWith("[")) { 146 name = "L" + name + ";"; 147 } 148 return Type.getType(name); 149 } 150 } 151