src/share/classes/com/sun/tools/javap/CodeWriter.java

Thu, 30 Jul 2009 09:18:55 -0700

author
jjg
date
Thu, 30 Jul 2009 09:18:55 -0700
changeset 346
e33efb09ed75
parent 338
777a3efad0d5
child 348
743f17b55b44
permissions
-rw-r--r--

4880672: javap does not output inner interfaces of an interface
Reviewed-by: mcimadamore

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

mercurial