1 17 package org.apache.bcel.generic; 18 19 import java.io.DataOutputStream ; 20 import java.io.IOException ; 21 import org.apache.bcel.util.ByteSequence; 22 23 32 public abstract class BranchInstruction extends Instruction implements InstructionTargeter { 33 34 protected int index; protected InstructionHandle target; protected int position; 38 39 43 BranchInstruction() { 44 } 45 46 47 51 protected BranchInstruction(short opcode, InstructionHandle target) { 52 super(opcode, (short) 3); 53 setTarget(target); 54 } 55 56 57 61 public void dump( DataOutputStream out ) throws IOException { 62 out.writeByte(opcode); 63 index = getTargetOffset(); 64 if (Math.abs(index) >= 32767) { 65 throw new ClassGenException("Branch target offset too large for short"); 66 } 67 out.writeShort(index); } 69 70 71 75 protected int getTargetOffset( InstructionHandle _target ) { 76 if (_target == null) { 77 throw new ClassGenException("Target of " + super.toString(true) 78 + " is invalid null handle"); 79 } 80 int t = _target.getPosition(); 81 if (t < 0) { 82 throw new ClassGenException("Invalid branch target position offset for " 83 + super.toString(true) + ":" + t + ":" + _target); 84 } 85 return t - position; 86 } 87 88 89 92 protected int getTargetOffset() { 93 return getTargetOffset(target); 94 } 95 96 97 107 protected int updatePosition( int offset, int max_offset ) { 108 position += offset; 109 return 0; 110 } 111 112 113 124 public String toString( boolean verbose ) { 125 String s = super.toString(verbose); 126 String t = "null"; 127 if (verbose) { 128 if (target != null) { 129 if (target.getInstruction() == this) { 130 t = "<points to itself>"; 131 } else if (target.getInstruction() == null) { 132 t = "<null instruction!!!?>"; 133 } else { 134 t = target.getInstruction().toString(false); } 136 } 137 } else { 138 if (target != null) { 139 index = getTargetOffset(); 140 t = "" + (index + position); 141 } 142 } 143 return s + " -> " + t; 144 } 145 146 147 155 protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { 156 length = 3; 157 index = bytes.readShort(); 158 } 159 160 161 164 public final int getIndex() { 165 return index; 166 } 167 168 169 172 public InstructionHandle getTarget() { 173 return target; 174 } 175 176 177 181 public void setTarget( InstructionHandle target ) { 182 notifyTarget(this.target, target, this); 183 this.target = target; 184 } 185 186 187 190 static final void notifyTarget( InstructionHandle old_ih, InstructionHandle new_ih, 191 InstructionTargeter t ) { 192 if (old_ih != null) { 193 old_ih.removeTargeter(t); 194 } 195 if (new_ih != null) { 196 new_ih.addTargeter(t); 197 } 198 } 199 200 201 205 public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) { 206 if (target == old_ih) { 207 setTarget(new_ih); 208 } else { 209 throw new ClassGenException("Not targeting " + old_ih + ", but " + target); 210 } 211 } 212 213 214 217 public boolean containsTarget( InstructionHandle ih ) { 218 return (target == ih); 219 } 220 221 222 225 void dispose() { 226 setTarget(null); 227 index = -1; 228 position = -1; 229 } 230 } 231 | Popular Tags |