Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 29085 invoked from network); 3 Jan 2008 13:13:48 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 3 Jan 2008 13:13:48 -0000 Received: (qmail 43391 invoked by uid 500); 3 Jan 2008 13:13:37 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 43293 invoked by uid 500); 3 Jan 2008 13:13:36 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 43284 invoked by uid 99); 3 Jan 2008 13:13:36 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 03 Jan 2008 05:13:36 -0800 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 03 Jan 2008 13:13:21 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 4FF2C1A9832; Thu, 3 Jan 2008 05:13:21 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r608472 - in /harmony/enhanced/classlib/trunk/modules/pack200/src: main/java/org/apache/harmony/pack200/ main/java/org/apache/harmony/pack200/bytecode/ main/java/org/apache/harmony/pack200/bytecode/forms/ test/java/org/apache/harmony/pack20... Date: Thu, 03 Jan 2008 13:13:17 -0000 To: commits@harmony.apache.org From: tellison@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080103131323.4FF2C1A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: tellison Date: Thu Jan 3 05:13:15 2008 New Revision: 608472 URL: http://svn.apache.org/viewvc?rev=608472&view=rev Log: Apply patch HARMONY-5289 ([pack200][classlib] Added code to support tableswitch/lookupswitch) Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java (with props) harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java (with props) Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IincForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java Thu Jan 3 05:13:15 2008 @@ -299,7 +299,15 @@ // other bytecode bands debug("Parsed *bc_codes (" + bcParsed + ")"); bcCaseCount = decodeBandInt("bc_case_count", in, Codec.UNSIGNED5, bcCaseCountCount); - bcCaseValue = decodeBandInt("bc_case_value", in, Codec.DELTA5, bcCaseCount); + // TODO HACK HACK: Not sure how this should be done. + // bcCaseValue = decodeBandInt("bc_case_value", in, Codec.DELTA5, new int[]{1} /* to test tableswitch */); + bcCaseValue = decodeBandInt("bc_case_value", in, Codec.DELTA5, bcCaseCount /* to test lookupswitch */); + // Every case value needs a label. We weren't able to count these + // above, because we didn't know how many cases there were. + // Have to correct it now. + for(int index=0; index < bcCaseCountCount; index++) { + bcLabelCount += bcCaseCount[index]; + } bcByte = decodeBandInt("bc_byte", in, Codec.BYTE1, bcByteCount); bcShort = decodeBandInt("bc_short", in, Codec.DELTA5, bcShortCount); bcLocal = decodeBandInt("bc_local", in, Codec.UNSIGNED5, bcLocalCount); @@ -337,10 +345,10 @@ bcEscSize = decodeBandInt("bc_escsize", in, Codec.UNSIGNED5, bcEscCount); bcEscByte = decodeBandInt("bc_escbyte", in, Codec.BYTE1, bcEscSize); - OperandManager operandManager = new OperandManager(bcByte, bcShort, - bcLocal, bcLabel, bcIntRef, bcFloatRef, bcLongRef, bcDoubleRef, - bcStringRef, bcClassRef, bcFieldRef, bcMethodRef, bcIMethodRef, - bcThisField, bcSuperField, bcThisMethod, bcSuperMethod, + OperandManager operandManager = new OperandManager(bcCaseCount, bcCaseValue, + bcByte, bcShort, bcLocal, bcLabel, bcIntRef, bcFloatRef, bcLongRef, + bcDoubleRef, bcStringRef, bcClassRef, bcFieldRef, bcMethodRef, + bcIMethodRef, bcThisField, bcSuperField, bcThisMethod, bcSuperMethod, bcInitRef); operandManager.setSegment(segment); @@ -373,7 +381,9 @@ // broken because these tables don't get renumbered // properly. Commenting out the add so the class files // will verify. - //attr.attributes.add(currentAttribute); + // if(currentAttribute.getClass() == LineNumberTableAttribute.class) { + attr.attributes.add(currentAttribute); + // } // Fix up the line numbers if needed if(currentAttribute.hasBCIRenumbering()) { ((BCIRenumberedAttribute)currentAttribute).renumber(attr.byteCodeOffsets); Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java Thu Jan 3 05:13:15 2008 @@ -36,7 +36,7 @@ private int[] rewrite; private int byteCodeOffset = -1; - private int byteCodeTarget = -1; + private int[] byteCodeTargets = null; protected ByteCode(int opcode) { this(opcode, ClassFileEntry.NONE); @@ -69,14 +69,13 @@ return true; } - public void extractOperands(OperandManager operandManager, Segment segment) { + public void extractOperands(OperandManager operandManager, Segment segment, int codeLength) { // Given an OperandTable, figure out which operands // the receiver needs and stuff them in operands. // Later on the operands can be rewritten (But that's // later, not now). - ByteCodeForm currentByteCodeForm = getByteCodeForm(); - currentByteCodeForm.setByteCodeOperands(this, operandManager); + currentByteCodeForm.setByteCodeOperands(this, operandManager, codeLength); } protected ByteCodeForm getByteCodeForm() { @@ -131,7 +130,7 @@ break; case 2: - setOperandInt(pool.indexOf(nested[index]), getNestedPosition(index)[0]); + setOperand2Bytes(pool.indexOf(nested[index]), getNestedPosition(index)[0]); break; case 4: @@ -172,7 +171,7 @@ rewrite[index + firstOperandIndex] = operands[index] & 0xFF; } } - + /** * Given an int operand, set the rewrite bytes for * that position and the one immediately following it @@ -184,7 +183,7 @@ * position 0 is the first -1, position 1 is the second -1, * etc. */ - public void setOperandInt(int operand, int position) { + public void setOperand2Bytes(int operand, int position) { int firstOperandIndex = getByteCodeForm().firstOperandIndex(); int byteCodeFormLength = getByteCodeForm().getRewrite().length; if (firstOperandIndex < 1) { @@ -206,12 +205,12 @@ * @param operand int to set the rewrite bytes to * @param position int position of the operands in the rewrite bytes */ - public void setOperandSignedInt(int operand, int position) { + public void setOperandSigned2Bytes(int operand, int position) { if(operand >= 0) { - setOperandInt(operand, position); + setOperand2Bytes(operand, position); } else { int twosComplementOperand = 0x10000 + operand; - setOperandInt(twosComplementOperand, position); + setOperand2Bytes(twosComplementOperand, position); } } @@ -315,31 +314,60 @@ } /** - * Some ByteCodes (in particular, LabelForm bytecodes) - * have to keep track of a byteCodeTarget. This is - * initially an offset in the CodeAttribute array - * relative to the byteCodeOffset, but later gets fixed + * Some ByteCodes (in particular, those with labels) + * have to keep track of byteCodeTargets. These are + * initially offsets in the CodeAttribute array + * relative to the byteCodeOffset, but later get fixed * up to point to the absolute position in the CodeAttribute - * array. This method sets the target. + * array. This method sets the targets. * * @param byteCodeTarget int index in array */ - public void setByteCodeTarget(int byteCodeTarget) { - this.byteCodeTarget = byteCodeTarget; + public void setByteCodeTargets(int[] byteCodeTargets) { + this.byteCodeTargets = byteCodeTargets; } - public int getByteCodeTarget() { - return byteCodeTarget; + public int[] getByteCodeTargets() { + return byteCodeTargets; } /** - * Some ByteCodes (in particular, those with the Label - * form) need to be fixed up after all the bytecodes - * in the CodeAttribute have been added. (This can't + * Some ByteCodes (in particular, those with labels + * need to be fixed up after all the bytecodes in the + * CodeAttribute have been added. (This can't * be done beforehand because the CodeAttribute needs * to be complete before targets can be assigned.) */ public void applyByteCodeTargetFixup(CodeAttribute codeAttribute) { - getByteCodeForm().fixUpByteCodeTarget(this, codeAttribute); + getByteCodeForm().fixUpByteCodeTargets(this, codeAttribute); + } + + /** + * Some bytecodes (the ones with variable lengths) can't + * have a static rewrite array - they need the ability to + * update the array. This method permits that. + * + * Note that this should not be called from bytecodes + * which have a static rewrite; use the table in ByteCodeForm + * instead to specify those rewrites. + * + * @param rewrite + */ + public void setRewrite(int[] rewrite) { + this.rewrite = rewrite; + } + + /** + * Some bytecodes (the ones with variable lengths) can't + * have a static rewrite array - they need the ability to + * update the array. This method permits their associated + * bytecode formst to query their rewrite array. + * + * Note that this should not be called from bytecodes + * which have a static rewrite; use the table in ByteCodeForm + * instead to specify those rewrites. + */ + public int[] getRewrite() { + return rewrite; } } Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java Thu Jan 3 05:13:15 2008 @@ -46,7 +46,7 @@ // Setting the offset must happen before extracting operands // because label bytecodes need to know their offsets. byteCode.setByteCodeIndex(i); - byteCode.extractOperands(operandManager, segment); + byteCode.extractOperands(operandManager, segment, codeLength); byteCodes.add(byteCode); codeLength += byteCode.getLength(); int lastBytecodePosition = ((Integer) byteCodeOffsets Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java Thu Jan 3 05:13:15 2008 @@ -90,8 +90,12 @@ public void renumber(List byteCodeOffsets) { // First fix up the start_pcs super.renumber(byteCodeOffsets); + // lengths are BRANCH5 encoded, not BCI-encoded. + // In other words - renumber(x) - renumber(x0)? + // Add the offset to the value? // Next fix up the lengths - int maxLength = ((Integer)byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue(); + int lastInstruction = ((Integer)byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue(); + int maxLength = lastInstruction + 1; for(int index=0; index < lengths.length; index++) { // Need to special case when the length is greater than the size int revisedLength = -1; @@ -100,7 +104,7 @@ // end of the byte code offsets. Need to determine which this is. if(encodedLength == byteCodeOffsets.size()) { // Pointing to one past the end of the byte code array - revisedLength = maxLength - start_pcs[index] + 1; + revisedLength = maxLength - start_pcs[index]; } else { // We're indexed into the byte code array revisedLength = ((Integer)byteCodeOffsets.get(encodedLength)).intValue(); Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java Thu Jan 3 05:13:15 2008 @@ -28,6 +28,8 @@ */ public class OperandManager { + int[] bcCaseCount; + int[][] bcCaseValue; int[] bcByte; int[] bcShort; int[] bcLocal; @@ -47,6 +49,8 @@ int[] bcSuperMethod; int[] bcInitRef; + int bcCaseCountIndex = 0; + int bcCaseValueIndex = 0; int bcByteIndex = 0; int bcShortIndex = 0; int bcLocalIndex = 0; @@ -72,7 +76,9 @@ String superClass = null; String newClass = null; - public OperandManager(int[] bcByte, int[] bcShort, int[] bcLocal, int[] bcLabel, int[] bcIntRef, int[] bcFloatRef, int[] bcLongRef, int[] bcDoubleRef, int[] bcStringRef, int[] bcClassRef, int[] bcFieldRef, int[] bcMethodRef, int[] bcIMethodRef, int[] bcThisField, int[] bcSuperField, int[] bcThisMethod, int[] bcSuperMethod, int[] bcInitRef) { + public OperandManager(int[] bcCaseCount, int[][] bcCaseValue, int[] bcByte, int[] bcShort, int[] bcLocal, int[] bcLabel, int[] bcIntRef, int[] bcFloatRef, int[] bcLongRef, int[] bcDoubleRef, int[] bcStringRef, int[] bcClassRef, int[] bcFieldRef, int[] bcMethodRef, int[] bcIMethodRef, int[] bcThisField, int[] bcSuperField, int[] bcThisMethod, int[] bcSuperMethod, int[] bcInitRef) { + this.bcCaseCount = bcCaseCount; + this.bcCaseValue = bcCaseValue; this.bcByte = bcByte; this.bcShort = bcShort; this.bcLocal = bcLocal; @@ -93,6 +99,14 @@ this.bcSuperMethod = bcSuperMethod; this.bcInitRef = bcInitRef; } + + public int nextCaseCount() { + return bcCaseCount[bcCaseCountIndex++]; + } + + public int[] nextCaseValues() { + return bcCaseValue[bcCaseValueIndex++]; + } public int nextByte() { return bcByte[bcByteIndex++]; Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java Thu Jan 3 05:13:15 2008 @@ -232,8 +232,8 @@ byteCodeArray[167] = new LabelForm(167, "goto", new int[] {167, -1, -1}); byteCodeArray[168] = new LabelForm(168, "jsr", new int[] {168, -1, -1}); byteCodeArray[169] = new LocalForm(169, "ret", new int[] {169, -1}); - byteCodeArray[170] = new SwitchForm(170, "tableswitch"); - byteCodeArray[171] = new SwitchForm(171, "lookupswitch"); + byteCodeArray[170] = new TableSwitchForm(170, "tableswitch"); + byteCodeArray[171] = new LookupSwitchForm(171, "lookupswitch"); byteCodeArray[172] = new NoArgumentForm(172, "ireturn"); byteCodeArray[173] = new NoArgumentForm(173, "lreturn"); byteCodeArray[174] = new NoArgumentForm(174, "freturn"); @@ -572,10 +572,13 @@ * * @param byteCode ByteCode to be updated (!) * @param operandManager OperandTable from which to draw info - * @param globalPool SegmentConstantPool used to index into + * @param codeLength Length of bytes (excluding this bytecode) + * from the beginning of the method. Used in calculating + * padding for some variable-length bytecodes (such as + * lookupswitch, tableswitch). */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { throw new Error("My subclass should have implemented this"); } @@ -587,7 +590,7 @@ * @param codeAttribute a CodeAttribute used to determine how * the ByteCode should be fixed up. */ - public void fixUpByteCodeTarget(ByteCode byteCode, CodeAttribute codeAttribute) { + public void fixUpByteCodeTargets(ByteCode byteCode, CodeAttribute codeAttribute) { // Most ByteCodeForms don't have any fixing up to do. return; } Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteForm.java Thu Jan 3 05:13:15 2008 @@ -41,7 +41,7 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { byteCode.setOperandByte(operandManager.nextByte() & 0xFF, 0); } } Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java Thu Jan 3 05:13:15 2008 @@ -43,7 +43,7 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { //TODO: implement this. Removed the error message because // it causes failures in the JUnit tests. // throw new Error("Not implemented yet"); Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IincForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IincForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IincForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IincForm.java Thu Jan 3 05:13:15 2008 @@ -41,7 +41,7 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { int local = operandManager.nextLocal(); int constant = operandManager.nextByte(); byteCode.setOperandBytes(new int[]{local, constant}); Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java Thu Jan 3 05:13:15 2008 @@ -50,9 +50,9 @@ /* (non-Javadoc) * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#fixUpByteCodeTarget(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.CodeAttribute) */ - public void fixUpByteCodeTarget(ByteCode byteCode, CodeAttribute codeAttribute) { + public void fixUpByteCodeTargets(ByteCode byteCode, CodeAttribute codeAttribute) { // LabelForms need to fix up the target of label operations - int originalTarget = byteCode.getByteCodeTarget(); + int originalTarget = byteCode.getByteCodeTargets()[0]; int sourceIndex = byteCode.getByteCodeIndex(); int absoluteInstructionTargetIndex = sourceIndex + originalTarget; int targetValue = ((Integer)codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex)).intValue(); @@ -60,7 +60,7 @@ // The operand is the difference between the source instruction // and the destination instruction. // TODO: Probably have to do something other than setOperandInt if this is widened. - byteCode.setOperandSignedInt(targetValue - sourceValue, 0); + byteCode.setOperandSigned2Bytes(targetValue - sourceValue, 0); if(widened) { byteCode.setNestedPositions(new int[][] {{0,4}}); } else { @@ -72,8 +72,8 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { - byteCode.setByteCodeTarget(operandManager.nextLabel()); + OperandManager operandManager, int codeLength) { + byteCode.setByteCodeTargets(new int[] {operandManager.nextLabel()}); // The byte code operands actually get set later - // once we have all the bytecodes - in fixUpByteCodeTarget(). return; Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java Thu Jan 3 05:13:15 2008 @@ -48,7 +48,7 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { byteCode.setOperandBytes(new int[]{operandManager.nextLocal()}); } } Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java?rev=608472&view=auto ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java (added) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java Thu Jan 3 05:13:15 2008 @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.harmony.pack200.bytecode.forms; + +import org.apache.harmony.pack200.bytecode.ByteCode; +import org.apache.harmony.pack200.bytecode.OperandManager; + +public class LookupSwitchForm extends SwitchForm { + + public LookupSwitchForm(int opcode, String name) { + super(opcode, name); + } + + public LookupSwitchForm(int opcode, String name, int[] rewrite) { + super(opcode, name, rewrite); + } + + public void setByteCodeOperands(ByteCode byteCode, + OperandManager operandManager, int codeLength) { + if (switchCaseCountingBroken) + return; + int case_count = operandManager.nextCaseCount(); + int default_pc = operandManager.nextLabel(); + int case_values[] = operandManager.nextCaseValues(); + int case_pcs[] = new int[case_count]; + for (int index = 0; index < case_count; index++) { + case_pcs[index] = operandManager.nextLabel(); + } + // All this gets dumped into the rewrite bytes of the + // poor bytecode. + + int[] labelsArray = new int[case_count + 1]; + labelsArray[0] = default_pc; + for (int index = 1; index < case_count + 1; index++) { + labelsArray[index] = case_pcs[index - 1]; + } + byteCode.setByteCodeTargets(labelsArray); + + // Unlike most byte codes, the LookupSwitch is a + // variable-sized bytecode. Because of this, the + // rewrite array has to be defined here individually + // for each bytecode, rather than in the ByteCodeForm + // class. + + // First, there's the bytecode. Then there are 0-3 + // bytes of padding so that the first (default) + // label is on a 4-byte offset. + int padLength = 3 - (codeLength % 4); + int rewriteSize = 1 + padLength + 4 // defaultbytes + + 4 // npairs + + (4 * case_values.length) + (4 * case_pcs.length); + + int[] newRewrite = new int[rewriteSize]; + int rewriteIndex = 0; + + // Fill in what we can now + // opcode + newRewrite[rewriteIndex++] = byteCode.getOpcode(); + + // padding + for (int index = 0; index < padLength; index++) { + newRewrite[rewriteIndex++] = 0; + } + + // defaultbyte + // This gets overwritten by fixUpByteCodeTargets + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + + // npairs + int npairsIndex = rewriteIndex; + setRewrite4Bytes(case_values.length, npairsIndex, newRewrite); + rewriteIndex += 4; + + // match-offset pairs + // The case_values aren't overwritten, but the + // case_pcs will get overwritten by fixUpByteCodeTargets + for (int index = 0; index < case_values.length; index++) { + // match + setRewrite4Bytes(case_values[index], rewriteIndex, newRewrite); + rewriteIndex += 4; + // offset + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + } + byteCode.setRewrite(newRewrite); + } +} Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java Thu Jan 3 05:13:15 2008 @@ -50,10 +50,10 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { // multianewarray has a class ref and a dimension. // The superclass handles the class ref. - super.setByteCodeOperands(byteCode, operandManager); + super.setByteCodeOperands(byteCode, operandManager, codeLength); // We have to handle the dimension. int dimension = operandManager.nextByte(); Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java Thu Jan 3 05:13:15 2008 @@ -44,7 +44,7 @@ * @see org.apache.harmony.pack200.bytecode.forms.ReferenceForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandManager) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { ClassFileEntry[] nested = null; int offset = getOffset(operandManager); if(offset == 0) { Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java Thu Jan 3 05:13:15 2008 @@ -44,7 +44,7 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { // Nothing to do for no-argument form } } Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java Thu Jan 3 05:13:15 2008 @@ -50,7 +50,7 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.Segment) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { int offset = getOffset(operandManager); try { setNestedEntries(byteCode, operandManager, offset); Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.java Thu Jan 3 05:13:15 2008 @@ -42,7 +42,7 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { - byteCode.setOperandInt(operandManager.nextShort(), 0); + OperandManager operandManager, int codeLength) { + byteCode.setOperand2Bytes(operandManager.nextShort(), 0); } } Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java Thu Jan 3 05:13:15 2008 @@ -17,9 +17,12 @@ package org.apache.harmony.pack200.bytecode.forms; import org.apache.harmony.pack200.bytecode.ByteCode; +import org.apache.harmony.pack200.bytecode.CodeAttribute; import org.apache.harmony.pack200.bytecode.OperandManager; -public class SwitchForm extends ByteCodeForm { +public abstract class SwitchForm extends ByteCodeForm { + + static boolean switchCaseCountingBroken = true; public SwitchForm(int opcode, String name) { super(opcode, name); @@ -42,10 +45,94 @@ /* (non-Javadoc) * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ - public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { -//TODO: implement this. Removed the error message because -// it causes failures in the JUnit tests. -// throw new Error("Not implemented yet"); + public abstract void setByteCodeOperands(ByteCode byteCode, + OperandManager operandManager, int codeLength); + + /** + * Given an int operand, set the rewrite bytes for + * the next available operand position and the three + * immediately following it to a highest-byte, + * mid-high, mid-low, low-byte encoding of the operand. + * + * Note that unlike the ByteCode setOperand* operations, this + * starts with an actual bytecode rewrite array (rather than + * a ByteCodeForm prototype rewrite array). Also, this method + * overwrites -1 values in the rewrite array - so if you start + * with an array that looks like: + * {100, -1, -1, -1, -1, 200, -1, -1, -1, -1} then calling + * setRewrite4Bytes(0, rewrite) the first time will convert + * it to: + * {100, 0, 0, 0, 0, 200, -1, -1, -1, -1} + * Calling setRewrite4Bytes(0, rewrite) a second time will + * convert it to: + * {100, 0, 0, 0, 0, 200, 0, 0, 0, 0} + * + * @param operand int to set the rewrite bytes to + * @param rewrite int[] bytes to rewrite + */ + public void setRewrite4Bytes(int operand, int[] rewrite) { + int firstOperandPosition = -1; + + // Find the first -1 in the rewrite array + for(int index=0; index < rewrite.length - 3; index++) { + if((rewrite[index] == -1) + && (rewrite[index+1] == -1) + && (rewrite[index+2] == -1) + && (rewrite[index+3] == -1)) { + firstOperandPosition = index; + break; + } + } + setRewrite4Bytes(operand, firstOperandPosition, rewrite); + } + + /** + * This method writes operand directly into the rewrite + * array at index position specified. + * @param operand value to write + * @param absPosition position in array to write. Note that + * this is absolute position in the array, so one can + * overwrite the bytecode if one isn't careful. + * @param rewrite array to write into + */ + public void setRewrite4Bytes(int operand, int absPosition, int[] rewrite) { + if(absPosition < 0) { + throw new Error("Trying to rewrite " + this + " but there is no room for 4 bytes"); + } + + int byteCodeRewriteLength = rewrite.length; + + if(absPosition + 3 > byteCodeRewriteLength) { + throw new Error("Trying to rewrite " + this + " with an int at position " + absPosition + " but this won't fit in the rewrite array"); + } + + rewrite[absPosition] = ((0xFF000000) & operand) >> 24; + rewrite[absPosition + 1] = ((0x00FF0000) & operand) >> 16; + rewrite[absPosition + 2] = ((0x0000FF00) & operand) >> 8; + rewrite[absPosition + 3] = ((0x000000FF) & operand); + } + + /* (non-Javadoc) + * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#fixUpByteCodeTargets(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.CodeAttribute) + */ + public void fixUpByteCodeTargets(ByteCode byteCode, CodeAttribute codeAttribute) { + if(switchCaseCountingBroken) return; + // SwitchForms need to fix up the target of label operations + int[] originalTargets = byteCode.getByteCodeTargets(); + int numberOfLabels = originalTargets.length; + int[] replacementTargets = new int[numberOfLabels]; + + int sourceIndex = byteCode.getByteCodeIndex(); + int sourceValue = ((Integer)codeAttribute.byteCodeOffsets.get(sourceIndex)).intValue(); + for(int index=0; index < numberOfLabels; index++) { + int absoluteInstructionTargetIndex = sourceIndex + originalTargets[index]; + int targetValue = ((Integer)codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex)).intValue(); + replacementTargets[index] = targetValue - sourceValue; + } + int[] rewriteArray = byteCode.getRewrite(); + for(int index=0; index < numberOfLabels; index++) { + setRewrite4Bytes(replacementTargets[index], rewriteArray); + } } + } Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java?rev=608472&view=auto ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java (added) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java Thu Jan 3 05:13:15 2008 @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.harmony.pack200.bytecode.forms; + +import org.apache.harmony.pack200.bytecode.ByteCode; +import org.apache.harmony.pack200.bytecode.OperandManager; + +public class TableSwitchForm extends SwitchForm { + + public TableSwitchForm(int opcode, String name) { + super(opcode, name); + } + + public TableSwitchForm(int opcode, String name, int[] rewrite) { + super(opcode, name, rewrite); + } + + public void setByteCodeOperands(ByteCode byteCode, + OperandManager operandManager, int codeLength) { + if (switchCaseCountingBroken) + return; + int case_count = operandManager.nextCaseCount(); + int default_pc = operandManager.nextLabel(); + int case_values[] = operandManager.nextCaseValues(); + int case_pcs[] = new int[case_count]; + for (int index = 0; index < case_count; index++) { + case_pcs[index] = operandManager.nextLabel(); + } + int lowValue = case_values[0]; + int highValue = lowValue + case_count - 1; + // All this gets dumped into the rewrite bytes of the + // poor bytecode. + + int[] labelsArray = new int[case_count + 1]; + labelsArray[0] = default_pc; + for (int index = 1; index < case_count + 1; index++) { + labelsArray[index] = case_pcs[index - 1]; + } + byteCode.setByteCodeTargets(labelsArray); + + // Unlike most byte codes, the TableSwitch is a + // variable-sized bytecode. Because of this, the + // rewrite array has to be defined here individually + // for each bytecode, rather than in the ByteCodeForm + // class. + + // First, there's the bytecode. Then there are 0-3 + // bytes of padding so that the first (default) + // label is on a 4-byte offset. + int padLength = 3 - (codeLength % 4); + int rewriteSize = 1 + padLength + 4 // defaultbytes + + 4 // lowbyte + + 4 // highbyte + + (4 * case_pcs.length); + + int[] newRewrite = new int[rewriteSize]; + int rewriteIndex = 0; + + // Fill in what we can now + // opcode + newRewrite[rewriteIndex++] = byteCode.getOpcode(); + + // padding + for (int index = 0; index < padLength; index++) { + newRewrite[rewriteIndex++] = 0; + } + + // defaultbyte + // This gets overwritten by fixUpByteCodeTargets + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + + // lowbyte + int lowbyteIndex = rewriteIndex; + setRewrite4Bytes(lowValue, lowbyteIndex, newRewrite); + rewriteIndex += 4; + + // highbyte + int highbyteIndex = rewriteIndex; + setRewrite4Bytes(highValue, highbyteIndex, newRewrite); + rewriteIndex += 4; + + // jump offsets + // The case_pcs will get overwritten by fixUpByteCodeTargets + for (int index = 0; index < case_count; index++) { + // offset + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + newRewrite[rewriteIndex++] = -1; + } + byteCode.setRewrite(newRewrite); + } +} Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java Thu Jan 3 05:13:15 2008 @@ -47,7 +47,7 @@ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool) */ public void setByteCodeOperands(ByteCode byteCode, - OperandManager operandManager) { + OperandManager operandManager, int codeLength) { //TODO: implement this. Removed the error message because // it causes failures in the JUnit tests. // throw new Error("Not implemented yet"); Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java Thu Jan 3 05:13:15 2008 @@ -294,8 +294,8 @@ public void testBcCaseBands() throws IOException, Pack200Exception { byte[] bytes = new byte[] {(byte)170,(byte)171, (byte)255, 2, 5, // bc_case_count - 8, 8, 8, 8, 8, 8, 8, // bc_case_value - 8, 8}; // bc_label + 0, 1, 0, 1, 2, 3, 4, // bc_case_value + 0, 0, 0, 0, 0, 0, 0, 0, 0}; // bc_label InputStream in = new ByteArrayInputStream(bytes); bcBands.unpack(in); assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length); @@ -307,7 +307,7 @@ assertEquals(2, bc_case_value.length); assertEquals(2, bc_case_value[0].length); assertEquals(5, bc_case_value[1].length); - assertEquals(2, bcBands.getBcLabel().length); + assertEquals(9, bcBands.getBcLabel().length); } /** Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java?rev=608472&r1=608471&r2=608472&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java (original) +++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java Thu Jan 3 05:13:15 2008 @@ -77,7 +77,9 @@ public class MockOperandManager extends OperandManager { public MockOperandManager() { - super(new int[] {}, // bcByte + super(new int[] {}, // bcCaseCount + new int[][] {}, // bcCaseValues + new int[] {}, // bcByte new int[] {}, // bcShort new int[] {}, // bcLocal new int[] {}, // bcLabel