001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.bcel.generic; 018 019import java.io.DataOutputStream; 020import java.io.IOException; 021 022import org.apache.bcel.util.ByteSequence; 023 024/** 025 * RET - Return from subroutine 026 * 027 * <PRE> 028 * Stack: ... -> ... 029 * </PRE> 030 */ 031public class RET extends Instruction implements IndexedInstruction, TypedInstruction { 032 033 private boolean wide; 034 private int index; // index to local variable containg the return address 035 036 /** 037 * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. 038 */ 039 RET() { 040 } 041 042 public RET(final int index) { 043 super(org.apache.bcel.Const.RET, (short) 2); 044 setIndex(index); // May set wide as side effect 045 } 046 047 /** 048 * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call 049 * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. 050 * 051 * @param v Visitor object 052 */ 053 @Override 054 public void accept(final Visitor v) { 055 v.visitRET(this); 056 } 057 058 /** 059 * Dump instruction as byte code to stream out. 060 * 061 * @param out Output stream 062 */ 063 @Override 064 public void dump(final DataOutputStream out) throws IOException { 065 if (wide) { 066 out.writeByte(org.apache.bcel.Const.WIDE); 067 } 068 out.writeByte(super.getOpcode()); 069 if (wide) { 070 out.writeShort(index); 071 } else { 072 out.writeByte(index); 073 } 074 } 075 076 /** 077 * @return index of local variable containg the return address 078 */ 079 @Override 080 public final int getIndex() { 081 return index; 082 } 083 084 /** 085 * @return return address type 086 */ 087 @Override 088 public Type getType(final ConstantPoolGen cp) { 089 return ReturnaddressType.NO_TARGET; 090 } 091 092 /** 093 * Read needed data (e.g. index) from file. 094 */ 095 @Override 096 protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { 097 this.wide = wide; 098 if (wide) { 099 index = bytes.readUnsignedShort(); 100 super.setLength(4); 101 } else { 102 index = bytes.readUnsignedByte(); 103 super.setLength(2); 104 } 105 } 106 107 /** 108 * Sets index of local variable containg the return address 109 */ 110 @Override 111 public final void setIndex(final int n) { 112 if (n < 0) { 113 throw new ClassGenException("Negative index value: " + n); 114 } 115 index = n; 116 setWide(); 117 } 118 119 private void setWide() { 120 wide = index > org.apache.bcel.Const.MAX_BYTE; 121 if (wide) { 122 super.setLength(4); // Including the wide byte 123 } else { 124 super.setLength(2); 125 } 126 } 127 128 /** 129 * @return mnemonic for instruction 130 */ 131 @Override 132 public String toString(final boolean verbose) { 133 return super.toString(verbose) + " " + index; 134 } 135}