You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2007/11/20 15:43:29 UTC
svn commit: r596693 [5/9] - in /harmony/enhanced/classlib/branches/java6: ./
depends/jars/ depends/libs/build/ make/
modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/
modules/auth/src/main/java/common/org/apache/harmony/auth/jgss...
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayoutMap.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayoutMap.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayoutMap.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayoutMap.java Tue Nov 20 06:42:33 2007
@@ -26,7 +26,8 @@
* internationalized, and should not be translated.
*/
public class AttributeLayoutMap {
- // create a whole bunch of AttributeLayouts here
+
+ // Create all the default AttributeLayouts here
private static AttributeLayout[] getDefaultAttributeLayouts()
throws Pack200Exception {
return new AttributeLayout[] {
@@ -137,7 +138,7 @@
new AttributeLayout(AttributeLayout.ATTRIBUTE_CONSTANT_VALUE,
AttributeLayout.CONTEXT_FIELD, "KQH", 17),
new AttributeLayout(AttributeLayout.ATTRIBUTE_CODE,
- AttributeLayout.CONTEXT_METHOD, "*", 17),
+ AttributeLayout.CONTEXT_METHOD, "", 17),
new AttributeLayout(AttributeLayout.ATTRIBUTE_ENCLOSING_METHOD,
AttributeLayout.CONTEXT_CLASS, "RCHRDNH", 18),
new AttributeLayout(AttributeLayout.ATTRIBUTE_EXCEPTIONS,
@@ -173,7 +174,7 @@
AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
AttributeLayout.CONTEXT_METHOD, "*", 22),
new AttributeLayout(AttributeLayout.ATTRIBUTE_INNER_CLASSES,
- AttributeLayout.CONTEXT_CLASS, "*", 23),
+ AttributeLayout.CONTEXT_CLASS, "", 23),
new AttributeLayout(
AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,
AttributeLayout.CONTEXT_METHOD, "*", 23),
@@ -257,4 +258,5 @@
}
}
}
+
}
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java Tue Nov 20 06:42:33 2007
@@ -21,6 +21,12 @@
import java.io.InputStream;
import java.io.OutputStream;
+import org.apache.harmony.pack200.bytecode.CPDouble;
+import org.apache.harmony.pack200.bytecode.CPFloat;
+import org.apache.harmony.pack200.bytecode.CPInteger;
+import org.apache.harmony.pack200.bytecode.CPLong;
+import org.apache.harmony.pack200.bytecode.CPUTF8;
+
public abstract class BandSet {
public abstract void unpack(InputStream inputStream) throws IOException, Pack200Exception;
@@ -380,5 +386,103 @@
segment.debug(message);
}
+ public CPInteger[] parseCPIntReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
+ int[] reference = segment.getCpBands().getCpInt();
+ int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+ CPInteger[] result = new CPInteger[indices.length];
+ for (int i1 = 0; i1 < count; i1++) {
+ int index = indices[i1];
+ 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 CPInteger(new Integer(reference[index]));
+ }
+ return result;
+ }
+
+ public CPDouble[] parseCPDoubleReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
+ double[] reference = segment.getCpBands().getCpDouble();
+ int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+ CPDouble[] result = new CPDouble[indices.length];
+ for (int i1 = 0; i1 < count; i1++) {
+ int index = indices[i1];
+ 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 CPDouble(new Double(reference[index]));
+ }
+ return result;
+ }
+
+ public CPFloat[] parseCPFloatReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
+ float[] reference = segment.getCpBands().getCpFloat();
+ int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+ CPFloat[] result = new CPFloat[indices.length];
+ for (int i1 = 0; i1 < count; i1++) {
+ int index = indices[i1];
+ 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 CPFloat(new Float(reference[index]));
+ }
+ return result;
+ }
+
+ public CPLong[] parseCPLongReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
+ long[] reference = segment.getCpBands().getCpLong();
+ int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+ CPLong[] result = new CPLong[indices.length];
+ for (int i1 = 0; i1 < count; i1++) {
+ int index = indices[i1];
+ 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 CPLong(new Long(reference[index]));
+ }
+ return result;
+ }
+
+ public CPUTF8[] parseCPUTF8References(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
+ String[] reference = segment.getCpBands().getCpUTF8();
+ int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+ CPUTF8[] result = new CPUTF8[indices.length];
+ for (int i1 = 0; i1 < count; i1++) {
+ int index = indices[i1];
+ 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]);
+ }
+ return result;
+ }
+
+
+ public CPUTF8[][] parseCPUTF8References(String name, InputStream in, BHSDCodec codec, int[] counts) throws IOException, Pack200Exception {
+ String[] reference = segment.getCpBands().getCpUTF8();
+ CPUTF8[][] result = new CPUTF8[counts.length][];
+ int sum = 0;
+ for (int i = 0; i < counts.length; i++) {
+ result[i] = new CPUTF8[counts[i]];
+ sum += counts[i];
+ }
+ CPUTF8[] result1 = new CPUTF8[sum];
+ int[] indices = decodeBandInt(name, in, codec, sum, reference.length - 1);
+ for (int i1 = 0; i1 < sum; i1++) {
+ int index = indices[i1];
+ 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]);
+ }
+ CPUTF8[] refs = result1;
+ int pos = 0;
+ for (int i = 0; i < counts.length; i++) {
+ int num = counts[i];
+ result[i] = new CPUTF8[num];
+ System.arraycopy(refs, pos, result[i], 0, num);
+ pos += num;
+ }
+ return result;
+ }
}
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java Tue Nov 20 06:42:33 2007
@@ -24,12 +24,13 @@
import org.apache.harmony.pack200.bytecode.ByteCode;
import org.apache.harmony.pack200.bytecode.CodeAttribute;
+import org.apache.harmony.pack200.bytecode.OperandManager;
/**
* Pack200 Bytecode bands
*/
public class BcBands extends BandSet {
-
+
// The bytecodes for each method in each class as they come (i.e. in their packed format)
private byte[][][] methodByteCodePacked;
@@ -177,7 +178,7 @@
case 187: // new
case 189: // anewarray
case 192: // checkcast
- case 193: // instanceof
+ case 193: // instanceof
bcClassRefCount++;
break;
case 20: // lldc2_w
@@ -285,7 +286,7 @@
} else if (startsWithIf(codePacked)) {
bcLabelCount++;
} else {
- debug("Found unhandled " + ByteCode.getByteCode(codePacked));
+ debug("Found unhandled " + codePacked + " " + ByteCode.getByteCode(codePacked));
}
}
}
@@ -332,7 +333,14 @@
bcEscRefSize = decodeBandInt("bc_escrefsize", in, Codec.UNSIGNED5, bcEscRefCount);
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,
+ bcInitRef);
+ operandManager.setSegment(segment);
+
int i = 0;
for (int c = 0; c < classCount; c++) {
int numberOfMethods = methodFlags[c].length;
@@ -347,15 +355,17 @@
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,
- methodByteCodePacked[c][m]);
+ methodByteCodePacked[c][m], segment, operandManager);
methodAttributes[c][m].add(attr);
i++;
}
}
}
}
-
+
private boolean startsWithIf(int codePacked) {
return (codePacked >= 153 && codePacked <= 166)
|| (codePacked == 198)
@@ -367,7 +377,7 @@
}
private boolean endsWithStore(int codePacked) {
- return (codePacked >= 54 && codePacked <= 58);
+ return (codePacked >= 54 && codePacked <= 58);
}
public byte[][][] getMethodByteCodePacked() {
@@ -461,7 +471,7 @@
public int[] getBcEscRefSize() {
return bcEscRefSize;
}
-
+
public int[] getBcEscSize() {
return bcEscSize;
}
@@ -469,4 +479,6 @@
public int[][] getBcEscByte() {
return bcEscByte;
}
+
+
}
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Tue Nov 20 06:42:33 2007
@@ -20,11 +20,18 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
import org.apache.harmony.pack200.IcBands.ICTuple;
import org.apache.harmony.pack200.bytecode.CPClass;
+import org.apache.harmony.pack200.bytecode.CPUTF8;
import org.apache.harmony.pack200.bytecode.ConstantValueAttribute;
import org.apache.harmony.pack200.bytecode.ExceptionsAttribute;
+import org.apache.harmony.pack200.bytecode.LineNumberTableAttribute;
+import org.apache.harmony.pack200.bytecode.LocalVariableTableAttribute;
+import org.apache.harmony.pack200.bytecode.LocalVariableTypeTableAttribute;
+import org.apache.harmony.pack200.bytecode.SignatureAttribute;
import org.apache.harmony.pack200.bytecode.SourceFileAttribute;
/**
@@ -43,15 +50,17 @@
private String[] classSuper;
private String[] classThis;
-
+
private ArrayList[] classAttributes;
-
+
private int[] classVersionMajor;
-
+
private int[] classVersionMinor;
-
+
private IcBands.ICTuple[][] icLocal;
+ private ArrayList[] codeAttributes;
+
private int[] codeHandlerCount;
private int[] codeMaxNALocals;
@@ -67,7 +76,7 @@
private ArrayList[][] methodAttributes;
private String[][] methodDescr;
-
+
private long[][] methodFlags;
private AttributeLayoutMap attrMap;
@@ -79,7 +88,7 @@
private int classCount;
private int[] methodAttrCalls;
-
+
/**
* @param segment
*/
@@ -90,7 +99,7 @@
this.cpBands = segment.getCpBands();
this.classCount = header.getClassCount();
this.options = header.getOptions();
-
+
}
/*
@@ -136,42 +145,32 @@
fieldFlags = parseFlags("field_flags", in, classFieldCount,
Codec.UNSIGNED5, options.hasFieldFlagsHi());
int fieldAttrCount = SegmentUtils.countBit16(fieldFlags);
- int[] fieldAttrCounts = decodeBandInt("field_attr_count", in, Codec.UNSIGNED5, fieldAttrCount);
- int[][] fieldAttrIndexes = decodeBandInt("field_attr_indexes", in, Codec.UNSIGNED5, fieldAttrCounts);
- int callCount = 0;
- for (int i = 0; i < fieldAttrIndexes.length; i++) {
- for (int j = 0; j < fieldAttrIndexes[i].length; j++) {
- int index = fieldAttrIndexes[i][j];
- AttributeLayout layout = attrMap.getAttributeLayout(index, AttributeLayout.CONTEXT_FIELD);
- callCount += layout.numBackwardsCallables();
- }
- }
- int layoutsUsed = 0;
- for (int i = 0; i < fieldFlags.length; i++) {
- for (int j = 0; j < fieldFlags[i].length; j++) {
- layoutsUsed |= fieldFlags[i][j];
- }
- }
- for (int i = 0; i < 16; i++) {
- if((layoutsUsed & 1<<i) != 0) {
- AttributeLayout layout = attrMap.getAttributeLayout(i, AttributeLayout.CONTEXT_FIELD);
- callCount += layout.numBackwardsCallables();
- }
- }
- int[] fieldAttrCalls = decodeBandInt("field_attr_calls", in, Codec.UNSIGNED5, callCount);
-
- AttributeLayout constantValueLayout = attrMap.getAttributeLayout("ConstantValue",
+ int[] fieldAttrCounts = decodeBandInt("field_attr_count", in,
+ Codec.UNSIGNED5, fieldAttrCount);
+ int[][] fieldAttrIndexes = decodeBandInt("field_attr_indexes", in,
+ Codec.UNSIGNED5, fieldAttrCounts);
+ int callCount = getCallCount(fieldAttrIndexes, fieldFlags,
AttributeLayout.CONTEXT_FIELD);
- int constantCount = SegmentUtils.countMatches(fieldFlags, constantValueLayout);
- int[] field_constantValue_KQ = decodeBandInt("field_ConstantValue_KQ", in, Codec.UNSIGNED5, constantCount);
+ int[] fieldAttrCalls = decodeBandInt("field_attr_calls", in,
+ Codec.UNSIGNED5, callCount);
+
+ AttributeLayout constantValueLayout = attrMap.getAttributeLayout(
+ "ConstantValue", AttributeLayout.CONTEXT_FIELD);
+ int constantCount = SegmentUtils.countMatches(fieldFlags,
+ constantValueLayout);
+ int[] field_constantValue_KQ = decodeBandInt("field_ConstantValue_KQ",
+ in, Codec.UNSIGNED5, constantCount);
int constantValueIndex = 0;
-
- AttributeLayout signatureLayout = attrMap.getAttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE,
+
+ AttributeLayout signatureLayout = attrMap.getAttributeLayout(
+ AttributeLayout.ATTRIBUTE_SIGNATURE,
AttributeLayout.CONTEXT_FIELD);
- int signatureCount = SegmentUtils.countMatches(fieldFlags, signatureLayout);
- int[] fieldSignatureRS = decodeBandInt("field_Signature_RS", in, Codec.UNSIGNED5, signatureCount);
+ int signatureCount = SegmentUtils.countMatches(fieldFlags,
+ signatureLayout);
+ int[] fieldSignatureRS = decodeBandInt("field_Signature_RS", in,
+ Codec.UNSIGNED5, signatureCount);
int signatureIndex = 0;
-
+
fieldAttributes = new ArrayList[classCount][];
for (int i = 0; i < classCount; i++) {
fieldAttributes[i] = new ArrayList[fieldFlags[i].length];
@@ -184,7 +183,8 @@
String desc = fieldDescr[i][j];
int colon = desc.indexOf(':');
String type = desc.substring(colon + 1);
- if (type.equals("B") || type.equals("S") || type.equals("C") || type.equals("Z"))
+ if (type.equals("B") || type.equals("S")
+ || type.equals("C") || type.equals("Z"))
type = "I";
Object value = constantValueLayout.getValue(result, type,
cpBands.getConstantPool());
@@ -198,15 +198,17 @@
String desc = fieldDescr[i][j];
int colon = desc.indexOf(':');
String type = desc.substring(colon + 1);
- Object value = signatureLayout.getValue(result, type, cpBands
- .getConstantPool());
+ CPUTF8 value = new CPUTF8((String) signatureLayout.getValue(result, type,
+ cpBands.getConstantPool()));
fieldAttributes[i][j]
- .add(new ConstantValueAttribute(value));
+ .add(new SignatureAttribute(value));
signatureIndex++;
}
}
}
- parseFieldMetadataBands();
+ parseFieldMetadataBands(in, fieldAttrCalls);
+
+ // TODO: Parse other attribute bands
}
private void parseMethodBands(InputStream in) throws IOException,
@@ -215,20 +217,17 @@
classMethodCount, cpBands.getCpDescriptor());
methodFlags = parseFlags("method_flags", in, classMethodCount,
Codec.UNSIGNED5, options.hasMethodFlagsHi());
-
+
int methodAttrCount = SegmentUtils.countBit16(methodFlags);
- int[] methodAttrCounts = decodeBandInt("method_attr_count", in, Codec.UNSIGNED5, methodAttrCount);
- int[][] methodAttrIndexes = decodeBandInt("method_attr_indexes", in, Codec.UNSIGNED5, methodAttrCounts);
- int callCount = 0;
- for (int i = 0; i < methodAttrIndexes.length; i++) {
- for (int j = 0; j < methodAttrIndexes[i].length; j++) {
- int index = methodAttrIndexes[i][j];
- AttributeLayout layout = attrMap.getAttributeLayout(index, AttributeLayout.CONTEXT_METHOD);
- callCount += layout.numBackwardsCallables();
- }
- }
- methodAttrCalls = decodeBandInt("code_attr_calls", in, Codec.UNSIGNED5, callCount);
-
+ int[] methodAttrCounts = decodeBandInt("method_attr_count", in,
+ Codec.UNSIGNED5, methodAttrCount);
+ int[][] methodAttrIndexes = decodeBandInt("method_attr_indexes", in,
+ Codec.UNSIGNED5, methodAttrCounts);
+ int callCount = getCallCount(methodAttrIndexes, methodFlags,
+ AttributeLayout.CONTEXT_METHOD);
+ methodAttrCalls = decodeBandInt("code_attr_calls", in, Codec.UNSIGNED5,
+ callCount);
+
// assign empty method attributes
methodAttributes = new ArrayList[classCount][];
for (int i = 0; i < classCount; i++) {
@@ -239,14 +238,45 @@
}
parseAttributeMethodExceptions(in);
parseAttributeMethodSigntaure(in);
- parseMethodMetadataBands();
+ parseMethodMetadataBands(in, methodAttrCalls);
+
+ // TODO: Parse other attribute bands
}
- private void parseAttributeMethodSigntaure(InputStream in) throws IOException, Pack200Exception {
- AttributeLayout layout = attrMap.getAttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE,
+ private int getCallCount(int[][] methodAttrIndexes, long[][] flags,
+ int context) throws Pack200Exception {
+ int callCount = 0;
+ for (int i = 0; i < methodAttrIndexes.length; i++) {
+ for (int j = 0; j < methodAttrIndexes[i].length; j++) {
+ int index = methodAttrIndexes[i][j];
+ AttributeLayout layout = attrMap.getAttributeLayout(index,
+ context);
+ callCount += layout.numBackwardsCallables();
+ }
+ }
+ int layoutsUsed = 0;
+ for (int i = 0; i < flags.length; i++) {
+ for (int j = 0; j < flags[i].length; j++) {
+ layoutsUsed |= flags[i][j];
+ }
+ }
+ for (int i = 0; i < 26; i++) {
+ if ((layoutsUsed & 1 << i) != 0) {
+ AttributeLayout layout = attrMap.getAttributeLayout(i, context);
+ callCount += layout.numBackwardsCallables();
+ }
+ }
+ return callCount;
+ }
+
+ private void parseAttributeMethodSigntaure(InputStream in)
+ throws IOException, Pack200Exception {
+ AttributeLayout layout = attrMap.getAttributeLayout(
+ AttributeLayout.ATTRIBUTE_SIGNATURE,
AttributeLayout.CONTEXT_METHOD);
int count = SegmentUtils.countMatches(methodFlags, layout);
- long[] methodSignatureRS = decodeBandLong("method_signature_RS", in, Codec.UNSIGNED5, count);
+ long[] methodSignatureRS = decodeBandLong("method_signature_RS", in,
+ Codec.UNSIGNED5, count);
int index = 0;
for (int i = 0; i < methodAttributes.length; i++) {
for (int j = 0; j < methodAttributes[i].length; j++) {
@@ -267,7 +297,7 @@
.add(new ConstantValueAttribute(value));
index++;
}
- }
+ }
}
}
@@ -281,21 +311,24 @@
AttributeLayout layout = attrMap.getAttributeLayout("Exceptions",
AttributeLayout.CONTEXT_METHOD);
int count = SegmentUtils.countMatches(methodFlags, layout);
- int[] numExceptions = decodeBandInt("method_Exceptions_n", in, Codec.UNSIGNED5, count);
- String[][] methodExceptionsRS = parseReferences("method_Exceptions_RC", in, Codec.UNSIGNED5, numExceptions, cpBands.getCpClass());
+ int[] numExceptions = decodeBandInt("method_Exceptions_n", in,
+ Codec.UNSIGNED5, count);
+ String[][] methodExceptionsRS = parseReferences("method_Exceptions_RC",
+ in, Codec.UNSIGNED5, numExceptions, cpBands.getCpClass());
int index = 0;
for (int i = 0; i < classCount; i++) {
for (int j = 0; j < methodFlags[i].length; j++) {
long flag = methodFlags[i][j];
- if(layout.matches(flag)) {
+ if (layout.matches(flag)) {
int n = numExceptions[index];
String[] exceptions = methodExceptionsRS[index];
CPClass[] exceptionClasses = new CPClass[n];
for (int k = 0; k < n; k++) {
exceptionClasses[k] = new CPClass(exceptions[k]);
}
- methodAttributes[i][j].add(new ExceptionsAttribute(exceptionClasses));
- index ++;
+ methodAttributes[i][j].add(new ExceptionsAttribute(
+ exceptionClasses));
+ index++;
}
}
}
@@ -305,22 +338,25 @@
Pack200Exception {
String[] cpUTF8 = cpBands.getCpUTF8();
String[] cpClass = cpBands.getCpClass();
+
+ // Prepare empty attribute lists
+ classAttributes = new ArrayList[classCount];
+ for (int i = 0; i < classCount; i++) {
+ classAttributes[i] = new ArrayList();
+ }
classFlags = parseFlags("class_flags", in, classCount, Codec.UNSIGNED5,
options.hasClassFlagsHi());
int classAttrCount = SegmentUtils.countBit16(classFlags);
- int[] classAttrCounts = decodeBandInt("class_attr_count", in, Codec.UNSIGNED5, classAttrCount);
- int[][] classAttrIndexes = decodeBandInt("class_attr_indexes", in, Codec.UNSIGNED5, classAttrCounts);
- int callCount = 0;
- for (int i = 0; i < classAttrIndexes.length; i++) {
- for (int j = 0; j < classAttrIndexes[i].length; j++) {
- int index = classAttrIndexes[i][j];
- AttributeLayout layout = attrMap.getAttributeLayout(index, AttributeLayout.CONTEXT_CLASS);
- callCount += layout.numBackwardsCallables();
- }
- }
- int[] classAttrCalls = decodeBandInt("class_attr_calls", in, Codec.UNSIGNED5, callCount);
-
+ int[] classAttrCounts = decodeBandInt("class_attr_count", in,
+ Codec.UNSIGNED5, classAttrCount);
+ int[][] classAttrIndexes = decodeBandInt("class_attr_indexes", in,
+ Codec.UNSIGNED5, classAttrCounts);
+ int callCount = getCallCount(classAttrIndexes, new long[][] {classFlags},
+ AttributeLayout.CONTEXT_CLASS);
+ int[] classAttrCalls = decodeBandInt("class_attr_calls", in,
+ Codec.UNSIGNED5, callCount);
+
AttributeLayout sourceFileLayout = attrMap.getAttributeLayout(
AttributeLayout.ATTRIBUTE_SOURCE_FILE,
AttributeLayout.CONTEXT_CLASS);
@@ -335,20 +371,20 @@
int enclosingMethodCount = SegmentUtils.countMatches(classFlags,
enclosingMethodLayout);
int[] enclosingMethodRC = decodeBandInt("class_EnclosingMethod_RC", in,
- Codec.UNSIGNED5, enclosingMethodCount);
- int[] enclosingMethodRDN = decodeBandInt("class_EnclosingMethod_RDN", in,
Codec.UNSIGNED5, enclosingMethodCount);
-
+ int[] enclosingMethodRDN = decodeBandInt("class_EnclosingMethod_RDN",
+ in, Codec.UNSIGNED5, enclosingMethodCount);
+
AttributeLayout signatureLayout = attrMap.getAttributeLayout(
AttributeLayout.ATTRIBUTE_SIGNATURE,
AttributeLayout.CONTEXT_CLASS);
int signatureCount = SegmentUtils.countMatches(classFlags,
signatureLayout);
int[] classSignature = decodeBandInt("class_Signature_RS", in,
- Codec.UNSIGNED5, signatureCount);
+ Codec.UNSIGNED5, signatureCount);
+
+ parseClassMetadataBands(in, classAttrCalls);
- parseClassMetadataBands();
-
AttributeLayout innerClassLayout = attrMap.getAttributeLayout(
AttributeLayout.ATTRIBUTE_INNER_CLASSES,
AttributeLayout.CONTEXT_CLASS);
@@ -356,20 +392,23 @@
innerClassLayout);
int[] classInnerClassesN = decodeBandInt("class_InnerClasses_N", in,
Codec.UNSIGNED5, innerClassCount);
- int[][] classInnerClassesRC = decodeBandInt("class_InnerClasses_RC", in, Codec.UNSIGNED5, classInnerClassesN);
- int[][] classInnerClassesF = decodeBandInt("class_InnerClasses_F", in, Codec.UNSIGNED5, classInnerClassesN);
+ int[][] classInnerClassesRC = decodeBandInt("class_InnerClasses_RC",
+ in, Codec.UNSIGNED5, classInnerClassesN);
+ int[][] classInnerClassesF = decodeBandInt("class_InnerClasses_F", in,
+ Codec.UNSIGNED5, classInnerClassesN);
int flagsCount = 0;
for (int i = 0; i < classInnerClassesF.length; i++) {
for (int j = 0; j < classInnerClassesF[i].length; j++) {
- if(classInnerClassesF[i][j] != 0) {
+ if (classInnerClassesF[i][j] != 0) {
flagsCount++;
}
}
}
- int[] classInnerClassesOuterRCN = decodeBandInt("class_InnerClasses_outer_RCN", in, Codec.UNSIGNED5, flagsCount);
- int[] classInnerClassesNameRUN = decodeBandInt("class_InnerClasses_name_RUN", in, Codec.UNSIGNED5, flagsCount);
-
-
+ int[] classInnerClassesOuterRCN = decodeBandInt(
+ "class_InnerClasses_outer_RCN", in, Codec.UNSIGNED5, flagsCount);
+ int[] classInnerClassesNameRUN = decodeBandInt(
+ "class_InnerClasses_name_RUN", in, Codec.UNSIGNED5, flagsCount);
+
AttributeLayout versionLayout = attrMap.getAttributeLayout(
AttributeLayout.ATTRIBUTE_CLASS_FILE_VERSION,
AttributeLayout.CONTEXT_CLASS);
@@ -378,13 +417,15 @@
"class_file_version_minor_H", in, Codec.UNSIGNED5, versionCount);
int[] classFileVersionMajorH = decodeBandInt(
"class_file_version_major_H", in, Codec.UNSIGNED5, versionCount);
- if(versionCount > 0) {
+ if (versionCount > 0) {
classVersionMajor = new int[classCount];
classVersionMinor = new int[classCount];
}
int defaultVersionMajor = header.getDefaultClassMajorVersion();
int defaultVersionMinor = header.getDefaultClassMinorVersion();
-
+
+ // TODO: Parse other attribute bands
+
// Now process the attribute bands we have parsed
int sourceFileIndex = 0;
int enclosingMethodIndex = 0;
@@ -392,31 +433,31 @@
int innerClassIndex = 0;
int innerClassC2NIndex = 0;
int versionIndex = 0;
- classAttributes = new ArrayList[classCount];
icLocal = new IcBands.ICTuple[classCount][];
for (int i = 0; i < classCount; i++) {
- classAttributes[i] = new ArrayList();
long flag = classFlags[i];
-
+
if (sourceFileLayout.matches(flag)) {
long result = classSourceFile[sourceFileIndex];
- String value = (String) sourceFileLayout.getValue(result, cpBands
- .getConstantPool());
- if(value == null) {
+ String value = (String) sourceFileLayout.getValue(result,
+ cpBands.getConstantPool());
+ if (value == null) {
// Remove package prefix
- String className = classThis[i].substring(classThis[i].lastIndexOf('/') + 1);
- className = className.substring(className.lastIndexOf('.') + 1);
-
+ String className = classThis[i].substring(classThis[i]
+ .lastIndexOf('/') + 1);
+ className = className
+ .substring(className.lastIndexOf('.') + 1);
+
// Remove mangled nested class names
char[] chars = className.toCharArray();
int index = -1;
for (int j = 0; j < chars.length; j++) {
- if(chars[j] <= 0x2D) {
+ if (chars[j] <= 0x2D) {
index = j;
break;
- }
+ }
}
- if(index > -1) {
+ if (index > -1) {
className = className.substring(0, index);
}
// Add .java to the end
@@ -425,17 +466,17 @@
classAttributes[i].add(new SourceFileAttribute(value));
sourceFileIndex++;
}
- if(enclosingMethodLayout.matches(flag)) {
-// long result =
+ if (enclosingMethodLayout.matches(flag)) {
+ // long result =
}
- if(signatureLayout.matches(flag)) {
+ if (signatureLayout.matches(flag)) {
long result = classSignature[signatureIndex];
Object value = signatureLayout.getValue(result, cpBands
.getConstantPool());
classAttributes[i].add(new ConstantValueAttribute(value));
signatureIndex++;
}
- if(innerClassLayout.matches(flag)) {
+ if (innerClassLayout.matches(flag)) {
// Just create the tuples for now because the attributes are
// decided at the end when creating class constant pools
icLocal[i] = new IcBands.ICTuple[classInnerClassesN[innerClassIndex]];
@@ -443,7 +484,7 @@
IcBands.ICTuple icTuple = new IcBands.ICTuple();
icTuple.C = cpClass[classInnerClassesRC[innerClassIndex][j]];
icTuple.F = classInnerClassesF[innerClassIndex][j];
- if(icTuple.F != 0) {
+ if (icTuple.F != 0) {
icTuple.C2 = cpClass[classInnerClassesOuterRCN[innerClassC2NIndex]];
icTuple.N = cpUTF8[classInnerClassesNameRUN[innerClassC2NIndex]];
innerClassC2NIndex++;
@@ -452,7 +493,7 @@
IcBands icBands = segment.getIcBands();
ICTuple[] icAll = icBands.getIcTuples();
for (int k = 0; k < icAll.length; k++) {
- if(icAll[k].C.equals(icTuple.C)) {
+ if (icAll[k].C.equals(icTuple.C)) {
icTuple.C2 = icAll[k].C2;
icTuple.N = icAll[k].N;
break;
@@ -461,13 +502,13 @@
}
icLocal[i][j] = icTuple;
}
- innerClassIndex++;
+ innerClassIndex++;
}
- if(versionLayout.matches(flag)) {
+ if (versionLayout.matches(flag)) {
classVersionMajor[i] = classFileVersionMajorH[versionIndex];
classVersionMinor[i] = classFileVersionMinorH[versionIndex];
versionIndex++;
- } else if(classVersionMajor != null) {
+ } else if (classVersionMajor != null) {
// Fill in with defaults
classVersionMajor[i] = defaultVersionMajor;
classVersionMinor[i] = defaultVersionMinor;
@@ -475,7 +516,6 @@
}
}
-
private void parseCodeBands(InputStream in) throws Pack200Exception,
IOException {
AttributeLayout layout = attrMap.getAttributeLayout(
@@ -527,56 +567,174 @@
}
int sumCodeHandlerCount = 0;
for (int i = 0; i < codeHandlerCount.length; i++) {
- sumCodeHandlerCount+= codeHandlerCount[i];
+ sumCodeHandlerCount += codeHandlerCount[i];
+ }
+ int[] codeHandlerStartP = decodeBandInt("code_handler_start_P", in,
+ Codec.BCI5, sumCodeHandlerCount);
+ int[] codeHandlerEndPO = decodeBandInt("code_handler_end_PO", in,
+ Codec.BRANCH5, sumCodeHandlerCount);
+ int[] codeHandlerCatchPO = decodeBandInt("code_handler_catch_PO", in,
+ Codec.BRANCH5, sumCodeHandlerCount);
+ int[] codeHandlerClassRCN = decodeBandInt("code_handler_class_RCN", in,
+ Codec.UNSIGNED5, sumCodeHandlerCount);
+
+ int codeFlagsCount = segment.getSegmentHeader().getOptions()
+ .hasAllCodeFlags() ? codeCount : codeSpecialHeader;
+
+ codeAttributes = new ArrayList[codeFlagsCount];
+ for (int i = 0; i < codeAttributes.length; i++) {
+ codeAttributes[i] = new ArrayList();
}
- int[] codeHandlerStartP = decodeBandInt("code_handler_start_P", in, Codec.BCI5, sumCodeHandlerCount);
- int[] codeHandlerEndPO = decodeBandInt("code_handler_end_PO", in, Codec.BRANCH5, sumCodeHandlerCount);
- int[] codeHandlerCatchPO = decodeBandInt("code_handler_catch_PO", in, Codec.BRANCH5, sumCodeHandlerCount);
- int[] codeHandlerClassRCN = decodeBandInt("code_handler_class_RCN", in, Codec.UNSIGNED5, sumCodeHandlerCount);
-
- int codeFlagsCount = segment.getSegmentHeader().getOptions().hasAllCodeFlags() ?
- codeCount : codeSpecialHeader;
parseCodeAttrBands(in, codeFlagsCount);
}
- private void parseCodeAttrBands(InputStream in, int codeFlagsCount) throws IOException, Pack200Exception {
- long[] codeFlags = parseFlags("code_flags", in, codeFlagsCount, Codec.UNSIGNED5, segment.getSegmentHeader().getOptions().hasCodeFlagsHi());
+ private void parseCodeAttrBands(InputStream in, int codeFlagsCount)
+ throws IOException, Pack200Exception {
+ long[] codeFlags = parseFlags("code_flags", in, codeFlagsCount,
+ Codec.UNSIGNED5, segment.getSegmentHeader().getOptions()
+ .hasCodeFlagsHi());
int codeAttrCount = SegmentUtils.countBit16(codeFlags);
- int[] codeAttrCounts = decodeBandInt("code_attr_count", in, Codec.UNSIGNED5, codeAttrCount);
- int[][] codeAttrIndexes = decodeBandInt("code_attr_indexes", in, Codec.UNSIGNED5, codeAttrCounts);
+ int[] codeAttrCounts = decodeBandInt("code_attr_count", in,
+ Codec.UNSIGNED5, codeAttrCount);
+ int[][] codeAttrIndexes = decodeBandInt("code_attr_indexes", in,
+ Codec.UNSIGNED5, codeAttrCounts);
int callCount = 0;
for (int i = 0; i < codeAttrIndexes.length; i++) {
for (int j = 0; j < codeAttrIndexes[i].length; j++) {
int index = codeAttrIndexes[i][j];
- AttributeLayout layout = attrMap.getAttributeLayout(index, AttributeLayout.CONTEXT_CODE);
+ AttributeLayout layout = attrMap.getAttributeLayout(index,
+ AttributeLayout.CONTEXT_CODE);
callCount += layout.numBackwardsCallables();
}
}
- int[] codeAttrCalls = decodeBandInt("code_attr_calls", in, Codec.UNSIGNED5, callCount);
-
- int lineNumberTableCount = SegmentUtils.countMatches(codeFlags, attrMap.getAttributeLayout(AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE, AttributeLayout.CONTEXT_CODE));
- int[] lineNumberTableN = decodeBandInt("code_LineNumberTable_N", in, Codec.UNSIGNED5, lineNumberTableCount);
- int[][] lineNumberTableBciP = decodeBandInt("code_LineNumberTable_bci_P", in, Codec.BCI5, lineNumberTableN);
- int[][] lineNumberTableLine = decodeBandInt("code_LineNumberTable_line", in, Codec.UNSIGNED5, lineNumberTableN);
- String[] types = { AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE, AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE };
- for (int i = 0; i < types.length; i++) {
- String type = types[i];
- int lengthNBand = SegmentUtils.countMatches(codeFlags, attrMap.getAttributeLayout(type, AttributeLayout.CONTEXT_CODE));
-
- int[] nBand = decodeBandInt("code_" + type + "_N", in, Codec.UNSIGNED5, lengthNBand);
- int[][] bciP = decodeBandInt("code_" + type + "_bci_P", in, Codec.BCI5, nBand);
- int[][] spanO = decodeBandInt("code_" + type + "_span_O", in, Codec.BRANCH5, nBand);
- String[][] nameRU = parseReferences("code_" + type + "_name_RU", in, Codec.UNSIGNED5, nBand, cpBands.getCpUTF8());
- String[][] typeRS = parseReferences("code_" + type + "_type_RS", in, Codec.UNSIGNED5, nBand, cpBands.getCpSignature());
- int[][] slot = decodeBandInt("code_" + type + "_slot", in, Codec.UNSIGNED5, nBand);
+ int[] codeAttrCalls = decodeBandInt("code_attr_calls", in,
+ Codec.UNSIGNED5, callCount);
+
+ AttributeLayout lineNumberTableLayout = attrMap.getAttributeLayout(
+ AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE,
+ AttributeLayout.CONTEXT_CODE);
+ int lineNumberTableCount = SegmentUtils.countMatches(codeFlags,
+ lineNumberTableLayout);
+ int[] lineNumberTableN = decodeBandInt("code_LineNumberTable_N", in,
+ Codec.UNSIGNED5, lineNumberTableCount);
+ int[][] lineNumberTableBciP = decodeBandInt(
+ "code_LineNumberTable_bci_P", in, Codec.BCI5, lineNumberTableN);
+ int[][] lineNumberTableLine = decodeBandInt(
+ "code_LineNumberTable_line", in, Codec.UNSIGNED5,
+ lineNumberTableN);
+
+ AttributeLayout localVariableTableLayout = attrMap.getAttributeLayout(
+ AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE,
+ AttributeLayout.CONTEXT_CODE);
+ AttributeLayout localVariableTypeTableLayout = attrMap
+ .getAttributeLayout(
+ AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE,
+ AttributeLayout.CONTEXT_CODE);
+
+ int lengthLocalVariableNBand = SegmentUtils.countMatches(codeFlags,
+ localVariableTableLayout);
+ int[] localVariableTableN = decodeBandInt("code_LocalVariableTable_N",
+ in, Codec.UNSIGNED5, lengthLocalVariableNBand);
+ int[][] localVariableTableBciP = decodeBandInt(
+ "code_LocalVariableTable_bci_P", in, Codec.BCI5,
+ localVariableTableN);
+ int[][] localVariableTableSpanO = decodeBandInt(
+ "code_LocalVariableTable_span_O", in, Codec.BRANCH5,
+ localVariableTableN);
+ CPUTF8[][] localVariableTableNameRU = stringsToCPUTF8(parseReferences(
+ "code_LocalVariableTable_name_RU", in, Codec.UNSIGNED5,
+ localVariableTableN, cpBands.getCpUTF8()));
+ CPUTF8[][] localVariableTableTypeRS = stringsToCPUTF8(parseReferences(
+ "code_LocalVariableTable_type_RS", in, Codec.UNSIGNED5,
+ localVariableTableN, cpBands.getCpSignature()));
+ int[][] localVariableTableSlot = decodeBandInt(
+ "code_LocalVariableTable_slot", in, Codec.UNSIGNED5,
+ localVariableTableN);
+
+ int lengthLocalVariableTypeTableNBand = SegmentUtils.countMatches(
+ codeFlags, localVariableTypeTableLayout);
+ int[] localVariableTypeTableN = decodeBandInt(
+ "code_LocalVariableTypeTable_N", in, Codec.UNSIGNED5,
+ lengthLocalVariableTypeTableNBand);
+ int[][] localVariableTypeTableBciP = decodeBandInt(
+ "code_LocalVariableTypeTable_bci_P", in, Codec.BCI5,
+ localVariableTypeTableN);
+ int[][] localVariableTypeTableSpanO = decodeBandInt(
+ "code_LocalVariableTypeTable_span_O", in, Codec.BRANCH5,
+ localVariableTypeTableN);
+ CPUTF8[][] localVariableTypeTableNameRU = stringsToCPUTF8(parseReferences(
+ "code_LocalVariableTypeTable_name_RU", in, Codec.UNSIGNED5,
+ localVariableTypeTableN, cpBands.getCpUTF8()));
+ CPUTF8[][] localVariableTypeTableTypeRS = stringsToCPUTF8(parseReferences(
+ "code_LocalVariableTypeTable_type_RS", in, Codec.UNSIGNED5,
+ localVariableTypeTableN, cpBands.getCpSignature()));
+ int[][] localVariableTypeTableSlot = decodeBandInt(
+ "code_LocalVariableTypeTable_slot", in, Codec.UNSIGNED5,
+ localVariableTypeTableN);
+
+ int lineNumberIndex = 0;
+ int lvtIndex = 0;
+ int lvttIndex = 0;
+ for (int i = 0; i < codeFlagsCount; i++) {
+ if (lineNumberTableLayout.matches(codeFlags[i])) {
+ LineNumberTableAttribute lnta = new LineNumberTableAttribute(
+ lineNumberTableN[lineNumberIndex],
+ lineNumberTableBciP[lineNumberIndex],
+ lineNumberTableLine[lineNumberIndex]);
+ lineNumberIndex++;
+ codeAttributes[i].add(lnta);
+ }
+ if (localVariableTableLayout.matches(codeFlags[i])) {
+ LocalVariableTableAttribute lvta = new LocalVariableTableAttribute(
+ localVariableTableN[lvtIndex],
+ localVariableTableBciP[lvtIndex],
+ localVariableTableSpanO[lvtIndex],
+ localVariableTableNameRU[lvtIndex],
+ localVariableTableTypeRS[lvtIndex],
+ localVariableTableSlot[lvtIndex]);
+ lvtIndex++;
+ codeAttributes[i].add(lvta);
+ }
+ if (localVariableTypeTableLayout.matches(codeFlags[i])) {
+ LocalVariableTypeTableAttribute lvtta = new LocalVariableTypeTableAttribute(
+ localVariableTypeTableN[lvttIndex],
+ localVariableTypeTableBciP[lvttIndex],
+ localVariableTypeTableSpanO[lvttIndex],
+ localVariableTypeTableNameRU[lvttIndex],
+ localVariableTypeTableTypeRS[lvttIndex],
+ localVariableTypeTableSlot[lvttIndex]);
+ lvttIndex++;
+ codeAttributes[i].add(lvtta);
+ }
+ }
+ // TODO: Parse other attribute bands
+ }
+
+ 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].length];
+ for (int j = 0; j < strings[i].length; j++) {
+ cpUTF8s[i][j] = new CPUTF8(strings[i][j]);
+ }
}
+ return cpUTF8s;
}
+
+ 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]);
+ }
+ return cpUTF8s;
+ }
- private void parseFieldMetadataBands() throws Pack200Exception {
+ private void parseFieldMetadataBands(InputStream in, int[] fieldAttrCalls)
+ throws Pack200Exception, IOException {
String[] RxA = new String[] { "RVA", "RIA" };
-
+
AttributeLayout rvaLayout = attrMap.getAttributeLayout(
AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
AttributeLayout.CONTEXT_FIELD);
@@ -586,45 +744,143 @@
int rvaCount = SegmentUtils.countMatches(fieldFlags, rvaLayout);
int riaCount = SegmentUtils.countMatches(fieldFlags, riaLayout);
- if (rvaCount > 0 || riaCount > 0) {
- throw new Error("Field metadata not handled");
+ int[] RxACount = new int[] { rvaCount, riaCount };
+ int[] backwardsCalls = new int[] {0, 0};
+ if(rvaCount > 0) {
+ backwardsCalls[0] = fieldAttrCalls[0];
+ if(riaCount > 0) {
+ backwardsCalls[1] = fieldAttrCalls[1];
+ }
+ } else if (riaCount > 0) {
+ backwardsCalls[1] = fieldAttrCalls[0];
+ }
+ MetadataBandGroup[] mb = parseMetadata(in, RxA, RxACount, backwardsCalls, "field");
+ Iterator rvaAttributesIterator = mb[0].getAttributes().iterator();
+ Iterator riaAttributesIterator = mb[1].getAttributes().iterator();
+ for (int i = 0; i < fieldFlags.length; i++) {
+ for (int j = 0; j < fieldFlags[i].length; j++) {
+ if(rvaLayout.matches(fieldFlags[i][j])) {
+ fieldAttributes[i][j].add(rvaAttributesIterator.next());
+ }
+ if(riaLayout.matches(fieldFlags[i][j])) {
+ fieldAttributes[i][j].add(riaAttributesIterator.next());
+ }
+ }
}
+ }
- // AttributeLayout layout =
- // map.get(RuntimeVisibleAnnotations,class/field/method as int)
- // foreachheader ...
- // if layout.matches(header[n] or whatever)
- String contextName = "field";
+ private MetadataBandGroup[] parseMetadata(InputStream in, String[] RxA, int[] RxACount,
+ int[] backwardsCallCounts, String contextName) throws IOException, Pack200Exception {
+ MetadataBandGroup[] mbg = new MetadataBandGroup[RxA.length];
for (int i = 0; i < RxA.length; i++) {
+ mbg[i] = new MetadataBandGroup(RxA[i]);
String rxa = RxA[i];
if (rxa.indexOf("P") >= 0) {
- debug("unimplemented " + contextName + "_" + rxa + "_param_NB");
+ mbg[i].param_NB = decodeBandInt(contextName + "_" + rxa
+ + "_param_NB", in, Codec.BYTE1, RxACount[i]);
}
+ int pairCount = 0;
if (!rxa.equals("AD")) {
- debug("unimplemented " + contextName + "_" + rxa + "_anno_N");
- debug("unimplemented " + contextName + "_" + rxa + "_type_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_pair_N");
- debug("unimplemented " + contextName + "_" + rxa + "_name_RU");
- }
- debug("unimplemented " + contextName + "_" + rxa + "_T");
- debug("unimplemented " + contextName + "_" + rxa + "_caseI_KI");
- debug("unimplemented " + contextName + "_" + rxa + "_caseD_KD");
- debug("unimplemented " + contextName + "_" + rxa + "_caseF_KF");
- debug("unimplemented " + contextName + "_" + rxa + "_caseJ_KJ");
- debug("unimplemented " + contextName + "_" + rxa + "_casec_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_caseet_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_caseec_RU");
- debug("unimplemented " + contextName + "_" + rxa + "_cases_RU");
- debug("unimplemented " + contextName + "_" + rxa + "_casearray_N");
- debug("unimplemented " + contextName + "_" + rxa + "_nesttype_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_nestpair_N");
- debug("unimplemented " + contextName + "_" + rxa + "_nestname_RU");
+ mbg[i].anno_N = decodeBandInt(contextName + "_" + rxa
+ + "_anno_N", in, Codec.UNSIGNED5, RxACount[i]);
+ mbg[i].type_RS = stringsToCPUTF8(parseReferences(contextName + "_" + rxa
+ + "_type_RS", in, Codec.UNSIGNED5, mbg[i].anno_N, cpBands.getCpSignature()));
+ mbg[i].pair_N = decodeBandInt(contextName + "_" + rxa
+ + "_pair_N", in, Codec.UNSIGNED5, mbg[i].anno_N);
+ for (int j = 0; j < mbg[i].pair_N.length; j++) {
+ for (int k = 0; k < mbg[i].pair_N[j].length; k++) {
+ pairCount += mbg[i].pair_N[j][k];
+ }
+ }
+
+ mbg[i].name_RU = stringsToCPUTF8(parseReferences(contextName + "_" + rxa
+ + "_name_RU", in, Codec.UNSIGNED5, pairCount, cpBands.getCpUTF8()));
+ }
+ mbg[i].T = decodeBandInt(contextName + "_" + rxa + "_T", in,
+ Codec.BYTE1, pairCount + backwardsCallCounts[i]);
+ int ICount = 0, DCount = 0, FCount = 0, JCount = 0, cCount = 0, eCount = 0, sCount = 0, arrayCount = 0, atCount = 0;
+ for (int j = 0; j < mbg[i].T.length; j++) {
+ char c = (char) mbg[i].T[j];
+ switch (c) {
+ case 'B':
+ case 'C':
+ case 'I':
+ case 'S':
+ case 'Z':
+ ICount++;
+ break;
+ case 'D':
+ DCount++;
+ break;
+ case 'F':
+ FCount++;
+ break;
+ case 'J':
+ JCount++;
+ break;
+ case 'c':
+ cCount++;
+ break;
+ case 'e':
+ eCount++;
+ break;
+ case 's':
+ sCount++;
+ break;
+ case '[':
+ arrayCount++;
+ break;
+ case '@':
+ atCount++;
+ break;
+ }
+ }
+ mbg[i].caseI_KI = parseCPIntReferences(contextName + "_" + rxa
+ + "_caseI_KI", in, Codec.UNSIGNED5, ICount);
+ mbg[i].caseD_KD = parseCPDoubleReferences(contextName + "_" + rxa
+ + "_caseD_KD", in, Codec.UNSIGNED5, DCount);
+ mbg[i].caseF_KF = parseCPFloatReferences(contextName + "_" + rxa
+ + "_caseF_KF", in, Codec.UNSIGNED5, FCount);
+ mbg[i].caseJ_KJ = parseCPLongReferences(contextName + "_" + rxa
+ + "_caseJ_KJ", in, Codec.UNSIGNED5, JCount);
+ mbg[i].casec_RS = parseCPUTF8References(contextName + "_" + rxa
+ + "_casec_RS", in, Codec.UNSIGNED5, cCount);
+ mbg[i].caseet_RS = parseReferences(contextName + "_" + rxa
+ + "_caseet_RS", in, Codec.UNSIGNED5, eCount, cpBands.getCpSignature());
+ mbg[i].caseec_RU = parseReferences(contextName + "_" + rxa
+ + "_caseec_RU", in, Codec.UNSIGNED5, eCount, cpBands.getCpUTF8());
+ mbg[i].cases_RU = parseCPUTF8References(contextName + "_" + rxa
+ + "_cases_RU", in, Codec.UNSIGNED5, sCount);
+ mbg[i].casearray_N = decodeBandInt(contextName + "_" + rxa
+ + "_casearray_N", in, Codec.UNSIGNED5, arrayCount);
+ mbg[i].nesttype_RS = parseCPUTF8References(contextName + "_" + rxa
+ + "_nesttype_RS", in, Codec.UNSIGNED5, atCount);
+ mbg[i].nestpair_N = decodeBandInt(contextName + "_" + rxa
+ + "_nestpair_N", in, Codec.UNSIGNED5, atCount);
+ int nestPairCount = 0;
+ for (int j = 0; j < mbg[i].nestpair_N.length; j++) {
+ nestPairCount += mbg[i].nestpair_N[j];
+ }
+ mbg[i].nestname_RU = parseCPUTF8References(contextName + "_" + rxa
+ + "_nestname_RU", in, Codec.UNSIGNED5, nestPairCount);
}
+ return mbg;
}
- private void parseMethodMetadataBands() throws Pack200Exception {
+ private void parseMethodMetadataBands(InputStream in, int[] methodAttrCalls)
+ throws Pack200Exception, IOException {
String[] RxA = new String[] { "RVA", "RIA", "RVPA", "RIPA", "AD" };
int[] rxaCounts = new int[] { 0, 0, 0, 0, 0 };
+ int[] backwardsCalls = new int[5];
+ int methodAttrIndex = 0;
+ for (int i = 0; i < backwardsCalls.length; i++) {
+ if(rxaCounts[i] > 0) {
+ backwardsCalls[i] = methodAttrCalls[methodAttrIndex];
+ methodAttrIndex++;
+ } else {
+ backwardsCalls[i] = 0;
+ }
+ }
AttributeLayout rvaLayout = attrMap.getAttributeLayout(
AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
AttributeLayout.CONTEXT_METHOD);
@@ -646,45 +902,26 @@
riaLayout, rvpaLayout, ripaLayout, adLayout };
for (int i = 0; i < rxaLayouts.length; i++) {
- rxaCounts[i] = SegmentUtils.countMatches(methodFlags, rxaLayouts[i]);
- if (rxaCounts[i] > 0) {
- throw new Error("Found method metadata");
- }
+ rxaCounts[i] = SegmentUtils
+ .countMatches(methodFlags, rxaLayouts[i]);
}
-
- // AttributeLayout layout =
- // map.get(RuntimeVisibleAnnotations,class/field/method as int)
- // foreachheader ...
- // if layout.matches(header[n] or whatever)
- String contextName = "method";
- for (int i = 0; i < RxA.length; i++) {
- String rxa = RxA[i];
- if (rxa.indexOf("P") >= 0) {
- debug("unimplemented " + contextName + "_" + rxa + "_param_NB");
+ MetadataBandGroup[] mbgs = parseMetadata(in, RxA, rxaCounts, backwardsCalls, "method");
+ Iterator[] attributeIterators = new Iterator[RxA.length];
+ for (int i = 0; i < mbgs.length; i++) {
+ attributeIterators[i] = mbgs[i].getAttributes().iterator();
+ }
+ for (int i = 0; i < methodFlags.length; i++) {
+ for (int j = 0; j < methodFlags[i].length; j++) {
+ for (int k = 0; k < rxaLayouts.length; k++) {
+ if(rxaLayouts[k].matches(methodFlags[i][j])) {
+ methodAttributes[i][j].add(attributeIterators[k].next());
+ }
+ }
}
- if (!rxa.equals("AD")) {
- debug("unimplemented " + contextName + "_" + rxa + "_anno_N");
- debug("unimplemented " + contextName + "_" + rxa + "_type_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_pair_N");
- debug("unimplemented " + contextName + "_" + rxa + "_name_RU");
- }
- debug("unimplemented " + contextName + "_" + rxa + "_T");
- debug("unimplemented " + contextName + "_" + rxa + "_caseI_KI");
- debug("unimplemented " + contextName + "_" + rxa + "_caseD_KD");
- debug("unimplemented " + contextName + "_" + rxa + "_caseF_KF");
- debug("unimplemented " + contextName + "_" + rxa + "_caseJ_KJ");
- debug("unimplemented " + contextName + "_" + rxa + "_casec_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_caseet_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_caseec_RU");
- debug("unimplemented " + contextName + "_" + rxa + "_cases_RU");
- debug("unimplemented " + contextName + "_" + rxa + "_casearray_N");
- debug("unimplemented " + contextName + "_" + rxa + "_nesttype_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_nestpair_N");
- debug("unimplemented " + contextName + "_" + rxa + "_nestname_RU");
}
}
- private void parseClassMetadataBands() throws Pack200Exception {
+ private void parseClassMetadataBands(InputStream in, int[] classAttrCalls) throws Pack200Exception, IOException {
String[] RxA = new String[] { "RVA", "RIA" };
AttributeLayout rvaLayout = attrMap.getAttributeLayout(
@@ -695,38 +932,26 @@
AttributeLayout.CONTEXT_CLASS);
int rvaCount = SegmentUtils.countMatches(classFlags, rvaLayout);
int riaCount = SegmentUtils.countMatches(classFlags, riaLayout);
- if (rvaCount > 0 || riaCount > 0) {
- throw new Error("Class metadata not handled");
- }
- // AttributeLayout layout =
- // map.get(RuntimeVisibleAnnotations,class/field/method as int)
- // foreachheader ...
- // if layout.matches(header[n] or whatever)
- String contextName = "class";
- for (int i = 0; i < RxA.length; i++) {
- String rxa = RxA[i];
- if (rxa.indexOf("P") >= 0) {
- debug("unimplemented " + contextName + "_" + rxa + "_param_NB");
+ int[] RxACount = new int[] { rvaCount, riaCount };
+ int[] backwardsCalls = new int[] {0, 0};
+ if(rvaCount > 0) {
+ backwardsCalls[0] = classAttrCalls[0];
+ if(riaCount > 0) {
+ backwardsCalls[1] = classAttrCalls[1];
+ }
+ } else if (riaCount > 0) {
+ backwardsCalls[1] = classAttrCalls[0];
+ }
+ MetadataBandGroup[] mbgs = parseMetadata(in, RxA, RxACount, backwardsCalls, "class");
+ Iterator rvaAttributesIterator = mbgs[0].getAttributes().iterator();
+ Iterator riaAttributesIterator = mbgs[1].getAttributes().iterator();
+ for (int i = 0; i < classFlags.length; i++) {
+ if(rvaLayout.matches(classFlags[i])) {
+ classAttributes[i].add(rvaAttributesIterator.next());
+ }
+ if(riaLayout.matches(classFlags[i])) {
+ classAttributes[i].add(riaAttributesIterator.next());
}
- if (!rxa.equals("AD")) {
- debug("unimplemented " + contextName + "_" + rxa + "_anno_N");
- debug("unimplemented " + contextName + "_" + rxa + "_type_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_pair_N");
- debug("unimplemented " + contextName + "_" + rxa + "_name_RU");
- }
- debug("unimplemented " + contextName + "_" + rxa + "_T");
- debug("unimplemented " + contextName + "_" + rxa + "_caseI_KI");
- debug("unimplemented " + contextName + "_" + rxa + "_caseD_KD");
- debug("unimplemented " + contextName + "_" + rxa + "_caseF_KF");
- debug("unimplemented " + contextName + "_" + rxa + "_caseJ_KJ");
- debug("unimplemented " + contextName + "_" + rxa + "_casec_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_caseet_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_caseec_RU");
- debug("unimplemented " + contextName + "_" + rxa + "_cases_RU");
- debug("unimplemented " + contextName + "_" + rxa + "_casearray_N");
- debug("unimplemented " + contextName + "_" + rxa + "_nesttype_RS");
- debug("unimplemented " + contextName + "_" + rxa + "_nestpair_N");
- debug("unimplemented " + contextName + "_" + rxa + "_nestname_RU");
}
}
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Tue Nov 20 06:42:33 2007
@@ -38,7 +38,7 @@
private String[] cpFieldClass;
- private Object cpFieldDescriptor;
+ private String[] cpFieldDescriptor;
private float[] cpFloat;
@@ -380,7 +380,7 @@
return cpFieldClass;
}
- public Object getCpFieldDescriptor() {
+ public String[] getCpFieldDescriptor() {
return cpFieldDescriptor;
}
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java Tue Nov 20 06:42:33 2007
@@ -164,7 +164,7 @@
classBands.getMethodFlags()[classNum][i], classBands.getMethodAttributes()[classNum][i]));
}
// sort CP according to cp_All
- cp.resolve();
+ cp.resolve(this);
// print out entries
debug("Constant pool looks like:");
for (i = 1; i <= cp.size(); i++) {
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java Tue Nov 20 06:42:33 2007
@@ -16,6 +16,22 @@
*/
package org.apache.harmony.pack200;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.apache.harmony.pack200.bytecode.CPClass;
+import org.apache.harmony.pack200.bytecode.CPDouble;
+import org.apache.harmony.pack200.bytecode.CPFieldRef;
+import org.apache.harmony.pack200.bytecode.CPFloat;
+import org.apache.harmony.pack200.bytecode.CPInteger;
+import org.apache.harmony.pack200.bytecode.CPInterfaceMethodRef;
+import org.apache.harmony.pack200.bytecode.CPLong;
+import org.apache.harmony.pack200.bytecode.CPMethodRef;
+import org.apache.harmony.pack200.bytecode.CPString;
+import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassFileEntry;
+import org.apache.harmony.pack200.bytecode.ConstantPoolEntry;
+
public class SegmentConstantPool {
/**
*
@@ -29,23 +45,21 @@
this.bands = bands;
}
- public static final int ALL = 0;
-
- public static final int CP_DOUBLE = 7;
-
// define in archive order
- public static final int CP_FLOAT = 4; // TODO Check this
-
- public static final int CP_INT = 3;
-
- public static final int CP_LONG = 6;
-
- public static final int CP_STRING = 5;
-
- public static final int SIGNATURE = 2; // TODO and more to come --
-
+ public static final int ALL = 0;
public static final int UTF_8 = 1;
+ public static final int CP_INT = 2;
+ public static final int CP_FLOAT = 3;
+ public static final int CP_LONG = 4;
+ public static final int CP_DOUBLE = 5;
+ public static final int CP_STRING = 6;
+ public static final int CP_CLASS = 7;
+ public static final int SIGNATURE = 8; // TODO and more to come --
+ public static final int CP_DESCR = 9;
+ public static final int CP_FIELD = 10;
+ public static final int CP_METHOD = 11;
+ public static final int CP_IMETHOD = 12;
public Object getValue(int cp, long value) throws Pack200Exception {
int index = (int) value;
@@ -55,21 +69,239 @@
throw new Pack200Exception("Cannot have a negative range");
} else if (cp == UTF_8) {
return bands.getCpUTF8()[index];
- } else if (cp == CP_STRING) {
- return bands.getCpString()[index];
- } else if (cp == SIGNATURE) {
- return bands.getCpSignature()[index];
} else if (cp == CP_INT) {
return new Integer(bands.getCpInt()[index]);
} else if (cp == CP_FLOAT) {
return new Float(bands.getCpFloat()[index]);
+ } else if (cp == CP_LONG) {
+ return new Long(bands.getCpLong()[index]);
} else if (cp == CP_DOUBLE) {
return new Double(bands.getCpDouble()[index]);
+ } else if (cp == CP_STRING) {
+ return bands.getCpString()[index];
+ } else if (cp == CP_CLASS) {
+ return bands.getCpClass()[index];
+ } else if (cp == SIGNATURE) {
+ return bands.getCpSignature()[index];
+ } else if (cp == CP_DESCR) {
+ return bands.getCpDescriptor()[index];
+ } else {
+ // etc
+ throw new Error("Get value incomplete");
+ }
+ }
+
+ /**
+ * Subset the constant pool of the specified type
+ * to be just that which has the specified class
+ * name. Answer the ConstantPoolEntry at the
+ * desiredIndex of the subsetted pool.
+ *
+ * @param cp type of constant pool array to search
+ * @param desiredIndex index of the constant pool
+ * @param desiredClassName class to use to generate a
+ * subset of the pool
+ * @return ConstantPoolEntry
+ * @throws Pack200Exception
+ */
+ public ConstantPoolEntry getClassSpecificPoolEntry(int cp, long desiredIndex, String desiredClassName) throws Pack200Exception {
+ int index = (int)desiredIndex;
+ int realIndex = -1;
+ String array[] = null;
+ if (cp == CP_FIELD) {
+ array = bands.getCpFieldClass();
+ } else if (cp == CP_METHOD) {
+ array = bands.getCpMethodClass();
+ } else if (cp == CP_IMETHOD) {
+ array = bands.getCpIMethodClass();
+ } else {
+ throw new Error("Don't know how to handle " + cp);
+ }
+ realIndex = matchSpecificPoolEntryIndex(array, desiredClassName, index);
+ return getConstantPoolEntry(cp, (long)realIndex);
+ }
+
+ /**
+ * Given the name of a class, answer the CPClass associated
+ * with that class. Answer null if the class doesn't exist.
+ * @param name Class name to look for (form: java/lang/Object)
+ * @return CPClass for that class name, or null if not found.
+ */
+ public ConstantPoolEntry getClassPoolEntry(String name) {
+ String classes[] = bands.getCpClass();
+ int index = matchSpecificPoolEntryIndex(classes, name, 0);
+ if(index == -1) {
+ return null;
+ }
+ try {
+ return getConstantPoolEntry(CP_CLASS, (long)index);
+ }
+ catch (Pack200Exception ex) {
+ throw new Error("Error getting class pool entry");
+ }
+ }
+
+ /**
+ * Answer the init method for the specified class.
+ * @param cp constant pool to search (must be CP_METHOD)
+ * @param value index of init method
+ * @param desiredClassName String class name of the init method
+ * @return CPMethod init method
+ * @throws Pack200Exception
+ */
+ public ConstantPoolEntry getInitMethodPoolEntry(int cp, long value, String desiredClassName) throws Pack200Exception {
+ int realIndex = -1;
+ String desiredRegex = "^<init>.*";
+ if (cp == CP_METHOD) {
+ realIndex = matchSpecificPoolEntryIndex(bands.getCpMethodClass(), bands.getCpMethodDescriptor(), desiredClassName, desiredRegex, (int)value);
+ } else {
+ throw new Error("Nothing but CP_METHOD can be an <init>");
+ }
+ return getConstantPoolEntry(cp, (long)realIndex);
+ }
+
+ /**
+ * A number of things make use of subsets of structures.
+ * In one particular example, _super bytecodes will use a subset
+ * of method or field classes which have just those methods /
+ * fields defined in the superclass. Similarly, _this bytecodes
+ * use just those methods/fields defined in this class, and _init
+ * bytecodes use just those methods that start with <init>.
+ *
+ * This method takes an array of names, a String to match for,
+ * an index and a boolean as parameters, and answers the array
+ * position in the array of the indexth element which matches
+ * (or equals) the String (depending on the state of the boolean)
+ *
+ * In other words, if the class array consists of:
+ * Object [position 0, 0th instance of Object]
+ * String [position 1, 0th instance of String]
+ * String [position 2, 1st instance of String]
+ * Object [position 3, 1st instance of Object]
+ * Object [position 4, 2nd instance of Object]
+ * then classSpecificPoolEntryIndex(..., "Object", 2, false) will
+ * answer 4. classSpecificPoolEntryIndex(..., "String", 0, false)
+ * will answer 1.
+ *
+ * @param nameArray Array of Strings against which the compareString is tested
+ * @param compareString String for which to search
+ * @param desiredIndex nth element with that match (counting from 0)
+ * @return int index into nameArray, or -1 if not found.
+ */
+ protected int matchSpecificPoolEntryIndex(String[] nameArray, String compareString, int desiredIndex) {
+ return matchSpecificPoolEntryIndex(nameArray, nameArray, compareString, ".*", desiredIndex);
+ }
+
+ /**
+ * This method's function is to look through pairs of arrays.
+ * It keeps track of the number of hits it finds using the
+ * following basis of comparison for a hit:
+ * - the primaryArray[index] must be .equals() to the primaryCompareString
+ * - the secondaryArray[index] .matches() the secondaryCompareString
+ * When the desiredIndex number of hits has been reached, the index
+ * into the original two arrays of the element hit is returned.
+ *
+ * @param primaryArray The first array to search
+ * @param secondaryArray The second array (must be same .length as primaryArray)
+ * @param primaryCompareString The String to compare against primaryArray using .equals()
+ * @param secondaryCompareRegex The String to compare against secondaryArray using .matches()
+ * @param desiredIndex The nth hit whose position we're seeking
+ * @return int index that represents the position of the nth hit in primaryArray and secondaryArray
+ */
+ protected int matchSpecificPoolEntryIndex(String[] primaryArray, String[] secondaryArray, String primaryCompareString, String secondaryCompareRegex, int desiredIndex) {
+ int instanceCount = -1;
+ for(int index=0; index < primaryArray.length; index++) {
+ if((primaryArray[index].equals(primaryCompareString)) &&
+ secondaryArray[index].matches(secondaryCompareRegex)) {
+ instanceCount++;
+ if(instanceCount == desiredIndex) {
+ return index;
+ }
+ }
+ }
+ // We didn't return in the for loop, so the desiredMatch
+ // with desiredIndex must not exist in the array.
+ return -1;
+ }
+
+
+ public ConstantPoolEntry getConstantPoolEntry(int cp, long value) throws Pack200Exception {
+ int index = (int) value;
+ if (index == -1) {
+ return null;
+ } else if (index < 0) {
+ throw new Pack200Exception("Cannot have a negative range");
+ } else if (cp == UTF_8) {
+ return new CPUTF8(bands.getCpUTF8()[index]);
+ } else if (cp == CP_INT) {
+ return new CPInteger(new Integer(bands.getCpInt()[index]));
+ } else if (cp == CP_FLOAT) {
+ return new CPFloat(new Float(bands.getCpFloat()[index]));
} else if (cp == CP_LONG) {
- return new Long(bands.getCpLong()[index]);
+ return new CPLong(new Long(bands.getCpLong()[index]));
+ } else if (cp == CP_DOUBLE) {
+ return new CPDouble(new Double(bands.getCpDouble()[index]));
+ } else if (cp == CP_STRING) {
+ return new CPString(bands.getCpString()[index]);
+ } else if (cp == CP_CLASS) {
+ return new CPClass(bands.getCpClass()[index]);
+ } else if (cp == SIGNATURE) {
+ throw new Error("I don't know what to do with signatures yet");
+// return null /* new CPSignature(bands.getCpSignature()[index]) */;
+ } else if (cp == CP_DESCR) {
+ throw new Error("I don't know what to do with descriptors yet");
+// return null /* new CPDescriptor(bands.getCpDescriptor()[index]) */;
+ } else if (cp == CP_FIELD) {
+ return new CPFieldRef(bands.getCpFieldClass()[index], bands.getCpFieldDescriptor()[index]);
+ } else if (cp == CP_METHOD) {
+ return new CPMethodRef(bands.getCpMethodClass()[index], bands.getCpMethodDescriptor()[index]);
+ } else if (cp == CP_IMETHOD) {
+ return new CPInterfaceMethodRef(bands.getCpIMethodClass()[index], bands.getCpIMethodDescriptor()[index]);
} else {
// etc
throw new Error("Get value incomplete");
}
}
-}
+
+ public ConstantPoolEntry[] getCpAll() throws Pack200Exception {
+ ArrayList cpAll = new ArrayList();
+ // TODO: this is 1.5-specific. Try to get rid
+ // of it.
+ for(int index=0; index < bands.getCpUTF8().length; index++) {
+ cpAll.add(getConstantPoolEntry(UTF_8, index));
+ }
+ for(int index=0; index < bands.getCpInt().length; index++) {
+ cpAll.add(getConstantPoolEntry(CP_INT, index));
+ }
+ for(int index=0; index < bands.getCpFloat().length; index++) {
+ cpAll.add(getConstantPoolEntry(CP_FLOAT, index));
+ }
+ for(int index=0; index < bands.getCpLong().length; index++) {
+ cpAll.add(getConstantPoolEntry(CP_LONG, index));
+ }
+ for(int index=0; index < bands.getCpDouble().length; index++) {
+ cpAll.add(getConstantPoolEntry(CP_DOUBLE, index));
+ }
+ for(int index=0; index < bands.getCpString().length; index++) {
+ cpAll.add(getConstantPoolEntry(CP_STRING, index));
+ }
+ for(int index=0; index < bands.getCpClass().length; index++) {
+ cpAll.add(getConstantPoolEntry(CP_CLASS, index));
+ }
+ for(int index=0; index < bands.getCpFieldClass().length; index++) {
+ cpAll.add(getConstantPoolEntry(CP_FIELD, index));
+ }
+ for(int index=0; index < bands.getCpMethodClass().length; index++) {
+ cpAll.add(getConstantPoolEntry(CP_METHOD, index));
+ }
+ for(int index=0; index < bands.getCpIMethodClass().length; index++) {
+ cpAll.add(getConstantPoolEntry(CP_IMETHOD, index));
+ }
+
+ ConstantPoolEntry[] result = new ConstantPoolEntry[cpAll.size()];
+ cpAll.toArray(result);
+ return result;
+ }
+
+
+ }