1 package com.sun.org.apache.bcel.internal.generic; 2 3 56 57 import java.io.*; 58 import com.sun.org.apache.bcel.internal.util.ByteSequence; 59 60 69 public abstract class BranchInstruction extends Instruction implements InstructionTargeter { 70 protected int index; protected InstructionHandle target; protected int position; 74 78 BranchInstruction() {} 79 80 84 protected BranchInstruction(short opcode, InstructionHandle target) { 85 super(opcode, (short)3); 86 setTarget(target); 87 } 88 89 93 public void dump(DataOutputStream out) throws IOException { 94 out.writeByte(opcode); 95 96 index = getTargetOffset(); 97 98 if(Math.abs(index) >= 32767) throw new ClassGenException("Branch target offset too large for short"); 100 101 out.writeShort(index); } 103 104 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 125 protected int getTargetOffset() { return getTargetOffset(target); } 126 127 137 protected int updatePosition(int offset, int max_offset) { 138 position += offset; 139 return 0; 140 } 141 142 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); } 166 } else { 167 if(target != null) { 168 index = getTargetOffset(); 169 t = "" + (index + position); 170 } 171 } 172 173 return s + " -> " + t; 174 } 175 176 184 protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException 185 { 186 length = 3; 187 index = bytes.readShort(); 188 } 189 190 193 public final int getIndex() { return index; } 194 195 198 public InstructionHandle getTarget() { return target; } 199 200 204 public void setTarget(InstructionHandle target) { 205 notifyTarget(this.target, target, this); 206 this.target = target; 207 } 208 209 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 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 234 public boolean containsTarget(InstructionHandle ih) { 235 return (target == ih); 236 } 237 238 241 void dispose() { 242 setTarget(null); 243 index=-1; 244 position=-1; 245 } 246 } 247 | Popular Tags |