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