1 cananian 1.1.2.2 // AttributeLocalVariableTable.java, created Mon Jan 18 22:44:36 1999 by cananian
  2 cananian 1.1.2.1 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1.2.1 package harpoon.IR.RawClass;
  5 cananian 1.1.2.1 
  6 cananian 1.1.2.1 /** 
  7 cananian 1.1.2.1  * The <code>LocalVariableTable</code> attribute is an optional
  8 cananian 1.1.2.1  * variable-length attribute of a <code>Code</code> attribute.  It may
  9 cananian 1.1.2.1  * be used by debuggers to determine the value of a given local variable
 10 cananian 1.1.2.1  * during the execution of a method.  If <code>LocalVariableTable</code>
 11 cananian 1.1.2.1  * attributes are present in the <code>attributes</code> table of a
 12 cananian 1.1.2.1  * given <code>Code</code> attribute, then they may appear in any
 13 cananian 1.1.2.1  * order.  There may be no more than one <code>LocalVariableTable</code>
 14 cananian 1.1.2.1  * attribute per local variable in the <code>Code</code> attribute.
 15 cananian 1.1.2.1  * <p>
 16 cananian 1.1.2.1  * This object represents a table mapping local variable indexes to
 17 cananian 1.1.2.1  * symbolic names.  This attribute is optional; typically it is
 18 cananian 1.1.2.1  * not included unless debugging flags are given to the compiler.
 19 cananian 1.1.2.1  *
 20 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 21 cananian 1.3      * @version $Id: AttributeLocalVariableTable.java,v 1.3 2003/09/05 21:45:16 cananian Exp $
 22 cananian 1.1.2.1  * @see "The Java Virtual Machine Specification, section 4.7.7"
 23 cananian 1.1.2.1  * @see AttributeCode
 24 cananian 1.1.2.1  * @see Attribute
 25 cananian 1.1.2.1  */
 26 cananian 1.1.2.1 public class AttributeLocalVariableTable extends Attribute {
 27 cananian 1.3       /** The string naming this <code>Attribute</code> type. */
 28 cananian 1.3       public static final String ATTRIBUTE_NAME = "LocalVariableTable";
 29 cananian 1.1.2.1   /** Each entry in the <code>local_variable_table</code> array
 30 cananian 1.1.2.1       indicates a range of <code>code</code> offsets within which a
 31 cananian 1.1.2.1       local variable has a value.  It also indicates the index into
 32 cananian 1.1.2.1       the local variables of the current frame at which that local
 33 cananian 1.1.2.1       variable can be found. */
 34 cananian 1.1.2.1   public LocalVariableTable local_variable_table[];
 35 cananian 1.1.2.1 
 36 cananian 1.1.2.1   /** Constructor. */
 37 cananian 1.1.2.1   AttributeLocalVariableTable(ClassFile parent, ClassDataInputStream in,
 38 cananian 1.1.2.1                               int attribute_name_index) 
 39 cananian 1.1.2.1     throws java.io.IOException
 40 cananian 1.1.2.1   {
 41 cananian 1.1.2.1     super(parent, attribute_name_index);
 42 cananian 1.1.2.1     long attribute_length = in.read_u4();
 43 cananian 1.1.2.1 
 44 cananian 1.1.2.1     int local_variable_table_length = in.read_u2();
 45 cananian 1.1.2.1     local_variable_table = new LocalVariableTable[local_variable_table_length];
 46 cananian 1.1.2.1     for (int i=0; i<local_variable_table_length; i++)
 47 cananian 1.1.2.1       local_variable_table[i] = new LocalVariableTable(parent, in);
 48 cananian 1.1.2.1 
 49 cananian 1.1.2.1     if (attribute_length != attribute_length())
 50 cananian 1.1.2.1       throw new ClassDataException("LocalVariableTable with length "
 51 cananian 1.1.2.1                                    + attribute_length);
 52 cananian 1.3         assert ATTRIBUTE_NAME.equals(attribute_name());
 53 cananian 1.1.2.1   }
 54 cananian 1.1.2.1   /** Constructor. */
 55 cananian 1.1.2.1   public AttributeLocalVariableTable(ClassFile parent,int attribute_name_index,
 56 cananian 1.1.2.1                                      LocalVariableTable local_variable_table[])
 57 cananian 1.1.2.1   {
 58 cananian 1.1.2.1     super(parent, attribute_name_index);
 59 cananian 1.1.2.1     this.local_variable_table = local_variable_table;
 60 cananian 1.3         assert ATTRIBUTE_NAME.equals(attribute_name());
 61 cananian 1.1.2.1   }
 62 cananian 1.1.2.1 
 63 cananian 1.1.2.1   public long attribute_length() { 
 64 cananian 1.1.2.1     return 2 + 10*local_variable_table_length();
 65 cananian 1.1.2.1   }
 66 cananian 1.1.2.1 
 67 cananian 1.1.2.1   // Convenience.
 68 cananian 1.1.2.1   public int local_variable_table_length() 
 69 cananian 1.1.2.1   { return local_variable_table.length; }
 70 cananian 1.1.2.1 
 71 cananian 1.1.2.1   /** Write to bytecode stream. */
 72 cananian 1.1.2.1   public void write(ClassDataOutputStream out) throws java.io.IOException {
 73 cananian 1.1.2.1     out.write_u2(attribute_name_index);
 74 cananian 1.1.2.1     out.write_u4(attribute_length());
 75 cananian 1.1.2.1 
 76 cananian 1.1.2.1     out.write_u2(local_variable_table_length());
 77 cananian 1.1.2.1     for (int i=0; i< local_variable_table.length; i++)
 78 cananian 1.1.2.1       local_variable_table[i].write(out);
 79 cananian 1.1.2.1   }
 80 cananian 1.1.2.1 
 81 cananian 1.1.2.1   /** Get the (debugging) name of a local variable.
 82 cananian 1.1.2.1    * @param  pc the pc at which the inquiry is being made.
 83 cananian 1.1.2.1    * @param  index the index of the local variable to query.
 84 cananian 1.1.2.1    * @return the name of the index'th local variable, or null
 85 cananian 1.1.2.1    *         if none can be found.
 86 cananian 1.1.2.1    */
 87 cananian 1.1.2.1   public String localName(int pc, int index) {
 88 cananian 1.1.2.1     for (int i=0; i<local_variable_table.length; i++)
 89 cananian 1.1.2.1       if ((local_variable_table[i].index == index) &&
 90 cananian 1.1.2.1           (local_variable_table[i].start_pc <= pc) &&
 91 cananian 1.1.2.1           (pc <= local_variable_table[i].end_pc()))
 92 cananian 1.1.2.1         return local_variable_table[i].name();
 93 cananian 1.1.2.1     return null;
 94 cananian 1.1.2.1   }
 95 cananian 1.1.2.1 
 96 cananian 1.1.2.1   /** Pretty-print the contents of this attribute.
 97 cananian 1.1.2.1    *  @param indent the indentation level to use.
 98 cananian 1.1.2.1    */
 99 cananian 1.1.2.1   public void print(java.io.PrintWriter pw, int indent) {
100 cananian 1.1.2.1     int in=indent;
101 cananian 1.1.2.1     indent(pw, in, 
102 cananian 1.1.2.1            "LocalVariableTable attribute ["+local_variable_table.length+"]:");
103 cananian 1.1.2.1     for (int i=0; i<local_variable_table.length; i++) {
104 cananian 1.1.2.1       indent(pw, in+1, "#"+i+":");
105 cananian 1.1.2.1       local_variable_table[i].print(pw, in+2);
106 cananian 1.1.2.1     }
107 cananian 1.1.2.1   }
108 cananian 1.2     }