You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2008/01/03 14:13:17 UTC

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...

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