85 ", Args_size=" + argCount); |
88 ", Args_size=" + argCount); |
86 |
89 |
87 } |
90 } |
88 |
91 |
89 public void writeInstrs(Code_attribute attr) { |
92 public void writeInstrs(Code_attribute attr) { |
90 try { |
93 for (Instruction instr: attr.getInstructions()) { |
91 for (int pc = 0; pc < attr.code_length;) { |
94 try { |
92 print(" " + pc + ":\t"); |
95 writeInstr(instr); |
93 pc += writeInstr(attr, pc); |
96 } catch (ArrayIndexOutOfBoundsException e) { |
94 println(); |
97 println(report("error at or after byte " + instr.getPC())); |
95 } |
98 break; |
96 } catch (Code_attribute.InvalidIndex e) { |
99 } |
97 println(report(e)); |
100 } |
98 } |
101 } |
99 } |
102 |
100 |
103 public void writeInstr(Instruction instr) { |
101 public int writeInstr(Code_attribute attr, int pc) |
104 print(" " + instr.getPC() + ":\t"); |
102 throws Code_attribute.InvalidIndex { |
105 print(instr.getMnemonic()); |
103 String lP = ""; |
106 instr.accept(instructionPrinter, null); |
104 int opcode = attr.getUnsignedByte(pc); |
107 println(); |
105 int opcode2; |
108 } |
106 String mnem; |
109 // where |
107 switch (opcode) { |
110 Instruction.KindVisitor<Void,Void> instructionPrinter = |
108 case opc_nonpriv: |
111 new Instruction.KindVisitor<Void,Void>() { |
109 case opc_priv: { |
112 |
110 opcode2 = attr.getUnsignedByte(pc + 1); |
113 public Void visitNoOperands(Instruction instr, Void p) { |
111 mnem = opcName((opcode << 8) + opcode2); |
114 return null; |
112 if (mnem == null) { |
115 } |
113 mnem = opcName(opcode) + " " + opcode2; |
116 |
114 } |
117 public Void visitArrayType(Instruction instr, TypeKind kind, Void p) { |
115 print(mnem); |
118 print(" " + kind.name); |
116 return 2; |
119 return null; |
117 } |
120 } |
118 case opc_wide: { |
121 |
119 opcode2 = attr.getUnsignedByte(pc + 1); |
122 public Void visitBranch(Instruction instr, int offset, Void p) { |
120 mnem = opcName((opcode << 8) + opcode2); |
123 print("\t" + (instr.getPC() + offset)); |
121 if (mnem == null) { |
124 return null; |
122 print("bytecode " + opcode); |
125 } |
123 return 1; |
126 |
124 } |
127 public Void visitConstantPoolRef(Instruction instr, int index, Void p) { |
125 print(mnem + " " + attr.getUnsignedShort(pc + 2)); |
128 print("\t#" + index + "; //"); |
126 if (opcode2 == opc_iinc) { |
129 printConstant(index); |
127 print(", " + attr.getShort(pc + 4)); |
130 return null; |
128 return 6; |
131 } |
129 } |
132 |
130 return 4; |
133 public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Void p) { |
131 } |
134 print("\t#" + index + ", " + value + "; //"); |
132 } |
135 printConstant(index); |
133 mnem = opcName(opcode); |
136 return null; |
134 if (mnem == null) { |
137 } |
135 print("bytecode " + opcode); |
138 |
136 return 1; |
139 public Void visitLocal(Instruction instr, int index, Void p) { |
137 } |
140 print("\t" + index); |
138 if (opcode > opc_jsr_w) { |
141 return null; |
139 print("bytecode " + opcode); |
142 } |
140 return 1; |
143 |
141 } |
144 public Void visitLocalAndValue(Instruction instr, int index, int value, Void p) { |
142 print(opcName(opcode)); |
145 print("\t" + index + ", " + value); |
143 switch (opcode) { |
146 return null; |
144 case opc_aload: |
147 } |
145 case opc_astore: |
148 |
146 case opc_fload: |
149 public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets) { |
147 case opc_fstore: |
150 int pc = instr.getPC(); |
148 case opc_iload: |
151 print("{ //" + npairs); |
149 case opc_istore: |
152 for (int i = 0; i < npairs; i++) { |
150 case opc_lload: |
153 print("\n\t\t" + matches[i] + ": " + (pc + offsets[i]) + ";"); |
151 case opc_lstore: |
154 } |
152 case opc_dload: |
155 print("\n\t\tdefault: " + (pc + default_) + " }"); |
153 case opc_dstore: |
156 return null; |
154 case opc_ret: |
157 } |
155 print("\t" + attr.getUnsignedByte(pc + 1)); |
158 |
156 return 2; |
159 public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets) { |
157 case opc_iinc: |
160 int pc = instr.getPC(); |
158 print("\t" + attr.getUnsignedByte(pc + 1) + ", " + attr.getByte(pc + 2)); |
161 print("{ //" + low + " to " + high); |
159 return 3; |
162 for (int i = 0; i < offsets.length; i++) { |
160 case opc_tableswitch: |
163 print("\n\t\t" + (low + i) + ": " + (pc + offsets[i]) + ";"); |
161 { |
164 } |
162 int tb = align(pc + 1); |
165 print("\n\t\tdefault: " + (pc + default_) + " }"); |
163 int default_skip = attr.getInt(tb); |
166 return null; |
164 int low = attr.getInt(tb + 4); |
167 } |
165 int high = attr.getInt(tb + 8); |
168 |
166 int count = high - low; |
169 public Void visitValue(Instruction instr, int value, Void p) { |
167 print("{ //" + low + " to " + high); |
170 print("\t" + value); |
168 for (int i = 0; i <= count; i++) { |
171 return null; |
169 print("\n\t\t" + (i + low) + ": " + lP + (pc + attr.getInt(tb + 12 + 4 * i)) + ";"); |
172 } |
170 } |
173 |
171 print("\n\t\tdefault: " + lP + (default_skip + pc) + " }"); |
174 public Void visitUnknown(Instruction instr, Void p) { |
172 return tb - pc + 16 + count * 4; |
175 return null; |
173 } |
176 } |
174 case opc_lookupswitch: |
177 }; |
175 { |
178 |
176 int tb = align(pc + 1); |
|
177 int default_skip = attr.getInt(tb); |
|
178 int npairs = attr.getInt(tb + 4); |
|
179 print("{ //" + npairs); |
|
180 for (int i = 1; i <= npairs; i++) { |
|
181 print("\n\t\t" + attr.getInt(tb + i * 8) + ": " + lP + (pc + attr.getInt(tb + 4 + i * 8)) + ";"); |
|
182 } |
|
183 print("\n\t\tdefault: " + lP + (default_skip + pc) + " }"); |
|
184 return tb - pc + (npairs + 1) * 8; |
|
185 } |
|
186 case opc_newarray: |
|
187 int type = attr.getUnsignedByte(pc + 1); |
|
188 switch (type) { |
|
189 case T_BOOLEAN: |
|
190 print(" boolean"); |
|
191 break; |
|
192 case T_BYTE: |
|
193 print(" byte"); |
|
194 break; |
|
195 case T_CHAR: |
|
196 print(" char"); |
|
197 break; |
|
198 case T_SHORT: |
|
199 print(" short"); |
|
200 break; |
|
201 case T_INT: |
|
202 print(" int"); |
|
203 break; |
|
204 case T_LONG: |
|
205 print(" long"); |
|
206 break; |
|
207 case T_FLOAT: |
|
208 print(" float"); |
|
209 break; |
|
210 case T_DOUBLE: |
|
211 print(" double"); |
|
212 break; |
|
213 case T_CLASS: |
|
214 print(" class"); |
|
215 break; |
|
216 default: |
|
217 print(" BOGUS TYPE:" + type); |
|
218 } |
|
219 return 2; |
|
220 case opc_anewarray: |
|
221 { |
|
222 int index = attr.getUnsignedShort(pc + 1); |
|
223 print("\t#" + index + "; //"); |
|
224 printConstant(index); |
|
225 return 3; |
|
226 } |
|
227 case opc_sipush: |
|
228 print("\t" + attr.getShort(pc + 1)); |
|
229 return 3; |
|
230 case opc_bipush: |
|
231 print("\t" + attr.getByte(pc + 1)); |
|
232 return 2; |
|
233 case opc_ldc: |
|
234 { |
|
235 int index = attr.getUnsignedByte(pc + 1); |
|
236 print("\t#" + index + "; //"); |
|
237 printConstant(index); |
|
238 return 2; |
|
239 } |
|
240 case opc_ldc_w: |
|
241 case opc_ldc2_w: |
|
242 case opc_instanceof: |
|
243 case opc_checkcast: |
|
244 case opc_new: |
|
245 case opc_putstatic: |
|
246 case opc_getstatic: |
|
247 case opc_putfield: |
|
248 case opc_getfield: |
|
249 case opc_invokevirtual: |
|
250 case opc_invokespecial: |
|
251 case opc_invokestatic: |
|
252 { |
|
253 int index = attr.getUnsignedShort(pc + 1); |
|
254 print("\t#" + index + "; //"); |
|
255 printConstant(index); |
|
256 return 3; |
|
257 } |
|
258 case opc_invokeinterface: |
|
259 { |
|
260 int index = attr.getUnsignedShort(pc + 1); |
|
261 int nargs = attr.getUnsignedByte(pc + 3); |
|
262 print("\t#" + index + ", " + nargs + "; //"); |
|
263 printConstant(index); |
|
264 return 5; |
|
265 } |
|
266 case opc_multianewarray: |
|
267 { |
|
268 int index = attr.getUnsignedShort(pc + 1); |
|
269 int dimensions = attr.getUnsignedByte(pc + 3); |
|
270 print("\t#" + index + ", " + dimensions + "; //"); |
|
271 printConstant(index); |
|
272 return 4; |
|
273 } |
|
274 case opc_jsr: |
|
275 case opc_goto: |
|
276 case opc_ifeq: |
|
277 case opc_ifge: |
|
278 case opc_ifgt: |
|
279 case opc_ifle: |
|
280 case opc_iflt: |
|
281 case opc_ifne: |
|
282 case opc_if_icmpeq: |
|
283 case opc_if_icmpne: |
|
284 case opc_if_icmpge: |
|
285 case opc_if_icmpgt: |
|
286 case opc_if_icmple: |
|
287 case opc_if_icmplt: |
|
288 case opc_if_acmpeq: |
|
289 case opc_if_acmpne: |
|
290 case opc_ifnull: |
|
291 case opc_ifnonnull: |
|
292 print("\t" + lP + (pc + attr.getShort(pc + 1))); |
|
293 return 3; |
|
294 case opc_jsr_w: |
|
295 case opc_goto_w: |
|
296 print("\t" + lP + (pc + attr.getInt(pc + 1))); |
|
297 return 5; |
|
298 default: |
|
299 return 1; |
|
300 } |
|
301 } |
|
302 |
179 |
303 public void writeExceptionTable(Code_attribute attr) { |
180 public void writeExceptionTable(Code_attribute attr) { |
304 if (attr.exception_table_langth > 0) { |
181 if (attr.exception_table_langth > 0) { |
305 println(" Exception table:"); |
182 println(" Exception table:"); |
306 println(" from to target type"); |
183 println(" from to target type"); |