1 23 24 25 package com.sun.jdo.api.persistence.enhancer.classfile; 26 27 import java.util.Vector ; 28 import java.io.*; 29 30 34 35 public class CodeAttribute extends ClassAttribute { 36 public final static String expectedAttrName = "Code"; 38 41 private byte theDataBytes[]; 42 43 44 private int maxStack; 45 46 47 private int maxLocals; 48 49 51 private byte theCodeBytes[]; 52 53 55 private Insn theCode; 56 57 59 private ExceptionTable exceptionTable; 60 61 62 private AttributeVector codeAttributes; 63 64 65 CodeEnv codeEnv; 66 67 68 69 70 73 public int stackUsed() { 74 makeValid(); 75 return maxStack; 76 } 77 78 81 public void setStackUsed(int used) { 82 makeValid(); 83 maxStack = used; 84 } 85 86 89 public int localsUsed() { 90 makeValid(); 91 return maxLocals; 92 } 93 94 97 public void setLocalsUsed(int used) { 98 makeValid(); 99 maxLocals = used; 100 } 101 102 106 public byte[] byteCodes() { 107 makeValid(); 108 return theCodeBytes; 109 } 110 111 115 public Insn theCode() { 116 makeValid(); 117 if (theCode == null && codeEnv != null) { 118 buildInstructions(codeEnv); 119 } 120 return theCode; 121 } 122 123 127 public void setTheCode(Insn insn) { 128 makeValid(); 129 if (insn != null && insn.opcode() != Insn.opc_target) 130 throw new InsnError( 131 "The initial instruction in all methods must be a target"); theCode = insn; 133 } 134 135 139 public ExceptionTable exceptionHandlers() { 140 makeValid(); 141 return exceptionTable; 142 } 143 144 147 public AttributeVector attributes() { 148 makeValid(); 149 return codeAttributes; 150 } 151 152 153 156 public CodeAttribute(ConstUtf8 attrName, 157 int maxStack, int maxLocals, 158 Insn code, 159 ExceptionTable excTable, 160 AttributeVector codeAttrs) { 161 this(attrName, maxStack, maxLocals, code, null, 162 excTable, codeAttrs, null ); 163 } 164 165 168 public CodeAttribute(ConstUtf8 attrName, 169 int maxStack, int maxLocals, 170 Insn code, byte[] codeBytes, 171 ExceptionTable excTable, 172 AttributeVector codeAttrs, 173 CodeEnv codeEnv) { 174 super(attrName); 175 this.maxStack = maxStack; 176 this.maxLocals = maxLocals; 177 theCode = code; 178 theCodeBytes = codeBytes; 179 exceptionTable = excTable; 180 codeAttributes = codeAttrs; 181 this.codeEnv = codeEnv; 182 } 183 184 185 188 public CodeAttribute(ConstUtf8 attrName, byte[] dataBytes, CodeEnv codeEnv) { 189 super(attrName); 190 this.theDataBytes = dataBytes; 191 this.codeEnv = codeEnv; 192 } 193 194 195 196 197 198 static CodeAttribute read(ConstUtf8 attrName, 199 DataInputStream data, ConstantPool pool) 200 throws IOException { 201 int maxStack = data.readUnsignedShort(); 202 int maxLocals = data.readUnsignedShort(); 203 int codeLength = data.readInt(); 204 byte codeBytes[] = new byte[codeLength]; 205 data.readFully(codeBytes); 206 Insn code = null; 207 CodeEnv codeEnv = new CodeEnv(pool); 208 209 ExceptionTable excTable = ExceptionTable.read(data, codeEnv); 210 211 AttributeVector codeAttrs = 212 AttributeVector.readAttributes(data, codeEnv); 213 214 return new CodeAttribute(attrName, maxStack, maxLocals, code, codeBytes, 215 excTable, codeAttrs, codeEnv); 216 } 217 218 220 static CodeAttribute read(ConstUtf8 attrName, int attrLength, 221 DataInputStream data, ConstantPool pool) 222 throws IOException { 223 byte dataBytes[] = new byte[attrLength]; 224 data.readFully(dataBytes); 225 return new CodeAttribute(attrName, dataBytes, new CodeEnv(pool)); 226 } 227 228 void write(DataOutputStream out) throws IOException { 229 out.writeShort(attrName().getIndex()); 230 if (theDataBytes == null) { 231 buildInstructionBytes(); 232 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 233 DataOutputStream tmpOut = new DataOutputStream(baos); 234 tmpOut.writeShort(maxStack); 235 tmpOut.writeShort(maxLocals); 236 tmpOut.writeInt(theCodeBytes.length); 237 tmpOut.write(theCodeBytes, 0, theCodeBytes.length); 238 exceptionTable.write(tmpOut); 239 codeAttributes.write(tmpOut); 240 241 tmpOut.flush(); 242 byte tmpBytes[] = baos.toByteArray(); 243 out.writeInt(tmpBytes.length); 244 out.write(tmpBytes, 0, tmpBytes.length); 245 } else { 246 out.writeInt(theDataBytes.length); 247 out.write(theDataBytes, 0, theDataBytes.length); 248 } 249 } 250 251 void print(PrintStream out, int indent) { 252 makeValid(); 253 ClassPrint.spaces(out, indent); 254 out.print("Code:"); out.print(" max_stack = " + Integer.toString(maxStack)); out.print(" max_locals = " + Integer.toString(maxLocals)); out.println(" Exceptions:"); exceptionTable.print(out, indent+2); 259 ClassPrint.spaces(out, indent); 260 out.println("Code Attributes:"); codeAttributes.print(out, indent+2); 262 263 Insn insn = theCode(); 264 if (insn != null) { 265 ClassPrint.spaces(out, indent); 266 out.println("Instructions:"); while (insn != null) { 268 insn.print(out, indent+2); 269 insn = insn.next(); 270 } 271 } 272 } 273 274 278 private int resolveOffsets() { 279 Insn insn = theCode; 280 int currPC = 0; 281 while (insn != null) { 282 currPC = insn.resolveOffset(currPC); 283 insn = insn.next(); 284 } 285 return currPC; 286 } 287 288 int codeSize() { 289 makeValid(); 290 return theCodeBytes.length; 291 } 292 293 296 private void buildInstructions(CodeEnv codeEnv) { 297 if (theCodeBytes != null) { 298 InsnReadEnv insnEnv = new InsnReadEnv(theCodeBytes, codeEnv); 299 theCode = insnEnv.getTarget(0); 300 Insn currInsn = theCode; 301 302 303 while (insnEnv.more()) { 304 Insn newInsn = Insn.read(insnEnv); 305 currInsn.setNext(newInsn); 306 currInsn = newInsn; 307 } 308 309 310 InsnTarget targ; 311 currInsn = theCode; 312 Insn prevInsn = null; 313 while (currInsn != null) { 314 int off = currInsn.offset(); 315 316 317 if (off > 0) { 318 targ = codeEnv.findTarget(off); 319 if (targ != null) 320 prevInsn.setNext(targ); 321 } 322 prevInsn = currInsn; 323 currInsn = currInsn.next(); 324 } 325 326 327 targ = codeEnv.findTarget(insnEnv.currentPC()); 328 if (targ != null) 329 prevInsn.setNext(targ); 330 } 331 } 332 333 338 private void buildInstructionBytes() { 339 if (theCode != null) { 340 341 int size = resolveOffsets(); 342 theCodeBytes = new byte[size]; 343 344 Insn insn = theCode; 345 int index = 0; 346 while (insn != null) { 347 index = insn.store(theCodeBytes, index); 348 insn = insn.next(); 349 } 350 } 351 } 352 353 355 private void makeValid() { 356 if (theDataBytes != null) { 357 DataInputStream dis = new DataInputStream( 358 new ByteArrayInputStream(theDataBytes)); 359 try { 360 maxStack = dis.readUnsignedShort(); 361 maxLocals = dis.readUnsignedShort(); 362 int codeLength = dis.readInt(); 363 theCodeBytes = new byte[codeLength]; 364 dis.readFully(theCodeBytes); 365 exceptionTable = ExceptionTable.read(dis, codeEnv); 366 codeAttributes = AttributeVector.readAttributes(dis, codeEnv); 367 } catch (java.io.IOException ioe) { 368 ClassFormatError cfe = new ClassFormatError ( 369 "IOException while reading code attribute"); cfe.initCause(ioe); 371 throw cfe; 372 } 373 374 theDataBytes = null; 375 } 376 } 377 378 } 379 380 | Popular Tags |