00001 package de.fub.bytecode.classfile;
00002
00003 import de.fub.bytecode.Constants;
00004 import java.io.*;
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 public final class Code extends Attribute {
00025 private int max_stack;
00026 private int max_locals;
00027 private int code_length;
00028 private byte[] code;
00029
00030 private int exception_table_length;
00031 private CodeException[] exception_table;
00032 private int attributes_count;
00033 private Attribute[] attributes;
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 public Code(int name_index, int length,
00046 int max_stack, int max_locals,
00047 byte[] code,
00048 CodeException[] exception_table,
00049 Attribute[] attributes,
00050 ConstantPool constant_pool)
00051 {
00052 super(ATTR_CODE, name_index, length, constant_pool);
00053
00054 this.max_stack = max_stack;
00055 this.max_locals = max_locals;
00056
00057 setCode(code);
00058 setExceptionTable(exception_table);
00059 setAttributes(attributes);
00060 }
00061
00062
00063
00064
00065
00066
00067 Code(int name_index, int length, DataInputStream file,
00068 ConstantPool constant_pool) throws IOException
00069 {
00070
00071 this(name_index, length,
00072 file.readUnsignedShort(), file.readUnsignedShort(),
00073 (byte[])null, (CodeException[])null, (Attribute[])null,
00074 constant_pool);
00075
00076 code_length = file.readInt();
00077 code = new byte[code_length];
00078 file.readFully(code);
00079
00080
00081
00082
00083 exception_table_length = file.readUnsignedShort();
00084 exception_table = new CodeException[exception_table_length];
00085
00086 for(int i=0; i < exception_table_length; i++)
00087 exception_table[i] = new CodeException(file);
00088
00089
00090
00091
00092 attributes_count = file.readUnsignedShort();
00093 attributes = new Attribute[attributes_count];
00094 for(int i=0; i < attributes_count; i++)
00095 attributes[i] = Attribute.readAttribute(file, constant_pool);
00096
00097
00098
00099
00100
00101 this.length = length;
00102 }
00103
00104
00105
00106
00107 public Code(Code c) {
00108 this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(),
00109 c.getCode(), c.getExceptionTable(), c.getAttributes(),
00110 c.getConstantPool());
00111 }
00112
00113
00114
00115
00116
00117
00118
00119 public void accept(Visitor v) {
00120 v.visitCode(this);
00121 }
00122
00123
00124
00125
00126 private final int calculateLength() {
00127 int len = 0;
00128
00129 for(int i=0; i < attributes_count; i++)
00130 len += attributes[i].length + 6 ;
00131
00132 return len + getInternalLength();
00133 }
00134
00135
00136
00137 public Attribute copy(ConstantPool constant_pool) {
00138 Code c = (Code)clone();
00139 c.code = (byte[])code.clone();
00140 c.constant_pool = constant_pool;
00141
00142 c.exception_table = new CodeException[exception_table_length];
00143 for(int i=0; i < exception_table_length; i++)
00144 c.exception_table[i] = exception_table[i].copy();
00145
00146 c.attributes = new Attribute[attributes_count];
00147 for(int i=0; i < attributes_count; i++)
00148 c.attributes[i] = attributes[i].copy(constant_pool);
00149
00150 return c;
00151 }
00152
00153
00154
00155
00156
00157
00158 public final void dump(DataOutputStream file) throws IOException
00159 {
00160 super.dump(file);
00161
00162 file.writeShort(max_stack);
00163 file.writeShort(max_locals);
00164 file.writeInt(code_length);
00165 file.write(code, 0, code_length);
00166
00167 file.writeShort(exception_table_length);
00168 for(int i=0; i < exception_table_length; i++)
00169 exception_table[i].dump(file);
00170
00171 file.writeShort(attributes_count);
00172 for(int i=0; i < attributes_count; i++)
00173 attributes[i].dump(file);
00174 }
00175
00176
00177
00178
00179 public final Attribute[] getAttributes() { return attributes; }
00180
00181
00182
00183 public final byte[] getCode() { return code; }
00184
00185
00186
00187
00188 public final CodeException[] getExceptionTable() { return exception_table; }
00189
00190
00191
00192
00193 private final int getInternalLength() {
00194 return 2 + 2 + 4
00195 + code_length
00196 + 2
00197 + 8 * exception_table_length
00198 + 2 ;
00199 }
00200
00201
00202
00203 public LineNumberTable getLineNumberTable() {
00204 for(int i=0; i < attributes_count; i++)
00205 if(attributes[i] instanceof LineNumberTable)
00206 return (LineNumberTable)attributes[i];
00207
00208 return null;
00209 }
00210
00211
00212
00213 public LocalVariableTable getLocalVariableTable() {
00214 for(int i=0; i < attributes_count; i++)
00215 if(attributes[i] instanceof LocalVariableTable)
00216 return (LocalVariableTable)attributes[i];
00217
00218 return null;
00219 }
00220
00221
00222
00223 public final int getMaxLocals() { return max_locals; }
00224
00225
00226
00227
00228 public final int getMaxStack() { return max_stack; }
00229
00230
00231
00232 public final void setAttributes(Attribute[] attributes) {
00233 this.attributes = attributes;
00234 attributes_count = (attributes == null)? 0 : attributes.length;
00235 length = calculateLength();
00236 }
00237
00238
00239
00240 public final void setCode(byte[] code) {
00241 this.code = code;
00242 code_length = (code == null)? 0 : code.length;
00243 }
00244
00245
00246
00247 public final void setExceptionTable(CodeException[] exception_table) {
00248 this.exception_table = exception_table;
00249 exception_table_length = (exception_table == null)? 0 :
00250 exception_table.length;
00251 }
00252
00253
00254
00255 public final void setMaxLocals(int max_locals) {
00256 this.max_locals = max_locals;
00257 }
00258
00259
00260
00261 public final void setMaxStack(int max_stack) {
00262 this.max_stack = max_stack;
00263 }
00264
00265
00266
00267 public final String toString() {
00268 return toString(true);
00269 }
00270
00271
00272
00273 public final String toString(boolean verbose) {
00274 StringBuffer buf;
00275
00276 buf = new StringBuffer("Code(max_stack = " + max_stack +
00277 ", max_locals = " + max_locals +
00278 ", code_length = " + code_length + ")\n" +
00279 Utility.codeToString(code, constant_pool, 0, -1, verbose));
00280
00281 if(exception_table_length > 0) {
00282 buf.append("\nException handler(s) = \n" + "From\tTo\tHandler\tType\n");
00283
00284 for(int i=0; i < exception_table_length; i++)
00285 buf.append(exception_table[i].toString(constant_pool, verbose) + "\n");
00286 }
00287
00288 if(attributes_count > 0) {
00289 buf.append("\nAttribute(s) = \n");
00290
00291 for(int i=0; i < attributes_count; i++)
00292 buf.append(attributes[i].toString() + "\n");
00293 }
00294
00295 return buf.toString();
00296 }
00297 }