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/04 11:10:36 UTC

svn commit: r608790 [1/2] - 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/...

Author: tellison
Date: Fri Jan  4 02:10:32 2008
New Revision: 608790

URL: http://svn.apache.org/viewvc?rev=608790&view=rev
Log:
Apply patch HARMONY-5368 ([pack200][classlib] Completed instructions / started sorting / branch5)

Added:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
    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/ClassBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.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/ConstantPoolEntry.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.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/SourceFileAttribute.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/LookupSwitchForm.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/TableSwitchForm.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
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/SegmentUtilsTest.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/bytecode/ClassFileEntryTest.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/bytecode/ConstantPoolTest.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java Fri Jan  4 02:10:32 2008
@@ -26,6 +26,7 @@
 import org.apache.harmony.pack200.bytecode.CPInteger;
 import org.apache.harmony.pack200.bytecode.CPLong;
 import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 
 public abstract class BandSet {
     
@@ -451,7 +452,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPUTF8(reference[index]);
+            result[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
         }
         return result;
     }
@@ -472,7 +473,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result1[i1] = new CPUTF8(reference[index]);
+            result1[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
         }
         CPUTF8[] refs = result1;
         int pos = 0;

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=608790&r1=608789&r2=608790&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 Fri Jan  4 02:10:32 2008
@@ -21,6 +21,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.harmony.pack200.bytecode.Attribute;
 import org.apache.harmony.pack200.bytecode.BCIRenumberedAttribute;
@@ -40,7 +41,7 @@
     // The bands
     // TODO:  Haven't resolved references yet.  Do we want to?
     private int[] bcCaseCount;
-    private int[][] bcCaseValue;
+    private int[] bcCaseValue;
     private int[] bcByte;
     private int[] bcLocal;
     private int[] bcShort;
@@ -126,6 +127,9 @@
                        AttributeLayout.CONTEXT_METHOD);
        methodByteCodePacked = new byte[classCount][][];
        int bcParsed = 0;
+       
+       List switchIsTableSwitch = new ArrayList();
+       List wideByteCodes = new ArrayList();
        for (int c = 0; c < classCount; c++) {
            int numberOfMethods = methodFlags[c].length;
            methodByteCodePacked[c] = new byte[numberOfMethods][];
@@ -200,7 +204,12 @@
                            bcLabelCount++;
                            break;
                        case 170: // tableswitch
+                           switchIsTableSwitch.add(new Boolean(true));
+                           bcCaseCountCount++;
+                           bcLabelCount++;
+                           break;
                        case 171: // lookupswitch
+                           switchIsTableSwitch.add(new Boolean(false));
                            bcCaseCountCount++;
                            bcLabelCount++;
                            break;
@@ -260,6 +269,7 @@
                            break;
                        case 196: // wide
                             int nextInstruction = 0xff & methodByteCodePacked[c][m][i+1];
+                            wideByteCodes.add(new Integer(nextInstruction));
                             if (nextInstruction == 132) { // iinc
                                 bcLocalCount += 2;
                                 bcShortCount++;
@@ -299,9 +309,16 @@
         // other bytecode bands
         debug("Parsed *bc_codes (" + bcParsed + ")");
         bcCaseCount = decodeBandInt("bc_case_count", in, Codec.UNSIGNED5, bcCaseCountCount);
-        // 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 */);
+        int bcCaseValueCount = 0;
+        for (int i = 0; i < bcCaseCount.length; i++) {
+            boolean isTableSwitch = ((Boolean)switchIsTableSwitch.get(i)).booleanValue();
+            if(isTableSwitch) {
+                bcCaseValueCount += 1;
+            } else {
+                bcCaseValueCount += bcCaseCount[i];
+            }
+        }
+        bcCaseValue = decodeBandInt("bc_case_value", in, Codec.DELTA5, bcCaseValueCount );
         // 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.
@@ -345,11 +362,15 @@
         bcEscSize = decodeBandInt("bc_escsize", in, Codec.UNSIGNED5, bcEscCount);
         bcEscByte = decodeBandInt("bc_escbyte", in, Codec.BYTE1, bcEscSize);
 
+        int[] wideByteCodeArray = new int[wideByteCodes.size()];
+        for(int index=0; index < wideByteCodeArray.length; index++) {
+            wideByteCodeArray[index] = ((Integer)wideByteCodes.get(index)).intValue();
+        }
         OperandManager operandManager = new OperandManager(bcCaseCount, bcCaseValue,
                 bcByte, bcShort, bcLocal, bcLabel, bcIntRef, bcFloatRef, bcLongRef,
                 bcDoubleRef, bcStringRef, bcClassRef, bcFieldRef, bcMethodRef,
                 bcIMethodRef, bcThisField, bcSuperField, bcThisMethod, bcSuperMethod,
-                bcInitRef);
+                bcInitRef, wideByteCodeArray);
         operandManager.setSegment(segment);
 
         int i = 0;
@@ -365,28 +386,19 @@
                    if (!staticModifier.matches(methodFlag))
                        maxLocal++; // one for 'this' parameter
                    maxLocal += SegmentUtils.countArgs(methodDescr[c][m]);
-                   // TODO Move creation of code attribute until after constant
-                   // pool resolved
                    operandManager.setCurrentClass(segment.getClassBands().getClassThis()[c]);
                    operandManager.setSuperClass(segment.getClassBands().getClassSuper()[c]);
-                   CodeAttribute attr = new CodeAttribute(maxStack, maxLocal,
+                   CodeAttribute codeAttr = new CodeAttribute(maxStack, maxLocal,
                            methodByteCodePacked[c][m], segment, operandManager);
-                   methodAttributes[c][m].add(attr);
+                   methodAttributes[c][m].add(codeAttr);
                    // Should I add all the attributes in here?
                  ArrayList currentAttributes = (ArrayList)orderedCodeAttributes.get(i);
                  for(int index=0;index < currentAttributes.size(); index++) {
                      Attribute currentAttribute = (Attribute)currentAttributes.get(index);
-                     // TODO: The line below adds the LocalVariableTable
-                     // and LineNumber attributes. Currently things are
-                     // broken because these tables don't get renumbered
-                     // properly. Commenting out the add so the class files
-                     // will verify.
-    //                 if(currentAttribute.getClass() == LineNumberTableAttribute.class) {
-                         attr.attributes.add(currentAttribute);
-    //                 }
+                     codeAttr.addAttribute(currentAttribute);
                      // Fix up the line numbers if needed
                      if(currentAttribute.hasBCIRenumbering()) {
-                         ((BCIRenumberedAttribute)currentAttribute).renumber(attr.byteCodeOffsets);
+                         ((BCIRenumberedAttribute)currentAttribute).renumber(codeAttr.byteCodeOffsets);
                      }
                  }
                  i++;
@@ -417,7 +429,7 @@
         return bcCaseCount;
     }
 
-    public int[][] getBcCaseValue() {
+    public int[] getBcCaseValue() {
         return bcCaseValue;
     }
 

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Fri Jan  4 02:10:32 2008
@@ -26,6 +26,7 @@
 import org.apache.harmony.pack200.bytecode.Attribute;
 import org.apache.harmony.pack200.bytecode.CPClass;
 import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 import org.apache.harmony.pack200.bytecode.ConstantValueAttribute;
 import org.apache.harmony.pack200.bytecode.ExceptionsAttribute;
 import org.apache.harmony.pack200.bytecode.LineNumberTableAttribute;
@@ -199,7 +200,7 @@
                     int colon = desc.indexOf(':');
                     String type = desc.substring(colon + 1);
                     CPUTF8 value = new CPUTF8((String) signatureLayout.getValue(result, type,
-                            cpBands.getConstantPool()));
+                            cpBands.getConstantPool()), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
                     fieldAttributes[i][j]
                             .add(new SignatureAttribute(value));
                     signatureIndex++;
@@ -651,6 +652,22 @@
                 "code_LocalVariableTable_slot", in, Codec.UNSIGNED5,
                 localVariableTableN);
 
+        // Fix up localVariableTableTypeRS - for some reason,
+        // native signatures end up in DOMAINNORMALASCIIZ
+        // while nonnatives end up in DOMAINSIGNATUREASCIIZ.
+        // TODO: is this the right thing to do?
+        for(int x=0; x < localVariableTableTypeRS.length; x++) {
+            for(int y=0; y < localVariableTableTypeRS[x].length; y++) {
+                CPUTF8 element = localVariableTableTypeRS[x][y];
+                // TODO: come up with a better test for native vs nonnative signatures?
+                if(element.underlyingString().length() > 2) {
+                    element.setDomain(ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
+                } else {
+                    element.setDomain(ClassConstantPool.DOMAIN_NORMALASCIIZ);
+                }
+            }
+        }
+        
         int lengthLocalVariableTypeTableNBand = SegmentUtils.countMatches(
                 codeFlags, localVariableTypeTableLayout);
         int[] localVariableTypeTableN = decodeBandInt(
@@ -715,7 +732,7 @@
         for (int i = 0; i < strings.length; i++) {
             cpUTF8s[i] = new CPUTF8[strings[i].length];
             for (int j = 0; j < strings[i].length; j++) {
-                cpUTF8s[i][j] = new CPUTF8(strings[i][j]);
+                cpUTF8s[i][j] = new CPUTF8(strings[i][j], ClassConstantPool.DOMAIN_NORMALASCIIZ);
             }
         }
         return cpUTF8s;
@@ -726,7 +743,7 @@
     private CPUTF8[] stringsToCPUTF8(String[] strings) {
         CPUTF8[] cpUTF8s = new CPUTF8[strings.length];
         for (int i = 0; i < strings.length; i++) {
-            cpUTF8s[i] = new CPUTF8(strings[i]);
+            cpUTF8s[i] = new CPUTF8(strings[i], ClassConstantPool.DOMAIN_UNDEFINED);
         }
         return cpUTF8s;
     }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java Fri Jan  4 02:10:32 2008
@@ -28,6 +28,7 @@
 import org.apache.harmony.pack200.bytecode.CPMethodRef;
 import org.apache.harmony.pack200.bytecode.CPString;
 import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 import org.apache.harmony.pack200.bytecode.ConstantPoolEntry;
 
 public class SegmentConstantPool {
@@ -230,7 +231,7 @@
         } else if (index < 0) {
             throw new Pack200Exception("Cannot have a negative range");
         } else if (cp == UTF_8) {
-            return new CPUTF8(bands.getCpUTF8()[index]);
+            return new CPUTF8(bands.getCpUTF8()[index], ClassConstantPool.DOMAIN_NORMALASCIIZ);
         } else if (cp == CP_INT) {
             return new CPInteger(new Integer(bands.getCpInt()[index]));
         } else if (cp == CP_FLOAT) {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java Fri Jan  4 02:10:32 2008
@@ -20,29 +20,81 @@
 public final class SegmentUtils {
     
 	public static int countArgs(String descriptor) {
-		int bra = descriptor.indexOf("(");
-		int ket = descriptor.indexOf(")");
-		if (bra == -1 || ket == -1 || ket < bra)
-			throw new IllegalArgumentException("No arguments");
+	    return countArgs(descriptor, 1);
+//		int bra = descriptor.indexOf("(");
+//		int ket = descriptor.indexOf(")");
+//		if (bra == -1 || ket == -1 || ket < bra)
+//			throw new IllegalArgumentException("No arguments");
+//
+//		boolean inType = false;
+//		int count = 0;
+//		for (int i = bra + 1; i < ket; i++) {
+//			char charAt = descriptor.charAt(i);
+//			if (inType && charAt == ';') {
+//				inType = false;
+//			} else if (!inType && charAt == 'L') {
+//				inType = true;
+//				count++;
+//			} else if (charAt == '[' || inType) {
+//				// NOP
+//			} else {
+//				count++;
+//			}
+//		}
+//		return count;
+	}
 
-		boolean inType = false;
-		int count = 0;
-		for (int i = bra + 1; i < ket; i++) {
-			char charAt = descriptor.charAt(i);
-			if (inType && charAt == ';') {
-				inType = false;
-			} else if (!inType && charAt == 'L') {
-				inType = true;
-				count++;
-			} else if (charAt == '[' || inType) {
-				// NOP
-			} else {
-				count++;
-			}
-		}
-		return count;
+	public static int countInvokeInterfaceArgs(String descriptor) {
+	    return countArgs(descriptor, 2);
 	}
+	
+	/**
+	 * Count the number of arguments in the descriptor. Each
+	 * long or double counts as widthOfLongsAndDoubles; all other
+	 * arguments count as 1.
+	 * @param descriptor String for which arguments are counted
+	 * @param widthOfLongsAndDoubles int increment to apply for longs
+	 *   doubles. This is typically 1 when counting arguments alone,
+	 *   or 2 when counting arguments for invokeinterface.
+	 * @return integer count
+	 */
+	protected static int countArgs(String descriptor, int widthOfLongsAndDoubles) {
+	    int bra = descriptor.indexOf("(");
+	    int ket = descriptor.indexOf(")");
+	    if (bra == -1 || ket == -1 || ket < bra)
+	        throw new IllegalArgumentException("No arguments");
 
+	    boolean inType = false;
+	    boolean consumingNextType = false;
+	    int count = 0;
+	    for (int i = bra + 1; i < ket; i++) {
+	        char charAt = descriptor.charAt(i);
+	        if (inType && charAt == ';') {
+	            inType = false;
+	            consumingNextType = false;
+	        } else if (!inType && charAt == 'L') {
+	            inType = true;
+	            count++;
+	        } else if (charAt == '[') {
+	            consumingNextType = true;
+	        } else if(inType) {
+	            // NOP
+	        } else {
+	            if(consumingNextType) {
+	                count++;
+	                consumingNextType = false;
+	            } else {
+	                if(charAt == 'D' || charAt == 'J') {
+	                    count+=widthOfLongsAndDoubles;
+	                } else {
+	                    count++;
+	                }
+	            }
+	        }
+	    }
+	    return count;
+	}
+	   
 	public static int countMatches(long[] flags, IMatcher matcher) {
 		int count = 0;
 		for (int i = 0; i < flags.length; i++) {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java Fri Jan  4 02:10:32 2008
@@ -25,7 +25,7 @@
     private int attributeNameIndex;
 
     public Attribute(String attributeName) {
-        this.attributeName = new CPUTF8(attributeName);
+        this.attributeName = new CPUTF8(attributeName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ);
     }
 
     protected void doWrite(DataOutputStream dos) throws IOException {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java Fri Jan  4 02:10:32 2008
@@ -30,7 +30,8 @@
 	public   CPClass(String name) {
 		super(ConstantPoolEntry.CP_Class);
 		this.name = name;
-		this.utf8 = new CPUTF8(name);
+		this.domain = ClassConstantPool.DOMAIN_CLASSREF;
+		this.utf8 = new CPUTF8(name, ClassConstantPool.DOMAIN_NORMALASCIIZ);
 	}
 
 	
@@ -84,4 +85,9 @@
 	protected void writeBody(DataOutputStream dos) throws IOException {
 		dos.writeShort(index);
 	}
+	
+   public String comparisonString() {
+        return getName();
+   }
+
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java Fri Jan  4 02:10:32 2008
@@ -22,6 +22,7 @@
 public class CPDouble extends CPConstantNumber {
 	public CPDouble(java.lang.Double value) {
 		super(ConstantPoolEntry.CP_Double,value);
+        this.domain = ClassConstantPool.DOMAIN_DOUBLE;
 	}
 
 	

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java Fri Jan  4 02:10:32 2008
@@ -30,6 +30,7 @@
 	transient int nameAndTypeIndex;
 	public CPFieldRef(String className, String descriptor) {
 		super(ConstantPoolEntry.CP_Fieldref);
+		this.domain = ClassConstantPool.DOMAIN_FIELD;
 		this.className = new CPClass(className);
 		this.nameAndType = new CPNameAndType(descriptor);
 	}

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java Fri Jan  4 02:10:32 2008
@@ -22,6 +22,7 @@
 public class CPFloat extends CPConstantNumber {
 	public CPFloat(java.lang.Float value) {
 		super(ConstantPoolEntry.CP_Float,value);
+	      this.domain = ClassConstantPool.DOMAIN_FLOAT;
 	}
 
 	

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java Fri Jan  4 02:10:32 2008
@@ -23,6 +23,7 @@
 
 	public CPInteger(java.lang.Integer value) {
 		super(ConstantPoolEntry.CP_Integer,value);
+		this.domain = ClassConstantPool.DOMAIN_INTEGER;
 	}
 
 	

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java Fri Jan  4 02:10:32 2008
@@ -20,6 +20,18 @@
 
 	public CPInterfaceMethodRef(String className, String descriptor) {
 		super(ConstantPoolEntry.CP_InterfaceMethodref, className, descriptor);
+		this.domain = ClassConstantPool.DOMAIN_METHOD;
 	}
 
+	/**
+	 * This method answers the value this method will use
+	 * for an invokeinterface call. This is equal to 1 + the
+	 * count of all the args, where longs and doubles count for
+	 * 2 and all others count for 1.
+	 * 
+	 * @return integer count
+	 */
+	public int invokeInterfaceCount() {
+	    return nameAndType.invokeInterfaceCount();
+	}
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java Fri Jan  4 02:10:32 2008
@@ -23,6 +23,7 @@
 
 	public CPLong(java.lang.Long value) {
 		super(ConstantPoolEntry.CP_Long,value);
+        this.domain = ClassConstantPool.DOMAIN_LONG;
 	}
 
 	

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java Fri Jan  4 02:10:32 2008
@@ -38,8 +38,8 @@
 	transient int descriptorIndex;
 	public CPMember(String descriptor, long flags, List attributes) {
 		int colon = descriptor.indexOf(':');
-		this.name = new CPUTF8(descriptor.substring(0,colon));
-		this.descriptor = new CPUTF8(descriptor.substring(colon+1));
+		this.name = new CPUTF8(descriptor.substring(0,colon), ClassConstantPool.DOMAIN_NORMALASCIIZ);
+		this.descriptor = new CPUTF8(descriptor.substring(colon+1), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
 		this.flags = (short) flags;
 		this.attributes = (attributes == null ? new ArrayList() : attributes);
 	}

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java Fri Jan  4 02:10:32 2008
@@ -25,6 +25,7 @@
 		super(ConstantPoolEntry.CP_Methodref, className, descriptor);
 		this.className = new CPClass(className);
 		this.descriptor = new CPNameAndType(descriptor);
+        this.domain = ClassConstantPool.DOMAIN_METHOD;
 	}
 
 	protected ClassFileEntry[] getNestedClassFileEntries() {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java Fri Jan  4 02:10:32 2008
@@ -19,6 +19,8 @@
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import org.apache.harmony.pack200.SegmentUtils;
+
 
 public class CPNameAndType extends ConstantPoolEntry {
 
@@ -32,9 +34,35 @@
 
 	public CPNameAndType(String descriptor) {
 		super(ConstantPoolEntry.CP_NameAndType);
+		int descriptorDomain = ClassConstantPool.DOMAIN_UNDEFINED;
 		int colon = descriptor.indexOf(':');
-		this.name = new CPUTF8(descriptor.substring(0,colon));
-		this.descriptor = new CPUTF8(descriptor.substring(colon+1));
+		String nameString = descriptor.substring(0,colon);
+		String descriptorString = descriptor.substring(colon+1);
+		// For some reason, descriptors which have just plain
+		// native types are stored in DOMAIN_NORMALASCIIZ rather
+		// than in DOMAIN_SIGNATUREASCIIZ. This might indicate
+		// that DOMAIN_SIGNATUREASCIIZ is poorly named.
+		boolean nativeDescriptor = true;
+		for(int index=0; index < descriptorString.length(); index++) {
+		    char currentChar = descriptorString.charAt(index);
+		    if(Character.isLetter(currentChar)) {
+		        if(currentChar == 'L') {
+		            nativeDescriptor = false;
+		        }
+		        break;
+		    }
+		}
+		this.domain = ClassConstantPool.DOMAIN_NAMEANDTYPE;
+		this.name = new CPUTF8(nameString, ClassConstantPool.DOMAIN_NORMALASCIIZ);
+		if((nameString.equals("<init>")) || (nameString.equals("<clinit>")) || nativeDescriptor ) {
+		    // Signatures for init methods are stored with the init methods.
+		    // Not sure why. Similarly, native signatures are stored
+		    // there as well.
+		    descriptorDomain = ClassConstantPool.DOMAIN_NORMALASCIIZ;
+		} else {
+		    descriptorDomain = ClassConstantPool.DOMAIN_SIGNATUREASCIIZ;
+		}
+		this.descriptor = new CPUTF8(descriptorString, descriptorDomain);
 	}
 
 	protected ClassFileEntry[] getNestedClassFileEntries() {
@@ -94,4 +122,14 @@
 		return true;
 	}
 
+	/**
+	 * Answers the invokeinterface count argument when the
+	 * receiver is treated as an invokeinterface target.
+	 * This value is not meaningful if the receiver is not
+     * an invokeinterface target.
+	 * @return count
+	 */
+	public int invokeInterfaceCount() {
+	    return 1 + SegmentUtils.countInvokeInterfaceArgs(descriptor.underlyingString());
+	}
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java Fri Jan  4 02:10:32 2008
@@ -24,7 +24,7 @@
 	CPClass className;
 	transient int classNameIndex;
 
-	private final CPNameAndType nameAndType;
+	protected final CPNameAndType nameAndType;
 	transient int nameAndTypeIndex;
 
 	public CPRef(byte type, String className, String descriptor) {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java Fri Jan  4 02:10:32 2008
@@ -25,7 +25,8 @@
 
 	public CPString(java.lang.String value) {
 		super(ConstantPoolEntry.CP_String,value);
-		this.name = new CPUTF8((String) getValue());
+		this.domain = ClassConstantPool.DOMAIN_STRING;
+		this.name = new CPUTF8((String) getValue(), ClassConstantPool.DOMAIN_NORMALASCIIZ);
 
 	}
 
@@ -53,4 +54,7 @@
 		return new ClassFileEntry[] { name };
  	}
 
+	public String comparisonString() {
+	    return (String)getValue();
+	}
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java Fri Jan  4 02:10:32 2008
@@ -23,9 +23,10 @@
 public class CPUTF8 extends ConstantPoolEntry {
 	private String utf8;
 
-	public CPUTF8(String utf8) {
+	public CPUTF8(String utf8, int domain) {
 		super(ConstantPoolEntry.CP_UTF8);
 		this.utf8 = utf8;
+		this.domain = domain;
 	}
 
 	
@@ -74,4 +75,25 @@
 		dos.write(bytes);
 	}
 
+	public String underlyingString() {
+	    return utf8;
+	}
+	
+	public String comparisonString() {
+	    String returnValue = utf8;
+	    if(utf8.endsWith(";")) {
+	        StringBuffer alphaChars = new StringBuffer();
+	        StringBuffer extraChars = new StringBuffer();
+	        extraChars.append((char)0xFFFF);
+	        for(int index=0; index < utf8.length(); index++) {
+	            if( (utf8.charAt(index) == '(') || (utf8.charAt(index) == ')') || (utf8.charAt(index) == '[') || (utf8.charAt(index) == ']') ) {
+	                extraChars.append(utf8.charAt(index));
+	            } else {
+	                alphaChars.append(utf8.charAt(index));
+	            }
+	        }
+	        returnValue = alphaChars.toString() + extraChars.toString();
+	    }
+	    return returnValue;
+	}
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java Fri Jan  4 02:10:32 2008
@@ -18,9 +18,13 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.apache.harmony.pack200.bytecode.ConstantPoolEntry;
 
 import org.apache.harmony.pack200.Pack200Exception;
 import org.apache.harmony.pack200.Segment;
@@ -28,6 +32,58 @@
 
 
 public class ClassConstantPool {
+    
+    class PoolComparator implements Comparator {
+        /* (non-Javadoc)
+         * Note: this comparator imposes orderings that are inconsistent with equals.
+         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+         */
+        public int compare(Object o1, Object o2) {
+            // If we compare anything other than ConstantPoolEntries
+            // with this comparator, it is an error.
+            ConstantPoolEntry cpe1 = (ConstantPoolEntry)o1;
+            ConstantPoolEntry cpe2 = (ConstantPoolEntry)o2;
+
+            int domain1 = cpe1.getDomain();
+            int domain2 = cpe2.getDomain();
+            
+            if(domain1 < domain2) {
+                return -1;
+            }
+            if(domain1 > domain2) {
+                return 1;
+            }
+            
+            // Domains must be the same, need to compare
+            // based on name.
+            // TODO: what means name?
+            String compare1 = cpe1.comparisonString();
+            String compare2 = cpe2.comparisonString();
+            return compare1.compareTo(compare2);
+//            if(cpe1.creationOrder < cpe2.creationOrder) {
+//                return -1;
+//            } else {
+//                return 1;
+//            }
+        }
+    }
+    // These are the domains in sorted order.
+    public static int DOMAIN_UNDEFINED = 0;
+    public static int DOMAIN_INTEGER = 1;
+    public static int DOMAIN_FLOAT = 2;
+    public static int DOMAIN_STRING = 3;
+    public static int DOMAIN_NORMALASCIIZ = 4;
+    public static int DOMAIN_LONG = 5;
+    public static int DOMAIN_DOUBLE = 6;
+    public static int DOMAIN_CLASSREF = 7;
+    public static int DOMAIN_SIGNATUREASCIIZ = 8;
+    public static int DOMAIN_NAMEANDTYPE = 9;
+    public static int DOMAIN_FIELD = 10;
+    public static int DOMAIN_METHOD = 11;
+    public static int DOMAIN_ATTRIBUTEASCIIZ = 12;
+
+    protected SortedSet sortedEntries = new TreeSet(new PoolComparator());
+    
 	public String toString() {
 		return entries.toString();
 	}
@@ -38,15 +94,50 @@
 	private boolean resolved;
 
 	public ClassFileEntry add(ClassFileEntry entry) {
-		// TODO this should be a set - we don't want duplicates
+		// We don't want duplicates.
 		// Only add in constant pools, but resolve all types since they may
 		// introduce new constant pool entries
+// This is a handy way to see what's adding a ClassFileEntry - set a breakpoint on the print 
+//	    if(entry instanceof CPUTF8) {
+//	        System.out.println("AAH:" + ((CPUTF8)entry).comparisonString());
+//	        if (((CPUTF8)entry).comparisonString().matches("Ljava.*")) {
+//	            System.out.println("Adding");
+//	        }
+//	    }
 		if (entry instanceof ConstantPoolEntry) {
 			if (!entries.contains(entry)) {
 				entries.add(entry);
+				sortedEntries.add(entry);
 				// TODO This will be a bugger when they're sorted.
 				if (entry instanceof CPLong ||entry instanceof CPDouble)
 					entries.add(entry); //these get 2 slots because of their size
+			} else {
+			    // TODO: This is awful. If I'm presented with
+			    // an entry that has a lower domain than the
+			    // current entry but is otherwise the same,
+			    // change its domain and rebalance the tree.
+			    // And by "rebalance" I mean destroy and recreate
+			    // the tree.
+			    Iterator iterator = sortedEntries.iterator();
+			    boolean replaceTree = false;
+			    SortedSet newSortedSet = new TreeSet(new PoolComparator());
+			    while(iterator.hasNext()) {
+			        ConstantPoolEntry storedEntry = (ConstantPoolEntry)iterator.next();
+			        if(storedEntry.equals(entry)) {
+			            if(storedEntry.getDomain() > ((ConstantPoolEntry)entry).getDomain()) {
+			                // need to blow away the tree.
+			                replaceTree = true;
+			                newSortedSet.add(entry);
+			            } else {
+			                newSortedSet.add(storedEntry);
+			            }
+			        } else {
+			            newSortedSet.add(storedEntry);
+			        }
+			        if(replaceTree) {
+			            sortedEntries = newSortedSet;
+			        }
+			    }
 			}
 		} else {
 			if (!others.contains(entry))
@@ -82,34 +173,46 @@
 
 	public void resolve(Segment segment) {
 		SegmentUtils.debug("\n\nResolving (Segment.resolve(Segment)");
-		HashMap sortMap = new HashMap();
-		List cpAll = null;
-		// TODO: HACK - this is a 1.5 api.
-		// Need to do the right thing and do it with 1.4 API.
-		try {
-			cpAll = Arrays.asList(segment.getConstantPool().getCpAll());
-		} catch (Pack200Exception ex) {
-			ex.printStackTrace();
-		}
-		Iterator it = entries.iterator();
-		while(it.hasNext()) {
-			ClassFileEntry entry = (ClassFileEntry) it.next();
-			int indexInCpAll = cpAll.indexOf(entry);
-			if(indexInCpAll > 0) {
-				sortMap.put(new Integer(indexInCpAll), entry);
-			} else {
-				sortMap.put(new Integer(99999), entry);
-			}
-		}
-		ArrayList sortedList = new ArrayList();
-		for(int index=0; index < 99999; index++) {
-			if(sortMap.containsKey(new Integer(index))) {
-				sortedList.add((ClassFileEntry)sortMap.get(new Integer(index)));
-			}
-		}
-		for(int xindex=0; xindex < sortedList.size(); xindex++) {
-			SegmentUtils.debug(sortedList.get(xindex).toString());
-		}
+		// TODO: Be careful here, you're obliterating the original entries.
+		// In an ideal world, you wouldn't actually add to it unless you're
+		// sure.
+        entries = new ArrayList();
+//      entries.addAll(sortedEntries);
+      Iterator sortedIterator = sortedEntries.iterator();
+      while(sortedIterator.hasNext()) {
+          ConstantPoolEntry entry = (ConstantPoolEntry)sortedIterator.next();
+          entries.add(entry);
+          if (entry instanceof CPLong ||entry instanceof CPDouble)
+              entries.add(entry); //these get 2 slots because of their size
+      }
+//		HashMap sortMap = new HashMap();
+//		List cpAll = null;
+//		// TODO: HACK - this is a 1.5 api.
+//		// Need to do the right thing and do it with 1.4 API.
+//		try {
+//			cpAll = Arrays.asList(segment.getConstantPool().getCpAll());
+//		} catch (Pack200Exception ex) {
+//			ex.printStackTrace();
+//		}
+//		Iterator it = entries.iterator();
+//		while(it.hasNext()) {
+//			ClassFileEntry entry = (ClassFileEntry) it.next();
+//			int indexInCpAll = cpAll.indexOf(entry);
+//			if(indexInCpAll > 0) {
+//				sortMap.put(new Integer(indexInCpAll), entry);
+//			} else {
+//				sortMap.put(new Integer(99999), entry);
+//			}
+//		}
+//		ArrayList sortedList = new ArrayList();
+//		for(int index=0; index < 99999; index++) {
+//			if(sortMap.containsKey(new Integer(index))) {
+//				sortedList.add((ClassFileEntry)sortMap.get(new Integer(index)));
+//			}
+//		}
+//		for(int xindex=0; xindex < sortedList.size(); xindex++) {
+//			SegmentUtils.debug(sortedList.get(xindex).toString());
+//		}
 		resolve();
 	}
 	
@@ -124,7 +227,7 @@
 		while (it.hasNext()) {
 			ClassFileEntry entry = (ClassFileEntry) it.next();
 			entry.resolve(this);
-		}
+		}		
 	}
 
 }

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=608790&r1=608789&r2=608790&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 Fri Jan  4 02:10:32 2008
@@ -64,13 +64,23 @@
                 byteCodeOffsets.add(new Integer(lastBytecodePosition
                         + byteCode.getLength()));
             }
+            if(byteCode.getOpcode() == 0xC4) {
+                // Special processing for wide bytecode - it knows what its
+                // instruction is from the opcode manager, so ignore the
+                // next instruction
+                i++;
+            }
         }
         // Now that all the bytecodes know their positions and
         // sizes, fix up the byte code targets
-        for (int i = 0; i < codePacked.length; i++) {
+        // At this point, byteCodes may be a different size than
+        // codePacked because of wide bytecodes.
+        for (int i = 0; i < byteCodes.size(); i++) {
             ByteCode byteCode = (ByteCode)byteCodes.get(i);
             byteCode.applyByteCodeTargetFixup(this);
         }
+        // TODO: By the time I get here, the input stream
+        // is somehow confused. 
     }
 
     protected int getLength() {
@@ -88,6 +98,9 @@
         ArrayList nestedEntries = new ArrayList();
         nestedEntries.add(getAttributeName());
         nestedEntries.addAll(byteCodes);
+        // TODO: Is this the right place to add code attribute
+        // attributes?
+        nestedEntries.addAll(attributes);
         ClassFileEntry[] nestedEntryArray = new ClassFileEntry[nestedEntries
                 .size()];
         nestedEntries.toArray(nestedEntryArray);
@@ -136,4 +149,11 @@
         }
     }
 
+    public void addAttribute(Attribute attribute) {
+        attributes.add(attribute);
+    }
+    
+    public List attributes() {
+        return attributes;
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java Fri Jan  4 02:10:32 2008
@@ -56,8 +56,15 @@
 
 	byte tag;
 
+	protected int domain = ClassConstantPool.DOMAIN_UNDEFINED;
+	public static int creationOrderCount = 100;
+	public String comparisonString() {
+	    return "" + creationOrder;
+	}
+	public int creationOrder = -1;
 	ConstantPoolEntry(byte tag) {
 		this.tag = tag;
+		this.creationOrder = creationOrderCount++;
 	}
 
 	public abstract boolean equals(Object obj);
@@ -66,6 +73,14 @@
 		return tag;
 	}
 
+	public int getDomain() {
+	    return domain;
+	}
+	
+	public void setDomain(int newDomain) {
+	    this.domain = newDomain;
+	}
+	
 	public abstract int hashCode();
 
 	public void doWrite(DataOutputStream dos) throws IOException {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java Fri Jan  4 02:10:32 2008
@@ -52,11 +52,17 @@
         return "LineNumberTable: " + line_number_table_length + " lines";
     }
 
+    /* (non-Javadoc)
+     * @see org.apache.harmony.pack200.bytecode.Attribute#getNestedClassFileEntries()
+     */
+    protected ClassFileEntry[] getNestedClassFileEntries() {
+        return new ClassFileEntry[] {getAttributeName()};
+    }
+    
 	/* (non-Javadoc)
 	 * @see org.apache.harmony.pack200.bytecode.Attribute#resolve(org.apache.harmony.pack200.bytecode.ClassConstantPool)
 	 */
 	protected void resolve(ClassConstantPool pool) {
-		pool.add(getAttributeName());
 		super.resolve(pool);
 	}
 

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=608790&r1=608789&r2=608790&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 Fri Jan  4 02:10:32 2008
@@ -18,6 +18,7 @@
 
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
 public class LocalVariableTableAttribute extends BCIRenumberedAttribute {
@@ -58,17 +59,25 @@
         }
     }
 
+
+    protected ClassFileEntry[] getNestedClassFileEntries() {
+        ArrayList nestedEntries = new ArrayList();
+        nestedEntries.add(getAttributeName());
+        for (int i = 0; i < local_variable_table_length; i++) {
+            nestedEntries.add(names[i]);
+            nestedEntries.add(descriptors[i]);
+        }
+        ClassFileEntry[] nestedEntryArray = new ClassFileEntry[nestedEntries
+                .size()];
+        nestedEntries.toArray(nestedEntryArray);
+        return nestedEntryArray;        
+    }
+    
     protected void resolve(ClassConstantPool pool) {
         super.resolve(pool);
-        pool.add(getAttributeName());
         name_indexes = new int[local_variable_table_length];
         descriptor_indexes = new int[local_variable_table_length];
         for (int i = 0; i < local_variable_table_length; i++) {
-            // TODO: is this the right place to add the names and descriptors?
-            // Maybe some API to say where they should be added if they're not
-            // already in the cp?
-            pool.add(names[i]);
-            pool.add(descriptors[i]);
             names[i].resolve(pool);
             descriptors[i].resolve(pool);
             name_indexes[i] = pool.indexOf(names[i]);
@@ -88,26 +97,47 @@
      * @see org.apache.harmony.pack200.bytecode.BCIRenumberedAttribute#renumber(java.util.List)
      */
     public void renumber(List byteCodeOffsets) {
-        // First fix up the start_pcs
+        // Remember the unrenumbered start_pcs, since that's used later
+        // to calculate end position.
+        int[] unrenumbered_start_pcs = new int[start_pcs.length];
+        System.arraycopy(start_pcs, 0, unrenumbered_start_pcs, 0, start_pcs.length);
+
+        // Next renumber start_pcs in place
         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
+        // In other words:
+        //  start_pc is BCI5 start_pc
+        //  end_pc is byteCodeOffset[(index of start_pc in byteCodeOffset) + (encoded length)]
+        //  real length = end_pc - start_pc
+        // special case if end_pc is beyond end of bytecode array
+
+        // First figure out the maximum size of the byteCodeOffsets array
         int lastInstruction = ((Integer)byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue();
-        int maxLength = lastInstruction + 1;
+        int maxSize = lastInstruction + 1;
+        
+        // Iterate through the lengths and update each in turn.
+        // This is done in place in the lengths array.
         for(int index=0; index < lengths.length; index++) {
-            // Need to special case when the length is greater than the size
+            int start_pc = start_pcs[index];
             int revisedLength = -1;
             int encodedLength = lengths[index];
+            
+            // First get the index of the start_pc in the byteCodeOffsets
+            int indexOfStartPC = unrenumbered_start_pcs[index];
+            // Given the index of the start_pc, we can now add
+            // the encodedLength to it to get the stop index.
+            int stopIndex = indexOfStartPC + encodedLength;
+            
             // Length can either be an index into the byte code offsets, or one beyond the
             // end of the byte code offsets. Need to determine which this is.
-            if(encodedLength == byteCodeOffsets.size()) {
+            if(stopIndex == byteCodeOffsets.size()) {
                 // Pointing to one past the end of the byte code array
-                revisedLength = maxLength - start_pcs[index];
+                revisedLength = maxSize - start_pc;
             } else {
                 // We're indexed into the byte code array
-                revisedLength = ((Integer)byteCodeOffsets.get(encodedLength)).intValue();                
+                int stopValue = ((Integer)byteCodeOffsets.get(stopIndex)).intValue();
+                revisedLength = stopValue - start_pc;                
             }
             lengths[index] = revisedLength;
         }

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=608790&r1=608789&r2=608790&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 Fri Jan  4 02:10:32 2008
@@ -29,7 +29,7 @@
 public class OperandManager {
 	
     int[] bcCaseCount;
-    int[][] bcCaseValue;
+    int[] bcCaseValue;
     int[] bcByte;
     int[] bcShort;
     int[] bcLocal;
@@ -48,6 +48,7 @@
 	int[] bcThisMethod;
 	int[] bcSuperMethod;
 	int[] bcInitRef;
+	int[] wideByteCodes;
     
 	int bcCaseCountIndex = 0;
 	int bcCaseValueIndex = 0;
@@ -69,6 +70,7 @@
 	int bcThisMethodIndex = 0;
 	int bcSuperMethodIndex = 0;
 	int bcInitRefIndex = 0;
+	int wideByteCodeIndex = 0;
     
 	Segment segment = null;
 	
@@ -76,7 +78,7 @@
 	String superClass = null;
 	String newClass = null;
 	
-	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) {
+	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, int[] wideByteCodes) {
 	    this.bcCaseCount = bcCaseCount;
 	    this.bcCaseValue = bcCaseValue;
 	    this.bcByte = bcByte;
@@ -98,13 +100,14 @@
 	    this.bcThisMethod = bcThisMethod;
 	    this.bcSuperMethod = bcSuperMethod;
 	    this.bcInitRef = bcInitRef;
+	    this.wideByteCodes = wideByteCodes;
 	}
     
     public int nextCaseCount() {
         return bcCaseCount[bcCaseCountIndex++];       
     }
     
-    public int[] nextCaseValues() {
+    public int nextCaseValues() {
         return bcCaseValue[bcCaseValueIndex++];       
     }
     
@@ -180,6 +183,10 @@
 		return bcInitRef[bcInitRefIndex++];
 	}
 
+	public int nextWideByteCode() {
+	    return wideByteCodes[wideByteCodeIndex++];
+	}
+	
 	public void setSegment(Segment segment) {
 		this.segment = segment;
 	}

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/SourceFileAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/SourceFileAttribute.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/SourceFileAttribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/SourceFileAttribute.java Fri Jan  4 02:10:32 2008
@@ -27,7 +27,7 @@
 
 	public SourceFileAttribute(String name) {
 		super("SourceFile"); //$NON-NLS-1$
-		this.name = new CPUTF8(name);
+		this.name = new CPUTF8(name, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ);
 	}
 
 	public boolean equals(Object obj) {

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=608790&r1=608789&r2=608790&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 Fri Jan  4 02:10:32 2008
@@ -16,7 +16,9 @@
  */
 package org.apache.harmony.pack200.bytecode.forms;
 
+import org.apache.harmony.pack200.SegmentConstantPool;
 import org.apache.harmony.pack200.bytecode.ByteCode;
+import org.apache.harmony.pack200.bytecode.CPInterfaceMethodRef;
 import org.apache.harmony.pack200.bytecode.OperandManager;
 
 /**
@@ -24,7 +26,7 @@
  * bytecodes which have IMethod references (and only
  * IMethod references).
  */
-public class IMethodRefForm extends ByteCodeForm {
+public class IMethodRefForm extends ReferenceForm {
 
     public IMethodRefForm(int opcode, String name, 
             int[] rewrite) {
@@ -39,13 +41,21 @@
         return true;
     }
 
+    protected int getOffset(OperandManager operandManager) {
+        return operandManager.nextIMethodRef();
+    }
+
+    protected int getPoolID() {
+        return SegmentConstantPool.CP_IMETHOD;
+    }
+    
     /* (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)
+     * @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, int codeLength) {
-//TODO: implement this. Removed the error message because
-//        it causes failures in the JUnit tests.
-//        throw new Error("Not implemented yet");        
+        super.setByteCodeOperands(byteCode, operandManager, codeLength);
+        int count=((CPInterfaceMethodRef)byteCode.getNestedClassFileEntries()[0]).invokeInterfaceCount();
+        byteCode.getRewrite()[3] = count;
     }
 }

Modified: 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=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java Fri Jan  4 02:10:32 2008
@@ -29,53 +29,61 @@
         super(opcode, name, rewrite);
     }
 
+    /* (non-Javadoc)
+     * @see org.apache.harmony.pack200.bytecode.forms.SwitchForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandManager, int)
+     */
     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_values[] = new int[case_count];
+        for(int index=0; index < case_count; index++) {
+            case_values[index] = operandManager.nextCaseValues();
+        }
         int case_pcs[] = new int[case_count];
-        for (int index = 0; index < case_count; index++) {
+        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];
+        for(int index=1; index < case_count + 1; index++) {
+            labelsArray[index] = case_pcs[index-1];
         }
         byteCode.setByteCodeTargets(labelsArray);
 
+
+        // All this gets dumped into the rewrite bytes of the
+        // poor bytecode.
+        
+        
         // 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 padLength = 3 - (codeLength % 4); 
         int rewriteSize = 1 + padLength + 4 // defaultbytes
-                + 4 // npairs
-                + (4 * case_values.length) + (4 * case_pcs.length);
-
+            + 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++) {
+        for(int index=0; index < padLength; index++) {
             newRewrite[rewriteIndex++] = 0;
         }
-
+        
         // defaultbyte
         // This gets overwritten by fixUpByteCodeTargets
         newRewrite[rewriteIndex++] = -1;
@@ -91,7 +99,7 @@
         // 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++) {
+        for(int index = 0; index < case_values.length; index++) {
             // match
             setRewrite4Bytes(case_values[index], rewriteIndex, newRewrite);
             rewriteIndex += 4;

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=608790&r1=608789&r2=608790&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 Fri Jan  4 02:10:32 2008
@@ -20,9 +20,7 @@
 import org.apache.harmony.pack200.bytecode.CodeAttribute;
 import org.apache.harmony.pack200.bytecode.OperandManager;
 
-public abstract class SwitchForm extends ByteCodeForm {
-
-    static boolean switchCaseCountingBroken = true;
+public abstract class SwitchForm extends VariableInstructionForm {
 
     public SwitchForm(int opcode, String name) {
         super(opcode, name);
@@ -45,78 +43,14 @@
     /* (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 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);
+    public void setByteCodeOperands(ByteCode byteCode,
+            OperandManager operandManager, int codeLength) {
     }
-
-    /**
-     * 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;

Modified: 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=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java Fri Jan  4 02:10:32 2008
@@ -20,7 +20,7 @@
 import org.apache.harmony.pack200.bytecode.OperandManager;
 
 public class TableSwitchForm extends SwitchForm {
-
+    
     public TableSwitchForm(int opcode, String name) {
         super(opcode, name);
     }
@@ -29,56 +29,62 @@
         super(opcode, name, rewrite);
     }
 
+    
+    /* (non-Javadoc)
+     * @see org.apache.harmony.pack200.bytecode.forms.SwitchForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandManager, int)
+     */
     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_value = -1;
+        case_value = operandManager.nextCaseValues();
+
         int case_pcs[] = new int[case_count];
-        for (int index = 0; index < case_count; index++) {
+        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];
+        for(int index=1; index < case_count + 1; index++) {
+            labelsArray[index] = case_pcs[index-1];
         }
         byteCode.setByteCodeTargets(labelsArray);
 
+        int lowValue = case_value;
+        int highValue = lowValue + case_count - 1;
+        // All this gets dumped into the rewrite bytes of the
+        // poor bytecode.
+
+
         // 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 padLength = 3 - (codeLength % 4); 
         int rewriteSize = 1 + padLength + 4 // defaultbytes
-                + 4 // lowbyte
-                + 4 // highbyte
-                + (4 * case_pcs.length);
-
+            + 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++) {
+        for(int index=0; index < padLength; index++) {
             newRewrite[rewriteIndex++] = 0;
         }
-
+        
         // defaultbyte
         // This gets overwritten by fixUpByteCodeTargets
         newRewrite[rewriteIndex++] = -1;
@@ -98,7 +104,7 @@
 
         // jump offsets
         // The case_pcs will get overwritten by fixUpByteCodeTargets
-        for (int index = 0; index < case_count; index++) {
+        for(int index = 0; index < case_count; index++) {
             // offset
             newRewrite[rewriteIndex++] = -1;
             newRewrite[rewriteIndex++] = -1;

Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java?rev=608790&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java Fri Jan  4 02:10:32 2008
@@ -0,0 +1,158 @@
+/*
+ *  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;
+
+/**
+ * This abstract class implements the common code for
+ * instructions which have variable lengths. This
+ * is currently the *switch instructions and some
+ * wide (_w) instructions.
+ */
+public abstract class VariableInstructionForm extends ByteCodeForm {
+
+    public VariableInstructionForm(int opcode, String name) {
+        super(opcode, name);
+    }
+
+    public VariableInstructionForm(int opcode, String name, int[] rewrite) {
+        super(opcode, name, rewrite);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * Given an int operand, set the rewrite bytes for
+     * the next available operand position and the byte
+     * immediately following it to a high-byte,
+     * 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
+     *  setRewrite2Bytes(0, rewrite) the first time will convert
+     *  it to:
+     *  {100, 0, 0, -1, -1, 200, -1, -1, -1, -1}
+     *  Calling setRewrite2Bytes(0, rewrite) a second time will
+     *  convert it to:
+     *  {100, 0, 0, 0, 0, 200, -1, -1, -1, -1}
+     * 
+     * @param operand int to set the rewrite bytes to
+     * @param rewrite int[] bytes to rewrite
+     */
+    public void setRewrite2Bytes(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)) {
+                firstOperandPosition = index;
+                break;
+            }
+        }
+        setRewrite2Bytes(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);
+    }
+
+    /**
+     * 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 setRewrite2Bytes(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 + 1 > 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] = ((0xFF00) & operand) >> 8;
+        rewrite[absPosition + 1] = ((0x00FF) & operand);
+    }
+}

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java
------------------------------------------------------------------------------
    svn:eol-style = native