View Javadoc
1 package org.apache.bcel.generic; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache BCEL" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache BCEL", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 import java.io.*; 58 import org.apache.bcel.util.ByteSequence; 59 60 /*** 61 * Abstract super class for branching instructions like GOTO, IFEQ, etc.. 62 * Branch instructions may have a variable length, namely GOTO, JSR, 63 * LOOKUPSWITCH and TABLESWITCH. 64 * 65 * @see InstructionList 66 * @version $Id: BranchInstruction.java,v 1.1.1.1 2001/10/29 20:00:07 jvanzyl Exp $ 67 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 68 */ 69 public abstract class BranchInstruction extends Instruction implements InstructionTargeter { 70 protected int index; // Branch target relative to this instruction 71 protected InstructionHandle target; // Target object in instruction list 72 protected int position; // Byte code offset 73 74 /*** 75 * Empty constructor needed for the Class.newInstance() statement in 76 * Instruction.readInstruction(). Not to be used otherwise. 77 */ 78 BranchInstruction() {} 79 80 /*** Common super constructor 81 * @param opcodee Instruction opcode 82 * @param target instruction to branch to 83 */ 84 protected BranchInstruction(short opcode, InstructionHandle target) { 85 super(opcode, (short)3); 86 setTarget(target); 87 } 88 89 /*** 90 * Dump instruction as byte code to stream out. 91 * @param out Output stream 92 */ 93 public void dump(DataOutputStream out) throws IOException { 94 out.writeByte(opcode); 95 96 index = getTargetOffset(); 97 98 if(Math.abs(index) >= 32767) // too large for short 99 throw new ClassGenException("Branch target offset too large for short"); 100 101 out.writeShort(index); // May be negative, i.e., point backwards 102 } 103 104 /*** 105 * @param target branch target 106 * @return the offset to `target' relative to this instruction 107 */ 108 protected int getTargetOffset(InstructionHandle target) { 109 if(target == null) 110 throw new ClassGenException("Target of " + super.toString(true) + 111 " is invalid null handle"); 112 113 int t = target.getPosition(); 114 115 if(t < 0) 116 throw new ClassGenException("Invalid branch target position offset for " + 117 super.toString(true) + ":" + t + ":" + target); 118 119 return t - position; 120 } 121 122 /*** 123 * @return the offset to this instruction's target 124 */ 125 protected int getTargetOffset() { return getTargetOffset(target); } 126 127 /*** 128 * Called by InstructionList.setPositions when setting the position for every 129 * instruction. In the presence of variable length instructions `setPositions' 130 * performs multiple passes over the instruction list to calculate the 131 * correct (byte) positions and offsets by calling this function. 132 * 133 * @param offset additional offset caused by preceding (variable length) instructions 134 * @param max_offset the maximum offset that may be caused by these instructions 135 * @return additional offset caused by possible change of this instruction's length 136 */ 137 protected int updatePosition(int offset, int max_offset) { 138 position += offset; 139 return 0; 140 } 141 142 /*** 143 * Long output format: 144 * 145 * <position in byte code> 146 * <name of opcode> "["<opcode number>"]" 147 * "("<length of instruction>")" 148 * "<"<target instruction>">" "@"<branch target offset> 149 * 150 * @param verbose long/short format switch 151 * @return mnemonic for instruction 152 */ 153 public String toString(boolean verbose) { 154 String s = super.toString(verbose); 155 String t = "null"; 156 157 if(verbose) { 158 if(target != null) { 159 if(target.getInstruction() == this) 160 t = "<points to itself>"; 161 else if(target.getInstruction() == null) 162 t = "<null instruction!!!?>"; 163 else 164 t = target.getInstruction().toString(false); // Avoid circles 165 } 166 } else { 167 if(target != null) { 168 index = getTargetOffset(); 169 t = "" + (index + position); 170 } 171 } 172 173 return s + " -> " + t; 174 } 175 176 /*** 177 * Read needed data (e.g. index) from file. Conversion to a InstructionHandle 178 * is done in InstructionList(byte[]). 179 * 180 * @param bytes input stream 181 * @param wide wide prefix? 182 * @see InstructionList 183 */ 184 protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException 185 { 186 length = 3; 187 index = bytes.readShort(); 188 } 189 190 /*** 191 * @return target offset in byte code 192 */ 193 public final int getIndex() { return index; } 194 195 /*** 196 * @return target of branch instruction 197 */ 198 public InstructionHandle getTarget() { return target; } 199 200 /*** 201 * Set branch target 202 * @param target branch target 203 */ 204 public void setTarget(InstructionHandle target) { 205 notifyTarget(this.target, target, this); 206 this.target = target; 207 } 208 209 /*** 210 * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen 211 */ 212 static final void notifyTarget(InstructionHandle old_ih, InstructionHandle new_ih, 213 InstructionTargeter t) { 214 if(old_ih != null) 215 old_ih.removeTargeter(t); 216 if(new_ih != null) 217 new_ih.addTargeter(t); 218 } 219 220 /*** 221 * @param old_ih old target 222 * @param new_ih new target 223 */ 224 public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { 225 if(target == old_ih) 226 setTarget(new_ih); 227 else 228 throw new ClassGenException("Not targeting " + old_ih + ", but " + target); 229 } 230 231 /*** 232 * @return true, if ih is target of this instruction 233 */ 234 public boolean containsTarget(InstructionHandle ih) { 235 return (target == ih); 236 } 237 238 /*** 239 * Inform target that it's not targeted anymore. 240 */ 241 void dispose() { 242 setTarget(null); 243 index=-1; 244 position=-1; 245 } 246 }

This page was automatically generated by Maven