Pack200 - more testing for annotations and some associated bug fixes

git-svn-id: https://svn.apache.org/repos/asf/harmony/enhanced/java/trunk@989168 13f79535-47bb-0310-9956-ffa450edef68
master
Sian January 14 years ago
parent d8216aad44
commit 743eb4d225
  1. 24
      src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java
  2. 4
      src/main/java/org/apache/harmony/pack200/ClassBands.java
  3. 31
      src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java
  4. 57
      src/main/java/org/apache/harmony/pack200/NewAttribute.java
  5. 56
      src/main/java/org/apache/harmony/pack200/PackingOptions.java
  6. 28
      src/main/java/org/apache/harmony/pack200/Segment.java
  7. 16
      src/main/java/org/apache/harmony/unpack200/MetadataBandGroup.java
  8. 18
      src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java
  9. 5
      src/test/java/org/apache/harmony/unpack200/tests/AttributeLayoutMapTest.java
  10. BIN
      src/test/resources/org/apache/harmony/pack200/tests/annotations2unpacked.jar

@ -59,17 +59,19 @@ public class AttributeDefinitionBands extends BandSet {
for (int i = 0; i < attributePrototypes.length; i++) {
NewAttribute newAttribute = (NewAttribute) attributePrototypes[i];
if (newAttribute.isContextClass()) {
classLayouts.put(newAttribute.type, newAttribute.getLayout());
}
if (newAttribute.isContextMethod()) {
methodLayouts.put(newAttribute.type, newAttribute.getLayout());
}
if (newAttribute.isContextField()) {
fieldLayouts.put(newAttribute.type, newAttribute.getLayout());
}
if (newAttribute.isContextCode()) {
codeLayouts.put(newAttribute.type, newAttribute.getLayout());
if(!(newAttribute instanceof NewAttribute.ErrorAttribute) && !(newAttribute instanceof NewAttribute.PassAttribute) && !(newAttribute instanceof NewAttribute.StripAttribute)) {
if (newAttribute.isContextClass()) {
classLayouts.put(newAttribute.type, newAttribute.getLayout());
}
if (newAttribute.isContextMethod()) {
methodLayouts.put(newAttribute.type, newAttribute.getLayout());
}
if (newAttribute.isContextField()) {
fieldLayouts.put(newAttribute.type, newAttribute.getLayout());
}
if (newAttribute.isContextCode()) {
codeLayouts.put(newAttribute.type, newAttribute.getLayout());
}
}
}
if (classLayouts.keySet().size() > 7) {

@ -1327,7 +1327,7 @@ public class ClassBands extends BandSet {
public void addParameterAnnotation(int parameter, String desc,
boolean visible, List nameRU, List t, List values, List caseArrayN, List nestTypeRS, List nestNameRU, List nestPairN) {
if(visible) {
method_RVPA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
method_RVPA_bands.addParameterAnnotation(parameter, desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
if((flag.intValue() & (1<<23)) != 0) {
method_RVPA_bands.incrementAnnoN();
@ -1336,7 +1336,7 @@ public class ClassBands extends BandSet {
}
tempMethodFlags.add(new Long(flag.longValue() | (1<<23)));
} else {
method_RIPA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
method_RIPA_bands.addParameterAnnotation(parameter, desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
if((flag.longValue() & (1<<24)) != 0) {
method_RIPA_bands.incrementAnnoN();

@ -35,7 +35,7 @@ public class MetadataBandGroup extends BandSet {
private final String type;
private int numBackwardsCalls = 0;
public List param_NB = new ArrayList(); // TODO: Lazy instantiation?
public IntList param_NB = new IntList(); // TODO: Lazy instantiation?
public IntList anno_N = new IntList();
public List type_RS = new ArrayList();
public IntList pair_N = new IntList();
@ -95,6 +95,16 @@ public class MetadataBandGroup extends BandSet {
}
byte[] encodedBand = null;
if(!type.equals("AD")) {
if(type.indexOf('P') != -1) {
// Parameter annotation so we need to transmit param_NB
encodedBand = encodeBandInt(
contextStr + "_" + type + " param_NB", param_NB.toArray(),
Codec.BYTE1);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length
+ " bytes from " + contextStr + "_" + type + " anno_N["
+ param_NB.size() + "]");
}
encodedBand = encodeBandInt(
contextStr + "_" + type + " anno_N", anno_N.toArray(),
Codec.UNSIGNED5);
@ -230,6 +240,23 @@ public class MetadataBandGroup extends BandSet {
return ints;
}
/**
* Add an annotation to this set of bands
*
* @param desc
* @param nameRU
* @param t
* @param values
* @param caseArrayN
* @param nestTypeRS
* @param nestNameRU
* @param nestPairN
*/
public void addParameterAnnotation(int parameter, String desc, List nameRU, List t, List values, List caseArrayN, List nestTypeRS, List nestNameRU, List nestPairN) {
param_NB.add(parameter);
addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
}
/**
* Add an annotation to this set of bands
*
@ -244,7 +271,7 @@ public class MetadataBandGroup extends BandSet {
*/
public void addAnnotation(String desc, List nameRU, List t, List values, List caseArrayN, List nestTypeRS, List nestNameRU, List nestPairN) {
type_RS.add(cpBands.getCPSignature(desc));
pair_N.add(t.size());
pair_N.add(nameRU.size());
for (Iterator iterator = nameRU.iterator(); iterator.hasNext();) {
String name = (String) iterator.next();

@ -142,4 +142,61 @@ public class NewAttribute extends Attribute {
public Label getLabel(int index) {
return labels[index];
}
/**
* ErrorAttribute extends <code>NewAttribute</code> and manages attributes
* encountered by ASM that have had an error action specified to pack200
* (e.g. via one of the -C, -M, -F or -D command line options such as
* -Cattribute-name=error)
*/
public static class ErrorAttribute extends NewAttribute {
public ErrorAttribute(String type, int context) {
super(type, "", context);
}
protected Attribute read(ClassReader cr, int off, int len, char[] buf,
int codeOff, Label[] labels) {
throw new Error("Attribute " + type + " was found");
}
}
/**
* StripAttribute extends <code>NewAttribute</code> and manages attributes
* encountered by ASM that have had an strip action specified to pack200
* (e.g. via one of the -C, -M, -F or -D command line options such as
* -Cattribute-name=strip)
*/
public static class StripAttribute extends NewAttribute {
public StripAttribute(String type, int context) {
super(type, "", context);
}
protected Attribute read(ClassReader cr, int off, int len, char[] buf,
int codeOff, Label[] labels) {
// TODO Not sure if this works, can we really strip an attribute if we don't know the layout?
return null;
}
}
/**
* PassAttribute extends <code>NewAttribute</code> and manages attributes
* encountered by ASM that have had an pass action specified to pack200
* (e.g. via one of the -C, -M, -F or -D command line options such as
* -Cattribute-name=pass)
*/
public static class PassAttribute extends NewAttribute {
public PassAttribute(String type, int context) {
super(type, "", context);
}
protected Attribute read(ClassReader cr, int off, int len, char[] buf,
int codeOff, Label[] labels) {
throw new Segment.PassException();
}
}
}

@ -209,10 +209,6 @@ public class PackingOptions {
}
}
public Map getClassAttributeActions() {
return classAttributeActions;
}
public void addClassAttributeAction(String attributeName, String action) {
if(classAttributeActions == null) {
classAttributeActions = new HashMap();
@ -220,10 +216,6 @@ public class PackingOptions {
classAttributeActions.put(attributeName, action);
}
public Map getFieldAttributeActions() {
return fieldAttributeActions;
}
public void addFieldAttributeAction(String attributeName, String action) {
if(fieldAttributeActions == null) {
fieldAttributeActions = new HashMap();
@ -231,10 +223,6 @@ public class PackingOptions {
fieldAttributeActions.put(attributeName, action);
}
public Map getMethodAttributeActions() {
return methodAttributeActions;
}
public void addMethodAttributeAction(String attributeName, String action) {
if(methodAttributeActions == null) {
methodAttributeActions = new HashMap();
@ -242,10 +230,6 @@ public class PackingOptions {
methodAttributeActions.put(attributeName, action);
}
public Map getCodeAttributeActions() {
return codeAttributeActions;
}
public void addCodeAttributeAction(String attributeName, String action) {
if(codeAttributeActions == null) {
codeAttributeActions = new HashMap();
@ -288,25 +272,29 @@ public class PackingOptions {
.hasNext();) {
name = (String) iteratorI.next();
action = (String) attributeActions.get(name);
if (!ERROR.equals(action) && !STRIP.equals(action)
&& !PASS.equals(action)) {
prototypeExists = false;
for (Iterator iteratorJ = prototypes.iterator(); iteratorJ
.hasNext();) {
newAttribute = (NewAttribute) iteratorJ.next();
if (newAttribute.type.equals(name)) {
// if the attribute exists, update its context
newAttribute.addContext(tag);
prototypeExists = true;
break;
}
// if no attribute is found, add a new attribute
if (!prototypeExists) {
newAttribute = new NewAttribute(name, action,
tag);
prototypes.add(newAttribute);
}
prototypeExists = false;
for (Iterator iteratorJ = prototypes.iterator(); iteratorJ
.hasNext();) {
newAttribute = (NewAttribute) iteratorJ.next();
if (newAttribute.type.equals(name)) {
// if the attribute exists, update its context
newAttribute.addContext(tag);
prototypeExists = true;
break;
}
}
// if no attribute is found, add a new attribute
if (!prototypeExists) {
if (ERROR.equals(action)) {
newAttribute = new NewAttribute.ErrorAttribute(name, tag);
} else if (STRIP.equals(action)) {
newAttribute = new NewAttribute.StripAttribute(name, tag);
} else if (PASS.equals(action)) {
newAttribute = new NewAttribute.PassAttribute(name, tag);
} else {
newAttribute = new NewAttribute(name, action, tag);
}
prototypes.add(newAttribute);
}
}
}

@ -53,7 +53,7 @@ public class Segment implements ClassVisitor {
private PackingOptions options;
private boolean stripDebug;
private Attribute[] nonStandardAttributePrototypes;
/**
* The main method on Segment. Reads in all the class files, packs them and
* then writes the packed segment out to the given OutputStream.
@ -76,11 +76,11 @@ public class Segment implements ClassVisitor {
this.stripDebug = options.isStripDebug();
int effort = options.getEffort();
nonStandardAttributePrototypes = options.getUnknownAttributePrototypes();
PackingUtils.log("Start to pack a new segment with "
+ segmentUnit.fileListSize() + " files including "
+ segmentUnit.classListSize() + " classes");
PackingUtils.log("Initialize a header for the segment");
segmentHeader = new SegmentHeader();
segmentHeader.setFile_count(segmentUnit.fileListSize());
@ -89,22 +89,22 @@ public class Segment implements ClassVisitor {
segmentHeader.setDeflate_hint("true".equals(options
.getDeflateHint()));
}
PackingUtils.log("Setup constant pool bands for the segment");
cpBands = new CpBands(this, effort);
PackingUtils.log("Setup attribute definition bands for the segment");
attributeDefinitionBands = new AttributeDefinitionBands(this, effort, nonStandardAttributePrototypes);
PackingUtils.log("Setup internal class bands for the segment");
icBands = new IcBands(segmentHeader, cpBands, effort);
PackingUtils.log("Setup class bands for the segment");
classBands = new ClassBands(this, segmentUnit.classListSize(), effort, stripDebug);
PackingUtils.log("Setup byte code bands for the segment");
bcBands = new BcBands(cpBands, this, effort);
PackingUtils.log("Setup file bands for the segment");
fileBands = new FileBands(cpBands, segmentHeader, options, segmentUnit, effort);
@ -136,10 +136,10 @@ public class Segment implements ClassVisitor {
headerOutputStream.writeTo(out);
bandsOutputStream.writeTo(out);
segmentUnit.addPackedByteAmount(headerOutputStream.size());
segmentUnit.addPackedByteAmount(bandsOutputStream.size());
PackingUtils.log("Wrote total of " + segmentUnit.getPackedByteAmount()
+ " bytes");
PackingUtils.log("Transmitted " + segmentUnit.fileListSize() + " files of "
@ -571,10 +571,6 @@ public class Segment implements ClassVisitor {
Integer numCases = (Integer) caseArrayN.remove(caseArrayN.size() - 1);
caseArrayN.add(new Integer(numCases.intValue() + 1));
T.add("e");
if(name == null) {
name = "";
}
nameRU.add(name);
values.add(desc);
values.add(value);
}
@ -677,7 +673,7 @@ public class Segment implements ClassVisitor {
* passed through as-is in the file_bands rather than being packed with
* pack200.
*/
public class PassException extends RuntimeException {
public static class PassException extends RuntimeException {
}
}

@ -22,6 +22,8 @@ import java.util.Iterator;
import java.util.List;
import org.apache.harmony.unpack200.bytecode.AnnotationDefaultAttribute;
import org.apache.harmony.unpack200.bytecode.AnnotationsAttribute.Annotation;
import org.apache.harmony.unpack200.bytecode.AnnotationsAttribute.ElementValue;
import org.apache.harmony.unpack200.bytecode.Attribute;
import org.apache.harmony.unpack200.bytecode.CPDouble;
import org.apache.harmony.unpack200.bytecode.CPFloat;
@ -30,8 +32,6 @@ import org.apache.harmony.unpack200.bytecode.CPLong;
import org.apache.harmony.unpack200.bytecode.CPUTF8;
import org.apache.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleAnnotationsAttribute;
import org.apache.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute;
import org.apache.harmony.unpack200.bytecode.AnnotationsAttribute.Annotation;
import org.apache.harmony.unpack200.bytecode.AnnotationsAttribute.ElementValue;
import org.apache.harmony.unpack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute.ParameterAnnotation;
/**
@ -117,8 +117,6 @@ public class MetadataBandGroup {
private int anno_N_Index;
private Iterator type_RS_Iterator;
private int pair_N_Index;
public List getAttributes() {
@ -149,7 +147,6 @@ public class MetadataBandGroup {
}
} else if (type.equals("RVPA") || type.equals("RIPA")) {
anno_N_Index = 0;
type_RS_Iterator = Arrays.asList(type_RS).iterator();
pair_N_Index = 0;
for (int i = 0; i < param_NB.length; i++) {
attributes.add(getParameterAttribute(param_NB[i],
@ -185,14 +182,13 @@ public class MetadataBandGroup {
int[] pairCounts = pair_N[pair_N_Index++];
Annotation[] annotations = new Annotation[numAnnotations];
for (int j = 0; j < annotations.length; j++) {
annotations[j] = getAnnotation(
(CPUTF8) type_RS_Iterator.next(), pairCounts[j],
namesIterator);
annotations[j] = getAnnotation(type_RS[anno_N_Index - 1][j],
pairCounts[j], namesIterator);
}
parameter_annotations[i] = new ParameterAnnotation(annotations);
}
return new RuntimeVisibleorInvisibleParameterAnnotationsAttribute(type
.equals("RVPA") ? rvpaUTF8 : ripaUTF8,
return new RuntimeVisibleorInvisibleParameterAnnotationsAttribute(
type.equals("RVPA") ? rvpaUTF8 : ripaUTF8,
parameter_annotations);
}

@ -344,7 +344,7 @@ public class ArchiveTest extends TestCase {
compareFiles(jarFile, jarFile2);
}
public void testAnnotations2() throws IOException, Pack200Exception,
URISyntaxException {
in = new JarFile(new File(Archive.class.getResource(
@ -357,6 +357,22 @@ public class ArchiveTest extends TestCase {
new Archive(in, out, options).pack();
in.close();
out.close();
// now unpack
InputStream in2 = new FileInputStream(file);
File file2 = File.createTempFile("annotationsout", ".jar");
// file2.deleteOnExit();
JarOutputStream out2 = new JarOutputStream(new FileOutputStream(file2));
org.apache.harmony.unpack200.Archive archive = new org.apache.harmony.unpack200.Archive(
in2, out2);
archive.unpack();
// TODO: This isn't quite right - to fix
// JarFile jarFile = new JarFile(file2);
// JarFile jarFile2 = new JarFile(new File(Archive.class.getResource(
// "/org/apache/harmony/pack200/tests/annotations2unpacked.jar")
// .toURI()));
// compareFiles(jarFile, jarFile2);
}
public void testE0() throws Pack200Exception, IOException, URISyntaxException {

@ -31,14 +31,15 @@ public class AttributeLayoutMapTest extends TestCase {
AttributeLayout.CONTEXT_CLASS);
assertNotNull(layout);
assertEquals("RUNH", layout.getLayout());
assertEquals(17, layout.getIndex());
// and that we can change it
a.add(new AttributeLayout("SourceFile", AttributeLayout.CONTEXT_CLASS,
"FROG", 15));
"FROG", 17));
layout = a.getAttributeLayout("SourceFile",
AttributeLayout.CONTEXT_CLASS);
assertNotNull(layout);
assertEquals("FROG", layout.getLayout());
assertTrue(layout.matches(1 << 15));
assertTrue(layout.matches(1 << 17));
assertFalse(layout.matches(1 << 16));
assertTrue(layout.matches(-1));
assertFalse(layout.matches(0));

Loading…
Cancel
Save