CPInstruction.java

  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. package org.apache.bcel.generic;

  18. import java.io.DataOutputStream;
  19. import java.io.IOException;

  20. import org.apache.bcel.classfile.Constant;
  21. import org.apache.bcel.classfile.ConstantClass;
  22. import org.apache.bcel.classfile.ConstantPool;
  23. import org.apache.bcel.classfile.Utility;
  24. import org.apache.bcel.util.ByteSequence;

  25. /**
  26.  * Abstract super class for instructions that use an index into the constant pool such as LDC, INVOKEVIRTUAL, etc.
  27.  *
  28.  * @see ConstantPoolGen
  29.  * @see LDC
  30.  * @see INVOKEVIRTUAL
  31.  */
  32. public abstract class CPInstruction extends Instruction implements TypedInstruction, IndexedInstruction {

  33.     /**
  34.      * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
  35.      */
  36.     @Deprecated
  37.     protected int index; // index to constant pool

  38.     /**
  39.      * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise.
  40.      */
  41.     CPInstruction() {
  42.     }

  43.     /**
  44.      * @param index to constant pool
  45.      */
  46.     protected CPInstruction(final short opcode, final int index) {
  47.         super(opcode, (short) 3);
  48.         setIndex(index);
  49.     }

  50.     /**
  51.      * Dump instruction as byte code to stream out.
  52.      *
  53.      * @param out Output stream
  54.      */
  55.     @Override
  56.     public void dump(final DataOutputStream out) throws IOException {
  57.         out.writeByte(super.getOpcode());
  58.         out.writeShort(index);
  59.     }

  60.     /**
  61.      * @return index in constant pool referred by this instruction.
  62.      */
  63.     @Override
  64.     public final int getIndex() {
  65.         return index;
  66.     }

  67.     /**
  68.      * @return type related with this instruction.
  69.      */
  70.     @Override
  71.     public Type getType(final ConstantPoolGen cpg) {
  72.         final ConstantPool cp = cpg.getConstantPool();
  73.         String name = cp.getConstantString(index, org.apache.bcel.Const.CONSTANT_Class);
  74.         if (!name.startsWith("[")) {
  75.             name = "L" + name + ";";
  76.         }
  77.         return Type.getType(name);
  78.     }

  79.     /**
  80.      * Read needed data (i.e., index) from file.
  81.      *
  82.      * @param bytes input stream
  83.      * @param wide wide prefix?
  84.      */
  85.     @Override
  86.     protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
  87.         setIndex(bytes.readUnsignedShort());
  88.         super.setLength(3);
  89.     }

  90.     /**
  91.      * Sets the index to constant pool.
  92.      *
  93.      * @param index in constant pool.
  94.      */
  95.     @Override
  96.     public void setIndex(final int index) { // TODO could be package-protected?
  97.         if (index < 0) {
  98.             throw new ClassGenException("Negative index value: " + index);
  99.         }
  100.         this.index = index;
  101.     }

  102.     /**
  103.      * Long output format:
  104.      *
  105.      * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" "("&lt;length of instruction&gt;")" "&lt;"&lt; constant pool
  106.      * index&gt;"&gt;"
  107.      *
  108.      * @param verbose long/short format switch
  109.      * @return mnemonic for instruction
  110.      */
  111.     @Override
  112.     public String toString(final boolean verbose) {
  113.         return super.toString(verbose) + " " + index;
  114.     }

  115.     /**
  116.      * @return mnemonic for instruction with symbolic references resolved
  117.      */
  118.     @Override
  119.     public String toString(final ConstantPool cp) {
  120.         final Constant c = cp.getConstant(index);
  121.         String str = cp.constantToString(c);
  122.         if (c instanceof ConstantClass) {
  123.             str = Utility.packageToPath(str);
  124.         }
  125.         return org.apache.bcel.Const.getOpcodeName(super.getOpcode()) + " " + str;
  126.     }
  127. }