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 2007/12/04 20:06:46 UTC

svn commit: r601041 - in /harmony/enhanced/classlib/trunk/modules/pack200/src: main/java/org/apache/harmony/pack200/ main/java/org/apache/harmony/pack200/bytecode/ main/java/org/apache/harmony/pack200/bytecode/forms/ test/java/org/apache/harmony/pack20...

Author: tellison
Date: Tue Dec  4 11:06:43 2007
New Revision: 601041

URL: http://svn.apache.org/viewvc?rev=601041&view=rev
Log:
Apply patch HARMONY-5244 ([classlib][pack200] LabelForm target addresses wrong)

Added:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/BCIRenumberedAttribute.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/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/bytecode/ByteCode.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/ClassFile.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/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/forms/ByteCodeForm.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.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=601041&r1=601040&r2=601041&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 Dec  4 11:06:43 2007
@@ -22,6 +22,8 @@
 import java.io.OutputStream;
 import java.util.ArrayList;
 
+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.CodeAttribute;
 import org.apache.harmony.pack200.bytecode.LineNumberTableAttribute;
@@ -343,6 +345,7 @@
         operandManager.setSegment(segment);
 
         int i = 0;
+        ArrayList orderedCodeAttributes = segment.getClassBands().getOrderedCodeAttributes();
         for (int c = 0; c < classCount; c++) {
            int numberOfMethods = methodFlags[c].length;
            for (int m = 0; m < numberOfMethods; m++) {
@@ -361,13 +364,22 @@
                    CodeAttribute attr = new CodeAttribute(maxStack, maxLocal,
                            methodByteCodePacked[c][m], segment, operandManager);
                    methodAttributes[c][m].add(attr);
-                   // Fix up the line numbers
-                   LineNumberTableAttribute lineNumberTable = (LineNumberTableAttribute)segment.getClassBands().getLineNumberAttributes().get(i);
-                   if(null != lineNumberTable) {
-                	   attr.attributes.add(lineNumberTable);
-                       lineNumberTable.renumberLineNumberTable(attr.byteCodeOffsets);
-                   }
-                   i++;
+                   // 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.
+                     //attr.attributes.add(currentAttribute);
+                     // Fix up the line numbers if needed
+                     if(currentAttribute.hasBCIRenumbering()) {
+                         ((BCIRenumberedAttribute)currentAttribute).renumber(attr.byteCodeOffsets);
+                     }
+                 }
+                 i++;
                }
            }
        }

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=601041&r1=601040&r2=601041&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 Dec  4 11:06:43 2007
@@ -1000,30 +1000,26 @@
     }
 
     /**
-     * Answer an ArrayList of the LineNumberTables corresponding to all classes.
-     * If a class doesn't have a LineNumberTable, the corresponding element in this
-     * list will be null.
+     * Answer an ArrayList of ArrayLists which hold the the code attributes
+     * corresponding to all classes in order.
+     * 
+     * If a class doesn't have any attributes, the corresponding element in this
+     * list will be an empty ArrayList.
      * @return ArrayList
      */
-    // TODO: the class file spec allows >1 LineNumberTable per method. Does Pack200 spec fold them all into one? (If not, need to handle that case.)
-    public ArrayList getLineNumberAttributes() {
-    	ArrayList lineNumberList = new ArrayList();
-    	for(int classIndex=0; classIndex < codeAttributes.length; classIndex++) {
-    		boolean foundLineNumberTable = false;
-    		for(int attributeIndex = 0; attributeIndex < codeAttributes[classIndex].size(); attributeIndex++) {
-    			Attribute attribute = (Attribute)codeAttributes[classIndex].get(attributeIndex);
-    			if(attribute.getClass() == LineNumberTableAttribute.class) {
-    				foundLineNumberTable = true;
-    				lineNumberList.add(attribute);
-    			}
-    		}
-    		if(!foundLineNumberTable) {
-    			lineNumberList.add(null);
-    		}
-    	}
-    	return lineNumberList;
+    public ArrayList getOrderedCodeAttributes() {
+        ArrayList orderedAttributeList = new ArrayList();
+        for(int classIndex=0; classIndex < codeAttributes.length; classIndex++) {
+            ArrayList currentAttributes = new ArrayList();
+            for(int attributeIndex = 0; attributeIndex < codeAttributes[classIndex].size(); attributeIndex++) {
+                Attribute attribute = (Attribute)codeAttributes[classIndex].get(attributeIndex);
+                currentAttributes.add(attribute);
+            }
+            orderedAttributeList.add(currentAttributes);
+        }
+        return orderedAttributeList;
     }
-    
+
     public ArrayList[][] getMethodAttributes() {
         return methodAttributes;
     }

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=601041&r1=601040&r2=601041&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 Tue Dec  4 11:06:43 2007
@@ -17,7 +17,6 @@
 package org.apache.harmony.pack200;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 
 import org.apache.harmony.pack200.bytecode.CPClass;
 import org.apache.harmony.pack200.bytecode.CPDouble;
@@ -29,7 +28,6 @@
 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.ClassFileEntry;
 import org.apache.harmony.pack200.bytecode.ConstantPoolEntry;
 
 public class SegmentConstantPool {

Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/BCIRenumberedAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/BCIRenumberedAttribute.java?rev=601041&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/BCIRenumberedAttribute.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/BCIRenumberedAttribute.java Tue Dec  4 11:06:43 2007
@@ -0,0 +1,68 @@
+/*
+ *  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;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.harmony.pack200.SegmentUtils;
+
+public abstract class BCIRenumberedAttribute extends Attribute {
+
+    protected boolean renumbered = false;
+    
+    /* (non-Javadoc)
+     * @see org.apache.harmony.pack200.bytecode.Attribute#hasBCIRenumbering()
+     */
+    public boolean hasBCIRenumbering() {
+        return true;
+    }
+    
+    public BCIRenumberedAttribute(String attributeName) {
+        super(attributeName);
+    }
+    
+    protected abstract int getLength();
+    protected abstract void writeBody(DataOutputStream dos) throws IOException;
+    public abstract String toString();
+    protected abstract int[] getStartPCs();
+    
+    /**
+     * In Pack200, line number tables are BCI renumbered.
+     * This method takes the byteCodeOffsets (which is
+     * a List of Integers specifying the offset in the
+     * byte code array of each instruction) and updates the
+     * start_pcs so that it points to the instruction index
+     * itself, not the BCI renumbering of the instruction.
+     * 
+     * @param byteCodeOffsets List of Integer offsets of the bytecode array
+     */
+    public void renumber(List byteCodeOffsets) {
+        if(renumbered) {
+            SegmentUtils.debug("Trying to renumber something renumbered");
+            return;
+//            throw new Error("Trying to renumber a line number table that has already been renumbered");
+        }
+        renumbered = true;
+        int[] startPCs = getStartPCs();
+        for(int index=0; index < startPCs.length; index++) {
+            startPCs[index] = ((Integer)byteCodeOffsets.get(startPCs[index])).intValue();
+        }
+    }
+
+}

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

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java?rev=601041&r1=601040&r2=601041&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java Tue Dec  4 11:06:43 2007
@@ -35,6 +35,9 @@
 	private int[][] nestedPositions;
 	private int[] rewrite;
 
+    private int byteCodeOffset = -1;
+    private int byteCodeTarget = -1;
+
 	protected ByteCode(int opcode) {
 		this(opcode, ClassFileEntry.NONE);
 	}
@@ -193,11 +196,26 @@
 			throw new Error("Trying to rewrite " + this + " with an int at position " + position + " but this won't fit in the rewrite array");
 		}
 		
-		rewrite[firstOperandIndex + position] = (operand & 0xFF00) >> 8;
-		rewrite[firstOperandIndex + position + 1] = operand & 0xFF;		
+	    rewrite[firstOperandIndex + position] = (operand & 0xFF00) >> 8;
+	    rewrite[firstOperandIndex + position + 1] = operand & 0xFF;
 	}
 	
 	/**
+	 * This is just like setOperandInt, but takes special care when the
+	 * operand is less than 0 to make sure it's written correctly.
+	 * @param operand int to set the rewrite bytes to
+	 * @param position int position of the operands in the rewrite bytes
+	 */
+	public void setOperandSignedInt(int operand, int position) {
+	    if(operand >= 0) {
+	        setOperandInt(operand, position);
+	    } else {
+	        int twosComplementOperand = 0x10000 + operand;
+	        setOperandInt(twosComplementOperand, position);
+	    }
+	}
+
+	/**
 	 * Given an int operand, treat it as a byte and set
 	 * the rewrite byte for that position to that value.
 	 * Mask of anything beyond 0xFF.
@@ -274,4 +292,54 @@
 	public boolean hasMultipleByteCodes() {
 		return getByteCodeForm().hasMultipleByteCodes();
 	}
+
+    /**
+     * ByteCodes may need to know their position in the
+     * code array (in particular, label byte codes need
+     * to know where they are in order to calculate their
+     * targets). This method lets the CodeAttribute specify
+     * where the byte code is.
+     * 
+     * Since there are no aload0+label instructions, this
+     * method doesn't worry about multioperation bytecodes.
+     * 
+     * @param byteCodeOffset int position in code array.
+     */
+    public void setByteCodeIndex(int byteCodeOffset) {
+        this.byteCodeOffset = byteCodeOffset;
+    }
+
+
+    public int getByteCodeIndex() {
+        return byteCodeOffset;
+    }
+    
+    /**
+     * Some ByteCodes (in particular, LabelForm bytecodes)
+     * have to keep track of a byteCodeTarget. This is
+     * initially an offset in the CodeAttribute array
+     * relative to the byteCodeOffset, but later gets fixed
+     * up to point to the absolute position in the CodeAttribute
+     * array. This method sets the target.
+     * 
+     * @param byteCodeTarget int index in array
+     */
+    public void setByteCodeTarget(int byteCodeTarget) {
+        this.byteCodeTarget = byteCodeTarget;
+    }
+    
+    public int getByteCodeTarget() {
+        return byteCodeTarget;
+    }
+    
+    /**
+     * Some ByteCodes (in particular, those with the Label
+     * form) need to be fixed up after all the bytecodes
+     * in the CodeAttribute have been added. (This can't
+     * be done beforehand because the CodeAttribute needs
+     * to be complete before targets can be assigned.)
+     */
+    public void applyByteCodeTargetFixup(CodeAttribute codeAttribute) {
+        getByteCodeForm().fixUpByteCodeTarget(this, codeAttribute);
+    }
 }

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=601041&r1=601040&r2=601041&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 Tue Dec  4 11:06:43 2007
@@ -62,7 +62,12 @@
 	public int indexOf(ClassFileEntry entry) {
 		if (!resolved)
 			throw new IllegalStateException("Constant pool is not yet resolved; this does not make any sense");
-		return entries.indexOf(entry) + 1;
+		int entryIndex = entries.indexOf(entry);
+		// If the entry isn't found, answer -1. Otherwise answer the entry.
+		if(entryIndex != -1) {
+		    return entryIndex + 1;
+		}
+		return -1;
 	}
 
 	public int size() {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassFile.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassFile.java?rev=601041&r1=601040&r2=601041&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassFile.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassFile.java Tue Dec  4 11:06:43 2007
@@ -56,7 +56,7 @@
 			fields[i].write(dos);
 		}
 		dos.writeShort(methods.length);
-		for(int i=0;i<methods.length;i++) {
+        for(int i=0;i<methods.length;i++) {
 			methods[i].write(dos);
 		}
 		dos.writeShort(attributes.length);

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=601041&r1=601040&r2=601041&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 Tue Dec  4 11:06:43 2007
@@ -43,9 +43,12 @@
         byteCodeOffsets.add(new Integer(0));
         for (int i = 0; i < codePacked.length; i++) {
             ByteCode byteCode = ByteCode.getByteCode(codePacked[i] & 0xff);
+            // Setting the offset must happen before extracting operands
+            // because label bytecodes need to know their offsets.
+            byteCode.setByteCodeIndex(i);
             byteCode.extractOperands(operandManager, segment);
             byteCodes.add(byteCode);
-            this.codeLength += byteCode.getLength();
+            codeLength += byteCode.getLength();
             int lastBytecodePosition = ((Integer) byteCodeOffsets
                     .get(byteCodeOffsets.size() - 1)).intValue();
             // This code assumes all multiple byte bytecodes are
@@ -61,6 +64,12 @@
                 byteCodeOffsets.add(new Integer(lastBytecodePosition
                         + byteCode.getLength()));
             }
+        }
+        // Now that all the bytecodes know their positions and
+        // sizes, fix up the byte code targets
+        for (int i = 0; i < codePacked.length; i++) {
+            ByteCode byteCode = (ByteCode)byteCodes.get(i);
+            byteCode.applyByteCodeTargetFixup(this);
         }
     }
 

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=601041&r1=601040&r2=601041&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 Tue Dec  4 11:06:43 2007
@@ -18,17 +18,13 @@
 
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.util.Iterator;
 import java.util.List;
 
-import org.apache.harmony.pack200.SegmentUtils;
-
-public class LineNumberTableAttribute extends Attribute {
+public class LineNumberTableAttribute extends BCIRenumberedAttribute {
 
     private int line_number_table_length;
     private int[] start_pcs;
     private int[] line_numbers;
-    private boolean renumbered = false;
     
     public LineNumberTableAttribute(int line_number_table_length, int[] start_pcs, int[] line_numbers) {
         super("LineNumberTable");
@@ -64,23 +60,7 @@
 		super.resolve(pool);
 	}
 
-	/**
-	 * In Pack200, line number tables are BCI renumbered.
-	 * This method takes the byteCodeOffsets (which is
-	 * a List of Integers specifying the offset in the
-	 * byte code array of each instruction) and updates the
-	 * start_pcs so that it points to the instruction index
-	 * itself, not the BCI renumbering of the instruction.
-	 * 
-	 * @param byteCodeOffsets List of Integer offsets of the bytecode array
-	 */
-	public void renumberLineNumberTable(List byteCodeOffsets) {
-		if(renumbered) {
-			throw new Error("Trying to renumber a line number table that has already been renumbered");
-		}
-		renumbered = true;
-		for(int index=0; index < line_numbers.length; index++) {
-			start_pcs[index] = ((Integer)byteCodeOffsets.get(start_pcs[index])).intValue();
-		}
-	}
+    protected int[] getStartPCs() {
+        return start_pcs;
+    }
 }

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=601041&r1=601040&r2=601041&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 Tue Dec  4 11:06:43 2007
@@ -18,9 +18,9 @@
 
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.util.List;
 
-public class LocalVariableTableAttribute extends Attribute {
-
+public class LocalVariableTableAttribute extends BCIRenumberedAttribute {
 
     private int local_variable_table_length;
     private int[] start_pcs;
@@ -60,9 +60,15 @@
 
     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]);
@@ -71,7 +77,35 @@
     }
     
     public String toString() {
-        return "LocalVariableTable: " + + local_variable_table_length + " varaibles";
+        return "LocalVariableTable: " + + local_variable_table_length + " variables";
+    }
+
+    protected int[] getStartPCs() {
+        return start_pcs;
     }
 
+    /* (non-Javadoc)
+     * @see org.apache.harmony.pack200.bytecode.BCIRenumberedAttribute#renumber(java.util.List)
+     */
+    public void renumber(List byteCodeOffsets) {
+        // First fix up the start_pcs
+        super.renumber(byteCodeOffsets);
+        // Next fix up the lengths
+        int maxLength = ((Integer)byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue();
+        for(int index=0; index < lengths.length; index++) {
+            // Need to special case when the length is greater than the size
+            int revisedLength = -1;
+            int encodedLength = lengths[index];
+            // 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()) {
+                // Pointing to one past the end of the byte code array
+                revisedLength = maxLength - start_pcs[index] + 1;
+            } else {
+                // We're indexed into the byte code array
+                revisedLength = ((Integer)byteCodeOffsets.get(encodedLength)).intValue();                
+            }
+            lengths[index] = revisedLength;
+        }
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java?rev=601041&r1=601040&r2=601041&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java Tue Dec  4 11:06:43 2007
@@ -20,6 +20,7 @@
 import java.util.Map;
 
 import org.apache.harmony.pack200.bytecode.ByteCode;
+import org.apache.harmony.pack200.bytecode.CodeAttribute;
 import org.apache.harmony.pack200.bytecode.OperandManager;
 
 public class ByteCodeForm {
@@ -295,7 +296,7 @@
         byteCodeArray[229] = new SuperFieldRefForm(229, "aload_0_invokestatic_super", new int[] {42, 184, -1, -1});
         byteCodeArray[230] = new ThisInitMethodRefForm(230, "invokespecial_this_init", new int[] {183, -1, -1});
         byteCodeArray[231] = new SuperInitMethodRefForm(231, "invokespecial_super_init", new int[] {183, -1, -1});
-        byteCodeArray[232] = new NewInitMethodRefForm(232, "invokespecial_new_init", new int[] {184, -1, -1});
+        byteCodeArray[232] = new NewInitMethodRefForm(232, "invokespecial_new_init", new int[] {183, -1, -1});
         byteCodeArray[233] = new ClassRefForm(233, "cldc", new int[] {18, -1}); 
         byteCodeArray[234] = new IntRefForm(234, "ildc", new int[] {18, -1});
         byteCodeArray[235] = new FloatRefForm(235, "fldc", new int[] {18, -1});
@@ -576,5 +577,18 @@
     public void setByteCodeOperands(ByteCode byteCode,
             OperandManager operandManager) {
         throw new Error("My subclass should have implemented this");        
+    }
+
+    /**
+     * The ByteCodeForm knows how to fix up a bytecode if
+     * it needs to be fixed up because it holds a Label
+     * bytecode.
+     * @param byteCode a ByteCode to be fixed up
+     * @param codeAttribute a CodeAttribute used to determine how
+     *   the ByteCode should be fixed up.
+     */
+    public void fixUpByteCodeTarget(ByteCode byteCode, CodeAttribute codeAttribute) {
+        // Most ByteCodeForms don't have any fixing up to do.
+        return;
     }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java?rev=601041&r1=601040&r2=601041&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LabelForm.java Tue Dec  4 11:06:43 2007
@@ -17,6 +17,7 @@
 package org.apache.harmony.pack200.bytecode.forms;
 
 import org.apache.harmony.pack200.bytecode.ByteCode;
+import org.apache.harmony.pack200.bytecode.CodeAttribute;
 import org.apache.harmony.pack200.bytecode.OperandManager;
 
 /**
@@ -47,17 +48,34 @@
     }
 
     /* (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#fixUpByteCodeTarget(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.CodeAttribute)
      */
-    public void setByteCodeOperands(ByteCode byteCode,
-            OperandManager operandManager) {
-        // TODO: if this is widened, probably need to do something
-        // different from setOperandInt().
-        byteCode.setOperandInt(operandManager.nextLabel(), 0);
+    public void fixUpByteCodeTarget(ByteCode byteCode, CodeAttribute codeAttribute) {
+        // LabelForms need to fix up the target of label operations
+        int originalTarget = byteCode.getByteCodeTarget();
+        int sourceIndex = byteCode.getByteCodeIndex();
+        int absoluteInstructionTargetIndex = sourceIndex + originalTarget;
+        int targetValue = ((Integer)codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex)).intValue();
+        int sourceValue = ((Integer)codeAttribute.byteCodeOffsets.get(sourceIndex)).intValue();
+        // The operand is the difference between the source instruction
+        // and the destination instruction.
+        // TODO: Probably have to do something other than setOperandInt if this is widened.
+        byteCode.setOperandSignedInt(targetValue - sourceValue, 0);
         if(widened) {
             byteCode.setNestedPositions(new int[][] {{0,4}});
         } else {
             byteCode.setNestedPositions(new int[][] {{0,2}});
         }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool)
+     */
+    public void setByteCodeOperands(ByteCode byteCode,
+            OperandManager operandManager) {
+        byteCode.setByteCodeTarget(operandManager.nextLabel());
+        // The byte code operands actually get set later -
+        // once we have all the bytecodes - in fixUpByteCodeTarget().
+        return;
     }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java?rev=601041&r1=601040&r2=601041&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java Tue Dec  4 11:06:43 2007
@@ -182,30 +182,17 @@
             return attributes;
         }
         
-        public ArrayList getLineNumberAttributes() {
-        	int totalMethods = 0;
-        	for(int classIndex = 0; classIndex < numMethods.length; classIndex++) {
-        		totalMethods = totalMethods + numMethods[classIndex];
-        	}
-        	ArrayList[] codeAttributes = new ArrayList[totalMethods];
-        	for(int index = 0; index < codeAttributes.length; index++) {
-        		codeAttributes[index] = new ArrayList();
-        	}
-        	ArrayList lineNumberList = new ArrayList();
-        	for(int classIndex=0; classIndex < codeAttributes.length; classIndex++) {
-        		boolean foundLineNumberTable = false;
-        		for(int attributeIndex = 0; attributeIndex < codeAttributes[classIndex].size(); attributeIndex++) {
-        			Attribute attribute = (Attribute)codeAttributes[classIndex].get(attributeIndex);
-        			if(attribute.getClass() == LineNumberTableAttribute.class) {
-        				foundLineNumberTable = true;
-        				lineNumberList.add(attribute);
-        			}
-        		}
-        		if(!foundLineNumberTable) {
-        			lineNumberList.add(null);
-        		}
-        	}
-        	return lineNumberList;
+        public ArrayList getOrderedCodeAttributes() {
+            int totalMethods = 0;
+            for(int classIndex = 0; classIndex < numMethods.length; classIndex++) {
+                totalMethods = totalMethods + numMethods[classIndex];
+            }
+            ArrayList orderedAttributeList = new ArrayList();
+            for(int classIndex=0; classIndex < totalMethods; classIndex++) {
+                ArrayList currentAttributes = new ArrayList();
+                orderedAttributeList.add(currentAttributes);
+            }
+            return orderedAttributeList;
         }
     }
 
@@ -392,7 +379,9 @@
                 (byte) 162, (byte) 163, (byte) 164, (byte) 165, (byte) 166,
                 (byte) 167, (byte) 168, (byte) 170, (byte) 171, (byte) 198, (byte) 199, (byte) 200, (byte) 201, (byte) 255,
                 0, 0, // bc_case_count (required by tableswitch (170) and lookupswitch (171))
-                8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; // bc_label band
+//                Now that we're actually doing real label lookup, need valid labels
+//                8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; // bc_label band                
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // bc_label band
         InputStream in = new ByteArrayInputStream(bytes);
         bcBands.unpack(in);
         assertEquals(16, bcBands.getMethodByteCodePacked()[0][0].length);