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

svn commit: r610778 - in /harmony/enhanced/classlib/trunk/modules/pack200/src: main/java/org/apache/harmony/pack200/ main/java/org/apache/harmony/pack200/bytecode/ test/java/org/apache/harmony/pack200/tests/

Author: odeakin
Date: Thu Jan 10 04:41:20 2008
New Revision: 610778

URL: http://svn.apache.org/viewvc?rev=610778&view=rev
Log:
Apply patch for HARMONY-5377 ([classlib] [pack200] Exception table missing from code attributes)

Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.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/ExceptionTableEntry.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java?rev=610778&r1=610777&r2=610778&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java Thu Jan 10 04:41:20 2008
@@ -25,7 +25,9 @@
 import org.apache.harmony.pack200.bytecode.Attribute;
 import org.apache.harmony.pack200.bytecode.BCIRenumberedAttribute;
 import org.apache.harmony.pack200.bytecode.ByteCode;
+import org.apache.harmony.pack200.bytecode.CPClass;
 import org.apache.harmony.pack200.bytecode.CodeAttribute;
+import org.apache.harmony.pack200.bytecode.ExceptionTableEntry;
 import org.apache.harmony.pack200.bytecode.OperandManager;
 
 /**
@@ -365,23 +367,46 @@
 
         int i = 0;
         ArrayList orderedCodeAttributes = segment.getClassBands().getOrderedCodeAttributes();
+        
+        // Exception table fields
+        int[] handlerCount = segment.getClassBands().getCodeHandlerCount();
+        int[][] handlerStartPCs = segment.getClassBands().getCodeHandlerStartP();
+        int[][] handlerEndPCs = segment.getClassBands().getCodeHandlerEndPO();
+        int[][] handlerCatchPCs = segment.getClassBands().getCodeHandlerCatchPO();
+        String[][] handlerClassTypes = segment.getClassBands().getCodeHandlerClassRCN();
+
         for (int c = 0; c < classCount; c++) {
-           int numberOfMethods = methodFlags[c].length;
-           for (int m = 0; m < numberOfMethods; m++) {
-               long methodFlag = methodFlags[c][m];
-               if (!abstractModifier.matches(methodFlag)
-                       && !nativeModifier.matches(methodFlag)) {
-                   int maxStack = codeMaxStack[i];
-                   int maxLocal = codeMaxNALocals[i];
-                   if (!staticModifier.matches(methodFlag))
-                       maxLocal++; // one for 'this' parameter
-                   maxLocal += SegmentUtils.countArgs(methodDescr[c][m]);
-                   operandManager.setCurrentClass(segment.getClassBands().getClassThis()[c]);
-                   operandManager.setSuperClass(segment.getClassBands().getClassSuper()[c]);
-                   CodeAttribute codeAttr = new CodeAttribute(maxStack, maxLocal,
-                           methodByteCodePacked[c][m], segment, operandManager);
-                   methodAttributes[c][m].add(codeAttr);
-                   // Should I add all the attributes in here?
+            int numberOfMethods = methodFlags[c].length;
+            for (int m = 0; m < numberOfMethods; m++) {
+                long methodFlag = methodFlags[c][m];
+                if (!abstractModifier.matches(methodFlag)
+                        && !nativeModifier.matches(methodFlag)) {
+                    int maxStack = codeMaxStack[i];
+                    int maxLocal = codeMaxNALocals[i];
+                    if (!staticModifier.matches(methodFlag))
+                        maxLocal++; // one for 'this' parameter
+                    maxLocal += SegmentUtils.countArgs(methodDescr[c][m]);
+                    operandManager.setCurrentClass(segment.getClassBands()
+                            .getClassThis()[c]);
+                    operandManager.setSuperClass(segment.getClassBands()
+                            .getClassSuper()[c]);
+                    List exceptionTable = new ArrayList();
+                    if(handlerCount != null) {
+                        for (int j = 0; j < handlerCount[i]; j++) {
+                            String handlerClass = handlerClassTypes[i][j];
+                            CPClass cpHandlerClass = new CPClass(handlerClass);
+                            ExceptionTableEntry entry = new ExceptionTableEntry(
+                                    handlerStartPCs[i][j], handlerEndPCs[i][j],
+                                    handlerCatchPCs[i][j], cpHandlerClass);
+                            exceptionTable.add(entry);
+                        }
+                    }
+                    CodeAttribute codeAttr = new CodeAttribute(maxStack,
+                            maxLocal, methodByteCodePacked[c][m], segment,
+                            operandManager, exceptionTable);
+                    methodAttributes[c][m].add(codeAttr);
+                    codeAttr.renumber(codeAttr.byteCodeOffsets);
+                    // 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);

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=610778&r1=610777&r2=610778&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 Thu Jan 10 04:41:20 2008
@@ -92,6 +92,14 @@
 
     private int[] methodAttrCalls;
 
+    private int[][] codeHandlerStartP;
+
+    private int[][] codeHandlerEndPO;
+
+    private int[][] codeHandlerCatchPO;
+
+    private String[][] codeHandlerClassRCN;
+
     /**
      * @param segment
      */
@@ -667,18 +675,29 @@
                 throw new IllegalStateException("Shouldn't get here either");
             }
         }
-        int sumCodeHandlerCount = 0;
-        for (int i = 0; i < codeHandlerCount.length; i++) {
-            sumCodeHandlerCount += codeHandlerCount[i];
-        }
-        int[] codeHandlerStartP = decodeBandInt("code_handler_start_P", in,
-                Codec.BCI5, sumCodeHandlerCount);
-        int[] codeHandlerEndPO = decodeBandInt("code_handler_end_PO", in,
-                Codec.BRANCH5, sumCodeHandlerCount);
-        int[] codeHandlerCatchPO = decodeBandInt("code_handler_catch_PO", in,
-                Codec.BRANCH5, sumCodeHandlerCount);
-        int[] codeHandlerClassRCN = decodeBandInt("code_handler_class_RCN", in,
-                Codec.UNSIGNED5, sumCodeHandlerCount);
+        codeHandlerStartP = decodeBandInt("code_handler_start_P", in,
+                        Codec.BCI5, codeHandlerCount);
+        codeHandlerEndPO = decodeBandInt("code_handler_end_PO", in,
+                        Codec.BRANCH5, codeHandlerCount);
+        codeHandlerCatchPO = decodeBandInt("code_handler_catch_PO", in,
+                        Codec.BRANCH5, codeHandlerCount);
+        int[][] codeHandlerClassRCNints = decodeBandInt("code_handler_class_RCN", in,
+                        Codec.UNSIGNED5, codeHandlerCount);
+        // The codeHandlerClassRCN band contains incremented references to
+        // cp_Class so we can't use parseReferences(..) here.
+        String[] cpClass = cpBands.getCpClass();
+        codeHandlerClassRCN = new String[codeHandlerClassRCNints.length][];
+        for (int i = 0; i < codeHandlerClassRCNints.length; i++) {
+            codeHandlerClassRCN[i] = new String[codeHandlerClassRCNints[i].length];
+            for (int j = 0; j < codeHandlerClassRCNints[i].length; j++) {
+                int handlerClassReference = codeHandlerClassRCNints[i][j];
+                if(handlerClassReference == 0) {
+                    codeHandlerClassRCN[i][j] = null;
+                } else {
+                    codeHandlerClassRCN[i][j] = cpClass[handlerClassReference - 1];
+                }
+            }
+        }
 
         int codeFlagsCount = segment.getSegmentHeader().getOptions()
                 .hasAllCodeFlags() ? codeCount : codeSpecialHeader;
@@ -1227,6 +1246,26 @@
      */
     public int[] getClassVersionMinor() {
         return classVersionMinor;
+    }
+
+    public int[] getCodeHandlerCount() {
+        return codeHandlerCount;
+    }
+
+    public int[][] getCodeHandlerCatchPO() {
+        return codeHandlerCatchPO;
+    }
+
+    public String[][] getCodeHandlerClassRCN() {
+        return codeHandlerClassRCN;
+    }
+
+    public int[][] getCodeHandlerEndPO() {
+        return codeHandlerEndPO;
+    }
+
+    public int[][] getCodeHandlerStartP() {
+        return codeHandlerStartP;
     }
 
 }

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=610778&r1=610777&r2=610778&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java Thu Jan 10 04:41:20 2008
@@ -24,22 +24,23 @@
 
 import org.apache.harmony.pack200.Segment;
 
-public class CodeAttribute extends Attribute {
+public class CodeAttribute extends BCIRenumberedAttribute {
     public List attributes = new ArrayList();
     // instances
     public List byteCodeOffsets = new ArrayList();
     public List byteCodes = new ArrayList();
     public int codeLength;
-    public List exceptionTable = new ArrayList(); // of ExceptionTableEntry
+    public List exceptionTable; // of ExceptionTableEntry
     public int maxLocals;
     public int maxStack;
 
     public CodeAttribute(int maxStack, int maxLocals, byte codePacked[],
-            Segment segment, OperandManager operandManager) {
+            Segment segment, OperandManager operandManager, List exceptionTable) {
         super("Code"); //$NON-NLS-1$
         this.maxLocals = maxLocals;
         this.maxStack = maxStack;
         this.codeLength = 0;
+        this.exceptionTable = exceptionTable;
         byteCodeOffsets.add(new Integer(0));
         for (int i = 0; i < codePacked.length; i++) {
             ByteCode byteCode = ByteCode.getByteCode(codePacked[i] & 0xff);
@@ -119,6 +120,10 @@
             ByteCode byteCode = (ByteCode) it.next();
             byteCode.resolve(pool);
         }
+        for (Iterator iter = exceptionTable.iterator(); iter.hasNext();) {
+            ExceptionTableEntry entry = (ExceptionTableEntry) iter.next();
+            entry.resolve(pool);            
+        }
     }
 
     public String toString() {
@@ -155,5 +160,17 @@
     
     public List attributes() {
         return attributes;
+    }
+
+    protected int[] getStartPCs() {
+        // Do nothing here as we've overriden renumber
+        return null;
+    }
+
+    public void renumber(List byteCodeOffsets) {
+        for (Iterator iter = exceptionTable.iterator(); iter.hasNext();) {
+            ExceptionTableEntry entry = (ExceptionTableEntry) iter.next();
+            entry.renumber(byteCodeOffsets);            
+        }
     }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ExceptionTableEntry.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ExceptionTableEntry.java?rev=610778&r1=610777&r2=610778&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ExceptionTableEntry.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ExceptionTableEntry.java Thu Jan 10 04:41:20 2008
@@ -18,18 +18,44 @@
 
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.util.List;
 
 public class ExceptionTableEntry {
 
-	public int catchType;
-	public int endPC;
-	public int handlerPC;
-	public int startPC;
+    private int startPC;
+    private int endPC;
+    private int handlerPC;
+    private CPClass catchType;    
+
+    private int startPcRenumbered;
+    private int endPcRenumbered;
+    private int handlerPcRenumbered;
+    private int catchTypeIndex;
+
+    public ExceptionTableEntry(int startPC, int endPC, int handlerPC, CPClass catchType) {
+        this.startPC = startPC;
+        this.endPC = endPC;
+        this.handlerPC = handlerPC;
+        this.catchType = catchType;
+    }
 
 	public void write(DataOutputStream dos) throws IOException {
-		dos.writeShort(startPC);
-		dos.writeShort(endPC);
-		dos.writeShort(handlerPC);
-		dos.writeShort(catchType);
+		dos.writeShort(startPcRenumbered);
+		dos.writeShort(endPcRenumbered);
+		dos.writeShort(handlerPcRenumbered);
+		dos.writeShort(catchTypeIndex);
 	}
+    
+    public void renumber(List byteCodeOffsets) {
+        startPcRenumbered = ((Integer)byteCodeOffsets.get(startPC)).intValue();
+        int endPcIndex = startPC + endPC;
+        endPcRenumbered = ((Integer)byteCodeOffsets.get(endPcIndex)).intValue();
+        int handlerPcIndex = endPcIndex + handlerPC;
+        handlerPcRenumbered = ((Integer)byteCodeOffsets.get(handlerPcIndex)).intValue();
+    }
+    
+    public void resolve(ClassConstantPool pool) {
+        catchType.resolve(pool);
+        catchTypeIndex = pool.indexOf(catchType);
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java?rev=610778&r1=610777&r2=610778&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java Thu Jan 10 04:41:20 2008
@@ -16,6 +16,9 @@
  */
 package org.apache.harmony.pack200.tests;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import junit.framework.TestCase;
 
 import org.apache.harmony.pack200.CpBands;
@@ -35,9 +38,8 @@
 
         public MockCodeAttribute(int maxStack, int maxLocals,
                 byte[] codePacked, Segment segment,
-                OperandManager operandManager) {
-            super(maxStack, maxLocals, codePacked, segment, operandManager);
-            // TODO Auto-generated constructor stub
+                OperandManager operandManager, List exceptionTable) {
+            super(maxStack, maxLocals, codePacked, segment, operandManager, exceptionTable);
         }
 
         public int getLength() {
@@ -146,7 +148,8 @@
                 2, // maxLocals
                 mixedByteArray, // codePacked
                 segment, // segment
-                operandManager // operandManager
+                operandManager, // operandManager
+                new ArrayList()
         );
         assertEquals(29, attribute.getLength());
 
@@ -164,7 +167,8 @@
                 2, // maxLocals
                 mixedByteArray, // codePacked
                 segment, // segment
-                operandManager // operandManager
+                operandManager, // operandManager
+                new ArrayList()
         );
         assertEquals(2, attribute.maxLocals);
         assertEquals(3, attribute.maxStack);
@@ -187,7 +191,8 @@
                 3, // maxLocals
                 singleByteArray, // codePacked
                 segment, // segment
-                operandManager // operandManager
+                operandManager, // operandManager
+                new ArrayList()
         );
         assertEquals(3, attribute.maxLocals);
         assertEquals(4, attribute.maxStack);