You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2008/01/04 11:10:36 UTC
svn commit: r608790 [1/2] - in
/harmony/enhanced/classlib/trunk/modules/pack200/src:
main/java/org/apache/harmony/pack200/
main/java/org/apache/harmony/pack200/bytecode/
main/java/org/apache/harmony/pack200/bytecode/forms/
test/java/org/apache/harmony/...
Author: tellison
Date: Fri Jan 4 02:10:32 2008
New Revision: 608790
URL: http://svn.apache.org/viewvc?rev=608790&view=rev
Log:
Apply patch HARMONY-5368 ([pack200][classlib] Completed instructions / started sorting / branch5)
Added:
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java (with props)
Modified:
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/SourceFileAttribute.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BcBandsTest.java
harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java
harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/SegmentUtilsTest.java
harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/bytecode/ClassFileEntryTest.java
harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/bytecode/ConstantPoolTest.java
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java Fri Jan 4 02:10:32 2008
@@ -26,6 +26,7 @@
import org.apache.harmony.pack200.bytecode.CPInteger;
import org.apache.harmony.pack200.bytecode.CPLong;
import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
public abstract class BandSet {
@@ -451,7 +452,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPUTF8(reference[index]);
+ result[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
}
return result;
}
@@ -472,7 +473,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result1[i1] = new CPUTF8(reference[index]);
+ result1[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
}
CPUTF8[] refs = result1;
int pos = 0;
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java Fri Jan 4 02:10:32 2008
@@ -21,6 +21,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.List;
import org.apache.harmony.pack200.bytecode.Attribute;
import org.apache.harmony.pack200.bytecode.BCIRenumberedAttribute;
@@ -40,7 +41,7 @@
// The bands
// TODO: Haven't resolved references yet. Do we want to?
private int[] bcCaseCount;
- private int[][] bcCaseValue;
+ private int[] bcCaseValue;
private int[] bcByte;
private int[] bcLocal;
private int[] bcShort;
@@ -126,6 +127,9 @@
AttributeLayout.CONTEXT_METHOD);
methodByteCodePacked = new byte[classCount][][];
int bcParsed = 0;
+
+ List switchIsTableSwitch = new ArrayList();
+ List wideByteCodes = new ArrayList();
for (int c = 0; c < classCount; c++) {
int numberOfMethods = methodFlags[c].length;
methodByteCodePacked[c] = new byte[numberOfMethods][];
@@ -200,7 +204,12 @@
bcLabelCount++;
break;
case 170: // tableswitch
+ switchIsTableSwitch.add(new Boolean(true));
+ bcCaseCountCount++;
+ bcLabelCount++;
+ break;
case 171: // lookupswitch
+ switchIsTableSwitch.add(new Boolean(false));
bcCaseCountCount++;
bcLabelCount++;
break;
@@ -260,6 +269,7 @@
break;
case 196: // wide
int nextInstruction = 0xff & methodByteCodePacked[c][m][i+1];
+ wideByteCodes.add(new Integer(nextInstruction));
if (nextInstruction == 132) { // iinc
bcLocalCount += 2;
bcShortCount++;
@@ -299,9 +309,16 @@
// other bytecode bands
debug("Parsed *bc_codes (" + bcParsed + ")");
bcCaseCount = decodeBandInt("bc_case_count", in, Codec.UNSIGNED5, bcCaseCountCount);
- // TODO HACK HACK: Not sure how this should be done.
- // bcCaseValue = decodeBandInt("bc_case_value", in, Codec.DELTA5, new int[]{1} /* to test tableswitch */);
- bcCaseValue = decodeBandInt("bc_case_value", in, Codec.DELTA5, bcCaseCount /* to test lookupswitch */);
+ int bcCaseValueCount = 0;
+ for (int i = 0; i < bcCaseCount.length; i++) {
+ boolean isTableSwitch = ((Boolean)switchIsTableSwitch.get(i)).booleanValue();
+ if(isTableSwitch) {
+ bcCaseValueCount += 1;
+ } else {
+ bcCaseValueCount += bcCaseCount[i];
+ }
+ }
+ bcCaseValue = decodeBandInt("bc_case_value", in, Codec.DELTA5, bcCaseValueCount );
// Every case value needs a label. We weren't able to count these
// above, because we didn't know how many cases there were.
// Have to correct it now.
@@ -345,11 +362,15 @@
bcEscSize = decodeBandInt("bc_escsize", in, Codec.UNSIGNED5, bcEscCount);
bcEscByte = decodeBandInt("bc_escbyte", in, Codec.BYTE1, bcEscSize);
+ int[] wideByteCodeArray = new int[wideByteCodes.size()];
+ for(int index=0; index < wideByteCodeArray.length; index++) {
+ wideByteCodeArray[index] = ((Integer)wideByteCodes.get(index)).intValue();
+ }
OperandManager operandManager = new OperandManager(bcCaseCount, bcCaseValue,
bcByte, bcShort, bcLocal, bcLabel, bcIntRef, bcFloatRef, bcLongRef,
bcDoubleRef, bcStringRef, bcClassRef, bcFieldRef, bcMethodRef,
bcIMethodRef, bcThisField, bcSuperField, bcThisMethod, bcSuperMethod,
- bcInitRef);
+ bcInitRef, wideByteCodeArray);
operandManager.setSegment(segment);
int i = 0;
@@ -365,28 +386,19 @@
if (!staticModifier.matches(methodFlag))
maxLocal++; // one for 'this' parameter
maxLocal += SegmentUtils.countArgs(methodDescr[c][m]);
- // TODO Move creation of code attribute until after constant
- // pool resolved
operandManager.setCurrentClass(segment.getClassBands().getClassThis()[c]);
operandManager.setSuperClass(segment.getClassBands().getClassSuper()[c]);
- CodeAttribute attr = new CodeAttribute(maxStack, maxLocal,
+ CodeAttribute codeAttr = new CodeAttribute(maxStack, maxLocal,
methodByteCodePacked[c][m], segment, operandManager);
- methodAttributes[c][m].add(attr);
+ methodAttributes[c][m].add(codeAttr);
// Should I add all the attributes in here?
ArrayList currentAttributes = (ArrayList)orderedCodeAttributes.get(i);
for(int index=0;index < currentAttributes.size(); index++) {
Attribute currentAttribute = (Attribute)currentAttributes.get(index);
- // TODO: The line below adds the LocalVariableTable
- // and LineNumber attributes. Currently things are
- // broken because these tables don't get renumbered
- // properly. Commenting out the add so the class files
- // will verify.
- // if(currentAttribute.getClass() == LineNumberTableAttribute.class) {
- attr.attributes.add(currentAttribute);
- // }
+ codeAttr.addAttribute(currentAttribute);
// Fix up the line numbers if needed
if(currentAttribute.hasBCIRenumbering()) {
- ((BCIRenumberedAttribute)currentAttribute).renumber(attr.byteCodeOffsets);
+ ((BCIRenumberedAttribute)currentAttribute).renumber(codeAttr.byteCodeOffsets);
}
}
i++;
@@ -417,7 +429,7 @@
return bcCaseCount;
}
- public int[][] getBcCaseValue() {
+ public int[] getBcCaseValue() {
return bcCaseValue;
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Fri Jan 4 02:10:32 2008
@@ -26,6 +26,7 @@
import org.apache.harmony.pack200.bytecode.Attribute;
import org.apache.harmony.pack200.bytecode.CPClass;
import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
import org.apache.harmony.pack200.bytecode.ConstantValueAttribute;
import org.apache.harmony.pack200.bytecode.ExceptionsAttribute;
import org.apache.harmony.pack200.bytecode.LineNumberTableAttribute;
@@ -199,7 +200,7 @@
int colon = desc.indexOf(':');
String type = desc.substring(colon + 1);
CPUTF8 value = new CPUTF8((String) signatureLayout.getValue(result, type,
- cpBands.getConstantPool()));
+ cpBands.getConstantPool()), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
fieldAttributes[i][j]
.add(new SignatureAttribute(value));
signatureIndex++;
@@ -651,6 +652,22 @@
"code_LocalVariableTable_slot", in, Codec.UNSIGNED5,
localVariableTableN);
+ // Fix up localVariableTableTypeRS - for some reason,
+ // native signatures end up in DOMAINNORMALASCIIZ
+ // while nonnatives end up in DOMAINSIGNATUREASCIIZ.
+ // TODO: is this the right thing to do?
+ for(int x=0; x < localVariableTableTypeRS.length; x++) {
+ for(int y=0; y < localVariableTableTypeRS[x].length; y++) {
+ CPUTF8 element = localVariableTableTypeRS[x][y];
+ // TODO: come up with a better test for native vs nonnative signatures?
+ if(element.underlyingString().length() > 2) {
+ element.setDomain(ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
+ } else {
+ element.setDomain(ClassConstantPool.DOMAIN_NORMALASCIIZ);
+ }
+ }
+ }
+
int lengthLocalVariableTypeTableNBand = SegmentUtils.countMatches(
codeFlags, localVariableTypeTableLayout);
int[] localVariableTypeTableN = decodeBandInt(
@@ -715,7 +732,7 @@
for (int i = 0; i < strings.length; i++) {
cpUTF8s[i] = new CPUTF8[strings[i].length];
for (int j = 0; j < strings[i].length; j++) {
- cpUTF8s[i][j] = new CPUTF8(strings[i][j]);
+ cpUTF8s[i][j] = new CPUTF8(strings[i][j], ClassConstantPool.DOMAIN_NORMALASCIIZ);
}
}
return cpUTF8s;
@@ -726,7 +743,7 @@
private CPUTF8[] stringsToCPUTF8(String[] strings) {
CPUTF8[] cpUTF8s = new CPUTF8[strings.length];
for (int i = 0; i < strings.length; i++) {
- cpUTF8s[i] = new CPUTF8(strings[i]);
+ cpUTF8s[i] = new CPUTF8(strings[i], ClassConstantPool.DOMAIN_UNDEFINED);
}
return cpUTF8s;
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java Fri Jan 4 02:10:32 2008
@@ -28,6 +28,7 @@
import org.apache.harmony.pack200.bytecode.CPMethodRef;
import org.apache.harmony.pack200.bytecode.CPString;
import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
import org.apache.harmony.pack200.bytecode.ConstantPoolEntry;
public class SegmentConstantPool {
@@ -230,7 +231,7 @@
} else if (index < 0) {
throw new Pack200Exception("Cannot have a negative range");
} else if (cp == UTF_8) {
- return new CPUTF8(bands.getCpUTF8()[index]);
+ return new CPUTF8(bands.getCpUTF8()[index], ClassConstantPool.DOMAIN_NORMALASCIIZ);
} else if (cp == CP_INT) {
return new CPInteger(new Integer(bands.getCpInt()[index]));
} else if (cp == CP_FLOAT) {
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java Fri Jan 4 02:10:32 2008
@@ -20,29 +20,81 @@
public final class SegmentUtils {
public static int countArgs(String descriptor) {
- int bra = descriptor.indexOf("(");
- int ket = descriptor.indexOf(")");
- if (bra == -1 || ket == -1 || ket < bra)
- throw new IllegalArgumentException("No arguments");
+ return countArgs(descriptor, 1);
+// int bra = descriptor.indexOf("(");
+// int ket = descriptor.indexOf(")");
+// if (bra == -1 || ket == -1 || ket < bra)
+// throw new IllegalArgumentException("No arguments");
+//
+// boolean inType = false;
+// int count = 0;
+// for (int i = bra + 1; i < ket; i++) {
+// char charAt = descriptor.charAt(i);
+// if (inType && charAt == ';') {
+// inType = false;
+// } else if (!inType && charAt == 'L') {
+// inType = true;
+// count++;
+// } else if (charAt == '[' || inType) {
+// // NOP
+// } else {
+// count++;
+// }
+// }
+// return count;
+ }
- boolean inType = false;
- int count = 0;
- for (int i = bra + 1; i < ket; i++) {
- char charAt = descriptor.charAt(i);
- if (inType && charAt == ';') {
- inType = false;
- } else if (!inType && charAt == 'L') {
- inType = true;
- count++;
- } else if (charAt == '[' || inType) {
- // NOP
- } else {
- count++;
- }
- }
- return count;
+ public static int countInvokeInterfaceArgs(String descriptor) {
+ return countArgs(descriptor, 2);
}
+
+ /**
+ * Count the number of arguments in the descriptor. Each
+ * long or double counts as widthOfLongsAndDoubles; all other
+ * arguments count as 1.
+ * @param descriptor String for which arguments are counted
+ * @param widthOfLongsAndDoubles int increment to apply for longs
+ * doubles. This is typically 1 when counting arguments alone,
+ * or 2 when counting arguments for invokeinterface.
+ * @return integer count
+ */
+ protected static int countArgs(String descriptor, int widthOfLongsAndDoubles) {
+ int bra = descriptor.indexOf("(");
+ int ket = descriptor.indexOf(")");
+ if (bra == -1 || ket == -1 || ket < bra)
+ throw new IllegalArgumentException("No arguments");
+ boolean inType = false;
+ boolean consumingNextType = false;
+ int count = 0;
+ for (int i = bra + 1; i < ket; i++) {
+ char charAt = descriptor.charAt(i);
+ if (inType && charAt == ';') {
+ inType = false;
+ consumingNextType = false;
+ } else if (!inType && charAt == 'L') {
+ inType = true;
+ count++;
+ } else if (charAt == '[') {
+ consumingNextType = true;
+ } else if(inType) {
+ // NOP
+ } else {
+ if(consumingNextType) {
+ count++;
+ consumingNextType = false;
+ } else {
+ if(charAt == 'D' || charAt == 'J') {
+ count+=widthOfLongsAndDoubles;
+ } else {
+ count++;
+ }
+ }
+ }
+ }
+ return count;
+ }
+
public static int countMatches(long[] flags, IMatcher matcher) {
int count = 0;
for (int i = 0; i < flags.length; i++) {
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java Fri Jan 4 02:10:32 2008
@@ -25,7 +25,7 @@
private int attributeNameIndex;
public Attribute(String attributeName) {
- this.attributeName = new CPUTF8(attributeName);
+ this.attributeName = new CPUTF8(attributeName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ);
}
protected void doWrite(DataOutputStream dos) throws IOException {
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java Fri Jan 4 02:10:32 2008
@@ -30,7 +30,8 @@
public CPClass(String name) {
super(ConstantPoolEntry.CP_Class);
this.name = name;
- this.utf8 = new CPUTF8(name);
+ this.domain = ClassConstantPool.DOMAIN_CLASSREF;
+ this.utf8 = new CPUTF8(name, ClassConstantPool.DOMAIN_NORMALASCIIZ);
}
@@ -84,4 +85,9 @@
protected void writeBody(DataOutputStream dos) throws IOException {
dos.writeShort(index);
}
+
+ public String comparisonString() {
+ return getName();
+ }
+
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPDouble.java Fri Jan 4 02:10:32 2008
@@ -22,6 +22,7 @@
public class CPDouble extends CPConstantNumber {
public CPDouble(java.lang.Double value) {
super(ConstantPoolEntry.CP_Double,value);
+ this.domain = ClassConstantPool.DOMAIN_DOUBLE;
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java Fri Jan 4 02:10:32 2008
@@ -30,6 +30,7 @@
transient int nameAndTypeIndex;
public CPFieldRef(String className, String descriptor) {
super(ConstantPoolEntry.CP_Fieldref);
+ this.domain = ClassConstantPool.DOMAIN_FIELD;
this.className = new CPClass(className);
this.nameAndType = new CPNameAndType(descriptor);
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFloat.java Fri Jan 4 02:10:32 2008
@@ -22,6 +22,7 @@
public class CPFloat extends CPConstantNumber {
public CPFloat(java.lang.Float value) {
super(ConstantPoolEntry.CP_Float,value);
+ this.domain = ClassConstantPool.DOMAIN_FLOAT;
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInteger.java Fri Jan 4 02:10:32 2008
@@ -23,6 +23,7 @@
public CPInteger(java.lang.Integer value) {
super(ConstantPoolEntry.CP_Integer,value);
+ this.domain = ClassConstantPool.DOMAIN_INTEGER;
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPInterfaceMethodRef.java Fri Jan 4 02:10:32 2008
@@ -20,6 +20,18 @@
public CPInterfaceMethodRef(String className, String descriptor) {
super(ConstantPoolEntry.CP_InterfaceMethodref, className, descriptor);
+ this.domain = ClassConstantPool.DOMAIN_METHOD;
}
+ /**
+ * This method answers the value this method will use
+ * for an invokeinterface call. This is equal to 1 + the
+ * count of all the args, where longs and doubles count for
+ * 2 and all others count for 1.
+ *
+ * @return integer count
+ */
+ public int invokeInterfaceCount() {
+ return nameAndType.invokeInterfaceCount();
+ }
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPLong.java Fri Jan 4 02:10:32 2008
@@ -23,6 +23,7 @@
public CPLong(java.lang.Long value) {
super(ConstantPoolEntry.CP_Long,value);
+ this.domain = ClassConstantPool.DOMAIN_LONG;
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java Fri Jan 4 02:10:32 2008
@@ -38,8 +38,8 @@
transient int descriptorIndex;
public CPMember(String descriptor, long flags, List attributes) {
int colon = descriptor.indexOf(':');
- this.name = new CPUTF8(descriptor.substring(0,colon));
- this.descriptor = new CPUTF8(descriptor.substring(colon+1));
+ this.name = new CPUTF8(descriptor.substring(0,colon), ClassConstantPool.DOMAIN_NORMALASCIIZ);
+ this.descriptor = new CPUTF8(descriptor.substring(colon+1), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
this.flags = (short) flags;
this.attributes = (attributes == null ? new ArrayList() : attributes);
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethodRef.java Fri Jan 4 02:10:32 2008
@@ -25,6 +25,7 @@
super(ConstantPoolEntry.CP_Methodref, className, descriptor);
this.className = new CPClass(className);
this.descriptor = new CPNameAndType(descriptor);
+ this.domain = ClassConstantPool.DOMAIN_METHOD;
}
protected ClassFileEntry[] getNestedClassFileEntries() {
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java Fri Jan 4 02:10:32 2008
@@ -19,6 +19,8 @@
import java.io.DataOutputStream;
import java.io.IOException;
+import org.apache.harmony.pack200.SegmentUtils;
+
public class CPNameAndType extends ConstantPoolEntry {
@@ -32,9 +34,35 @@
public CPNameAndType(String descriptor) {
super(ConstantPoolEntry.CP_NameAndType);
+ int descriptorDomain = ClassConstantPool.DOMAIN_UNDEFINED;
int colon = descriptor.indexOf(':');
- this.name = new CPUTF8(descriptor.substring(0,colon));
- this.descriptor = new CPUTF8(descriptor.substring(colon+1));
+ String nameString = descriptor.substring(0,colon);
+ String descriptorString = descriptor.substring(colon+1);
+ // For some reason, descriptors which have just plain
+ // native types are stored in DOMAIN_NORMALASCIIZ rather
+ // than in DOMAIN_SIGNATUREASCIIZ. This might indicate
+ // that DOMAIN_SIGNATUREASCIIZ is poorly named.
+ boolean nativeDescriptor = true;
+ for(int index=0; index < descriptorString.length(); index++) {
+ char currentChar = descriptorString.charAt(index);
+ if(Character.isLetter(currentChar)) {
+ if(currentChar == 'L') {
+ nativeDescriptor = false;
+ }
+ break;
+ }
+ }
+ this.domain = ClassConstantPool.DOMAIN_NAMEANDTYPE;
+ this.name = new CPUTF8(nameString, ClassConstantPool.DOMAIN_NORMALASCIIZ);
+ if((nameString.equals("<init>")) || (nameString.equals("<clinit>")) || nativeDescriptor ) {
+ // Signatures for init methods are stored with the init methods.
+ // Not sure why. Similarly, native signatures are stored
+ // there as well.
+ descriptorDomain = ClassConstantPool.DOMAIN_NORMALASCIIZ;
+ } else {
+ descriptorDomain = ClassConstantPool.DOMAIN_SIGNATUREASCIIZ;
+ }
+ this.descriptor = new CPUTF8(descriptorString, descriptorDomain);
}
protected ClassFileEntry[] getNestedClassFileEntries() {
@@ -94,4 +122,14 @@
return true;
}
+ /**
+ * Answers the invokeinterface count argument when the
+ * receiver is treated as an invokeinterface target.
+ * This value is not meaningful if the receiver is not
+ * an invokeinterface target.
+ * @return count
+ */
+ public int invokeInterfaceCount() {
+ return 1 + SegmentUtils.countInvokeInterfaceArgs(descriptor.underlyingString());
+ }
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java Fri Jan 4 02:10:32 2008
@@ -24,7 +24,7 @@
CPClass className;
transient int classNameIndex;
- private final CPNameAndType nameAndType;
+ protected final CPNameAndType nameAndType;
transient int nameAndTypeIndex;
public CPRef(byte type, String className, String descriptor) {
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPString.java Fri Jan 4 02:10:32 2008
@@ -25,7 +25,8 @@
public CPString(java.lang.String value) {
super(ConstantPoolEntry.CP_String,value);
- this.name = new CPUTF8((String) getValue());
+ this.domain = ClassConstantPool.DOMAIN_STRING;
+ this.name = new CPUTF8((String) getValue(), ClassConstantPool.DOMAIN_NORMALASCIIZ);
}
@@ -53,4 +54,7 @@
return new ClassFileEntry[] { name };
}
+ public String comparisonString() {
+ return (String)getValue();
+ }
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java Fri Jan 4 02:10:32 2008
@@ -23,9 +23,10 @@
public class CPUTF8 extends ConstantPoolEntry {
private String utf8;
- public CPUTF8(String utf8) {
+ public CPUTF8(String utf8, int domain) {
super(ConstantPoolEntry.CP_UTF8);
this.utf8 = utf8;
+ this.domain = domain;
}
@@ -74,4 +75,25 @@
dos.write(bytes);
}
+ public String underlyingString() {
+ return utf8;
+ }
+
+ public String comparisonString() {
+ String returnValue = utf8;
+ if(utf8.endsWith(";")) {
+ StringBuffer alphaChars = new StringBuffer();
+ StringBuffer extraChars = new StringBuffer();
+ extraChars.append((char)0xFFFF);
+ for(int index=0; index < utf8.length(); index++) {
+ if( (utf8.charAt(index) == '(') || (utf8.charAt(index) == ')') || (utf8.charAt(index) == '[') || (utf8.charAt(index) == ']') ) {
+ extraChars.append(utf8.charAt(index));
+ } else {
+ alphaChars.append(utf8.charAt(index));
+ }
+ }
+ returnValue = alphaChars.toString() + extraChars.toString();
+ }
+ return returnValue;
+ }
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java Fri Jan 4 02:10:32 2008
@@ -18,9 +18,13 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.apache.harmony.pack200.bytecode.ConstantPoolEntry;
import org.apache.harmony.pack200.Pack200Exception;
import org.apache.harmony.pack200.Segment;
@@ -28,6 +32,58 @@
public class ClassConstantPool {
+
+ class PoolComparator implements Comparator {
+ /* (non-Javadoc)
+ * Note: this comparator imposes orderings that are inconsistent with equals.
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Object o1, Object o2) {
+ // If we compare anything other than ConstantPoolEntries
+ // with this comparator, it is an error.
+ ConstantPoolEntry cpe1 = (ConstantPoolEntry)o1;
+ ConstantPoolEntry cpe2 = (ConstantPoolEntry)o2;
+
+ int domain1 = cpe1.getDomain();
+ int domain2 = cpe2.getDomain();
+
+ if(domain1 < domain2) {
+ return -1;
+ }
+ if(domain1 > domain2) {
+ return 1;
+ }
+
+ // Domains must be the same, need to compare
+ // based on name.
+ // TODO: what means name?
+ String compare1 = cpe1.comparisonString();
+ String compare2 = cpe2.comparisonString();
+ return compare1.compareTo(compare2);
+// if(cpe1.creationOrder < cpe2.creationOrder) {
+// return -1;
+// } else {
+// return 1;
+// }
+ }
+ }
+ // These are the domains in sorted order.
+ public static int DOMAIN_UNDEFINED = 0;
+ public static int DOMAIN_INTEGER = 1;
+ public static int DOMAIN_FLOAT = 2;
+ public static int DOMAIN_STRING = 3;
+ public static int DOMAIN_NORMALASCIIZ = 4;
+ public static int DOMAIN_LONG = 5;
+ public static int DOMAIN_DOUBLE = 6;
+ public static int DOMAIN_CLASSREF = 7;
+ public static int DOMAIN_SIGNATUREASCIIZ = 8;
+ public static int DOMAIN_NAMEANDTYPE = 9;
+ public static int DOMAIN_FIELD = 10;
+ public static int DOMAIN_METHOD = 11;
+ public static int DOMAIN_ATTRIBUTEASCIIZ = 12;
+
+ protected SortedSet sortedEntries = new TreeSet(new PoolComparator());
+
public String toString() {
return entries.toString();
}
@@ -38,15 +94,50 @@
private boolean resolved;
public ClassFileEntry add(ClassFileEntry entry) {
- // TODO this should be a set - we don't want duplicates
+ // We don't want duplicates.
// Only add in constant pools, but resolve all types since they may
// introduce new constant pool entries
+// This is a handy way to see what's adding a ClassFileEntry - set a breakpoint on the print
+// if(entry instanceof CPUTF8) {
+// System.out.println("AAH:" + ((CPUTF8)entry).comparisonString());
+// if (((CPUTF8)entry).comparisonString().matches("Ljava.*")) {
+// System.out.println("Adding");
+// }
+// }
if (entry instanceof ConstantPoolEntry) {
if (!entries.contains(entry)) {
entries.add(entry);
+ sortedEntries.add(entry);
// TODO This will be a bugger when they're sorted.
if (entry instanceof CPLong ||entry instanceof CPDouble)
entries.add(entry); //these get 2 slots because of their size
+ } else {
+ // TODO: This is awful. If I'm presented with
+ // an entry that has a lower domain than the
+ // current entry but is otherwise the same,
+ // change its domain and rebalance the tree.
+ // And by "rebalance" I mean destroy and recreate
+ // the tree.
+ Iterator iterator = sortedEntries.iterator();
+ boolean replaceTree = false;
+ SortedSet newSortedSet = new TreeSet(new PoolComparator());
+ while(iterator.hasNext()) {
+ ConstantPoolEntry storedEntry = (ConstantPoolEntry)iterator.next();
+ if(storedEntry.equals(entry)) {
+ if(storedEntry.getDomain() > ((ConstantPoolEntry)entry).getDomain()) {
+ // need to blow away the tree.
+ replaceTree = true;
+ newSortedSet.add(entry);
+ } else {
+ newSortedSet.add(storedEntry);
+ }
+ } else {
+ newSortedSet.add(storedEntry);
+ }
+ if(replaceTree) {
+ sortedEntries = newSortedSet;
+ }
+ }
}
} else {
if (!others.contains(entry))
@@ -82,34 +173,46 @@
public void resolve(Segment segment) {
SegmentUtils.debug("\n\nResolving (Segment.resolve(Segment)");
- HashMap sortMap = new HashMap();
- List cpAll = null;
- // TODO: HACK - this is a 1.5 api.
- // Need to do the right thing and do it with 1.4 API.
- try {
- cpAll = Arrays.asList(segment.getConstantPool().getCpAll());
- } catch (Pack200Exception ex) {
- ex.printStackTrace();
- }
- Iterator it = entries.iterator();
- while(it.hasNext()) {
- ClassFileEntry entry = (ClassFileEntry) it.next();
- int indexInCpAll = cpAll.indexOf(entry);
- if(indexInCpAll > 0) {
- sortMap.put(new Integer(indexInCpAll), entry);
- } else {
- sortMap.put(new Integer(99999), entry);
- }
- }
- ArrayList sortedList = new ArrayList();
- for(int index=0; index < 99999; index++) {
- if(sortMap.containsKey(new Integer(index))) {
- sortedList.add((ClassFileEntry)sortMap.get(new Integer(index)));
- }
- }
- for(int xindex=0; xindex < sortedList.size(); xindex++) {
- SegmentUtils.debug(sortedList.get(xindex).toString());
- }
+ // TODO: Be careful here, you're obliterating the original entries.
+ // In an ideal world, you wouldn't actually add to it unless you're
+ // sure.
+ entries = new ArrayList();
+// entries.addAll(sortedEntries);
+ Iterator sortedIterator = sortedEntries.iterator();
+ while(sortedIterator.hasNext()) {
+ ConstantPoolEntry entry = (ConstantPoolEntry)sortedIterator.next();
+ entries.add(entry);
+ if (entry instanceof CPLong ||entry instanceof CPDouble)
+ entries.add(entry); //these get 2 slots because of their size
+ }
+// HashMap sortMap = new HashMap();
+// List cpAll = null;
+// // TODO: HACK - this is a 1.5 api.
+// // Need to do the right thing and do it with 1.4 API.
+// try {
+// cpAll = Arrays.asList(segment.getConstantPool().getCpAll());
+// } catch (Pack200Exception ex) {
+// ex.printStackTrace();
+// }
+// Iterator it = entries.iterator();
+// while(it.hasNext()) {
+// ClassFileEntry entry = (ClassFileEntry) it.next();
+// int indexInCpAll = cpAll.indexOf(entry);
+// if(indexInCpAll > 0) {
+// sortMap.put(new Integer(indexInCpAll), entry);
+// } else {
+// sortMap.put(new Integer(99999), entry);
+// }
+// }
+// ArrayList sortedList = new ArrayList();
+// for(int index=0; index < 99999; index++) {
+// if(sortMap.containsKey(new Integer(index))) {
+// sortedList.add((ClassFileEntry)sortMap.get(new Integer(index)));
+// }
+// }
+// for(int xindex=0; xindex < sortedList.size(); xindex++) {
+// SegmentUtils.debug(sortedList.get(xindex).toString());
+// }
resolve();
}
@@ -124,7 +227,7 @@
while (it.hasNext()) {
ClassFileEntry entry = (ClassFileEntry) it.next();
entry.resolve(this);
- }
+ }
}
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java Fri Jan 4 02:10:32 2008
@@ -64,13 +64,23 @@
byteCodeOffsets.add(new Integer(lastBytecodePosition
+ byteCode.getLength()));
}
+ if(byteCode.getOpcode() == 0xC4) {
+ // Special processing for wide bytecode - it knows what its
+ // instruction is from the opcode manager, so ignore the
+ // next instruction
+ i++;
+ }
}
// Now that all the bytecodes know their positions and
// sizes, fix up the byte code targets
- for (int i = 0; i < codePacked.length; i++) {
+ // At this point, byteCodes may be a different size than
+ // codePacked because of wide bytecodes.
+ for (int i = 0; i < byteCodes.size(); i++) {
ByteCode byteCode = (ByteCode)byteCodes.get(i);
byteCode.applyByteCodeTargetFixup(this);
}
+ // TODO: By the time I get here, the input stream
+ // is somehow confused.
}
protected int getLength() {
@@ -88,6 +98,9 @@
ArrayList nestedEntries = new ArrayList();
nestedEntries.add(getAttributeName());
nestedEntries.addAll(byteCodes);
+ // TODO: Is this the right place to add code attribute
+ // attributes?
+ nestedEntries.addAll(attributes);
ClassFileEntry[] nestedEntryArray = new ClassFileEntry[nestedEntries
.size()];
nestedEntries.toArray(nestedEntryArray);
@@ -136,4 +149,11 @@
}
}
+ public void addAttribute(Attribute attribute) {
+ attributes.add(attribute);
+ }
+
+ public List attributes() {
+ return attributes;
+ }
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java Fri Jan 4 02:10:32 2008
@@ -56,8 +56,15 @@
byte tag;
+ protected int domain = ClassConstantPool.DOMAIN_UNDEFINED;
+ public static int creationOrderCount = 100;
+ public String comparisonString() {
+ return "" + creationOrder;
+ }
+ public int creationOrder = -1;
ConstantPoolEntry(byte tag) {
this.tag = tag;
+ this.creationOrder = creationOrderCount++;
}
public abstract boolean equals(Object obj);
@@ -66,6 +73,14 @@
return tag;
}
+ public int getDomain() {
+ return domain;
+ }
+
+ public void setDomain(int newDomain) {
+ this.domain = newDomain;
+ }
+
public abstract int hashCode();
public void doWrite(DataOutputStream dos) throws IOException {
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java Fri Jan 4 02:10:32 2008
@@ -52,11 +52,17 @@
return "LineNumberTable: " + line_number_table_length + " lines";
}
+ /* (non-Javadoc)
+ * @see org.apache.harmony.pack200.bytecode.Attribute#getNestedClassFileEntries()
+ */
+ protected ClassFileEntry[] getNestedClassFileEntries() {
+ return new ClassFileEntry[] {getAttributeName()};
+ }
+
/* (non-Javadoc)
* @see org.apache.harmony.pack200.bytecode.Attribute#resolve(org.apache.harmony.pack200.bytecode.ClassConstantPool)
*/
protected void resolve(ClassConstantPool pool) {
- pool.add(getAttributeName());
super.resolve(pool);
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/LocalVariableTableAttribute.java Fri Jan 4 02:10:32 2008
@@ -18,6 +18,7 @@
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
public class LocalVariableTableAttribute extends BCIRenumberedAttribute {
@@ -58,17 +59,25 @@
}
}
+
+ protected ClassFileEntry[] getNestedClassFileEntries() {
+ ArrayList nestedEntries = new ArrayList();
+ nestedEntries.add(getAttributeName());
+ for (int i = 0; i < local_variable_table_length; i++) {
+ nestedEntries.add(names[i]);
+ nestedEntries.add(descriptors[i]);
+ }
+ ClassFileEntry[] nestedEntryArray = new ClassFileEntry[nestedEntries
+ .size()];
+ nestedEntries.toArray(nestedEntryArray);
+ return nestedEntryArray;
+ }
+
protected void resolve(ClassConstantPool pool) {
super.resolve(pool);
- pool.add(getAttributeName());
name_indexes = new int[local_variable_table_length];
descriptor_indexes = new int[local_variable_table_length];
for (int i = 0; i < local_variable_table_length; i++) {
- // TODO: is this the right place to add the names and descriptors?
- // Maybe some API to say where they should be added if they're not
- // already in the cp?
- pool.add(names[i]);
- pool.add(descriptors[i]);
names[i].resolve(pool);
descriptors[i].resolve(pool);
name_indexes[i] = pool.indexOf(names[i]);
@@ -88,26 +97,47 @@
* @see org.apache.harmony.pack200.bytecode.BCIRenumberedAttribute#renumber(java.util.List)
*/
public void renumber(List byteCodeOffsets) {
- // First fix up the start_pcs
+ // Remember the unrenumbered start_pcs, since that's used later
+ // to calculate end position.
+ int[] unrenumbered_start_pcs = new int[start_pcs.length];
+ System.arraycopy(start_pcs, 0, unrenumbered_start_pcs, 0, start_pcs.length);
+
+ // Next renumber start_pcs in place
super.renumber(byteCodeOffsets);
+
// lengths are BRANCH5 encoded, not BCI-encoded.
- // In other words - renumber(x) - renumber(x0)?
- // Add the offset to the value?
- // Next fix up the lengths
+ // In other words:
+ // start_pc is BCI5 start_pc
+ // end_pc is byteCodeOffset[(index of start_pc in byteCodeOffset) + (encoded length)]
+ // real length = end_pc - start_pc
+ // special case if end_pc is beyond end of bytecode array
+
+ // First figure out the maximum size of the byteCodeOffsets array
int lastInstruction = ((Integer)byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue();
- int maxLength = lastInstruction + 1;
+ int maxSize = lastInstruction + 1;
+
+ // Iterate through the lengths and update each in turn.
+ // This is done in place in the lengths array.
for(int index=0; index < lengths.length; index++) {
- // Need to special case when the length is greater than the size
+ int start_pc = start_pcs[index];
int revisedLength = -1;
int encodedLength = lengths[index];
+
+ // First get the index of the start_pc in the byteCodeOffsets
+ int indexOfStartPC = unrenumbered_start_pcs[index];
+ // Given the index of the start_pc, we can now add
+ // the encodedLength to it to get the stop index.
+ int stopIndex = indexOfStartPC + encodedLength;
+
// Length can either be an index into the byte code offsets, or one beyond the
// end of the byte code offsets. Need to determine which this is.
- if(encodedLength == byteCodeOffsets.size()) {
+ if(stopIndex == byteCodeOffsets.size()) {
// Pointing to one past the end of the byte code array
- revisedLength = maxLength - start_pcs[index];
+ revisedLength = maxSize - start_pc;
} else {
// We're indexed into the byte code array
- revisedLength = ((Integer)byteCodeOffsets.get(encodedLength)).intValue();
+ int stopValue = ((Integer)byteCodeOffsets.get(stopIndex)).intValue();
+ revisedLength = stopValue - start_pc;
}
lengths[index] = revisedLength;
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/OperandManager.java Fri Jan 4 02:10:32 2008
@@ -29,7 +29,7 @@
public class OperandManager {
int[] bcCaseCount;
- int[][] bcCaseValue;
+ int[] bcCaseValue;
int[] bcByte;
int[] bcShort;
int[] bcLocal;
@@ -48,6 +48,7 @@
int[] bcThisMethod;
int[] bcSuperMethod;
int[] bcInitRef;
+ int[] wideByteCodes;
int bcCaseCountIndex = 0;
int bcCaseValueIndex = 0;
@@ -69,6 +70,7 @@
int bcThisMethodIndex = 0;
int bcSuperMethodIndex = 0;
int bcInitRefIndex = 0;
+ int wideByteCodeIndex = 0;
Segment segment = null;
@@ -76,7 +78,7 @@
String superClass = null;
String newClass = null;
- public OperandManager(int[] bcCaseCount, int[][] bcCaseValue, int[] bcByte, int[] bcShort, int[] bcLocal, int[] bcLabel, int[] bcIntRef, int[] bcFloatRef, int[] bcLongRef, int[] bcDoubleRef, int[] bcStringRef, int[] bcClassRef, int[] bcFieldRef, int[] bcMethodRef, int[] bcIMethodRef, int[] bcThisField, int[] bcSuperField, int[] bcThisMethod, int[] bcSuperMethod, int[] bcInitRef) {
+ public OperandManager(int[] bcCaseCount, int[] bcCaseValue, int[] bcByte, int[] bcShort, int[] bcLocal, int[] bcLabel, int[] bcIntRef, int[] bcFloatRef, int[] bcLongRef, int[] bcDoubleRef, int[] bcStringRef, int[] bcClassRef, int[] bcFieldRef, int[] bcMethodRef, int[] bcIMethodRef, int[] bcThisField, int[] bcSuperField, int[] bcThisMethod, int[] bcSuperMethod, int[] bcInitRef, int[] wideByteCodes) {
this.bcCaseCount = bcCaseCount;
this.bcCaseValue = bcCaseValue;
this.bcByte = bcByte;
@@ -98,13 +100,14 @@
this.bcThisMethod = bcThisMethod;
this.bcSuperMethod = bcSuperMethod;
this.bcInitRef = bcInitRef;
+ this.wideByteCodes = wideByteCodes;
}
public int nextCaseCount() {
return bcCaseCount[bcCaseCountIndex++];
}
- public int[] nextCaseValues() {
+ public int nextCaseValues() {
return bcCaseValue[bcCaseValueIndex++];
}
@@ -180,6 +183,10 @@
return bcInitRef[bcInitRefIndex++];
}
+ public int nextWideByteCode() {
+ return wideByteCodes[wideByteCodeIndex++];
+ }
+
public void setSegment(Segment segment) {
this.segment = segment;
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/SourceFileAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/SourceFileAttribute.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/SourceFileAttribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/SourceFileAttribute.java Fri Jan 4 02:10:32 2008
@@ -27,7 +27,7 @@
public SourceFileAttribute(String name) {
super("SourceFile"); //$NON-NLS-1$
- this.name = new CPUTF8(name);
+ this.name = new CPUTF8(name, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ);
}
public boolean equals(Object obj) {
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IMethodRefForm.java Fri Jan 4 02:10:32 2008
@@ -16,7 +16,9 @@
*/
package org.apache.harmony.pack200.bytecode.forms;
+import org.apache.harmony.pack200.SegmentConstantPool;
import org.apache.harmony.pack200.bytecode.ByteCode;
+import org.apache.harmony.pack200.bytecode.CPInterfaceMethodRef;
import org.apache.harmony.pack200.bytecode.OperandManager;
/**
@@ -24,7 +26,7 @@
* bytecodes which have IMethod references (and only
* IMethod references).
*/
-public class IMethodRefForm extends ByteCodeForm {
+public class IMethodRefForm extends ReferenceForm {
public IMethodRefForm(int opcode, String name,
int[] rewrite) {
@@ -39,13 +41,21 @@
return true;
}
+ protected int getOffset(OperandManager operandManager) {
+ return operandManager.nextIMethodRef();
+ }
+
+ protected int getPoolID() {
+ return SegmentConstantPool.CP_IMETHOD;
+ }
+
/* (non-Javadoc)
- * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool)
+ * @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.Segment)
*/
public void setByteCodeOperands(ByteCode byteCode,
OperandManager operandManager, int codeLength) {
-//TODO: implement this. Removed the error message because
-// it causes failures in the JUnit tests.
-// throw new Error("Not implemented yet");
+ super.setByteCodeOperands(byteCode, operandManager, codeLength);
+ int count=((CPInterfaceMethodRef)byteCode.getNestedClassFileEntries()[0]).invokeInterfaceCount();
+ byteCode.getRewrite()[3] = count;
}
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java Fri Jan 4 02:10:32 2008
@@ -29,53 +29,61 @@
super(opcode, name, rewrite);
}
+ /* (non-Javadoc)
+ * @see org.apache.harmony.pack200.bytecode.forms.SwitchForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandManager, int)
+ */
public void setByteCodeOperands(ByteCode byteCode,
OperandManager operandManager, int codeLength) {
- if (switchCaseCountingBroken)
- return;
int case_count = operandManager.nextCaseCount();
int default_pc = operandManager.nextLabel();
- int case_values[] = operandManager.nextCaseValues();
+ int case_values[] = new int[case_count];
+ for(int index=0; index < case_count; index++) {
+ case_values[index] = operandManager.nextCaseValues();
+ }
int case_pcs[] = new int[case_count];
- for (int index = 0; index < case_count; index++) {
+ for(int index=0; index < case_count; index++) {
case_pcs[index] = operandManager.nextLabel();
}
- // All this gets dumped into the rewrite bytes of the
- // poor bytecode.
int[] labelsArray = new int[case_count + 1];
labelsArray[0] = default_pc;
- for (int index = 1; index < case_count + 1; index++) {
- labelsArray[index] = case_pcs[index - 1];
+ for(int index=1; index < case_count + 1; index++) {
+ labelsArray[index] = case_pcs[index-1];
}
byteCode.setByteCodeTargets(labelsArray);
+
+ // All this gets dumped into the rewrite bytes of the
+ // poor bytecode.
+
+
// Unlike most byte codes, the LookupSwitch is a
// variable-sized bytecode. Because of this, the
// rewrite array has to be defined here individually
// for each bytecode, rather than in the ByteCodeForm
// class.
-
+
// First, there's the bytecode. Then there are 0-3
// bytes of padding so that the first (default)
// label is on a 4-byte offset.
- int padLength = 3 - (codeLength % 4);
+ int padLength = 3 - (codeLength % 4);
int rewriteSize = 1 + padLength + 4 // defaultbytes
- + 4 // npairs
- + (4 * case_values.length) + (4 * case_pcs.length);
-
+ + 4 // npairs
+ + (4 * case_values.length)
+ + (4 * case_pcs.length);
+
int[] newRewrite = new int[rewriteSize];
int rewriteIndex = 0;
-
+
// Fill in what we can now
// opcode
newRewrite[rewriteIndex++] = byteCode.getOpcode();
-
+
// padding
- for (int index = 0; index < padLength; index++) {
+ for(int index=0; index < padLength; index++) {
newRewrite[rewriteIndex++] = 0;
}
-
+
// defaultbyte
// This gets overwritten by fixUpByteCodeTargets
newRewrite[rewriteIndex++] = -1;
@@ -91,7 +99,7 @@
// match-offset pairs
// The case_values aren't overwritten, but the
// case_pcs will get overwritten by fixUpByteCodeTargets
- for (int index = 0; index < case_values.length; index++) {
+ for(int index = 0; index < case_values.length; index++) {
// match
setRewrite4Bytes(case_values[index], rewriteIndex, newRewrite);
rewriteIndex += 4;
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/SwitchForm.java Fri Jan 4 02:10:32 2008
@@ -20,9 +20,7 @@
import org.apache.harmony.pack200.bytecode.CodeAttribute;
import org.apache.harmony.pack200.bytecode.OperandManager;
-public abstract class SwitchForm extends ByteCodeForm {
-
- static boolean switchCaseCountingBroken = true;
+public abstract class SwitchForm extends VariableInstructionForm {
public SwitchForm(int opcode, String name) {
super(opcode, name);
@@ -45,78 +43,14 @@
/* (non-Javadoc)
* @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandTable, org.apache.harmony.pack200.SegmentConstantPool)
*/
- public abstract void setByteCodeOperands(ByteCode byteCode,
- OperandManager operandManager, int codeLength);
-
- /**
- * Given an int operand, set the rewrite bytes for
- * the next available operand position and the three
- * immediately following it to a highest-byte,
- * mid-high, mid-low, low-byte encoding of the operand.
- *
- * Note that unlike the ByteCode setOperand* operations, this
- * starts with an actual bytecode rewrite array (rather than
- * a ByteCodeForm prototype rewrite array). Also, this method
- * overwrites -1 values in the rewrite array - so if you start
- * with an array that looks like:
- * {100, -1, -1, -1, -1, 200, -1, -1, -1, -1} then calling
- * setRewrite4Bytes(0, rewrite) the first time will convert
- * it to:
- * {100, 0, 0, 0, 0, 200, -1, -1, -1, -1}
- * Calling setRewrite4Bytes(0, rewrite) a second time will
- * convert it to:
- * {100, 0, 0, 0, 0, 200, 0, 0, 0, 0}
- *
- * @param operand int to set the rewrite bytes to
- * @param rewrite int[] bytes to rewrite
- */
- public void setRewrite4Bytes(int operand, int[] rewrite) {
- int firstOperandPosition = -1;
-
- // Find the first -1 in the rewrite array
- for(int index=0; index < rewrite.length - 3; index++) {
- if((rewrite[index] == -1)
- && (rewrite[index+1] == -1)
- && (rewrite[index+2] == -1)
- && (rewrite[index+3] == -1)) {
- firstOperandPosition = index;
- break;
- }
- }
- setRewrite4Bytes(operand, firstOperandPosition, rewrite);
+ public void setByteCodeOperands(ByteCode byteCode,
+ OperandManager operandManager, int codeLength) {
}
-
- /**
- * This method writes operand directly into the rewrite
- * array at index position specified.
- * @param operand value to write
- * @param absPosition position in array to write. Note that
- * this is absolute position in the array, so one can
- * overwrite the bytecode if one isn't careful.
- * @param rewrite array to write into
- */
- public void setRewrite4Bytes(int operand, int absPosition, int[] rewrite) {
- if(absPosition < 0) {
- throw new Error("Trying to rewrite " + this + " but there is no room for 4 bytes");
- }
-
- int byteCodeRewriteLength = rewrite.length;
-
- if(absPosition + 3 > byteCodeRewriteLength) {
- throw new Error("Trying to rewrite " + this + " with an int at position " + absPosition + " but this won't fit in the rewrite array");
- }
-
- rewrite[absPosition] = ((0xFF000000) & operand) >> 24;
- rewrite[absPosition + 1] = ((0x00FF0000) & operand) >> 16;
- rewrite[absPosition + 2] = ((0x0000FF00) & operand) >> 8;
- rewrite[absPosition + 3] = ((0x000000FF) & operand);
- }
-
+
/* (non-Javadoc)
* @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#fixUpByteCodeTargets(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.CodeAttribute)
*/
public void fixUpByteCodeTargets(ByteCode byteCode, CodeAttribute codeAttribute) {
- if(switchCaseCountingBroken) return;
// SwitchForms need to fix up the target of label operations
int[] originalTargets = byteCode.getByteCodeTargets();
int numberOfLabels = originalTargets.length;
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java?rev=608790&r1=608789&r2=608790&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java Fri Jan 4 02:10:32 2008
@@ -20,7 +20,7 @@
import org.apache.harmony.pack200.bytecode.OperandManager;
public class TableSwitchForm extends SwitchForm {
-
+
public TableSwitchForm(int opcode, String name) {
super(opcode, name);
}
@@ -29,56 +29,62 @@
super(opcode, name, rewrite);
}
+
+ /* (non-Javadoc)
+ * @see org.apache.harmony.pack200.bytecode.forms.SwitchForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandManager, int)
+ */
public void setByteCodeOperands(ByteCode byteCode,
OperandManager operandManager, int codeLength) {
- if (switchCaseCountingBroken)
- return;
int case_count = operandManager.nextCaseCount();
int default_pc = operandManager.nextLabel();
- int case_values[] = operandManager.nextCaseValues();
+ int case_value = -1;
+ case_value = operandManager.nextCaseValues();
+
int case_pcs[] = new int[case_count];
- for (int index = 0; index < case_count; index++) {
+ for(int index=0; index < case_count; index++) {
case_pcs[index] = operandManager.nextLabel();
}
- int lowValue = case_values[0];
- int highValue = lowValue + case_count - 1;
- // All this gets dumped into the rewrite bytes of the
- // poor bytecode.
int[] labelsArray = new int[case_count + 1];
labelsArray[0] = default_pc;
- for (int index = 1; index < case_count + 1; index++) {
- labelsArray[index] = case_pcs[index - 1];
+ for(int index=1; index < case_count + 1; index++) {
+ labelsArray[index] = case_pcs[index-1];
}
byteCode.setByteCodeTargets(labelsArray);
+ int lowValue = case_value;
+ int highValue = lowValue + case_count - 1;
+ // All this gets dumped into the rewrite bytes of the
+ // poor bytecode.
+
+
// Unlike most byte codes, the TableSwitch is a
// variable-sized bytecode. Because of this, the
// rewrite array has to be defined here individually
// for each bytecode, rather than in the ByteCodeForm
// class.
-
+
// First, there's the bytecode. Then there are 0-3
// bytes of padding so that the first (default)
// label is on a 4-byte offset.
- int padLength = 3 - (codeLength % 4);
+ int padLength = 3 - (codeLength % 4);
int rewriteSize = 1 + padLength + 4 // defaultbytes
- + 4 // lowbyte
- + 4 // highbyte
- + (4 * case_pcs.length);
-
+ + 4 // lowbyte
+ + 4 // highbyte
+ + (4 * case_pcs.length);
+
int[] newRewrite = new int[rewriteSize];
int rewriteIndex = 0;
-
+
// Fill in what we can now
// opcode
newRewrite[rewriteIndex++] = byteCode.getOpcode();
-
+
// padding
- for (int index = 0; index < padLength; index++) {
+ for(int index=0; index < padLength; index++) {
newRewrite[rewriteIndex++] = 0;
}
-
+
// defaultbyte
// This gets overwritten by fixUpByteCodeTargets
newRewrite[rewriteIndex++] = -1;
@@ -98,7 +104,7 @@
// jump offsets
// The case_pcs will get overwritten by fixUpByteCodeTargets
- for (int index = 0; index < case_count; index++) {
+ for(int index = 0; index < case_count; index++) {
// offset
newRewrite[rewriteIndex++] = -1;
newRewrite[rewriteIndex++] = -1;
Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java?rev=608790&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java Fri Jan 4 02:10:32 2008
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.pack200.bytecode.forms;
+
+/**
+ * This abstract class implements the common code for
+ * instructions which have variable lengths. This
+ * is currently the *switch instructions and some
+ * wide (_w) instructions.
+ */
+public abstract class VariableInstructionForm extends ByteCodeForm {
+
+ public VariableInstructionForm(int opcode, String name) {
+ super(opcode, name);
+ }
+
+ public VariableInstructionForm(int opcode, String name, int[] rewrite) {
+ super(opcode, name, rewrite);
+ }
+
+ /**
+ * Given an int operand, set the rewrite bytes for
+ * the next available operand position and the three
+ * immediately following it to a highest-byte,
+ * mid-high, mid-low, low-byte encoding of the operand.
+ *
+ * Note that unlike the ByteCode setOperand* operations, this
+ * starts with an actual bytecode rewrite array (rather than
+ * a ByteCodeForm prototype rewrite array). Also, this method
+ * overwrites -1 values in the rewrite array - so if you start
+ * with an array that looks like:
+ * {100, -1, -1, -1, -1, 200, -1, -1, -1, -1} then calling
+ * setRewrite4Bytes(0, rewrite) the first time will convert
+ * it to:
+ * {100, 0, 0, 0, 0, 200, -1, -1, -1, -1}
+ * Calling setRewrite4Bytes(0, rewrite) a second time will
+ * convert it to:
+ * {100, 0, 0, 0, 0, 200, 0, 0, 0, 0}
+ *
+ * @param operand int to set the rewrite bytes to
+ * @param rewrite int[] bytes to rewrite
+ */
+ public void setRewrite4Bytes(int operand, int[] rewrite) {
+ int firstOperandPosition = -1;
+
+ // Find the first -1 in the rewrite array
+ for(int index=0; index < rewrite.length - 3; index++) {
+ if((rewrite[index] == -1)
+ && (rewrite[index+1] == -1)
+ && (rewrite[index+2] == -1)
+ && (rewrite[index+3] == -1)) {
+ firstOperandPosition = index;
+ break;
+ }
+ }
+ setRewrite4Bytes(operand, firstOperandPosition, rewrite);
+ }
+
+ /**
+ * Given an int operand, set the rewrite bytes for
+ * the next available operand position and the byte
+ * immediately following it to a high-byte,
+ * low-byte encoding of the operand.
+ *
+ * Note that unlike the ByteCode setOperand* operations, this
+ * starts with an actual bytecode rewrite array (rather than
+ * a ByteCodeForm prototype rewrite array). Also, this method
+ * overwrites -1 values in the rewrite array - so if you start
+ * with an array that looks like:
+ * {100, -1, -1, -1, -1, 200, -1, -1, -1, -1} then calling
+ * setRewrite2Bytes(0, rewrite) the first time will convert
+ * it to:
+ * {100, 0, 0, -1, -1, 200, -1, -1, -1, -1}
+ * Calling setRewrite2Bytes(0, rewrite) a second time will
+ * convert it to:
+ * {100, 0, 0, 0, 0, 200, -1, -1, -1, -1}
+ *
+ * @param operand int to set the rewrite bytes to
+ * @param rewrite int[] bytes to rewrite
+ */
+ public void setRewrite2Bytes(int operand, int[] rewrite) {
+ int firstOperandPosition = -1;
+
+ // Find the first -1 in the rewrite array
+ for(int index=0; index < rewrite.length - 3; index++) {
+ if((rewrite[index] == -1)
+ && (rewrite[index+1] == -1)) {
+ firstOperandPosition = index;
+ break;
+ }
+ }
+ setRewrite2Bytes(operand, firstOperandPosition, rewrite);
+ }
+
+ /**
+ * This method writes operand directly into the rewrite
+ * array at index position specified.
+ * @param operand value to write
+ * @param absPosition position in array to write. Note that
+ * this is absolute position in the array, so one can
+ * overwrite the bytecode if one isn't careful.
+ * @param rewrite array to write into
+ */
+ public void setRewrite4Bytes(int operand, int absPosition, int[] rewrite) {
+ if(absPosition < 0) {
+ throw new Error("Trying to rewrite " + this + " but there is no room for 4 bytes");
+ }
+
+ int byteCodeRewriteLength = rewrite.length;
+
+ if(absPosition + 3 > byteCodeRewriteLength) {
+ throw new Error("Trying to rewrite " + this + " with an int at position " + absPosition + " but this won't fit in the rewrite array");
+ }
+
+ rewrite[absPosition] = ((0xFF000000) & operand) >> 24;
+ rewrite[absPosition + 1] = ((0x00FF0000) & operand) >> 16;
+ rewrite[absPosition + 2] = ((0x0000FF00) & operand) >> 8;
+ rewrite[absPosition + 3] = ((0x000000FF) & operand);
+ }
+
+ /**
+ * This method writes operand directly into the rewrite
+ * array at index position specified.
+ * @param operand value to write
+ * @param absPosition position in array to write. Note that
+ * this is absolute position in the array, so one can
+ * overwrite the bytecode if one isn't careful.
+ * @param rewrite array to write into
+ */
+ public void setRewrite2Bytes(int operand, int absPosition, int[] rewrite) {
+ if(absPosition < 0) {
+ throw new Error("Trying to rewrite " + this + " but there is no room for 4 bytes");
+ }
+
+ int byteCodeRewriteLength = rewrite.length;
+
+ if(absPosition + 1 > byteCodeRewriteLength) {
+ throw new Error("Trying to rewrite " + this + " with an int at position " + absPosition + " but this won't fit in the rewrite array");
+ }
+
+ rewrite[absPosition] = ((0xFF00) & operand) >> 8;
+ rewrite[absPosition + 1] = ((0x00FF) & operand);
+ }
+}
Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/VariableInstructionForm.java
------------------------------------------------------------------------------
svn:eol-style = native