equal
deleted
inserted
replaced
95 Select(short opcode, int[] match, InstructionHandle[] targets, |
95 Select(short opcode, int[] match, InstructionHandle[] targets, |
96 InstructionHandle target) { |
96 InstructionHandle target) { |
97 super(opcode, target); |
97 super(opcode, target); |
98 |
98 |
99 this.targets = targets; |
99 this.targets = targets; |
100 for(int i=0; i < targets.length; i++) |
100 for(int i=0; i < targets.length; i++) { |
101 notifyTarget(null, targets[i], this); |
101 BranchInstruction.notifyTargetChanged(targets[i], this); |
|
102 } |
102 |
103 |
103 this.match = match; |
104 this.match = match; |
104 |
105 |
105 if((match_length = match.length) != targets.length) |
106 if((match_length = match.length) != targets.length) |
106 throw new ClassGenException("Match and target array have not the same length"); |
107 throw new ClassGenException("Match and target array have not the same length"); |
119 * |
120 * |
120 * @param offset additional offset caused by preceding (variable length) instructions |
121 * @param offset additional offset caused by preceding (variable length) instructions |
121 * @param max_offset the maximum offset that may be caused by these instructions |
122 * @param max_offset the maximum offset that may be caused by these instructions |
122 * @return additional offset caused by possible change of this instruction's length |
123 * @return additional offset caused by possible change of this instruction's length |
123 */ |
124 */ |
|
125 @Override |
124 protected int updatePosition(int offset, int max_offset) { |
126 protected int updatePosition(int offset, int max_offset) { |
125 position += offset; // Additional offset caused by preceding SWITCHs, GOTOs, etc. |
127 position += offset; // Additional offset caused by preceding SWITCHs, GOTOs, etc. |
126 |
128 |
127 short old_length = length; |
129 short old_length = length; |
128 |
130 |
136 |
138 |
137 /** |
139 /** |
138 * Dump instruction as byte code to stream out. |
140 * Dump instruction as byte code to stream out. |
139 * @param out Output stream |
141 * @param out Output stream |
140 */ |
142 */ |
|
143 @Override |
141 public void dump(DataOutputStream out) throws IOException { |
144 public void dump(DataOutputStream out) throws IOException { |
142 out.writeByte(opcode); |
145 out.writeByte(opcode); |
143 |
146 |
144 for(int i=0; i < padding; i++) // Padding bytes |
147 for(int i=0; i < padding; i++) // Padding bytes |
145 out.writeByte(0); |
148 out.writeByte(0); |
149 } |
152 } |
150 |
153 |
151 /** |
154 /** |
152 * Read needed data (e.g. index) from file. |
155 * Read needed data (e.g. index) from file. |
153 */ |
156 */ |
|
157 @Override |
154 protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException |
158 protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException |
155 { |
159 { |
156 padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes |
160 padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes |
157 |
161 |
158 for(int i=0; i < padding; i++) { |
162 for(int i=0; i < padding; i++) { |
164 } |
168 } |
165 |
169 |
166 /** |
170 /** |
167 * @return mnemonic for instruction |
171 * @return mnemonic for instruction |
168 */ |
172 */ |
|
173 @Override |
169 public String toString(boolean verbose) { |
174 public String toString(boolean verbose) { |
170 StringBuffer buf = new StringBuffer(super.toString(verbose)); |
175 final StringBuilder buf = new StringBuilder(super.toString(verbose)); |
171 |
176 |
172 if(verbose) { |
177 if(verbose) { |
173 for(int i=0; i < match_length; i++) { |
178 for(int i=0; i < match_length; i++) { |
174 String s = "null"; |
179 String s = "null"; |
175 |
180 |
176 if(targets[i] != null) |
181 if(targets[i] != null) |
177 s = targets[i].getInstruction().toString(); |
182 s = targets[i].getInstruction().toString(); |
178 |
183 |
179 buf.append("(" + match[i] + ", " + s + " = {" + indices[i] + "})"); |
184 buf.append("(").append(match[i]).append(", ") |
|
185 .append(s).append(" = {").append(indices[i]).append("})"); |
180 } |
186 } |
181 } |
187 } |
182 else |
188 else |
183 buf.append(" ..."); |
189 buf.append(" ..."); |
184 |
190 |
186 } |
192 } |
187 |
193 |
188 /** |
194 /** |
189 * Set branch target for `i'th case |
195 * Set branch target for `i'th case |
190 */ |
196 */ |
191 public void setTarget(int i, InstructionHandle target) { |
197 public final void setTarget(int i, InstructionHandle target) { |
192 notifyTarget(targets[i], target, this); |
198 notifyTargetChanging(targets[i], this); |
193 targets[i] = target; |
199 targets[i] = target; |
|
200 notifyTargetChanged(targets[i], this); |
194 } |
201 } |
195 |
202 |
196 /** |
203 /** |
197 * @param old_ih old target |
204 * @param old_ih old target |
198 * @param new_ih new target |
205 * @param new_ih new target |
199 */ |
206 */ |
|
207 @Override |
200 public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { |
208 public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { |
201 boolean targeted = false; |
209 boolean targeted = false; |
202 |
210 |
203 if(target == old_ih) { |
211 if(target == old_ih) { |
204 targeted = true; |
212 targeted = true; |
217 } |
225 } |
218 |
226 |
219 /** |
227 /** |
220 * @return true, if ih is target of this instruction |
228 * @return true, if ih is target of this instruction |
221 */ |
229 */ |
|
230 @Override |
222 public boolean containsTarget(InstructionHandle ih) { |
231 public boolean containsTarget(InstructionHandle ih) { |
223 if(target == ih) |
232 if(target == ih) |
224 return true; |
233 return true; |
225 |
234 |
226 for(int i=0; i < targets.length; i++) |
235 for(int i=0; i < targets.length; i++) |
231 } |
240 } |
232 |
241 |
233 /** |
242 /** |
234 * Inform targets that they're not targeted anymore. |
243 * Inform targets that they're not targeted anymore. |
235 */ |
244 */ |
|
245 @Override |
236 void dispose() { |
246 void dispose() { |
237 super.dispose(); |
247 super.dispose(); |
238 |
248 |
239 for(int i=0; i < targets.length; i++) |
249 for(int i=0; i < targets.length; i++) |
240 targets[i].removeTargeter(this); |
250 targets[i].removeTargeter(this); |