KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > go > trove > classfile > CodeAttr


1 /* ====================================================================
2  * Trove - Copyright (c) 1997-2000 Walt Disney Internet Group
3  * ====================================================================
4  * The Tea Software License, Version 1.1
5  *
6  * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Walt Disney Internet Group (http://opensource.go.com/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact opensource@dig.com.
31  *
32  * 5. Products derived from this software may not be called "Tea",
33  * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
34  * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
35  * written permission of the Walt Disney Internet Group.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
41  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * For more information about Tea, please see http://opensource.go.com/.
51  */

52
53 package com.go.trove.classfile;
54
55 import java.util.*;
56 import java.io.*;
57
58 /******************************************************************************
59  * This class corresponds to the Code_attribute structure as defined in
60  * section 4.7.4 of <i>The Java Virtual Machine Specification</i>.
61  * To make it easier to create bytecode for the CodeAttr, use the
62  * CodeBuilder.
63  *
64  * @author Brian S O'Neill
65  * @version
66  * <!--$$Revision:--> 34 <!-- $-->, <!--$$JustDate:--> 01/01/02 <!-- $-->
67  * @see Opcode
68  * @see CodeBuilder
69  */

70 public class CodeAttr extends Attribute {
71     private CodeBuffer mCodeBuffer;
72     private List mAttributes = new ArrayList(2);
73     
74     private LineNumberTableAttr mLineNumberTable;
75     private LocalVariableTableAttr mLocalVariableTable;
76
77     CodeAttr(ConstantPool cp) {
78         super(cp, CODE);
79     }
80     
81     /**
82      * Returns null if no CodeBuffer is defined for this CodeAttr.
83      */

84     public CodeBuffer getCodeBuffer() {
85         return mCodeBuffer;
86     }
87
88     public void setCodeBuffer(CodeBuffer code) {
89         mCodeBuffer = code;
90     }
91     
92     /**
93      * Returns the line number in the source code from the given bytecode
94      * address (start_pc).
95      *
96      * @return -1 if no line number is mapped for the start_pc.
97      */

98     public int getLineNumber(Location start) {
99         if (mLineNumberTable == null || start.getLocation() < 0) {
100             return -1;
101         }
102         else {
103             return mLineNumberTable.getLineNumber(start);
104         }
105     }
106
107     /**
108      * Map a bytecode address (start_pc) to a line number in the source code
109      * as a debugging aid.
110      */

111     public void mapLineNumber(Location start, int line_number) {
112         if (mLineNumberTable == null) {
113             addAttribute(new LineNumberTableAttr(mCp));
114         }
115
116         mLineNumberTable.addEntry(start, line_number);
117     }
118
119     /**
120      * Indicate a local variable's use information be recorded in the
121      * ClassFile as a debugging aid. If the LocalVariable doesn't provide
122      * both a start and end location, then its information is not recorded.
123      * This method should be called at most once per LocalVariable instance.
124      */

125     public void localVariableUse(LocalVariable localVar) {
126         if (mLocalVariableTable == null) {
127             addAttribute(new LocalVariableTableAttr(mCp));
128         }
129
130         mLocalVariableTable.addEntry(localVar);
131     }
132
133     public void addAttribute(Attribute attr) {
134         if (attr instanceof LineNumberTableAttr) {
135             if (mLineNumberTable != null) {
136                 mAttributes.remove(mLineNumberTable);
137             }
138             mLineNumberTable = (LineNumberTableAttr)attr;
139         }
140         else if (attr instanceof LocalVariableTableAttr) {
141             if (mLocalVariableTable != null) {
142                 mAttributes.remove(mLocalVariableTable);
143             }
144             mLocalVariableTable = (LocalVariableTableAttr)attr;
145         }
146
147         mAttributes.add(attr);
148     }
149     
150     public Attribute[] getAttributes() {
151         Attribute[] attrs = new Attribute[mAttributes.size()];
152         return (Attribute[])mAttributes.toArray(attrs);
153     }
154
155     /**
156      * Returns the length (in bytes) of this object in the class file.
157      */

158     public int getLength() {
159         int length = 12;
160
161         if (mCodeBuffer != null) {
162             length += mCodeBuffer.getByteCodes().length;
163             ExceptionHandler[] handlers = mCodeBuffer.getExceptionHandlers();
164             if (handlers != null) {
165                 length += 8 * handlers.length;
166             }
167         }
168         
169         int size = mAttributes.size();
170         for (int i=0; i<size; i++) {
171             length += ((Attribute)mAttributes.get(i)).getLength();
172             length += 6; // attributes have an intial 6 byte length
173
}
174         
175         return length;
176     }
177
178     public void writeDataTo(DataOutput dout) throws IOException {
179         if (mCodeBuffer == null) {
180             throw new NullPointerException JavaDoc("CodeAttr has no CodeBuffer set");
181         }
182
183         ExceptionHandler[] handlers = mCodeBuffer.getExceptionHandlers();
184         
185         dout.writeShort(mCodeBuffer.getMaxStackDepth());
186         dout.writeShort(mCodeBuffer.getMaxLocals());
187         
188         byte[] byteCodes = mCodeBuffer.getByteCodes();
189         dout.writeInt(byteCodes.length);
190         dout.write(byteCodes);
191
192         if (handlers != null) {
193             int exceptionHandlerCount = handlers.length;
194             dout.writeShort(exceptionHandlerCount);
195
196             for (int i=0; i<exceptionHandlerCount; i++) {
197                 handlers[i].writeTo(dout);
198             }
199         }
200         else {
201             dout.writeShort(0);
202         }
203         
204         int size = mAttributes.size();
205         dout.writeShort(size);
206         for (int i=0; i<size; i++) {
207             Attribute attr = (Attribute)mAttributes.get(i);
208             attr.writeTo(dout);
209         }
210     }
211
212     static Attribute define(ConstantPool cp,
213                             String JavaDoc name,
214                             int length,
215                             DataInput din,
216                             AttributeFactory attrFactory)
217         throws IOException
218     {
219         CodeAttr code = new CodeAttr(cp);
220
221         final int maxStackDepth = din.readUnsignedShort();
222         final int maxLocals = din.readUnsignedShort();
223
224         final byte[] byteCodes = new byte[din.readInt()];
225         din.readFully(byteCodes);
226
227         int exceptionHandlerCount = din.readUnsignedShort();
228         final ExceptionHandler[] handlers =
229             new ExceptionHandler[exceptionHandlerCount];
230
231         for (int i=0; i<exceptionHandlerCount; i++) {
232             handlers[i] = ExceptionHandler.readFrom(cp, din);
233         }
234         
235         code.mCodeBuffer = new CodeBuffer() {
236             public int getMaxStackDepth() {
237                 return maxStackDepth;
238             }
239             
240             public int getMaxLocals() {
241                 return maxLocals;
242             }
243             
244             public byte[] getByteCodes() {
245                 return (byte[])byteCodes.clone();
246             }
247             
248             public ExceptionHandler[] getExceptionHandlers() {
249                 return (ExceptionHandler[])handlers.clone();
250             }
251         };
252
253         int attributeCount = din.readUnsignedShort();
254         for (int i=0; i<attributeCount; i++) {
255             code.addAttribute(Attribute.readFrom(cp, din, attrFactory));
256         }
257
258         return code;
259     }
260 }
261
Popular Tags