1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javap/LocalVariableTableWriter.java Tue May 19 13:53:00 2009 -0700 1.3 @@ -0,0 +1,158 @@ 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.LocalVariableTable_attribute; 1.39 +import java.util.ArrayList; 1.40 +import java.util.HashMap; 1.41 +import java.util.List; 1.42 +import java.util.ListIterator; 1.43 +import java.util.Map; 1.44 + 1.45 +/** 1.46 + * Annotate instructions with details about local variables. 1.47 + * 1.48 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 1.49 + * you write code that depends on this, you do so at your own risk. 1.50 + * This code and its internal interfaces are subject to change or 1.51 + * deletion without notice.</b> 1.52 + */ 1.53 +public class LocalVariableTableWriter extends InstructionDetailWriter { 1.54 + public enum NoteKind { 1.55 + START("start") { 1.56 + public boolean match(LocalVariableTable_attribute.Entry entry, int pc) { 1.57 + return (pc == entry.start_pc); 1.58 + } 1.59 + }, 1.60 + END("end") { 1.61 + public boolean match(LocalVariableTable_attribute.Entry entry, int pc) { 1.62 + return (pc == entry.start_pc + entry.length); 1.63 + } 1.64 + }; 1.65 + NoteKind(String text) { 1.66 + this.text = text; 1.67 + } 1.68 + public abstract boolean match(LocalVariableTable_attribute.Entry entry, int pc); 1.69 + public final String text; 1.70 + }; 1.71 + 1.72 + static LocalVariableTableWriter instance(Context context) { 1.73 + LocalVariableTableWriter instance = context.get(LocalVariableTableWriter.class); 1.74 + if (instance == null) 1.75 + instance = new LocalVariableTableWriter(context); 1.76 + return instance; 1.77 + } 1.78 + 1.79 + protected LocalVariableTableWriter(Context context) { 1.80 + super(context); 1.81 + context.put(LocalVariableTableWriter.class, this); 1.82 + classWriter = ClassWriter.instance(context); 1.83 + } 1.84 + 1.85 + public void reset(Code_attribute attr) { 1.86 + codeAttr = attr; 1.87 + pcMap = new HashMap<Integer, List<LocalVariableTable_attribute.Entry>>(); 1.88 + LocalVariableTable_attribute lvt = 1.89 + (LocalVariableTable_attribute) (attr.attributes.get(Attribute.LocalVariableTable)); 1.90 + if (lvt == null) 1.91 + return; 1.92 + 1.93 + for (int i = 0; i < lvt.local_variable_table.length; i++) { 1.94 + LocalVariableTable_attribute.Entry entry = lvt.local_variable_table[i]; 1.95 + put(entry.start_pc, entry); 1.96 + put(entry.start_pc + entry.length, entry); 1.97 + } 1.98 + } 1.99 + 1.100 + public void writeDetails(Instruction instr) { 1.101 + int pc = instr.getPC(); 1.102 + writeLocalVariables(pc, NoteKind.END); 1.103 + writeLocalVariables(pc, NoteKind.START); 1.104 + } 1.105 + 1.106 + @Override 1.107 + public void flush() { 1.108 + int pc = codeAttr.code_length; 1.109 + writeLocalVariables(pc, NoteKind.END); 1.110 + } 1.111 + 1.112 + public void writeLocalVariables(int pc, NoteKind kind) { 1.113 + ConstantPool constant_pool = classWriter.getClassFile().constant_pool; 1.114 + String indent = space(2); // get from Options? 1.115 + List<LocalVariableTable_attribute.Entry> entries = pcMap.get(pc); 1.116 + if (entries != null) { 1.117 + for (ListIterator<LocalVariableTable_attribute.Entry> iter = 1.118 + entries.listIterator(kind == NoteKind.END ? entries.size() : 0); 1.119 + kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) { 1.120 + LocalVariableTable_attribute.Entry entry = 1.121 + kind == NoteKind.END ? iter.previous() : iter.next(); 1.122 + if (kind.match(entry, pc)) { 1.123 + print(indent); 1.124 + print(kind.text); 1.125 + print(" local "); 1.126 + print(entry.index); 1.127 + print(" // "); 1.128 + Descriptor d = new Descriptor(entry.descriptor_index); 1.129 + try { 1.130 + print(d.getFieldType(constant_pool)); 1.131 + } catch (InvalidDescriptor e) { 1.132 + print(report(e)); 1.133 + } catch (ConstantPoolException e) { 1.134 + print(report(e)); 1.135 + } 1.136 + print(" "); 1.137 + try { 1.138 + print(constant_pool.getUTF8Value(entry.name_index)); 1.139 + } catch (ConstantPoolException e) { 1.140 + print(report(e)); 1.141 + } 1.142 + println(); 1.143 + } 1.144 + } 1.145 + } 1.146 + } 1.147 + 1.148 + private void put(int pc, LocalVariableTable_attribute.Entry entry) { 1.149 + List<LocalVariableTable_attribute.Entry> list = pcMap.get(pc); 1.150 + if (list == null) { 1.151 + list = new ArrayList<LocalVariableTable_attribute.Entry>(); 1.152 + pcMap.put(pc, list); 1.153 + } 1.154 + if (!list.contains(entry)) 1.155 + list.add(entry); 1.156 + } 1.157 + 1.158 + private ClassWriter classWriter; 1.159 + private Code_attribute codeAttr; 1.160 + private Map<Integer, List<LocalVariableTable_attribute.Entry>> pcMap; 1.161 +}