RET.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.util.ByteSequence;

  21. /**
  22.  * RET - Return from subroutine
  23.  *
  24.  * <PRE>
  25.  * Stack: ... -&gt; ...
  26.  * </PRE>
  27.  */
  28. public class RET extends Instruction implements IndexedInstruction, TypedInstruction {

  29.     private boolean wide;
  30.     private int index; // index to local variable containg the return address

  31.     /**
  32.      * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise.
  33.      */
  34.     RET() {
  35.     }

  36.     public RET(final int index) {
  37.         super(org.apache.bcel.Const.RET, (short) 2);
  38.         setIndex(index); // May set wide as side effect
  39.     }

  40.     /**
  41.      * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call
  42.      * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last.
  43.      *
  44.      * @param v Visitor object
  45.      */
  46.     @Override
  47.     public void accept(final Visitor v) {
  48.         v.visitRET(this);
  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.         if (wide) {
  58.             out.writeByte(org.apache.bcel.Const.WIDE);
  59.         }
  60.         out.writeByte(super.getOpcode());
  61.         if (wide) {
  62.             out.writeShort(index);
  63.         } else {
  64.             out.writeByte(index);
  65.         }
  66.     }

  67.     /**
  68.      * @return index of local variable containg the return address
  69.      */
  70.     @Override
  71.     public final int getIndex() {
  72.         return index;
  73.     }

  74.     /**
  75.      * @return return address type
  76.      */
  77.     @Override
  78.     public Type getType(final ConstantPoolGen cp) {
  79.         return ReturnaddressType.NO_TARGET;
  80.     }

  81.     /**
  82.      * Read needed data (e.g. index) from file.
  83.      */
  84.     @Override
  85.     protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
  86.         this.wide = wide;
  87.         if (wide) {
  88.             index = bytes.readUnsignedShort();
  89.             super.setLength(4);
  90.         } else {
  91.             index = bytes.readUnsignedByte();
  92.             super.setLength(2);
  93.         }
  94.     }

  95.     /**
  96.      * Sets index of local variable containg the return address
  97.      */
  98.     @Override
  99.     public final void setIndex(final int n) {
  100.         if (n < 0) {
  101.             throw new ClassGenException("Negative index value: " + n);
  102.         }
  103.         index = n;
  104.         setWide();
  105.     }

  106.     private void setWide() {
  107.         wide = index > org.apache.bcel.Const.MAX_BYTE;
  108.         if (wide) {
  109.             super.setLength(4); // Including the wide byte
  110.         } else {
  111.             super.setLength(2);
  112.         }
  113.     }

  114.     /**
  115.      * @return mnemonic for instruction
  116.      */
  117.     @Override
  118.     public String toString(final boolean verbose) {
  119.         return super.toString(verbose) + " " + index;
  120.     }
  121. }