001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.bcel.generic; 020 021import java.io.DataOutputStream; 022import java.io.IOException; 023 024import org.apache.bcel.classfile.Constant; 025import org.apache.bcel.classfile.ConstantClass; 026import org.apache.bcel.classfile.ConstantPool; 027import org.apache.bcel.classfile.Utility; 028import org.apache.bcel.util.ByteSequence; 029 030/** 031 * Abstract super class for instructions that use an index into the constant pool such as LDC, INVOKEVIRTUAL, etc. 032 * 033 * @see ConstantPoolGen 034 * @see LDC 035 * @see INVOKEVIRTUAL 036 */ 037public abstract class CPInstruction extends Instruction implements TypedInstruction, IndexedInstruction { 038 039 /** 040 * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter 041 */ 042 @Deprecated 043 protected int index; // index to constant pool 044 045 /** 046 * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. 047 */ 048 CPInstruction() { 049 } 050 051 /** 052 * @param index to constant pool 053 */ 054 protected CPInstruction(final short opcode, final int index) { 055 super(opcode, (short) 3); 056 setIndex(index); 057 } 058 059 /** 060 * Dump instruction as byte code to stream out. 061 * 062 * @param out Output stream 063 */ 064 @Override 065 public void dump(final DataOutputStream out) throws IOException { 066 out.writeByte(super.getOpcode()); 067 out.writeShort(index); 068 } 069 070 /** 071 * @return index in constant pool referred by this instruction. 072 */ 073 @Override 074 public final int getIndex() { 075 return index; 076 } 077 078 /** 079 * @return type related with this instruction. 080 */ 081 @Override 082 public Type getType(final ConstantPoolGen cpg) { 083 final ConstantPool cp = cpg.getConstantPool(); 084 String name = cp.getConstantString(index, org.apache.bcel.Const.CONSTANT_Class); 085 if (!name.startsWith("[")) { 086 name = "L" + name + ";"; 087 } 088 return Type.getType(name); 089 } 090 091 /** 092 * Reads needed data (i.e., index) from file. 093 * 094 * @param bytes input stream 095 * @param wide wide prefix? 096 */ 097 @Override 098 protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { 099 setIndex(bytes.readUnsignedShort()); 100 super.setLength(3); 101 } 102 103 /** 104 * Sets the index to constant pool. 105 * 106 * @param index in constant pool. 107 */ 108 @Override 109 public void setIndex(final int index) { // TODO could be package-protected? 110 if (index < 0) { 111 throw new ClassGenException("Negative index value: " + index); 112 } 113 this.index = index; 114 } 115 116 /** 117 * Long output format: 118 * 119 * <name of opcode> "["<opcode number>"]" "("<length of instruction>")" "<"< constant pool 120 * index>">" 121 * 122 * @param verbose long/short format switch 123 * @return mnemonic for instruction 124 */ 125 @Override 126 public String toString(final boolean verbose) { 127 return super.toString(verbose) + " " + index; 128 } 129 130 /** 131 * @return mnemonic for instruction with symbolic references resolved 132 */ 133 @Override 134 public String toString(final ConstantPool cp) { 135 final Constant c = cp.getConstant(index); 136 String str = cp.constantToString(c); 137 if (c instanceof ConstantClass) { 138 str = Utility.packageToPath(str); 139 } 140 return org.apache.bcel.Const.getOpcodeName(super.getOpcode()) + " " + str; 141 } 142}