src/share/classes/com/sun/tools/javap/LocalVariableTableWriter.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.LocalVariableTable_attribute;
jjg@284 36 import java.util.ArrayList;
jjg@284 37 import java.util.HashMap;
jjg@284 38 import java.util.List;
jjg@284 39 import java.util.ListIterator;
jjg@284 40 import java.util.Map;
jjg@284 41
jjg@284 42 /**
jjg@284 43 * Annotate instructions with details about local variables.
jjg@284 44 *
jjg@581 45 * <p><b>This is NOT part of any supported API.
jjg@581 46 * If you write code that depends on this, you do so at your own risk.
jjg@284 47 * This code and its internal interfaces are subject to change or
jjg@284 48 * deletion without notice.</b>
jjg@284 49 */
jjg@284 50 public class LocalVariableTableWriter extends InstructionDetailWriter {
jjg@284 51 public enum NoteKind {
jjg@284 52 START("start") {
jjg@284 53 public boolean match(LocalVariableTable_attribute.Entry entry, int pc) {
jjg@284 54 return (pc == entry.start_pc);
jjg@284 55 }
jjg@284 56 },
jjg@284 57 END("end") {
jjg@284 58 public boolean match(LocalVariableTable_attribute.Entry entry, int pc) {
jjg@284 59 return (pc == entry.start_pc + entry.length);
jjg@284 60 }
jjg@284 61 };
jjg@284 62 NoteKind(String text) {
jjg@284 63 this.text = text;
jjg@284 64 }
jjg@284 65 public abstract boolean match(LocalVariableTable_attribute.Entry entry, int pc);
jjg@284 66 public final String text;
jjg@284 67 };
jjg@284 68
jjg@284 69 static LocalVariableTableWriter instance(Context context) {
jjg@284 70 LocalVariableTableWriter instance = context.get(LocalVariableTableWriter.class);
jjg@284 71 if (instance == null)
jjg@284 72 instance = new LocalVariableTableWriter(context);
jjg@284 73 return instance;
jjg@284 74 }
jjg@284 75
jjg@284 76 protected LocalVariableTableWriter(Context context) {
jjg@284 77 super(context);
jjg@284 78 context.put(LocalVariableTableWriter.class, this);
jjg@284 79 classWriter = ClassWriter.instance(context);
jjg@284 80 }
jjg@284 81
jjg@284 82 public void reset(Code_attribute attr) {
jjg@284 83 codeAttr = attr;
jjg@284 84 pcMap = new HashMap<Integer, List<LocalVariableTable_attribute.Entry>>();
jjg@284 85 LocalVariableTable_attribute lvt =
jjg@284 86 (LocalVariableTable_attribute) (attr.attributes.get(Attribute.LocalVariableTable));
jjg@284 87 if (lvt == null)
jjg@284 88 return;
jjg@284 89
jjg@284 90 for (int i = 0; i < lvt.local_variable_table.length; i++) {
jjg@284 91 LocalVariableTable_attribute.Entry entry = lvt.local_variable_table[i];
jjg@284 92 put(entry.start_pc, entry);
jjg@284 93 put(entry.start_pc + entry.length, entry);
jjg@284 94 }
jjg@284 95 }
jjg@284 96
jjg@284 97 public void writeDetails(Instruction instr) {
jjg@284 98 int pc = instr.getPC();
jjg@284 99 writeLocalVariables(pc, NoteKind.END);
jjg@284 100 writeLocalVariables(pc, NoteKind.START);
jjg@284 101 }
jjg@284 102
jjg@284 103 @Override
jjg@284 104 public void flush() {
jjg@284 105 int pc = codeAttr.code_length;
jjg@284 106 writeLocalVariables(pc, NoteKind.END);
jjg@284 107 }
jjg@284 108
jjg@284 109 public void writeLocalVariables(int pc, NoteKind kind) {
jjg@284 110 ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
jjg@284 111 String indent = space(2); // get from Options?
jjg@284 112 List<LocalVariableTable_attribute.Entry> entries = pcMap.get(pc);
jjg@284 113 if (entries != null) {
jjg@284 114 for (ListIterator<LocalVariableTable_attribute.Entry> iter =
jjg@284 115 entries.listIterator(kind == NoteKind.END ? entries.size() : 0);
jjg@284 116 kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) {
jjg@284 117 LocalVariableTable_attribute.Entry entry =
jjg@284 118 kind == NoteKind.END ? iter.previous() : iter.next();
jjg@284 119 if (kind.match(entry, pc)) {
jjg@284 120 print(indent);
jjg@284 121 print(kind.text);
jjg@284 122 print(" local ");
jjg@284 123 print(entry.index);
jjg@284 124 print(" // ");
jjg@284 125 Descriptor d = new Descriptor(entry.descriptor_index);
jjg@284 126 try {
jjg@284 127 print(d.getFieldType(constant_pool));
jjg@284 128 } catch (InvalidDescriptor e) {
jjg@284 129 print(report(e));
jjg@284 130 } catch (ConstantPoolException e) {
jjg@284 131 print(report(e));
jjg@284 132 }
jjg@284 133 print(" ");
jjg@284 134 try {
jjg@284 135 print(constant_pool.getUTF8Value(entry.name_index));
jjg@284 136 } catch (ConstantPoolException e) {
jjg@284 137 print(report(e));
jjg@284 138 }
jjg@284 139 println();
jjg@284 140 }
jjg@284 141 }
jjg@284 142 }
jjg@284 143 }
jjg@284 144
jjg@284 145 private void put(int pc, LocalVariableTable_attribute.Entry entry) {
jjg@284 146 List<LocalVariableTable_attribute.Entry> list = pcMap.get(pc);
jjg@284 147 if (list == null) {
jjg@284 148 list = new ArrayList<LocalVariableTable_attribute.Entry>();
jjg@284 149 pcMap.put(pc, list);
jjg@284 150 }
jjg@284 151 if (!list.contains(entry))
jjg@284 152 list.add(entry);
jjg@284 153 }
jjg@284 154
jjg@284 155 private ClassWriter classWriter;
jjg@284 156 private Code_attribute codeAttr;
jjg@284 157 private Map<Integer, List<LocalVariableTable_attribute.Entry>> pcMap;
jjg@284 158 }

mercurial