1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javap/LocalVariableTypeTableWriter.java Tue May 19 13:53:00 2009 -0700 1.3 @@ -0,0 +1,159 @@ 1.4 +/* 1.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Sun designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Sun in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.26 + * have any questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javap; 1.30 + 1.31 +import com.sun.tools.classfile.Attribute; 1.32 +import com.sun.tools.classfile.Code_attribute; 1.33 +import com.sun.tools.classfile.ConstantPool; 1.34 +import com.sun.tools.classfile.ConstantPoolException; 1.35 +import com.sun.tools.classfile.Descriptor; 1.36 +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; 1.37 +import com.sun.tools.classfile.Instruction; 1.38 +import com.sun.tools.classfile.LocalVariableTypeTable_attribute; 1.39 +import com.sun.tools.classfile.Signature; 1.40 +import java.util.ArrayList; 1.41 +import java.util.HashMap; 1.42 +import java.util.List; 1.43 +import java.util.ListIterator; 1.44 +import java.util.Map; 1.45 + 1.46 +/** 1.47 + * Annotate instructions with details about local variables. 1.48 + * 1.49 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 1.50 + * you write code that depends on this, you do so at your own risk. 1.51 + * This code and its internal interfaces are subject to change or 1.52 + * deletion without notice.</b> 1.53 + */ 1.54 +public class LocalVariableTypeTableWriter extends InstructionDetailWriter { 1.55 + public enum NoteKind { 1.56 + START("start") { 1.57 + public boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc) { 1.58 + return (pc == entry.start_pc); 1.59 + } 1.60 + }, 1.61 + END("end") { 1.62 + public boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc) { 1.63 + return (pc == entry.start_pc + entry.length); 1.64 + } 1.65 + }; 1.66 + NoteKind(String text) { 1.67 + this.text = text; 1.68 + } 1.69 + public abstract boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc); 1.70 + public final String text; 1.71 + }; 1.72 + 1.73 + static LocalVariableTypeTableWriter instance(Context context) { 1.74 + LocalVariableTypeTableWriter instance = context.get(LocalVariableTypeTableWriter.class); 1.75 + if (instance == null) 1.76 + instance = new LocalVariableTypeTableWriter(context); 1.77 + return instance; 1.78 + } 1.79 + 1.80 + protected LocalVariableTypeTableWriter(Context context) { 1.81 + super(context); 1.82 + context.put(LocalVariableTypeTableWriter.class, this); 1.83 + classWriter = ClassWriter.instance(context); 1.84 + } 1.85 + 1.86 + public void reset(Code_attribute attr) { 1.87 + codeAttr = attr; 1.88 + pcMap = new HashMap<Integer, List<LocalVariableTypeTable_attribute.Entry>>(); 1.89 + LocalVariableTypeTable_attribute lvt = 1.90 + (LocalVariableTypeTable_attribute) (attr.attributes.get(Attribute.LocalVariableTypeTable)); 1.91 + if (lvt == null) 1.92 + return; 1.93 + 1.94 + for (int i = 0; i < lvt.local_variable_table.length; i++) { 1.95 + LocalVariableTypeTable_attribute.Entry entry = lvt.local_variable_table[i]; 1.96 + put(entry.start_pc, entry); 1.97 + put(entry.start_pc + entry.length, entry); 1.98 + } 1.99 + } 1.100 + 1.101 + public void writeDetails(Instruction instr) { 1.102 + int pc = instr.getPC(); 1.103 + writeLocalVariables(pc, NoteKind.END); 1.104 + writeLocalVariables(pc, NoteKind.START); 1.105 + } 1.106 + 1.107 + @Override 1.108 + public void flush() { 1.109 + int pc = codeAttr.code_length; 1.110 + writeLocalVariables(pc, NoteKind.END); 1.111 + } 1.112 + 1.113 + public void writeLocalVariables(int pc, NoteKind kind) { 1.114 + ConstantPool constant_pool = classWriter.getClassFile().constant_pool; 1.115 + String indent = space(2); // get from Options? 1.116 + List<LocalVariableTypeTable_attribute.Entry> entries = pcMap.get(pc); 1.117 + if (entries != null) { 1.118 + for (ListIterator<LocalVariableTypeTable_attribute.Entry> iter = 1.119 + entries.listIterator(kind == NoteKind.END ? entries.size() : 0); 1.120 + kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) { 1.121 + LocalVariableTypeTable_attribute.Entry entry = 1.122 + kind == NoteKind.END ? iter.previous() : iter.next(); 1.123 + if (kind.match(entry, pc)) { 1.124 + print(indent); 1.125 + print(kind.text); 1.126 + print(" generic local "); 1.127 + print(entry.index); 1.128 + print(" // "); 1.129 + Descriptor d = new Signature(entry.signature_index); 1.130 + try { 1.131 + print(d.getFieldType(constant_pool)); 1.132 + } catch (InvalidDescriptor e) { 1.133 + print(report(e)); 1.134 + } catch (ConstantPoolException e) { 1.135 + print(report(e)); 1.136 + } 1.137 + print(" "); 1.138 + try { 1.139 + print(constant_pool.getUTF8Value(entry.name_index)); 1.140 + } catch (ConstantPoolException e) { 1.141 + print(report(e)); 1.142 + } 1.143 + println(); 1.144 + } 1.145 + } 1.146 + } 1.147 + } 1.148 + 1.149 + private void put(int pc, LocalVariableTypeTable_attribute.Entry entry) { 1.150 + List<LocalVariableTypeTable_attribute.Entry> list = pcMap.get(pc); 1.151 + if (list == null) { 1.152 + list = new ArrayList<LocalVariableTypeTable_attribute.Entry>(); 1.153 + pcMap.put(pc, list); 1.154 + } 1.155 + if (!list.contains(entry)) 1.156 + list.add(entry); 1.157 + } 1.158 + 1.159 + private ClassWriter classWriter; 1.160 + private Code_attribute codeAttr; 1.161 + private Map<Integer, List<LocalVariableTypeTable_attribute.Entry>> pcMap; 1.162 +}