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

Tue, 28 Dec 2010 15:54:52 -0800

author
ohair
date
Tue, 28 Dec 2010 15:54:52 -0800
changeset 798
4868a36f6fd8
parent 581
f2fdd52e4e87
child 2525
2eb010b6cb22
permissions
-rw-r--r--

6962318: Update copyright year
Reviewed-by: xdono

jjg@284 1 /*
ohair@554 2 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
jjg@284 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@284 4 *
jjg@284 5 * This code is free software; you can redistribute it and/or modify it
jjg@284 6 * under the terms of the GNU General Public License version 2 only, as
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
jjg@284 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
jjg@284 10 *
jjg@284 11 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@284 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@284 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@284 14 * version 2 for more details (a copy is included in the LICENSE file that
jjg@284 15 * accompanied this code).
jjg@284 16 *
jjg@284 17 * You should have received a copy of the GNU General Public License version
jjg@284 18 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@284 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@284 20 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
jjg@284 24 */
jjg@284 25
jjg@284 26 package com.sun.tools.javap;
jjg@284 27
jjg@284 28 import com.sun.tools.classfile.Attribute;
jjg@284 29 import com.sun.tools.classfile.Code_attribute;
jjg@284 30 import com.sun.tools.classfile.ConstantPool;
jjg@284 31 import com.sun.tools.classfile.ConstantPoolException;
jjg@284 32 import com.sun.tools.classfile.Descriptor;
jjg@284 33 import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
jjg@284 34 import com.sun.tools.classfile.Instruction;
jjg@284 35 import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
jjg@284 36 import com.sun.tools.classfile.Signature;
jjg@284 37 import java.util.ArrayList;
jjg@284 38 import java.util.HashMap;
jjg@284 39 import java.util.List;
jjg@284 40 import java.util.ListIterator;
jjg@284 41 import java.util.Map;
jjg@284 42
jjg@284 43 /**
jjg@284 44 * Annotate instructions with details about local variables.
jjg@284 45 *
jjg@581 46 * <p><b>This is NOT part of any supported API.
jjg@581 47 * If you write code that depends on this, you do so at your own risk.
jjg@284 48 * This code and its internal interfaces are subject to change or
jjg@284 49 * deletion without notice.</b>
jjg@284 50 */
jjg@284 51 public class LocalVariableTypeTableWriter extends InstructionDetailWriter {
jjg@284 52 public enum NoteKind {
jjg@284 53 START("start") {
jjg@284 54 public boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc) {
jjg@284 55 return (pc == entry.start_pc);
jjg@284 56 }
jjg@284 57 },
jjg@284 58 END("end") {
jjg@284 59 public boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc) {
jjg@284 60 return (pc == entry.start_pc + entry.length);
jjg@284 61 }
jjg@284 62 };
jjg@284 63 NoteKind(String text) {
jjg@284 64 this.text = text;
jjg@284 65 }
jjg@284 66 public abstract boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc);
jjg@284 67 public final String text;
jjg@284 68 };
jjg@284 69
jjg@284 70 static LocalVariableTypeTableWriter instance(Context context) {
jjg@284 71 LocalVariableTypeTableWriter instance = context.get(LocalVariableTypeTableWriter.class);
jjg@284 72 if (instance == null)
jjg@284 73 instance = new LocalVariableTypeTableWriter(context);
jjg@284 74 return instance;
jjg@284 75 }
jjg@284 76
jjg@284 77 protected LocalVariableTypeTableWriter(Context context) {
jjg@284 78 super(context);
jjg@284 79 context.put(LocalVariableTypeTableWriter.class, this);
jjg@284 80 classWriter = ClassWriter.instance(context);
jjg@284 81 }
jjg@284 82
jjg@284 83 public void reset(Code_attribute attr) {
jjg@284 84 codeAttr = attr;
jjg@284 85 pcMap = new HashMap<Integer, List<LocalVariableTypeTable_attribute.Entry>>();
jjg@284 86 LocalVariableTypeTable_attribute lvt =
jjg@284 87 (LocalVariableTypeTable_attribute) (attr.attributes.get(Attribute.LocalVariableTypeTable));
jjg@284 88 if (lvt == null)
jjg@284 89 return;
jjg@284 90
jjg@284 91 for (int i = 0; i < lvt.local_variable_table.length; i++) {
jjg@284 92 LocalVariableTypeTable_attribute.Entry entry = lvt.local_variable_table[i];
jjg@284 93 put(entry.start_pc, entry);
jjg@284 94 put(entry.start_pc + entry.length, entry);
jjg@284 95 }
jjg@284 96 }
jjg@284 97
jjg@284 98 public void writeDetails(Instruction instr) {
jjg@284 99 int pc = instr.getPC();
jjg@284 100 writeLocalVariables(pc, NoteKind.END);
jjg@284 101 writeLocalVariables(pc, NoteKind.START);
jjg@284 102 }
jjg@284 103
jjg@284 104 @Override
jjg@284 105 public void flush() {
jjg@284 106 int pc = codeAttr.code_length;
jjg@284 107 writeLocalVariables(pc, NoteKind.END);
jjg@284 108 }
jjg@284 109
jjg@284 110 public void writeLocalVariables(int pc, NoteKind kind) {
jjg@284 111 ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
jjg@284 112 String indent = space(2); // get from Options?
jjg@284 113 List<LocalVariableTypeTable_attribute.Entry> entries = pcMap.get(pc);
jjg@284 114 if (entries != null) {
jjg@284 115 for (ListIterator<LocalVariableTypeTable_attribute.Entry> iter =
jjg@284 116 entries.listIterator(kind == NoteKind.END ? entries.size() : 0);
jjg@284 117 kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) {
jjg@284 118 LocalVariableTypeTable_attribute.Entry entry =
jjg@284 119 kind == NoteKind.END ? iter.previous() : iter.next();
jjg@284 120 if (kind.match(entry, pc)) {
jjg@284 121 print(indent);
jjg@284 122 print(kind.text);
jjg@284 123 print(" generic local ");
jjg@284 124 print(entry.index);
jjg@284 125 print(" // ");
jjg@284 126 Descriptor d = new Signature(entry.signature_index);
jjg@284 127 try {
jjg@427 128 print(d.getFieldType(constant_pool).toString().replace("/", "."));
jjg@284 129 } catch (InvalidDescriptor e) {
jjg@284 130 print(report(e));
jjg@284 131 } catch (ConstantPoolException e) {
jjg@284 132 print(report(e));
jjg@284 133 }
jjg@284 134 print(" ");
jjg@284 135 try {
jjg@284 136 print(constant_pool.getUTF8Value(entry.name_index));
jjg@284 137 } catch (ConstantPoolException e) {
jjg@284 138 print(report(e));
jjg@284 139 }
jjg@284 140 println();
jjg@284 141 }
jjg@284 142 }
jjg@284 143 }
jjg@284 144 }
jjg@284 145
jjg@284 146 private void put(int pc, LocalVariableTypeTable_attribute.Entry entry) {
jjg@284 147 List<LocalVariableTypeTable_attribute.Entry> list = pcMap.get(pc);
jjg@284 148 if (list == null) {
jjg@284 149 list = new ArrayList<LocalVariableTypeTable_attribute.Entry>();
jjg@284 150 pcMap.put(pc, list);
jjg@284 151 }
jjg@284 152 if (!list.contains(entry))
jjg@284 153 list.add(entry);
jjg@284 154 }
jjg@284 155
jjg@284 156 private ClassWriter classWriter;
jjg@284 157 private Code_attribute codeAttr;
jjg@284 158 private Map<Integer, List<LocalVariableTypeTable_attribute.Entry>> pcMap;
jjg@284 159 }

mercurial