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/03 14:13:17 UTC
svn commit: r608472 - 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: Thu Jan 3 05:13:15 2008
New Revision: 608472
URL: http://svn.apache.org/viewvc?rev=608472&view=rev
Log:
Apply patch HARMONY-5289 ([pack200][classlib] Added code to support tableswitch/lookupswitch)
Added:
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java (with props)
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.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/bytecode/ByteCode.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/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/forms/ByteCodeForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteForm.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/IincForm.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/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.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/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
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=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java Thu Jan 3 05:13:15 2008
@@ -299,7 +299,15 @@
// other bytecode bands
debug("Parsed *bc_codes (" + bcParsed + ")");
bcCaseCount = decodeBandInt("bc_case_count", in, Codec.UNSIGNED5, bcCaseCountCount);
- bcCaseValue = decodeBandInt("bc_case_value", in, Codec.DELTA5, bcCaseCount);
+ // 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 */);
+ // 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.
+ for(int index=0; index < bcCaseCountCount; index++) {
+ bcLabelCount += bcCaseCount[index];
+ }
bcByte = decodeBandInt("bc_byte", in, Codec.BYTE1, bcByteCount);
bcShort = decodeBandInt("bc_short", in, Codec.DELTA5, bcShortCount);
bcLocal = decodeBandInt("bc_local", in, Codec.UNSIGNED5, bcLocalCount);
@@ -337,10 +345,10 @@
bcEscSize = decodeBandInt("bc_escsize", in, Codec.UNSIGNED5, bcEscCount);
bcEscByte = decodeBandInt("bc_escbyte", in, Codec.BYTE1, bcEscSize);
- OperandManager operandManager = new OperandManager(bcByte, bcShort,
- bcLocal, bcLabel, bcIntRef, bcFloatRef, bcLongRef, bcDoubleRef,
- bcStringRef, bcClassRef, bcFieldRef, bcMethodRef, bcIMethodRef,
- bcThisField, bcSuperField, bcThisMethod, bcSuperMethod,
+ OperandManager operandManager = new OperandManager(bcCaseCount, bcCaseValue,
+ bcByte, bcShort, bcLocal, bcLabel, bcIntRef, bcFloatRef, bcLongRef,
+ bcDoubleRef, bcStringRef, bcClassRef, bcFieldRef, bcMethodRef,
+ bcIMethodRef, bcThisField, bcSuperField, bcThisMethod, bcSuperMethod,
bcInitRef);
operandManager.setSegment(segment);
@@ -373,7 +381,9 @@
// broken because these tables don't get renumbered
// properly. Commenting out the add so the class files
// will verify.
- //attr.attributes.add(currentAttribute);
+ // if(currentAttribute.getClass() == LineNumberTableAttribute.class) {
+ attr.attributes.add(currentAttribute);
+ // }
// Fix up the line numbers if needed
if(currentAttribute.hasBCIRenumbering()) {
((BCIRenumberedAttribute)currentAttribute).renumber(attr.byteCodeOffsets);
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=608472&r1=608471&r2=608472&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 Thu Jan 3 05:13:15 2008
@@ -36,7 +36,7 @@
private int[] rewrite;
private int byteCodeOffset = -1;
- private int byteCodeTarget = -1;
+ private int[] byteCodeTargets = null;
protected ByteCode(int opcode) {
this(opcode, ClassFileEntry.NONE);
@@ -69,14 +69,13 @@
return true;
}
- public void extractOperands(OperandManager operandManager, Segment segment) {
+ public void extractOperands(OperandManager operandManager, Segment segment, int codeLength) {
// Given an OperandTable, figure out which operands
// the receiver needs and stuff them in operands.
// Later on the operands can be rewritten (But that's
// later, not now).
-
ByteCodeForm currentByteCodeForm = getByteCodeForm();
- currentByteCodeForm.setByteCodeOperands(this, operandManager);
+ currentByteCodeForm.setByteCodeOperands(this, operandManager, codeLength);
}
protected ByteCodeForm getByteCodeForm() {
@@ -131,7 +130,7 @@
break;
case 2:
- setOperandInt(pool.indexOf(nested[index]), getNestedPosition(index)[0]);
+ setOperand2Bytes(pool.indexOf(nested[index]), getNestedPosition(index)[0]);
break;
case 4:
@@ -172,7 +171,7 @@
rewrite[index + firstOperandIndex] = operands[index] & 0xFF;
}
}
-
+
/**
* Given an int operand, set the rewrite bytes for
* that position and the one immediately following it
@@ -184,7 +183,7 @@
* position 0 is the first -1, position 1 is the second -1,
* etc.
*/
- public void setOperandInt(int operand, int position) {
+ public void setOperand2Bytes(int operand, int position) {
int firstOperandIndex = getByteCodeForm().firstOperandIndex();
int byteCodeFormLength = getByteCodeForm().getRewrite().length;
if (firstOperandIndex < 1) {
@@ -206,12 +205,12 @@
* @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) {
+ public void setOperandSigned2Bytes(int operand, int position) {
if(operand >= 0) {
- setOperandInt(operand, position);
+ setOperand2Bytes(operand, position);
} else {
int twosComplementOperand = 0x10000 + operand;
- setOperandInt(twosComplementOperand, position);
+ setOperand2Bytes(twosComplementOperand, position);
}
}
@@ -315,31 +314,60 @@
}
/**
- * 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
+ * Some ByteCodes (in particular, those with labels)
+ * have to keep track of byteCodeTargets. These are
+ * initially offsets in the CodeAttribute array
+ * relative to the byteCodeOffset, but later get fixed
* up to point to the absolute position in the CodeAttribute
- * array. This method sets the target.
+ * array. This method sets the targets.
*
* @param byteCodeTarget int index in array
*/
- public void setByteCodeTarget(int byteCodeTarget) {
- this.byteCodeTarget = byteCodeTarget;
+ public void setByteCodeTargets(int[] byteCodeTargets) {
+ this.byteCodeTargets = byteCodeTargets;
}
- public int getByteCodeTarget() {
- return byteCodeTarget;
+ public int[] getByteCodeTargets() {
+ return byteCodeTargets;
}
/**
- * 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
+ * Some ByteCodes (in particular, those with labels
+ * 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);
+ getByteCodeForm().fixUpByteCodeTargets(this, codeAttribute);
+ }
+
+ /**
+ * Some bytecodes (the ones with variable lengths) can't
+ * have a static rewrite array - they need the ability to
+ * update the array. This method permits that.
+ *
+ * Note that this should not be called from bytecodes
+ * which have a static rewrite; use the table in ByteCodeForm
+ * instead to specify those rewrites.
+ *
+ * @param rewrite
+ */
+ public void setRewrite(int[] rewrite) {
+ this.rewrite = rewrite;
+ }
+
+ /**
+ * Some bytecodes (the ones with variable lengths) can't
+ * have a static rewrite array - they need the ability to
+ * update the array. This method permits their associated
+ * bytecode formst to query their rewrite array.
+ *
+ * Note that this should not be called from bytecodes
+ * which have a static rewrite; use the table in ByteCodeForm
+ * instead to specify those rewrites.
+ */
+ public int[] getRewrite() {
+ return rewrite;
}
}
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=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java Thu Jan 3 05:13:15 2008
@@ -46,7 +46,7 @@
// Setting the offset must happen before extracting operands
// because label bytecodes need to know their offsets.
byteCode.setByteCodeIndex(i);
- byteCode.extractOperands(operandManager, segment);
+ byteCode.extractOperands(operandManager, segment, codeLength);
byteCodes.add(byteCode);
codeLength += byteCode.getLength();
int lastBytecodePosition = ((Integer) byteCodeOffsets
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=608472&r1=608471&r2=608472&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 Thu Jan 3 05:13:15 2008
@@ -90,8 +90,12 @@
public void renumber(List byteCodeOffsets) {
// First fix up the start_pcs
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
- int maxLength = ((Integer)byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue();
+ int lastInstruction = ((Integer)byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue();
+ int maxLength = lastInstruction + 1;
for(int index=0; index < lengths.length; index++) {
// Need to special case when the length is greater than the size
int revisedLength = -1;
@@ -100,7 +104,7 @@
// 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;
+ revisedLength = maxLength - start_pcs[index];
} else {
// We're indexed into the byte code array
revisedLength = ((Integer)byteCodeOffsets.get(encodedLength)).intValue();
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=608472&r1=608471&r2=608472&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 Thu Jan 3 05:13:15 2008
@@ -28,6 +28,8 @@
*/
public class OperandManager {
+ int[] bcCaseCount;
+ int[][] bcCaseValue;
int[] bcByte;
int[] bcShort;
int[] bcLocal;
@@ -47,6 +49,8 @@
int[] bcSuperMethod;
int[] bcInitRef;
+ int bcCaseCountIndex = 0;
+ int bcCaseValueIndex = 0;
int bcByteIndex = 0;
int bcShortIndex = 0;
int bcLocalIndex = 0;
@@ -72,7 +76,9 @@
String superClass = null;
String newClass = null;
- public OperandManager(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) {
+ this.bcCaseCount = bcCaseCount;
+ this.bcCaseValue = bcCaseValue;
this.bcByte = bcByte;
this.bcShort = bcShort;
this.bcLocal = bcLocal;
@@ -93,6 +99,14 @@
this.bcSuperMethod = bcSuperMethod;
this.bcInitRef = bcInitRef;
}
+
+ public int nextCaseCount() {
+ return bcCaseCount[bcCaseCountIndex++];
+ }
+
+ public int[] nextCaseValues() {
+ return bcCaseValue[bcCaseValueIndex++];
+ }
public int nextByte() {
return bcByte[bcByteIndex++];
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=608472&r1=608471&r2=608472&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 Thu Jan 3 05:13:15 2008
@@ -232,8 +232,8 @@
byteCodeArray[167] = new LabelForm(167, "goto", new int[] {167, -1, -1});
byteCodeArray[168] = new LabelForm(168, "jsr", new int[] {168, -1, -1});
byteCodeArray[169] = new LocalForm(169, "ret", new int[] {169, -1});
- byteCodeArray[170] = new SwitchForm(170, "tableswitch");
- byteCodeArray[171] = new SwitchForm(171, "lookupswitch");
+ byteCodeArray[170] = new TableSwitchForm(170, "tableswitch");
+ byteCodeArray[171] = new LookupSwitchForm(171, "lookupswitch");
byteCodeArray[172] = new NoArgumentForm(172, "ireturn");
byteCodeArray[173] = new NoArgumentForm(173, "lreturn");
byteCodeArray[174] = new NoArgumentForm(174, "freturn");
@@ -572,10 +572,13 @@
*
* @param byteCode ByteCode to be updated (!)
* @param operandManager OperandTable from which to draw info
- * @param globalPool SegmentConstantPool used to index into
+ * @param codeLength Length of bytes (excluding this bytecode)
+ * from the beginning of the method. Used in calculating
+ * padding for some variable-length bytecodes (such as
+ * lookupswitch, tableswitch).
*/
public void setByteCodeOperands(ByteCode byteCode,
- OperandManager operandManager) {
+ OperandManager operandManager, int codeLength) {
throw new Error("My subclass should have implemented this");
}
@@ -587,7 +590,7 @@
* @param codeAttribute a CodeAttribute used to determine how
* the ByteCode should be fixed up.
*/
- public void fixUpByteCodeTarget(ByteCode byteCode, CodeAttribute codeAttribute) {
+ public void fixUpByteCodeTargets(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/ByteForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteForm.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteForm.java Thu Jan 3 05:13:15 2008
@@ -41,7 +41,7 @@
* @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) {
+ OperandManager operandManager, int codeLength) {
byteCode.setOperandByte(operandManager.nextByte() & 0xFF, 0);
}
}
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=608472&r1=608471&r2=608472&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 Thu Jan 3 05:13:15 2008
@@ -43,7 +43,7 @@
* @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) {
+ 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");
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IincForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IincForm.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IincForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/IincForm.java Thu Jan 3 05:13:15 2008
@@ -41,7 +41,7 @@
* @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) {
+ OperandManager operandManager, int codeLength) {
int local = operandManager.nextLocal();
int constant = operandManager.nextByte();
byteCode.setOperandBytes(new int[]{local, constant});
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=608472&r1=608471&r2=608472&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 Thu Jan 3 05:13:15 2008
@@ -50,9 +50,9 @@
/* (non-Javadoc)
* @see org.apache.harmony.pack200.bytecode.forms.ByteCodeForm#fixUpByteCodeTarget(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.CodeAttribute)
*/
- public void fixUpByteCodeTarget(ByteCode byteCode, CodeAttribute codeAttribute) {
+ public void fixUpByteCodeTargets(ByteCode byteCode, CodeAttribute codeAttribute) {
// LabelForms need to fix up the target of label operations
- int originalTarget = byteCode.getByteCodeTarget();
+ int originalTarget = byteCode.getByteCodeTargets()[0];
int sourceIndex = byteCode.getByteCodeIndex();
int absoluteInstructionTargetIndex = sourceIndex + originalTarget;
int targetValue = ((Integer)codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex)).intValue();
@@ -60,7 +60,7 @@
// 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);
+ byteCode.setOperandSigned2Bytes(targetValue - sourceValue, 0);
if(widened) {
byteCode.setNestedPositions(new int[][] {{0,4}});
} else {
@@ -72,8 +72,8 @@
* @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());
+ OperandManager operandManager, int codeLength) {
+ byteCode.setByteCodeTargets(new int[] {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/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LocalForm.java Thu Jan 3 05:13:15 2008
@@ -48,7 +48,7 @@
* @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) {
+ OperandManager operandManager, int codeLength) {
byteCode.setOperandBytes(new int[]{operandManager.nextLocal()});
}
}
Added: 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=608472&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java Thu Jan 3 05:13:15 2008
@@ -0,0 +1,106 @@
+/*
+ * 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;
+
+import org.apache.harmony.pack200.bytecode.ByteCode;
+import org.apache.harmony.pack200.bytecode.OperandManager;
+
+public class LookupSwitchForm extends SwitchForm {
+
+ public LookupSwitchForm(int opcode, String name) {
+ super(opcode, name);
+ }
+
+ public LookupSwitchForm(int opcode, String name, int[] rewrite) {
+ super(opcode, name, rewrite);
+ }
+
+ 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_pcs[] = new int[case_count];
+ 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];
+ }
+ byteCode.setByteCodeTargets(labelsArray);
+
+ // 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 rewriteSize = 1 + padLength + 4 // defaultbytes
+ + 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++) {
+ newRewrite[rewriteIndex++] = 0;
+ }
+
+ // defaultbyte
+ // This gets overwritten by fixUpByteCodeTargets
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+
+ // npairs
+ int npairsIndex = rewriteIndex;
+ setRewrite4Bytes(case_values.length, npairsIndex, newRewrite);
+ rewriteIndex += 4;
+
+ // 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++) {
+ // match
+ setRewrite4Bytes(case_values[index], rewriteIndex, newRewrite);
+ rewriteIndex += 4;
+ // offset
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ }
+ byteCode.setRewrite(newRewrite);
+ }
+}
Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/LookupSwitchForm.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/MultiANewArrayForm.java Thu Jan 3 05:13:15 2008
@@ -50,10 +50,10 @@
* @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) {
+ OperandManager operandManager, int codeLength) {
// multianewarray has a class ref and a dimension.
// The superclass handles the class ref.
- super.setByteCodeOperands(byteCode, operandManager);
+ super.setByteCodeOperands(byteCode, operandManager, codeLength);
// We have to handle the dimension.
int dimension = operandManager.nextByte();
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NewClassRefForm.java Thu Jan 3 05:13:15 2008
@@ -44,7 +44,7 @@
* @see org.apache.harmony.pack200.bytecode.forms.ReferenceForm#setByteCodeOperands(org.apache.harmony.pack200.bytecode.ByteCode, org.apache.harmony.pack200.bytecode.OperandManager)
*/
public void setByteCodeOperands(ByteCode byteCode,
- OperandManager operandManager) {
+ OperandManager operandManager, int codeLength) {
ClassFileEntry[] nested = null;
int offset = getOffset(operandManager);
if(offset == 0) {
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NoArgumentForm.java Thu Jan 3 05:13:15 2008
@@ -44,7 +44,7 @@
* @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) {
+ OperandManager operandManager, int codeLength) {
// Nothing to do for no-argument form
}
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ReferenceForm.java Thu Jan 3 05:13:15 2008
@@ -50,7 +50,7 @@
* @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) {
+ OperandManager operandManager, int codeLength) {
int offset = getOffset(operandManager);
try {
setNestedEntries(byteCode, operandManager, offset);
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ShortForm.java Thu Jan 3 05:13:15 2008
@@ -42,7 +42,7 @@
* @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.setOperandInt(operandManager.nextShort(), 0);
+ OperandManager operandManager, int codeLength) {
+ byteCode.setOperand2Bytes(operandManager.nextShort(), 0);
}
}
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=608472&r1=608471&r2=608472&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 Thu Jan 3 05:13:15 2008
@@ -17,9 +17,12 @@
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;
-public class SwitchForm extends ByteCodeForm {
+public abstract class SwitchForm extends ByteCodeForm {
+
+ static boolean switchCaseCountingBroken = true;
public SwitchForm(int opcode, String name) {
super(opcode, name);
@@ -42,10 +45,94 @@
/* (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) {
-//TODO: implement this. Removed the error message because
-// it causes failures in the JUnit tests.
-// throw new Error("Not implemented yet");
+ 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);
+ }
+
+ /**
+ * 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;
+ int[] replacementTargets = new int[numberOfLabels];
+
+ int sourceIndex = byteCode.getByteCodeIndex();
+ int sourceValue = ((Integer)codeAttribute.byteCodeOffsets.get(sourceIndex)).intValue();
+ for(int index=0; index < numberOfLabels; index++) {
+ int absoluteInstructionTargetIndex = sourceIndex + originalTargets[index];
+ int targetValue = ((Integer)codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex)).intValue();
+ replacementTargets[index] = targetValue - sourceValue;
+ }
+ int[] rewriteArray = byteCode.getRewrite();
+ for(int index=0; index < numberOfLabels; index++) {
+ setRewrite4Bytes(replacementTargets[index], rewriteArray);
+ }
}
+
}
Added: 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=608472&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java Thu Jan 3 05:13:15 2008
@@ -0,0 +1,110 @@
+/*
+ * 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;
+
+import org.apache.harmony.pack200.bytecode.ByteCode;
+import org.apache.harmony.pack200.bytecode.OperandManager;
+
+public class TableSwitchForm extends SwitchForm {
+
+ public TableSwitchForm(int opcode, String name) {
+ super(opcode, name);
+ }
+
+ public TableSwitchForm(int opcode, String name, int[] rewrite) {
+ super(opcode, name, rewrite);
+ }
+
+ 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_pcs[] = new int[case_count];
+ 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];
+ }
+ byteCode.setByteCodeTargets(labelsArray);
+
+ // 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 rewriteSize = 1 + padLength + 4 // defaultbytes
+ + 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++) {
+ newRewrite[rewriteIndex++] = 0;
+ }
+
+ // defaultbyte
+ // This gets overwritten by fixUpByteCodeTargets
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+
+ // lowbyte
+ int lowbyteIndex = rewriteIndex;
+ setRewrite4Bytes(lowValue, lowbyteIndex, newRewrite);
+ rewriteIndex += 4;
+
+ // highbyte
+ int highbyteIndex = rewriteIndex;
+ setRewrite4Bytes(highValue, highbyteIndex, newRewrite);
+ rewriteIndex += 4;
+
+ // jump offsets
+ // The case_pcs will get overwritten by fixUpByteCodeTargets
+ for (int index = 0; index < case_count; index++) {
+ // offset
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ newRewrite[rewriteIndex++] = -1;
+ }
+ byteCode.setRewrite(newRewrite);
+ }
+}
Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/TableSwitchForm.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/WideForm.java Thu Jan 3 05:13:15 2008
@@ -47,7 +47,7 @@
* @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) {
+ 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");
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=608472&r1=608471&r2=608472&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 Thu Jan 3 05:13:15 2008
@@ -294,8 +294,8 @@
public void testBcCaseBands() throws IOException, Pack200Exception {
byte[] bytes = new byte[] {(byte)170,(byte)171, (byte)255,
2, 5, // bc_case_count
- 8, 8, 8, 8, 8, 8, 8, // bc_case_value
- 8, 8}; // bc_label
+ 0, 1, 0, 1, 2, 3, 4, // bc_case_value
+ 0, 0, 0, 0, 0, 0, 0, 0, 0}; // bc_label
InputStream in = new ByteArrayInputStream(bytes);
bcBands.unpack(in);
assertEquals(2, bcBands.getMethodByteCodePacked()[0][0].length);
@@ -307,7 +307,7 @@
assertEquals(2, bc_case_value.length);
assertEquals(2, bc_case_value[0].length);
assertEquals(5, bc_case_value[1].length);
- assertEquals(2, bcBands.getBcLabel().length);
+ assertEquals(9, bcBands.getBcLabel().length);
}
/**
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java?rev=608472&r1=608471&r2=608472&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodeAttributeTest.java Thu Jan 3 05:13:15 2008
@@ -77,7 +77,9 @@
public class MockOperandManager extends OperandManager {
public MockOperandManager() {
- super(new int[] {}, // bcByte
+ super(new int[] {}, // bcCaseCount
+ new int[][] {}, // bcCaseValues
+ new int[] {}, // bcByte
new int[] {}, // bcShort
new int[] {}, // bcLocal
new int[] {}, // bcLabel