1 52 53 package com.go.trove.classfile; 54 55 import java.util.*; 56 import java.io.*; 57 58 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 84 public CodeBuffer getCodeBuffer() { 85 return mCodeBuffer; 86 } 87 88 public void setCodeBuffer(CodeBuffer code) { 89 mCodeBuffer = code; 90 } 91 92 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 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 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 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; } 174 175 return length; 176 } 177 178 public void writeDataTo(DataOutput dout) throws IOException { 179 if (mCodeBuffer == null) { 180 throw new NullPointerException ("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 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 |