00001 package de.fub.bytecode.generic;
00002
00003 import java.io.*;
00004 import de.fub.bytecode.util.ByteSequence;
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 public abstract class Select extends BranchInstruction implements VariableLengthInstruction
00016 {
00017 protected int[] match;
00018 protected int[] indices;
00019 protected InstructionHandle[] targets;
00020 protected int fixed_length;
00021 protected int match_length;
00022 protected int padding = 0;
00023
00024
00025
00026
00027
00028 Select() {}
00029
00030
00031
00032
00033
00034
00035
00036
00037 Select(short tag, int[] match, InstructionHandle[] targets,
00038 InstructionHandle target) {
00039 super(tag, target);
00040
00041 this.targets = targets;
00042 for(int i=0; i < targets.length; i++)
00043 notifyTarget(null, targets[i], this);
00044
00045 this.match = match;
00046
00047 if((match_length = match.length) != targets.length)
00048 throw new ClassGenException("Match and target array have not the same length");
00049
00050 indices = new int[match_length];
00051 }
00052
00053
00054
00055 public boolean containsTarget(InstructionHandle ih) {
00056 if(target == ih)
00057 return true;
00058
00059 for(int i=0; i < targets.length; i++)
00060 if(targets[i] == ih)
00061 return true;
00062
00063 return false;
00064 }
00065
00066
00067
00068 void dispose() {
00069 super.dispose();
00070
00071 for(int i=0; i < targets.length; i++)
00072 targets[i].removeTargeter(this);
00073 }
00074
00075
00076
00077
00078 public void dump(DataOutputStream out) throws IOException {
00079 out.writeByte(tag);
00080
00081 for(int i=0; i < padding; i++)
00082 out.writeByte(0);
00083
00084 index = getTargetOffset();
00085 out.writeInt(index);
00086 }
00087
00088
00089
00090 public int[] getIndices() { return indices; }
00091
00092
00093
00094 public int[] getMatchs() { return match; }
00095
00096
00097
00098 public InstructionHandle[] getTargets() { return targets; }
00099
00100
00101
00102 protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException
00103 {
00104 padding = (4 - (bytes.getIndex() % 4)) % 4;
00105
00106 for(int i=0; i < padding; i++) {
00107 byte b;
00108 if((b=bytes.readByte()) != 0)
00109 throw new ClassGenException("Padding byte != 0: " + b);
00110 }
00111
00112
00113 index = bytes.readInt();
00114 }
00115
00116
00117
00118 public void setTarget(int i, InstructionHandle target) {
00119 notifyTarget(targets[i], target, this);
00120 targets[i] = target;
00121 }
00122
00123
00124
00125 public String toString(boolean verbose) {
00126 StringBuffer buf = new StringBuffer(super.toString(verbose));
00127
00128 if(verbose) {
00129 for(int i=0; i < match_length; i++) {
00130 String s = "null";
00131
00132 if(targets[i] != null)
00133 s = targets[i].getInstruction().toString();
00134
00135 buf.append("(" + match[i] + ", " + s + " = {" + indices[i] + "})");
00136 }
00137 }
00138 else
00139 buf.append(" ...");
00140
00141 return buf.toString();
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 protected int updatePosition(int offset, int max_offset) {
00157 position += offset;
00158
00159 short old_length = length;
00160
00161
00162
00163 padding = (4 - ((position + 1) % 4)) % 4;
00164 length = (short)(fixed_length + padding);
00165
00166 return length - old_length;
00167 }
00168
00169
00170
00171
00172 public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
00173 boolean targeted = false;
00174
00175 if(target == old_ih) {
00176 targeted = true;
00177 setTarget(new_ih);
00178 }
00179
00180 for(int i=0; i < targets.length; i++) {
00181 if(targets[i] == old_ih) {
00182 targeted = true;
00183 setTarget(i, new_ih);
00184 }
00185 }
00186
00187 if(!targeted)
00188 throw new ClassGenException("Not targeting " + old_ih);
00189 }
00190 }