1 cananian 1.1.2.2 // AttributeExceptions.java, created Mon Jan 18 22:44:34 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>Exceptions</code> attribute is a variable-length
 8 cananian 1.1.2.1  * attribute used in the <code>attributes</code> table of a
 9 cananian 1.1.2.1  * <code>method_info</code> structure.  The <code>Exceptions</code>
10 cananian 1.1.2.1  * attribute indicates which checked exceptions a method may throw.  The
11 cananian 1.1.2.1  * must be exactly one <code>Exceptions</code> attribute in each
12 cananian 1.1.2.1  * <code>method_info</code> structure.
13 cananian 1.1.2.1  *
14 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
15 cananian 1.3      * @version $Id: AttributeExceptions.java,v 1.3 2003/09/05 21:45:16 cananian Exp $
16 cananian 1.1.2.1  * @see "The Java Virtual Machine Specification, section 4.7.5"
17 cananian 1.1.2.1  * @see Attribute
18 cananian 1.1.2.1  * @see MethodInfo
19 cananian 1.1.2.1  */
20 cananian 1.1.2.1 public class AttributeExceptions extends Attribute {
21 cananian 1.3       /** The string naming this <code>Attribute</code> type. */
22 cananian 1.3       public static final String ATTRIBUTE_NAME = "Exceptions";
23 cananian 1.1.2.1   /** Each nonzero value in the <code>exception_index_table</code>
24 cananian 1.1.2.1       must be a valid index into the <code>constant_pool</code>
25 cananian 1.1.2.1       table.  For each table item, if
26 cananian 1.1.2.1       <code>exception_index_table[i] != 0</code>, where <code>0 <= i <
27 cananian 1.1.2.1       number_of_exceptions</code>, then the <code>constant_pool</code>
28 cananian 1.1.2.1       entry at index <code>exception_index_table[i]</code> must be a
29 cananian 1.1.2.1       <code>CONSTANT_Class_info</code> structure representing a class
30 cananian 1.1.2.1       type that this method is declared to throw. */
31 cananian 1.1.2.1   public int exception_index_table[];
32 cananian 1.1.2.1   
33 cananian 1.1.2.1   /** Constructor. */
34 cananian 1.1.2.1   AttributeExceptions(ClassFile parent, ClassDataInputStream in,
35 cananian 1.1.2.1                       int attribute_name_index) throws java.io.IOException
36 cananian 1.1.2.1   {
37 cananian 1.1.2.1     super(parent, attribute_name_index);
38 cananian 1.1.2.1     long attribute_length = in.read_u4();
39 cananian 1.1.2.1 
40 cananian 1.1.2.1     int number_of_exceptions = in.read_u2();
41 cananian 1.1.2.1     exception_index_table = new int[number_of_exceptions];
42 cananian 1.1.2.1     for(int i=0; i<number_of_exceptions; i++)
43 cananian 1.1.2.1       exception_index_table[i] = in.read_u2();
44 cananian 1.1.2.1 
45 cananian 1.1.2.1     if (attribute_length != attribute_length())
46 cananian 1.1.2.1       throw new ClassDataException("Exceptions attribute with length "
47 cananian 1.1.2.1                                    + attribute_length);
48 cananian 1.3         assert ATTRIBUTE_NAME.equals(attribute_name());
49 cananian 1.1.2.1   }
50 cananian 1.1.2.1   
51 cananian 1.1.2.1   /** Constructor. */
52 cananian 1.1.2.1   public AttributeExceptions(ClassFile parent, int attribute_name_index,
53 cananian 1.1.2.1                              int exception_index_table[]) {
54 cananian 1.1.2.1     super(parent, attribute_name_index);
55 cananian 1.1.2.1     this.exception_index_table = exception_index_table;
56 cananian 1.3         assert ATTRIBUTE_NAME.equals(attribute_name());
57 cananian 1.1.2.1   }
58 cananian 1.1.2.1 
59 cananian 1.1.2.1   public long attribute_length() { return 2 + 2*number_of_exceptions(); }
60 cananian 1.1.2.1 
61 cananian 1.1.2.1   // convenience.
62 cananian 1.1.2.1   public int number_of_exceptions() { return exception_index_table.length; }
63 cananian 1.1.2.1   /** Returns the CONSTANT_Class_info corresponding to an entry in
64 cananian 1.1.2.1    *  the exception_index_table.  Returns <code>null</code> if the
65 cananian 1.1.2.1    *  entry is zero.
66 cananian 1.1.2.1    */
67 cananian 1.1.2.1   public ConstantClass exception_index_table(int i) {
68 cananian 1.1.2.1     if (exception_index_table[i]==0) return null;
69 cananian 1.1.2.1     else return (ConstantClass)
70 cananian 1.1.2.1            parent.constant_pool[exception_index_table[i]];
71 cananian 1.1.2.1   }
72 cananian 1.1.2.1 
73 cananian 1.1.2.1   /** Write to bytecode stream. */
74 cananian 1.1.2.1   public void write(ClassDataOutputStream out) throws java.io.IOException {
75 cananian 1.1.2.1     out.write_u2(attribute_name_index);
76 cananian 1.1.2.1     out.write_u4(attribute_length());
77 cananian 1.1.2.1     out.write_u2(number_of_exceptions());
78 cananian 1.1.2.1     for (int i=0; i<exception_index_table.length; i++)
79 cananian 1.1.2.1       out.write_u2(exception_index_table[i]);
80 cananian 1.1.2.1   }
81 cananian 1.1.2.1 
82 cananian 1.1.2.1   /** Pretty-print the contents of this attribute.
83 cananian 1.1.2.1    *  @param indent the indentation level to use.
84 cananian 1.1.2.1    */
85 cananian 1.1.2.1   public void print(java.io.PrintWriter pw, int indent) {
86 cananian 1.1.2.1     int in=indent;
87 cananian 1.1.2.1     indent(pw, in, "Exceptions attribute ["+number_of_exceptions()+"]:");
88 cananian 1.1.2.1     for (int i=0; i<exception_index_table.length; i++)
89 cananian 1.1.2.1       indent(pw, in+1, "#"+i+": " +
90 cananian 1.1.2.1              (exception_index_table(i)==null?"<nothing>":
91 cananian 1.1.2.1               exception_index_table(i).name()) +
92 cananian 1.1.2.1              " {"+exception_index_table[i]+"}");
93 cananian 1.1.2.1   }
94 cananian 1.2     }