You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sj...@apache.org on 2008/07/22 15:48:50 UTC

svn commit: r678762 - in /harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200: BandSet.java BcBands.java CPClass.java CPMethodOrField.java CPSignature.java ClassBands.java CpBands.java FileBands.java Segment.java

Author: sjanuary
Date: Tue Jul 22 06:48:50 2008
New Revision: 678762

URL: http://svn.apache.org/viewvc?rev=678762&view=rev
Log:
Pack200 - some progress on bytecode bands

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/CPClass.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.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/CpBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.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=678762&r1=678761&r2=678762&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 Tue Jul 22 06:48:50 2008
@@ -18,6 +18,7 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.List;
 
 
 public abstract class BandSet {
@@ -74,4 +75,37 @@
         }
     }
 
+    protected int[] listToArray(List integerList) {
+        int[] array = new int[integerList.size()];
+        for (int i = 0; i < array.length; i++) {
+            array[i] = ((Integer)integerList.get(i)).intValue();
+        }
+        return array;
+    }
+
+    protected long[] longListToArray(List longList) {
+        long[] array = new long[longList.size()];
+        for (int i = 0; i < array.length; i++) {
+            array[i] = ((Long)longList.get(i)).longValue();
+        }
+        return array;
+    }
+
+    protected int[] cpEntryListToArray(List list) {
+        int[] array = new int[list.size()];
+        for (int i = 0; i < array.length; i++) {
+            array[i] = ((ConstantPoolEntry)list.get(i)).getIndex();
+        }
+        return array;
+    }
+
+    protected int[] cpEntryOrNullListToArray(List theList) {
+        int[] array = new int[theList.size()];
+        for (int j = 0; j < array.length; j++) {
+            ConstantPoolEntry cpEntry = (ConstantPoolEntry) theList.get(j);
+            array[j] = cpEntry == null ? 0 : cpEntry.getIndex() + 1;
+        }
+        return array;
+    }
+
 }

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=678762&r1=678761&r2=678762&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 Tue Jul 22 06:48:50 2008
@@ -16,25 +16,440 @@
  */
 package org.apache.harmony.pack200;
 
+import java.io.IOException;
 import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.bcel.classfile.Code;
+import org.apache.bcel.classfile.Constant;
+import org.apache.bcel.classfile.ConstantClass;
+import org.apache.bcel.classfile.ConstantDouble;
+import org.apache.bcel.classfile.ConstantFieldref;
+import org.apache.bcel.classfile.ConstantFloat;
+import org.apache.bcel.classfile.ConstantInteger;
+import org.apache.bcel.classfile.ConstantInterfaceMethodref;
+import org.apache.bcel.classfile.ConstantLong;
+import org.apache.bcel.classfile.ConstantMethodref;
+import org.apache.bcel.classfile.ConstantNameAndType;
+import org.apache.bcel.classfile.ConstantPool;
+import org.apache.bcel.classfile.ConstantString;
 
-
+/**
+ * Bytecode bands
+ */
 public class BcBands extends BandSet {
 
-    public void finaliseBands() {
+    private CpBands cpBands;
 
+    public BcBands(CpBands cpBands) {
+        this.cpBands = cpBands;
     }
 
-    public void pack(OutputStream out) {
-        // TODO Auto-generated method stub
-
+    private List bcCodes = new ArrayList();
+    private List bcCaseCount = new ArrayList();
+    private List bcCaseValue = new ArrayList();
+    private List bcByte = new ArrayList();
+    private List bcShort = new ArrayList();
+    private List bcLocal = new ArrayList();
+    private List bcLabel = new ArrayList();
+    private List bcIntref = new ArrayList();
+    private List bcFloatRef = new ArrayList();
+    private List bcLongRef = new ArrayList();
+    private List bcDoubleRef = new ArrayList();
+    private List bcStringRef = new ArrayList();
+    private List bcClassRef = new ArrayList();
+    private List bcFieldRef = new ArrayList();
+    private List bcMethodRef = new ArrayList();
+    private List bcIMethodRef = new ArrayList();
+    private List bcThisField = new ArrayList();
+    private List bcSuperField = new ArrayList();
+    private List bcThisMethod = new ArrayList();
+    private List bcSuperMethod = new ArrayList();
+    private List bcInitRef = new ArrayList();
+//    private List bcEscRef = new ArrayList();
+//    private List bcEscRefSize = new ArrayList();
+//    private List bcEscSize = new ArrayList();
+//    private List bcEscByte = new ArrayList();
+
+    public void addCode(Code obj, String thisClass, String superClass) {
+        ConstantPool cp = obj.getConstantPool();
+        byte[] bytecodes = obj.getCode();
+        boolean aload_0 = false;
+        boolean wide = false;
+        for (int i = 0; i < bytecodes.length; i++) {
+            int bytecode = 0xff & bytecodes[i];
+            switch (bytecode) {
+            case 16: // bipush
+            case 17: // sipush
+                bcCodes.add(new Integer(bytecode));
+                byte b1 = bytecodes[++i];
+                byte b2 = bytecodes[++i];
+                short s = (short) (b1 << 8 | b2);
+                bcShort.add(new Integer(s));
+                break;
+            case 18: // ldc
+                Constant constant = cp.getConstant(bytecodes[++i] & 0xFF);
+                if (constant instanceof ConstantInteger) {
+                    bcCodes.add(new Integer(234)); // ildc
+                    bcIntref.add(cpBands.getCPConstant(constant, cp));
+                } else if (constant instanceof ConstantFloat) {
+                    bcCodes.add(new Integer(235)); // fldc
+                    bcFloatRef.add(cpBands.getCPConstant(constant, cp));
+                } else if (constant instanceof ConstantString) {
+                    bcCodes.add(new Integer(18)); // aldc
+                    bcStringRef.add(cpBands.getCPConstant(constant, cp));
+                } else if (constant instanceof ConstantClass) {
+                    bcCodes.add(new Integer(233)); // cldc
+                    bcClassRef.add(cpBands.getCPConstant(constant, cp));
+                }
+                break;
+            case 19: // aldc_w
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                int index = b1 << 8 | b2;
+                constant = cp.getConstant(index);
+                if (constant instanceof ConstantInteger) {
+                    bcCodes.add(new Integer(237)); // ildc_w
+                    bcIntref.add(cpBands.getCPConstant(constant, cp));
+                } else if (constant instanceof ConstantFloat) {
+                    bcCodes.add(new Integer(238)); // fldc_w
+                    bcFloatRef.add(cpBands.getCPConstant(constant, cp));
+                } else if (constant instanceof ConstantString) {
+                    bcCodes.add(new Integer(19)); // aldc_w
+                    bcStringRef.add(cpBands.getCPConstant(constant, cp));
+                } else if (constant instanceof ConstantClass) {
+                    bcCodes.add(new Integer(236)); // cldc_w
+                    bcClassRef.add(cpBands.getCPConstant(constant, cp));
+                }
+                break;
+            case 20: // ldc2_w
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                index = b1 << 8 | b2;
+                constant = cp.getConstant(index);
+                if (constant instanceof ConstantLong) {
+                    bcCodes.add(new Integer(20)); // lldc2_w
+                    bcLongRef.add(cpBands.getCPConstant(constant, cp));
+                } else if (constant instanceof ConstantDouble) {
+                    bcCodes.add(new Integer(239)); // dldc2_w
+                    bcDoubleRef.add(cpBands.getCPConstant(constant, cp));
+                }
+                break;
+            case 21:
+            case 22:
+            case 23:
+            case 24:
+            case 25:
+            case 54:
+            case 55:
+            case 56:
+            case 57:
+            case 58:
+                bcCodes.add(new Integer(bytecode));
+                if(wide) {
+                    b1 = bytecodes[++i];
+                    b2 = bytecodes[++i];
+                    index = b1 << 8 | b2;
+                    bcLocal.add(new Integer(index));
+                    wide = false;
+                } else {
+                    bcLocal.add(new Integer(0xff & bytecodes[++i]));
+                }
+                break;
+            case 42:
+                int next = 0;
+                if(bytecodes.length >= i) {
+                    next = bytecodes[i+1] & 0xFF;
+                }
+                if(next >= 178 && next <= 184) {
+                    aload_0 = true;
+                } else {
+                    bcCodes.add(new Integer(42));
+                }
+                break;
+            case 132: // iinc
+                bcCodes.add(new Integer(132));
+                if(wide) {
+                    b1 = bytecodes[++i];
+                    b2 = bytecodes[++i];
+                    index = b1 << 8 | b2;
+                    b1 = bytecodes[++i];
+                    b2 = bytecodes[++i];
+                    short cnst = (short) (b1 << 8 | b2);
+                    bcLocal.add(new Integer(index));
+                    bcShort.add(new Integer(cnst));
+                    wide = false;
+                } else {
+                    index = bytecodes[++i];
+                    byte cnst = bytecodes[++i];
+                    bcLocal.add(new Integer(index));
+                    bcByte.add(new Integer(cnst));
+                }
+                break;
+            case 153:
+            case 154:
+            case 155:
+            case 156:
+            case 157:
+            case 158:
+            case 159:
+            case 160:
+            case 161:
+            case 162:
+            case 163:
+            case 164:
+            case 165:
+            case 166:
+            case 198:
+            case 199:
+                bcCodes.add(new Integer(bytecode));
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                index = b1 << 8 | b2;
+                bcLabel.add(new Integer(index));
+                break;
+            case 167: // goto
+            case 168: // jsr
+                bcCodes.add(new Integer(bytecode));
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                int offset = b1 << 8 | b2;
+                bcLabel.add(new Integer(offset));
+                break;
+            case 169: // ret
+                bcCodes.add(new Integer(bytecode));
+                if(wide) {
+                    b1 = bytecodes[++i];
+                    b2 = bytecodes[++i];
+                    index = b1 << 8 | b2;
+                    bcLocal.add(new Integer(index));
+                    wide = false;
+                } else {
+                    bcLocal.add(new Integer(0xff & bytecodes[++i]));
+                }
+                break;
+            case 170: // tableswitch
+                bcCodes.add(new Integer(bytecode));
+                int padding = (i + 1) % 4 == 0 ? 0 : 4 - i + 1;
+                i+= padding;
+                b1 = bytecodes[i];
+                b2 = bytecodes[++i];
+                byte b3 = bytecodes[++i];
+                byte b4 = bytecodes[++i];
+                int defaultValue = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                b3 = bytecodes[++i];
+                b4 = bytecodes[++i];
+                int low = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                b3 = bytecodes[++i];
+                b4 = bytecodes[++i];
+                int high = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+                bcLabel.add(new Integer(defaultValue));
+                bcCaseValue.add(new Integer(low));
+                int count = high - low + 1;
+                bcCaseCount.add(new Integer(count));
+                for (int j = 0; j < count; j++) {
+                    b1 = bytecodes[++i];
+                    b2 = bytecodes[++i];
+                    b3 = bytecodes[++i];
+                    b4 = bytecodes[++i];
+                    int label = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+                    bcLabel.add(new Integer(label));
+                }
+                break;
+            case 171: // lookupswitch
+                bcCodes.add(new Integer(bytecode));
+                padding = (i + 1) % 4 == 0 ? 0 : 4 - i + 1;
+                i+= padding;
+                b1 = bytecodes[i];
+                b2 = bytecodes[++i];
+                b3 = bytecodes[++i];
+                b4 = bytecodes[++i];
+                defaultValue = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+                bcLabel.add(new Integer(defaultValue));
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                b3 = bytecodes[++i];
+                b4 = bytecodes[++i];
+                int npairs = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+                bcCaseCount.add(new Integer(npairs));
+                for (int j = 0; j < npairs; j++) {
+                    b1 = bytecodes[++i];
+                    b2 = bytecodes[++i];
+                    b3 = bytecodes[++i];
+                    b4 = bytecodes[++i];
+                    int caseValue = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+                    bcCaseValue.add(new Integer(caseValue));
+                    b1 = bytecodes[++i];
+                    b2 = bytecodes[++i];
+                    b3 = bytecodes[++i];
+                    b4 = bytecodes[++i];
+                    int label = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+                    bcLabel.add(new Integer(label));
+                }
+                break;
+            case 178: // getstatic
+            case 179: // putstatic
+            case 180: // getfield
+            case 181: // putfield
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                index = b1 << 8 | b2;
+                ConstantFieldref cfr = (ConstantFieldref) cp.getConstant(index);
+                String className = cfr.getClass(cp);
+                CPMethodOrField cpField = cpBands.getCPMethodOrField(cfr);
+                if(aload_0) {
+                    bytecode += 7;
+                }
+                if(className.equals(thisClass)) {
+                    bytecode += 24; // change to getstatic_this, putstatic_this etc.
+                    bcThisField.add(cpField);
+                } else if (className.equals(superClass)){
+                    bytecode += 38; // change to getstatic_super etc.
+                    bcSuperField.add(cpField);
+                } else {
+                    if(aload_0) {
+                        bytecode -= 7;
+                        bcCodes.add(new Integer(42)); // add aload_0 back in because there's no special rewrite in this case.
+                    }
+                    bcFieldRef.add(cpField);
+                }
+                aload_0 = false;
+                bcCodes.add(new Integer(bytecode));
+                break;
+            case 182: // invokevirtual
+            case 183: // invokespecial
+            case 184: // invokestatic
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                index = b1 << 8 | b2;
+                ConstantMethodref cmr = (ConstantMethodref) cp.getConstant(index);
+                className = cmr.getClass(cp);
+                CPMethodOrField cpMethod = cpBands.getCPMethodOrField(cmr);
+                if(aload_0) {
+                    bytecode += 7;
+                }
+                if(className.equals(thisClass)) {
+                    if(bytecode == 183) { // invokespecial
+                        ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
+                        String name = cnat.getName(cp);
+                        if(name.equals("this")) {
+
+                        }
+                    }
+                    bytecode += 24; // change to invokevirtual_this, invokespecial_this etc.
+                    bcThisMethod.add(cpMethod);
+                } else if(className.equals(superClass)) {
+                    bytecode += 38; // change to invokevirtual_super, invokespecial_super etc.
+                    bcSuperMethod.add(cpMethod);
+                } else {
+                    if(aload_0) {
+                        bytecode -= 7;
+                        bcCodes.add(new Integer(42)); // add aload_0 back in because there's no special rewrite in this case.
+                    }
+                    bcMethodRef.add(cpMethod);
+                }
+                aload_0 = false;
+                bcCodes.add(new Integer(bytecode));
+                break;
+            case 185: // invokeinterface
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                index = b1 << 8 | b2;
+                ConstantInterfaceMethodref cmir = (ConstantInterfaceMethodref) cp.getConstant(index);
+                className = cmir.getClass(cp);
+                CPMethodOrField cpIMethod = cpBands.getCPMethodOrField(cmir);
+                bcIMethodRef.add(cpIMethod);
+                bcCodes.add(new Integer(bytecode));
+                i+= 2; // ignore count and zero fields as this can be recreated by the decompressor
+                break;
+            case 187: // new
+            case 189: // anewarray
+            case 192: // checkcast
+            case 193: // instanceof
+                bcCodes.add(new Integer(bytecode));
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                index = b1 << 8 | b2;
+                ConstantClass constantClass = (ConstantClass) cp.getConstant(index);
+                bcClassRef.add(cpBands.getCPClass(constantClass.getBytes(cp)));
+                break;
+            case 188: // newarray
+                bcCodes.add(new Integer(bytecode));
+                bcByte.add(new Integer(0xff & bytecodes[++i]));
+                break;
+            case 196: // wide
+                bcCodes.add(new Integer(196));
+                wide = true;
+            case 197: // multianewarray
+                bcCodes.add(new Integer(bytecode));
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                index = b1 << 8 | b2;
+                constantClass = (ConstantClass) cp.getConstant(index);
+                bcClassRef.add(cpBands.getCPClass(constantClass.getBytes(cp)));
+                byte dimensions = bytecodes[++i];
+                bcByte.add(new Integer(0xff & dimensions));
+                break;
+            case 200: // goto_w
+            case 201: // jsr_w
+                bcCodes.add(new Integer(bytecode));
+                b1 = bytecodes[++i];
+                b2 = bytecodes[++i];
+                b3 = bytecodes[++i];
+                b4 = bytecodes[++i];
+                offset = b1 << 24 | b2 << 16 | b3 << 8 | b4;
+                bcLabel.add(new Integer(offset));
+                break;
+//   TODO         case 230: // invokespecial_this_init
+//            case 231: // invokespecial_super_init
+//            case 232: // invokespecial_new_init
+//                bcInitRefCount++;
+//                break;
+            default:
+                if(bytecode >= 202) {
+                    throw new RuntimeException("Non-standard bytecode instructions not supported");
+                } else {
+                    bcCodes.add(new Integer(bytecode));
+                }
+            }
+        }
     }
 
-    public void addCode(Code obj) {
-        // TODO Auto-generated method stub
+    public void finaliseBands() {
+
+    }
 
+    public void pack(OutputStream out) throws IOException, Pack200Exception {
+        out.write(encodeBandInt(listToArray(bcCodes), Codec.BYTE1));
+        out.write(encodeBandInt(listToArray(bcCaseCount), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(bcCaseValue), Codec.DELTA5));
+        out.write(encodeBandInt(listToArray(bcByte), Codec.BYTE1));
+        out.write(encodeBandInt(listToArray(bcShort), Codec.DELTA5));
+        out.write(encodeBandInt(listToArray(bcLocal), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(bcLabel), Codec.BRANCH5));
+        out.write(encodeBandInt(cpEntryListToArray(bcIntref), Codec.DELTA5));
+        out.write(encodeBandInt(cpEntryListToArray(bcFloatRef), Codec.DELTA5));
+        out.write(encodeBandInt(cpEntryListToArray(bcLongRef), Codec.DELTA5));
+        out.write(encodeBandInt(cpEntryListToArray(bcDoubleRef), Codec.DELTA5));
+        out.write(encodeBandInt(cpEntryListToArray(bcStringRef), Codec.DELTA5));
+        out.write(encodeBandInt(cpEntryOrNullListToArray(bcClassRef), Codec.UNSIGNED5));
+        out.write(encodeBandInt(cpEntryListToArray(bcFieldRef), Codec.DELTA5));
+        out.write(encodeBandInt(cpEntryListToArray(bcMethodRef), Codec.UNSIGNED5));
+        out.write(encodeBandInt(cpEntryListToArray(bcIMethodRef), Codec.DELTA5));
+        out.write(encodeBandInt(listToArray(bcThisField), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(bcSuperField), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(bcThisMethod), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(bcSuperMethod), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(bcInitRef), Codec.UNSIGNED5));
+//        out.write(encodeBandInt(cpEntryListToArray(bcEscRef), Codec.UNSIGNED5));
+//        out.write(encodeBandInt(listToArray(bcEscRefSize), Codec.UNSIGNED5));
+//        out.write(encodeBandInt(listToArray(bcEscSize), Codec.UNSIGNED5));
+//        out.write(encodeBandInt(listToArray(bcEscByte), Codec.BYTE1));
     }
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPClass.java?rev=678762&r1=678761&r2=678762&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPClass.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPClass.java Tue Jul 22 06:48:50 2008
@@ -17,7 +17,7 @@
 package org.apache.harmony.pack200;
 
 
-public class CPClass extends ConstantPoolEntry implements Comparable {
+public class CPClass extends CPConstant implements Comparable {
 
     private final String className;
     private final CPUTF8 utf8;

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java?rev=678762&r1=678761&r2=678762&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java Tue Jul 22 06:48:50 2008
@@ -54,11 +54,11 @@
         }
         return 0;
     }
-    
+
     public int getClassIndex() {
         return className.getIndex();
     }
-    
+
     public int getDescIndex() {
         return nameAndType.getIndex();
     }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java?rev=678762&r1=678761&r2=678762&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java Tue Jul 22 06:48:50 2008
@@ -19,7 +19,7 @@
 import java.util.List;
 
 public class CPSignature extends ConstantPoolEntry implements Comparable {
-    
+
     private final CPUTF8 signatureForm;
     private final List classes;
     private final String signature;
@@ -37,11 +37,11 @@
     public int getIndexInCpUtf8() {
         return signatureForm.getIndex();
     }
-    
+
     public List getClasses() {
         return classes;
     }
-    
+
     public String toString() {
         return signature;
     }

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=678762&r1=678761&r2=678762&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 Tue Jul 22 06:48:50 2008
@@ -66,10 +66,14 @@
     private final CPNameAndType[][] field_descr;
     private List fieldFlags = new ArrayList();
     private List fieldConstantValueKQ = new ArrayList();
+    private List fieldSignature = new ArrayList();
 
     private final int[] class_method_count;
     private final CPNameAndType[][] method_descr;
     private List methodFlags = new ArrayList();
+    private List methodSignature = new ArrayList();
+    private List methodExceptionNumber = new ArrayList();
+    private List methodExceptionClasses = new ArrayList();
 
     private List codeHeaders = new ArrayList();
     private List codeMaxStack = new ArrayList();
@@ -172,8 +176,14 @@
                     flags |= (1<<17);
                 } else if (attributes[j] instanceof ExceptionTable) {
                     flags |= (1<<18);
+                    String[] exceptionNames = ((ExceptionTable)attributes[j]).getExceptionNames();
+                    methodExceptionNumber.add(new Integer(exceptionNames.length));
+                    for (int k = 0; k < exceptionNames.length; k++) {
+                        methodExceptionClasses.add(cpBands.getCPClass(exceptionNames[k]));
+                    }
                 } else if (attributes[j] instanceof Signature) {
                     flags |= (1<<19);
+                    methodSignature.add(cpBands.getCPSignature(((Signature)attributes[j]).getSignature()));
                 } else if (attributes[j] instanceof Deprecated) {
                     flags |= (1<<20);
 //                } else if (attributes[j] instanceof RuntimeVisibleAnnotations) {
@@ -214,6 +224,7 @@
                     fieldConstantValueKQ.add(cpConstant);
                 } else if (attributes[j] instanceof Signature) {
                     flags |= (1<<19);
+                    fieldSignature.add(cpBands.getCPSignature(((Signature)attributes[j]).getSignature()));
                 } else if (attributes[j] instanceof Deprecated) {
                     flags |= (1<<20);
 //                } else if (attributes[j] instanceof RuntimeVisibleAnnotations) {
@@ -304,22 +315,6 @@
         }
     }
 
-    private int[] listToArray(List integerList) {
-        int[] array = new int[integerList.size()];
-        for (int i = 0; i < array.length; i++) {
-            array[i] = ((Integer)integerList.get(i)).intValue();
-        }
-        return array;
-    }
-
-    private long[] longListToArray(List longList) {
-        long[] array = new long[longList.size()];
-        for (int i = 0; i < array.length; i++) {
-            array[i] = ((Long)longList.get(i)).longValue();
-        }
-        return array;
-    }
-
     private int[] renumberBCI(byte[] code) {
         int[] instructionBoundaries = getInstructionBoundaries(code);
         int[] renumbered = new int[code.length];
@@ -477,83 +472,41 @@
     }
 
     private void writeFieldAttributeBands(OutputStream out) throws IOException, Pack200Exception {
-        long[] field_flags = longListToArray(fieldFlags);
-        int[] field_constant_value = listToArray(fieldConstantValueKQ);
-
-        out.write(encodeFlags(field_flags, Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_field_flags_hi()));
+        out.write(encodeFlags(longListToArray(fieldFlags), Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_field_flags_hi()));
+        out.write(encodeBandInt(cpEntryListToArray(fieldConstantValueKQ), Codec.UNSIGNED5));
+        out.write(encodeBandInt(cpEntryListToArray(fieldSignature), Codec.UNSIGNED5));
     }
 
     private void writeMethodAttributeBands(OutputStream out) throws IOException, Pack200Exception {
-        long[] method_flags = longListToArray(methodFlags);
+        out.write(encodeFlags(longListToArray(methodFlags), Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_method_flags_hi()));
+        out.write(encodeBandInt(listToArray(methodExceptionNumber), Codec.UNSIGNED5));
+        out.write(encodeBandInt(cpEntryListToArray(methodExceptionClasses), Codec.UNSIGNED5));
+        out.write(encodeBandInt(cpEntryListToArray(methodSignature), Codec.UNSIGNED5));
 
-        out.write(encodeFlags(method_flags, Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_method_flags_hi()));
     }
 
     private void writeClassAttributeBands(OutputStream out) throws IOException, Pack200Exception {
         out.write(encodeFlags(class_flags, Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_class_flags_hi()));
-        int[] class_source_file = new int[classSourceFile.size()];
-        for (int i = 0; i < class_source_file.length; i++) {
-            CPUTF8 sourceFile = (CPUTF8) classSourceFile.get(i);
-            if(sourceFile == null) {
-                class_source_file[i] = 0;
-            } else {
-                class_source_file[i] = sourceFile.getIndex() + 1;
-            }
-        }
-        out.write(encodeBandInt(class_source_file, Codec.UNSIGNED5));
-
+        out.write(encodeBandInt(cpEntryOrNullListToArray(classSourceFile), Codec.UNSIGNED5));
+        out.write(encodeBandInt(cpEntryListToArray(classSignature), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(classFileVersionMinor), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(classFileVersionMajor), Codec.UNSIGNED5));
     }
 
     private void writeCodeBands(OutputStream out) throws IOException, Pack200Exception {
-        int[] code_headers = listToArray(codeHeaders);
-        int[] code_max_stack = listToArray(codeMaxStack);
-        int[] code_max_na_locals = listToArray(codeMaxLocals);
-        int[] code_handler_count = listToArray(codeHandlerCount);
-        int[] code_handler_start_P = listToArray(codeHandlerStartP);
-        int[] code_handler_end_PO = listToArray(codeHandlerEndPO);
-        int[] code_handler_catch_PO = listToArray(codeHandlerCatchPO);
-        int[] code_handler_class = new int[codeHandlerClass.size()];
-        for (int j = 0; j < code_handler_class.length; j++) {
-            CPClass cpClass = (CPClass) codeHandlerClass.get(j);
-            code_handler_class[j] = cpClass == null ? 0 : cpClass.getIndex() + 1;
-        }
-        out.write(encodeBandInt(code_headers, Codec.BYTE1));
-        out.write(encodeBandInt(code_max_stack, Codec.UNSIGNED5));
-        out.write(encodeBandInt(code_max_na_locals, Codec.UNSIGNED5));
-        out.write(encodeBandInt(code_handler_count, Codec.UNSIGNED5));
-        out.write(encodeBandInt(code_handler_start_P, Codec.BCI5));
-        out.write(encodeBandInt(code_handler_end_PO, Codec.BRANCH5));
-        out.write(encodeBandInt(code_handler_catch_PO, Codec.BRANCH5));
-        out.write(encodeBandInt(code_handler_class, Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(codeHeaders), Codec.BYTE1));
+        out.write(encodeBandInt(listToArray(codeMaxStack), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(codeMaxLocals), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(codeHandlerCount), Codec.UNSIGNED5));
+        out.write(encodeBandInt(listToArray(codeHandlerStartP), Codec.BCI5));
+        out.write(encodeBandInt(listToArray(codeHandlerEndPO), Codec.BRANCH5));
+        out.write(encodeBandInt(listToArray(codeHandlerCatchPO), Codec.BRANCH5));
+        out.write(encodeBandInt(cpEntryOrNullListToArray(codeHandlerClass), Codec.UNSIGNED5));
         writeCodeAttributeBands(out);
     }
 
-    private int[] flatten(int[][] twoDInts) {
-        int[] ints = new int[totalSize(twoDInts)];
-        int index = 0;
-        for (int i = 0; i < twoDInts.length; i++) {
-            for (int j = 0; j < twoDInts[i].length; j++) {
-                ints[index] = twoDInts[i][j];
-                index++;
-            }
-        }
-        return ints;
-    }
-
-    private int totalSize(int[][] ints) {
-        int count = 0;
-        for (int i = 0; i < ints.length; i++) {
-            for (int j = 0; j < ints[i].length; j++) {
-                count++;
-            }
-        }
-        return count;
-    }
-
     private void writeCodeAttributeBands(OutputStream out) throws IOException, Pack200Exception {
-        long[] code_flags = longListToArray(codeFlags);
-
-        out.write(encodeFlags(code_flags, Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_code_flags_hi()));
+        out.write(encodeFlags(longListToArray(codeFlags), Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_code_flags_hi()));
     }
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=678762&r1=678761&r2=678762&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Tue Jul 22 06:48:50 2008
@@ -71,7 +71,7 @@
     private final Map stringsToCpClass = new HashMap();
     private final Map stringsToCpSignature = new HashMap();
 
-    private final Map constantsToCPConstant = new HashMap();
+    private final Map objectsToCPConstant = new HashMap();
 
     private ConstantPool currentConstantPool;
     private JavaClass currentClass;
@@ -366,11 +366,11 @@
     public void addConstantDouble(ConstantDouble constant) {
         double d = (constant).getBytes();
         Double bigD = new Double(d);
-        CPDouble cpd = (CPDouble) constantsToCPConstant.get(bigD);
+        CPDouble cpd = (CPDouble) objectsToCPConstant.get(bigD);
         if(cpd == null) {
             cpd = new CPDouble(d);
             cp_Double.add(cpd);
-            constantsToCPConstant.put(bigD, cpd);
+            objectsToCPConstant.put(bigD, cpd);
         }
     }
 
@@ -387,22 +387,22 @@
     public void addConstantFloat(ConstantFloat constant) {
         float f = (constant).getBytes();
         Float bigF = new Float(f);
-        CPFloat cpf = (CPFloat) constantsToCPConstant.get(bigF);
+        CPFloat cpf = (CPFloat) objectsToCPConstant.get(bigF);
         if(cpf == null) {
             cpf = new CPFloat(f);
             cp_Float.add(cpf);
-            constantsToCPConstant.put(bigF, cpf);
+            objectsToCPConstant.put(bigF, cpf);
         }
     }
 
     public void addConstantInteger(ConstantInteger constant) {
         int i = (constant).getBytes();
         Integer bigI = new Integer(i);
-        CPInt cpi = (CPInt) constantsToCPConstant.get(bigI);
+        CPInt cpi = (CPInt) objectsToCPConstant.get(bigI);
         if(cpi == null) {
             cpi = new CPInt(i);
             cp_Int.add(cpi);
-            constantsToCPConstant.put(bigI, cpi);
+            objectsToCPConstant.put(bigI, cpi);
         }
     }
 
@@ -420,11 +420,11 @@
     public void addConstantLong(ConstantLong constant) {
         long l = (constant).getBytes();
         Long bigL = new Long(l);
-        CPLong cpl = (CPLong) constantsToCPConstant.get(bigL);
+        CPLong cpl = (CPLong) objectsToCPConstant.get(bigL);
         if(cpl == null) {
             cpl = new CPLong(l);
             cp_Long.add(cpl);
-            constantsToCPConstant.put(bigL, cpl);
+            objectsToCPConstant.put(bigL, cpl);
         }
     }
 
@@ -446,11 +446,11 @@
 
     public void addConstantString(ConstantString constant) {
         String string = constant.getBytes(currentConstantPool);
-        CPString cpString = (CPString) constantsToCPConstant.get(string);
+        CPString cpString = (CPString) objectsToCPConstant.get(string);
         if (cpString == null) {
             cpString = new CPString(getCPUtf8(string));
             cp_String.add(cpString);
-            constantsToCPConstant.put(string, cpString);
+            objectsToCPConstant.put(string, cpString);
         }
     }
 
@@ -562,21 +562,58 @@
     }
 
     public CPConstant getCPConstant(Constant theConstant, ConstantPool cp) {
-        Object key;
+        CPConstant cpC;
         if(theConstant instanceof ConstantDouble) {
-            key = new Double(((ConstantDouble)theConstant).getBytes());
+            Double key = new Double(((ConstantDouble)theConstant).getBytes());
+            cpC = (CPConstant) objectsToCPConstant.get(key);
+            if(cpC == null) {
+                cpC = new CPDouble(key.doubleValue());
+                cp_Double.add(cpC);
+                objectsToCPConstant.put(key, cpC);
+            }
         } else if (theConstant instanceof ConstantFloat) {
-            key = new Float(((ConstantFloat)theConstant).getBytes());
+            Float key = new Float(((ConstantFloat)theConstant).getBytes());
+            cpC = (CPConstant) objectsToCPConstant.get(key);
+            if(cpC == null) {
+                cpC = new CPFloat(key.floatValue());
+                cp_Float.add(cpC);
+                objectsToCPConstant.put(key, cpC);
+            }
         } else if (theConstant instanceof ConstantInteger) {
-            key = new Integer(((ConstantInteger)theConstant).getBytes());
+            Integer key = new Integer(((ConstantInteger)theConstant).getBytes());
+            cpC = (CPConstant) objectsToCPConstant.get(key);
+            if(cpC == null) {
+                cpC = new CPInt(key.intValue());
+                cp_Int.add(cpC);
+                objectsToCPConstant.put(key, cpC);
+            }
         } else if (theConstant instanceof ConstantLong) {
-            key = new Long(((ConstantLong)theConstant).getBytes());
+            Long key = new Long(((ConstantLong)theConstant).getBytes());
+            cpC = (CPConstant) objectsToCPConstant.get(key);
+            if(cpC == null) {
+                cpC = new CPLong(key.longValue());
+                cp_Long.add(cpC);
+                objectsToCPConstant.put(key, cpC);
+            }
         } else if (theConstant instanceof ConstantString) {
-            key = ((ConstantString)theConstant).getBytes(cp);
+            String key = ((ConstantString)theConstant).getBytes(cp);
+            cpC = (CPConstant) objectsToCPConstant.get(key);
+            if(cpC == null) {
+                cpC = new CPString(getCPUtf8(key));
+                cp_String.add(cpC);
+                objectsToCPConstant.put(key, cpC);
+            }
+        } else if (theConstant instanceof ConstantClass) {
+            cpC = getCPClass(((ConstantClass)theConstant).getBytes(cp));
         } else {
             throw new RuntimeException("Unexpected constant type: " + theConstant.getClass());
         }
-        return (CPConstant) constantsToCPConstant.get(key);
+        return cpC;
+    }
+
+    public CPMethodOrField getCPMethodOrField(Constant constant) {
+        // TODO Auto-generated method stub
+        return null;
     }
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java?rev=678762&r1=678761&r2=678762&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java Tue Jul 22 06:48:50 2008
@@ -30,7 +30,7 @@
         this.files = files;
         int size = files.size();
         if(size > 0) {
-            
+
         }
     }
 

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=678762&r1=678761&r2=678762&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java Tue Jul 22 06:48:50 2008
@@ -68,6 +68,10 @@
     private BcBands bcBands;
     private FileBands fileBands;
 
+    // The current class - only to be used when processing the classes
+    private String currentClass;
+    private String superClass;
+
 
     public void pack(List classes, List files, OutputStream out) throws IOException, Pack200Exception {
         segmentHeader = new SegmentHeader();
@@ -75,7 +79,7 @@
         attributeDefinitionBands = new AttributeDefinitionBands(segmentHeader, cpBands);
         icBands = new IcBands(segmentHeader);
         classBands = new ClassBands(segmentHeader, cpBands, attributeDefinitionBands, classes.size());
-        bcBands = new BcBands();
+        bcBands = new BcBands(cpBands);
         fileBands = new FileBands(segmentHeader, files);
 
         processClasses(classes);
@@ -104,7 +108,7 @@
     }
 
     public void visitCode(Code obj) {
-        bcBands.addCode(obj);
+        bcBands.addCode(obj, currentClass, superClass);
         Attribute[] attributes = obj.getAttributes();
         for (int i = 0; i < attributes.length; i++) {
             if(attributes[i] instanceof Unknown) {
@@ -198,6 +202,8 @@
 
     public void visitJavaClass(JavaClass obj) {
         cpBands.setCurrentClass(obj);
+        currentClass = obj.getClassName();
+        superClass = obj.getSuperclassName();
         classBands.addClass(obj);
         segmentHeader.addMinorVersion(obj.getMinor());
         segmentHeader.addMajorVersion(obj.getMajor());