1 25 26 package org.netbeans.modules.classfile; 27 28 import java.io.DataInputStream ; 29 import java.io.IOException ; 30 31 36 public final class Code { 37 private static final boolean debug = false; 38 39 private int maxStack; 40 private int maxLocals; 41 private byte[] byteCodes; 42 private ExceptionTableEntry[] exceptionTable; 43 private int[] lineNumberTable; 44 private LocalVariableTableEntry[] localVariableTable; 45 private LocalVariableTypeTableEntry[] localVariableTypeTable; 46 private StackMapFrame[] stackMapTable; 47 48 49 Code(DataInputStream in, ConstantPool pool) throws IOException { 50 if (in == null) 51 throw new IllegalArgumentException ("input stream not specified"); 52 if (pool == null) 53 throw new IllegalArgumentException ("constant pool not specified"); 54 try { 55 loadCode(in, pool); 56 } catch (IndexOutOfBoundsException e) { 57 throw new InvalidClassFileAttributeException("invalid code attribute", e); 58 } 59 } 60 61 private void loadCode(DataInputStream in, ConstantPool pool) 62 throws IOException { 63 maxStack = in.readUnsignedShort(); 64 maxLocals = in.readUnsignedShort(); 65 int len = in.readInt(); 66 byteCodes = new byte[len]; 67 in.readFully(byteCodes); 68 exceptionTable = ExceptionTableEntry.loadExceptionTable(in, pool); 69 loadCodeAttributes(in, pool); 70 } 71 72 private void loadCodeAttributes(DataInputStream in, ConstantPool pool) 73 throws IOException { 74 int count = in.readUnsignedShort(); 75 for (int i = 0; i < count; i++) { 76 Object o = pool.get(in.readUnsignedShort()); 77 if (!(o instanceof CPUTF8Info)) 78 throw new InvalidClassFormatException(); 79 CPUTF8Info entry = (CPUTF8Info)o; 80 int len = in.readInt(); 81 String name = entry.getName(); 82 if (name.equals("LineNumberTable")) loadLineNumberTable(in, pool); 84 else if (name.equals("LocalVariableTable")) localVariableTable = 86 LocalVariableTableEntry.loadLocalVariableTable(in, pool); 87 else if (name.equals("LocalVariableTypeTable")) localVariableTypeTable = 89 LocalVariableTypeTableEntry.loadLocalVariableTypeTable(in, pool); 90 else if (name.equals("StackMapTable")) stackMapTable = StackMapFrame.loadStackMapTable(in, pool); 92 else { 93 if (debug) 94 System.out.println("skipped unknown code attribute: " + name); 95 int n; 97 while ((n = (int)in.skip(len)) > 0 && n < len) 98 len -= n; 99 } 100 } 101 if (lineNumberTable == null) 102 lineNumberTable = new int[0]; 103 if (localVariableTable == null) 104 localVariableTable = new LocalVariableTableEntry[0]; 105 if (localVariableTypeTable == null) 106 localVariableTypeTable = new LocalVariableTypeTableEntry[0]; 107 if (stackMapTable == null) 108 stackMapTable = new StackMapFrame[0]; 109 } 110 111 private void loadLineNumberTable(DataInputStream in, ConstantPool pool) throws IOException { 112 int n = in.readUnsignedShort(); 113 lineNumberTable = new int[n * 2]; 114 for (int i = 0; i < n; i++) { 115 lineNumberTable[i * 2] = in.readUnsignedShort(); lineNumberTable[i * 2 + 1] = in.readUnsignedShort(); } 118 } 119 120 public final int getMaxStack() { 121 return maxStack; 122 } 123 124 public final int getMaxLocals() { 125 return maxLocals; 126 } 127 128 public final byte[] getByteCodes() { 129 return byteCodes.clone(); 130 } 131 132 public final ExceptionTableEntry[] getExceptionTable() { 133 return exceptionTable.clone(); 134 } 135 136 141 public final int[] getLineNumberTable() { 142 return lineNumberTable.clone(); 143 } 144 145 148 public final LocalVariableTableEntry[] getLocalVariableTable() { 149 return localVariableTable.clone(); 150 } 151 152 157 public final LocalVariableTypeTableEntry[] getLocalVariableTypeTable() { 158 return localVariableTypeTable.clone(); 159 } 160 161 165 public final StackMapFrame[] getStackMapTable() { 166 return stackMapTable.clone(); 167 } 168 169 public String toString() { 170 StringBuffer sb = new StringBuffer ("Code: bytes="); 171 sb.append(byteCodes.length); 172 sb.append(", stack="); 173 sb.append(maxStack); 174 sb.append(", locals="); 175 sb.append(maxLocals); 176 return sb.toString(); 177 } 178 } 179 | Popular Tags |