Index: main/java/org/apache/harmony/pack200/bytecode/Attribute.java =================================================================== --- main/java/org/apache/harmony/pack200/bytecode/Attribute.java (revision 598833) +++ main/java/org/apache/harmony/pack200/bytecode/Attribute.java (working copy) @@ -20,59 +20,81 @@ import java.io.IOException; public abstract class Attribute extends ClassFileEntry { - private final CPUTF8 attributeName; + private final CPUTF8 attributeName; - private int attributeNameIndex; + private int attributeNameIndex; - public Attribute(String attributeName) { - this.attributeName = new CPUTF8(attributeName); - } + public Attribute(String attributeName) { + this.attributeName = new CPUTF8(attributeName); + } - protected void doWrite(DataOutputStream dos) throws IOException { - dos.writeShort(attributeNameIndex); - dos.writeInt(getLength()); - writeBody(dos); - } + protected void doWrite(DataOutputStream dos) throws IOException { + dos.writeShort(attributeNameIndex); + dos.writeInt(getLength()); + writeBody(dos); + } - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (this.getClass() != obj.getClass()) - return false; - final Attribute other = (Attribute) obj; - if (attributeName == null) { - if (other.attributeName != null) - return false; - } else if (!attributeName.equals(other.attributeName)) - return false; - return true; - } + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (this.getClass() != obj.getClass()) + return false; + final Attribute other = (Attribute) obj; + if (attributeName == null) { + if (other.attributeName != null) + return false; + } else if (!attributeName.equals(other.attributeName)) + return false; + return true; + } - protected CPUTF8 getAttributeName() { - return attributeName; - } + protected CPUTF8 getAttributeName() { + return attributeName; + } - protected abstract int getLength(); + protected abstract int getLength(); - protected ClassFileEntry[] getNestedClassFileEntries() { - return new ClassFileEntry[] { getAttributeName() }; - } + /** + * Answer the length of the receiver including its + * header (the u2 for the attribute name and the + * u4 for the attribute length). This is relevant + * when attributes are nested within other attributes - + * the outer attribute needs to take the inner attribute + * headers into account when calculating its length. + * @return int adjusted length + */ + protected int getLengthIncludingHeader() { + return getLength() + 2 + 4; + } + + protected ClassFileEntry[] getNestedClassFileEntries() { + return new ClassFileEntry[] { getAttributeName() }; + } - public int hashCode() { - final int PRIME = 31; - int result = 1; - result = PRIME * result - + ((attributeName == null) ? 0 : attributeName.hashCode()); - return result; - } + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = PRIME * result + + ((attributeName == null) ? 0 : attributeName.hashCode()); + return result; + } - protected void resolve(ClassConstantPool pool) { - super.resolve(pool); - attributeNameIndex = pool.indexOf(attributeName); - } + protected void resolve(ClassConstantPool pool) { + super.resolve(pool); + attributeNameIndex = pool.indexOf(attributeName); + } - protected abstract void writeBody(DataOutputStream dos) throws IOException; + /** + * Answer true if the receiver needs to have BCI renumbering + * applied to it; otherwise answer false. + * @return boolean BCI renumbering required + */ + public boolean hasBCIRenumbering() { + return false; + } + + protected abstract void writeBody(DataOutputStream dos) throws IOException; } \ No newline at end of file Index: main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java =================================================================== --- main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java (revision 598833) +++ main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java (working copy) @@ -26,105 +26,102 @@ import org.apache.harmony.pack200.SegmentUtils; public class CodeAttribute extends Attribute { - public List attributes = new ArrayList(); - public List byteCodes = new ArrayList(); - public int codeLength; - public List exceptionTable = new ArrayList(); // of ExceptionTableEntry - // instances - public List byteCodeOffsets = new ArrayList(); - public int maxLocals; - public int maxStack; + public List attributes = new ArrayList(); + public List byteCodes = new ArrayList(); + public int codeLength; + public List exceptionTable = new ArrayList(); // of ExceptionTableEntry + // instances + public List byteCodeOffsets = new ArrayList(); + public int maxLocals; + public int maxStack; - public CodeAttribute(int maxStack, int maxLocals, byte codePacked[], - Segment segment, OperandManager operandManager) { - super("Code"); //$NON-NLS-1$ - this.maxLocals = maxLocals; - this.maxStack = maxStack; - this.codeLength = 0; - byteCodeOffsets.add(new Integer(0)); - for (int i = 0; i < codePacked.length; i++) { - ByteCode byteCode = ByteCode.getByteCode(codePacked[i] & 0xff); - byteCode.extractOperands(operandManager, segment); - byteCodes.add(byteCode); - this.codeLength += byteCode.getLength(); - int lastBytecodePosition = ((Integer)byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue(); - // This code assumes all multiple byte bytecodes are - // replaced by a single-byte bytecode followed by - // another bytecode. - if(byteCode.hasMultipleByteCodes()) { - byteCodeOffsets.add(new Integer(lastBytecodePosition + 1)); - } - // I've already added the first element (at 0) before - // entering this loop, so make sure I don't add one - // after the last element. - if(i < (codePacked.length - 1)) { - byteCodeOffsets.add(new Integer(lastBytecodePosition + byteCode.getLength())); - } - } - } + public CodeAttribute(int maxStack, int maxLocals, byte codePacked[], + Segment segment, OperandManager operandManager) { + super("Code"); //$NON-NLS-1$ + this.maxLocals = maxLocals; + this.maxStack = maxStack; + this.codeLength = 0; + byteCodeOffsets.add(new Integer(0)); + for (int i = 0; i < codePacked.length; i++) { + ByteCode byteCode = ByteCode.getByteCode(codePacked[i] & 0xff); + byteCode.extractOperands(operandManager, segment); + byteCodes.add(byteCode); + this.codeLength += byteCode.getLength(); + int lastBytecodePosition = ((Integer)byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue(); + // This code assumes all multiple byte bytecodes are + // replaced by a single-byte bytecode followed by + // another bytecode. + if(byteCode.hasMultipleByteCodes()) { + byteCodeOffsets.add(new Integer(lastBytecodePosition + 1)); + } + // I've already added the first element (at 0) before + // entering this loop, so make sure I don't add one + // after the last element. + if(i < (codePacked.length - 1)) { + byteCodeOffsets.add(new Integer(lastBytecodePosition + byteCode.getLength())); + } + } + } - protected int getLength() { - int attributesSize = 0; - Iterator it = attributes.iterator(); - while (it.hasNext()) { - Attribute attribute = (Attribute) it.next(); - attributesSize += attribute.getLength(); - } - return 2 + 2 + 4 + codeLength + exceptionTable.size() * (2 + 2 + 2 + 2) - + 2 + attributesSize; - } + protected int getLength() { + int attributesSize = 0; + Iterator it = attributes.iterator(); + while (it.hasNext()) { + Attribute attribute = (Attribute) it.next(); + attributesSize += attribute.getLengthIncludingHeader(); + } + return 2 + 2 + 4 + codeLength + 2 + (exceptionTable.size() * (2 + 2 + 2 + 2)) + + 2 + attributesSize; + } - protected ClassFileEntry[] getNestedClassFileEntries() { - ArrayList nestedEntries = new ArrayList(); - nestedEntries.add(getAttributeName()); - nestedEntries.addAll(byteCodes); - ClassFileEntry[] nestedEntryArray = new ClassFileEntry[nestedEntries.size()]; - nestedEntries.toArray(nestedEntryArray); - return nestedEntryArray; - } + protected ClassFileEntry[] getNestedClassFileEntries() { + ArrayList nestedEntries = new ArrayList(); + nestedEntries.add(getAttributeName()); + nestedEntries.addAll(byteCodes); + ClassFileEntry[] nestedEntryArray = new ClassFileEntry[nestedEntries.size()]; + nestedEntries.toArray(nestedEntryArray); + return nestedEntryArray; + } - protected void resolve(ClassConstantPool pool) { - super.resolve(pool); - Iterator it = attributes.iterator(); - while (it.hasNext()) { - Attribute attribute = (Attribute) it.next(); - SegmentUtils.debug("CodeAttribute resolving " + attribute); - attribute.resolve(pool); - } - it = byteCodes.iterator(); - while (it.hasNext()) { - ByteCode byteCode = (ByteCode) it.next(); - byteCode.resolve(pool); - } - } + protected void resolve(ClassConstantPool pool) { + super.resolve(pool); + Iterator it = attributes.iterator(); + while (it.hasNext()) { + Attribute attribute = (Attribute) it.next(); + attribute.resolve(pool); + } + it = byteCodes.iterator(); + while (it.hasNext()) { + ByteCode byteCode = (ByteCode) it.next(); + byteCode.resolve(pool); + } + } - public String toString() { - // TODO More Info here later - return "Code: " + getLength() + " bytes"; - } + public String toString() { + return "Code: " + getLength() + " bytes"; + } - protected void writeBody(DataOutputStream dos) throws IOException { - dos.writeShort(maxStack); - dos.writeShort(maxLocals); - dos.writeInt(codeLength); - Iterator it = byteCodes.iterator(); - while (it.hasNext()) { - ByteCode byteCode = (ByteCode) it.next(); - byteCode.write(dos); - } - dos.writeShort(exceptionTable.size()); - Iterator exceptionTableEntries = exceptionTable.iterator(); - while (exceptionTableEntries.hasNext()) { - ExceptionTableEntry entry = (ExceptionTableEntry) exceptionTableEntries - .next(); - entry.write(dos); - } - dos.writeShort(attributes.size()); - it = attributes.iterator(); - while (it.hasNext()) { - Attribute attribute = (Attribute) it.next(); - attribute.write(dos); - } - } - + protected void writeBody(DataOutputStream dos) throws IOException { + dos.writeShort(maxStack); + dos.writeShort(maxLocals); + dos.writeInt(codeLength); + Iterator it = byteCodes.iterator(); + while (it.hasNext()) { + ByteCode byteCode = (ByteCode) it.next(); + byteCode.write(dos); + } + dos.writeShort(exceptionTable.size()); + Iterator exceptionTableEntries = exceptionTable.iterator(); + while (exceptionTableEntries.hasNext()) { + ExceptionTableEntry entry = (ExceptionTableEntry) exceptionTableEntries + .next(); + entry.write(dos); + } + dos.writeShort(attributes.size()); + it = attributes.iterator(); + while (it.hasNext()) { + Attribute attribute = (Attribute) it.next(); + attribute.write(dos); + } + } }