Mon, 25 Mar 2013 16:55:14 -0700
8010521: jdk8 l10n resource file translation update 2
Reviewed-by: naoto, yhuang
1 /*
2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javap;
28 import java.util.ArrayList;
29 import java.util.List;
31 import com.sun.tools.classfile.AccessFlags;
32 import com.sun.tools.classfile.Code_attribute;
33 import com.sun.tools.classfile.ConstantPool;
34 import com.sun.tools.classfile.ConstantPoolException;
35 import com.sun.tools.classfile.DescriptorException;
36 import com.sun.tools.classfile.Instruction;
37 import com.sun.tools.classfile.Instruction.TypeKind;
38 import com.sun.tools.classfile.Method;
40 /*
41 * Write the contents of a Code attribute.
42 *
43 * <p><b>This is NOT part of any supported API.
44 * If you write code that depends on this, you do so at your own risk.
45 * This code and its internal interfaces are subject to change or
46 * deletion without notice.</b>
47 */
48 public class CodeWriter extends BasicWriter {
49 public static CodeWriter instance(Context context) {
50 CodeWriter instance = context.get(CodeWriter.class);
51 if (instance == null)
52 instance = new CodeWriter(context);
53 return instance;
54 }
56 protected CodeWriter(Context context) {
57 super(context);
58 context.put(CodeWriter.class, this);
59 attrWriter = AttributeWriter.instance(context);
60 classWriter = ClassWriter.instance(context);
61 constantWriter = ConstantWriter.instance(context);
62 sourceWriter = SourceWriter.instance(context);
63 tryBlockWriter = TryBlockWriter.instance(context);
64 stackMapWriter = StackMapWriter.instance(context);
65 localVariableTableWriter = LocalVariableTableWriter.instance(context);
66 localVariableTypeTableWriter = LocalVariableTypeTableWriter.instance(context);
67 typeAnnotationWriter = TypeAnnotationWriter.instance(context);
68 options = Options.instance(context);
69 }
71 void write(Code_attribute attr, ConstantPool constant_pool) {
72 println("Code:");
73 indent(+1);
74 writeVerboseHeader(attr, constant_pool);
75 writeInstrs(attr);
76 writeExceptionTable(attr);
77 attrWriter.write(attr, attr.attributes, constant_pool);
78 indent(-1);
79 }
81 public void writeVerboseHeader(Code_attribute attr, ConstantPool constant_pool) {
82 Method method = classWriter.getMethod();
83 String argCount;
84 try {
85 int n = method.descriptor.getParameterCount(constant_pool);
86 if (!method.access_flags.is(AccessFlags.ACC_STATIC))
87 ++n; // for 'this'
88 argCount = Integer.toString(n);
89 } catch (ConstantPoolException e) {
90 argCount = report(e);
91 } catch (DescriptorException e) {
92 argCount = report(e);
93 }
95 println("stack=" + attr.max_stack +
96 ", locals=" + attr.max_locals +
97 ", args_size=" + argCount);
99 }
101 public void writeInstrs(Code_attribute attr) {
102 List<InstructionDetailWriter> detailWriters = getDetailWriters(attr);
104 for (Instruction instr: attr.getInstructions()) {
105 try {
106 for (InstructionDetailWriter w: detailWriters)
107 w.writeDetails(instr);
108 writeInstr(instr);
109 } catch (ArrayIndexOutOfBoundsException e) {
110 println(report("error at or after byte " + instr.getPC()));
111 break;
112 }
113 }
115 for (InstructionDetailWriter w: detailWriters)
116 w.flush();
117 }
119 public void writeInstr(Instruction instr) {
120 print(String.format("%4d: %-13s ", instr.getPC(), instr.getMnemonic()));
121 // compute the number of indentations for the body of multi-line instructions
122 // This is 6 (the width of "%4d: "), divided by the width of each indentation level,
123 // and rounded up to the next integer.
124 int indentWidth = options.indentWidth;
125 int indent = (6 + indentWidth - 1) / indentWidth;
126 instr.accept(instructionPrinter, indent);
127 println();
128 }
129 // where
130 Instruction.KindVisitor<Void,Integer> instructionPrinter =
131 new Instruction.KindVisitor<Void,Integer>() {
133 public Void visitNoOperands(Instruction instr, Integer indent) {
134 return null;
135 }
137 public Void visitArrayType(Instruction instr, TypeKind kind, Integer indent) {
138 print(" " + kind.name);
139 return null;
140 }
142 public Void visitBranch(Instruction instr, int offset, Integer indent) {
143 print((instr.getPC() + offset));
144 return null;
145 }
147 public Void visitConstantPoolRef(Instruction instr, int index, Integer indent) {
148 print("#" + index);
149 tab();
150 print("// ");
151 printConstant(index);
152 return null;
153 }
155 public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Integer indent) {
156 print("#" + index + ", " + value);
157 tab();
158 print("// ");
159 printConstant(index);
160 return null;
161 }
163 public Void visitLocal(Instruction instr, int index, Integer indent) {
164 print(index);
165 return null;
166 }
168 public Void visitLocalAndValue(Instruction instr, int index, int value, Integer indent) {
169 print(index + ", " + value);
170 return null;
171 }
173 public Void visitLookupSwitch(Instruction instr,
174 int default_, int npairs, int[] matches, int[] offsets, Integer indent) {
175 int pc = instr.getPC();
176 print("{ // " + npairs);
177 indent(indent);
178 for (int i = 0; i < npairs; i++) {
179 print(String.format("%n%12d: %d", matches[i], (pc + offsets[i])));
180 }
181 print("\n default: " + (pc + default_) + "\n}");
182 indent(-indent);
183 return null;
184 }
186 public Void visitTableSwitch(Instruction instr,
187 int default_, int low, int high, int[] offsets, Integer indent) {
188 int pc = instr.getPC();
189 print("{ // " + low + " to " + high);
190 indent(indent);
191 for (int i = 0; i < offsets.length; i++) {
192 print(String.format("%n%12d: %d", (low + i), (pc + offsets[i])));
193 }
194 print("\n default: " + (pc + default_) + "\n}");
195 indent(-indent);
196 return null;
197 }
199 public Void visitValue(Instruction instr, int value, Integer indent) {
200 print(value);
201 return null;
202 }
204 public Void visitUnknown(Instruction instr, Integer indent) {
205 return null;
206 }
207 };
210 public void writeExceptionTable(Code_attribute attr) {
211 if (attr.exception_table_langth > 0) {
212 println("Exception table:");
213 indent(+1);
214 println(" from to target type");
215 for (int i = 0; i < attr.exception_table.length; i++) {
216 Code_attribute.Exception_data handler = attr.exception_table[i];
217 print(String.format(" %5d %5d %5d",
218 handler.start_pc, handler.end_pc, handler.handler_pc));
219 print(" ");
220 int catch_type = handler.catch_type;
221 if (catch_type == 0) {
222 println("any");
223 } else {
224 print("Class ");
225 println(constantWriter.stringValue(catch_type));
226 }
227 }
228 indent(-1);
229 }
231 }
233 private void printConstant(int index) {
234 constantWriter.write(index);
235 }
237 private List<InstructionDetailWriter> getDetailWriters(Code_attribute attr) {
238 List<InstructionDetailWriter> detailWriters =
239 new ArrayList<InstructionDetailWriter>();
240 if (options.details.contains(InstructionDetailWriter.Kind.SOURCE)) {
241 sourceWriter.reset(classWriter.getClassFile(), attr);
242 if (sourceWriter.hasSource())
243 detailWriters.add(sourceWriter);
244 else
245 println("(Source code not available)");
246 }
248 if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VARS)) {
249 localVariableTableWriter.reset(attr);
250 detailWriters.add(localVariableTableWriter);
251 }
253 if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VAR_TYPES)) {
254 localVariableTypeTableWriter.reset(attr);
255 detailWriters.add(localVariableTypeTableWriter);
256 }
258 if (options.details.contains(InstructionDetailWriter.Kind.STACKMAPS)) {
259 stackMapWriter.reset(attr);
260 stackMapWriter.writeInitialDetails();
261 detailWriters.add(stackMapWriter);
262 }
264 if (options.details.contains(InstructionDetailWriter.Kind.TRY_BLOCKS)) {
265 tryBlockWriter.reset(attr);
266 detailWriters.add(tryBlockWriter);
267 }
269 if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) {
270 typeAnnotationWriter.reset(attr);
271 detailWriters.add(typeAnnotationWriter);
272 }
274 return detailWriters;
275 }
277 private AttributeWriter attrWriter;
278 private ClassWriter classWriter;
279 private ConstantWriter constantWriter;
280 private LocalVariableTableWriter localVariableTableWriter;
281 private LocalVariableTypeTableWriter localVariableTypeTableWriter;
282 private TypeAnnotationWriter typeAnnotationWriter;
283 private SourceWriter sourceWriter;
284 private StackMapWriter stackMapWriter;
285 private TryBlockWriter tryBlockWriter;
286 private Options options;
287 }