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 * 017 */ 018package org.apache.bcel.generic; 019 020import java.io.DataOutputStream; 021import java.io.IOException; 022 023import org.apache.bcel.util.ByteSequence; 024 025/** 026 * RET - Return from subroutine 027 * 028 * <PRE>Stack: ... -> ...</PRE> 029 * 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 /** 038 * Empty constructor needed for Instruction.readInstruction. 039 * Not to be used otherwise. 040 */ 041 RET() { 042 } 043 044 045 public RET(final int index) { 046 super(org.apache.bcel.Const.RET, (short) 2); 047 setIndex(index); // May set wide as side effect 048 } 049 050 051 /** 052 * Dump instruction as byte code to stream out. 053 * @param out Output stream 054 */ 055 @Override 056 public void dump( final DataOutputStream out ) throws IOException { 057 if (wide) { 058 out.writeByte(org.apache.bcel.Const.WIDE); 059 } 060 out.writeByte(super.getOpcode()); 061 if (wide) { 062 out.writeShort(index); 063 } else { 064 out.writeByte(index); 065 } 066 } 067 068 069 private void setWide() { 070 wide = index > org.apache.bcel.Const.MAX_BYTE; 071 if (wide) { 072 super.setLength(4); // Including the wide byte 073 } else { 074 super.setLength(2); 075 } 076 } 077 078 079 /** 080 * Read needed data (e.g. index) from file. 081 */ 082 @Override 083 protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { 084 this.wide = wide; 085 if (wide) { 086 index = bytes.readUnsignedShort(); 087 super.setLength(4); 088 } else { 089 index = bytes.readUnsignedByte(); 090 super.setLength(2); 091 } 092 } 093 094 095 /** 096 * @return index of local variable containg the return address 097 */ 098 @Override 099 public final int getIndex() { 100 return index; 101 } 102 103 104 /** 105 * Set index of local variable containg the return address 106 */ 107 @Override 108 public final void setIndex( final int n ) { 109 if (n < 0) { 110 throw new ClassGenException("Negative index value: " + n); 111 } 112 index = n; 113 setWide(); 114 } 115 116 117 /** 118 * @return mnemonic for instruction 119 */ 120 @Override 121 public String toString( final boolean verbose ) { 122 return super.toString(verbose) + " " + index; 123 } 124 125 126 /** @return return address type 127 */ 128 @Override 129 public Type getType( final ConstantPoolGen cp ) { 130 return ReturnaddressType.NO_TARGET; 131 } 132 133 134 /** 135 * Call corresponding visitor method(s). The order is: 136 * Call visitor methods of implemented interfaces first, then 137 * call methods according to the class hierarchy in descending order, 138 * i.e., the most specific visitXXX() call comes last. 139 * 140 * @param v Visitor object 141 */ 142 @Override 143 public void accept( final Visitor v ) { 144 v.visitRET(this); 145 } 146}