001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package components;
028:
029: import java.io.DataOutput;
030: import java.io.DataInput;
031: import java.io.IOException;
032: import util.DataFormatException;
033: import java.util.Hashtable;
034:
035: /*
036: * A class to represent the Code Attribute
037: * of a method
038: */
039:
040: public class CodeAttribute extends Attribute {
041: public int stack;
042: public int locals;
043: public byte code[];
044: public ExceptionEntry exceptionTable[];
045: public Attribute codeAttributes[];
046:
047: public CodeAttribute(UnicodeConstant name, int l, int ns, int nl,
048: byte c[], ExceptionEntry et[], Attribute ca[]) {
049: super (name, l);
050: stack = ns;
051: locals = nl;
052: code = c;
053: exceptionTable = et;
054: codeAttributes = ca;
055: }
056:
057: public void externalize(ConstantPool p) {
058: super .externalize(p);
059: Attribute.externalizeAttributes(codeAttributes, p);
060: }
061:
062: public void countConstantReferences(boolean isRelocatable) {
063: super .countConstantReferences(isRelocatable);
064: if (exceptionTable != null) {
065: for (int i = 0; i < exceptionTable.length; i++) {
066: exceptionTable[i].countConstantReferences();
067: }
068: }
069: Attribute
070: .countConstantReferences(codeAttributes, isRelocatable);
071: }
072:
073: protected int writeData(DataOutput o) throws IOException {
074: int trueLength = 8 + code.length;
075: o.writeShort(stack);
076: o.writeShort(locals);
077: o.writeInt(code.length);
078: o.write(code, 0, code.length);
079: if (exceptionTable == null) {
080: o.writeShort(0);
081: trueLength += 2;
082: } else {
083: o.writeShort(exceptionTable.length);
084: for (int i = 0; i < exceptionTable.length; i++) {
085: exceptionTable[i].write(o);
086: }
087: trueLength += 2 + exceptionTable.length
088: * ExceptionEntry.size;
089: }
090: if (codeAttributes == null) {
091: o.writeShort(0);
092: trueLength += 2;
093: } else {
094: Attribute.writeAttributes(codeAttributes, o, false);
095: trueLength += Attribute.length(codeAttributes);
096: }
097: return trueLength;
098: }
099:
100: /*
101: * This hashtable is for use when reading code attributes.
102: * The only code attribute we're interested in is
103: * the LineNumberTableAttribute.
104: * Other stuff we ignore.
105: */
106: static private Hashtable codeAttributeTypes = new Hashtable();
107: static {
108: codeAttributeTypes.put("LineNumberTable",
109: LineNumberTableAttributeFactory.instance);
110: codeAttributeTypes.put("LocalVariableTable",
111: LocalVariableTableAttributeFactory.instance);
112: codeAttributeTypes.put("StackMap",
113: StackMapAttributeFactory.instance);
114: }
115:
116: public static Attribute readAttribute(DataInput i,
117: ConstantObject locals[], ConstantObject globals[])
118: throws IOException {
119: UnicodeConstant name;
120:
121: name = (UnicodeConstant) globals[i.readUnsignedShort()];
122: return finishReadAttribute(i, name, locals, globals);
123: }
124:
125: //
126: // for those cases where we already read the name index
127: // and know that its not something requiring special handling.
128: //
129: public static Attribute finishReadAttribute(DataInput in,
130: UnicodeConstant name, ConstantObject locals[],
131: ConstantObject globals[]) throws IOException {
132: int l;
133: int nstack;
134: int nlocals;
135: ConstantObject d;
136: ExceptionEntry exceptionTable[];
137:
138: l = in.readInt();
139: nstack = in.readUnsignedShort();
140: nlocals = in.readUnsignedShort();
141:
142: int codesize = in.readInt();
143: byte code[] = new byte[codesize];
144: in.readFully(code);
145:
146: int tableSize = in.readUnsignedShort();
147: exceptionTable = new ExceptionEntry[tableSize];
148: for (int j = 0; j < tableSize; j++) {
149: int sPC = in.readUnsignedShort();
150: int e = in.readUnsignedShort();
151: int h = in.readUnsignedShort();
152: int catchTypeIndex = in.readUnsignedShort();
153: ClassConstant ctype;
154: if (catchTypeIndex == 0) {
155: ctype = null;
156: } else {
157: ctype = (ClassConstant) locals[catchTypeIndex];
158: }
159: exceptionTable[j] = new ExceptionEntry(sPC, e, h, ctype);
160: }
161:
162: Attribute a[] = Attribute.readAttributes(in, locals, globals,
163: codeAttributeTypes, false);
164: return new CodeAttribute(name, l, nstack, nlocals, code,
165: exceptionTable, a);
166: }
167:
168: }
|