Commit 4accca37 authored by ebruneton's avatar ebruneton

workaround for a javac bug (see asm bug report #307392)

parent c6079dff
...@@ -281,15 +281,20 @@ final class AnnotationWriter implements AnnotationVisitor { ...@@ -281,15 +281,20 @@ final class AnnotationWriter implements AnnotationVisitor {
* Puts the given annotation lists into the given byte vector. * Puts the given annotation lists into the given byte vector.
* *
* @param panns an array of annotation writer lists. * @param panns an array of annotation writer lists.
* @param off index of the first annotation to be written.
* @param out where the annotations must be put. * @param out where the annotations must be put.
*/ */
static void put(final AnnotationWriter[] panns, final ByteVector out) { static void put(
int size = 1 + 2 * panns.length; final AnnotationWriter[] panns,
for (int i = 0; i < panns.length; ++i) { final int off,
final ByteVector out)
{
int size = 1 + 2 * (panns.length - off);
for (int i = off; i < panns.length; ++i) {
size += panns[i] == null ? 0 : panns[i].getSize(); size += panns[i] == null ? 0 : panns[i].getSize();
} }
out.putInt(size).putByte(panns.length); out.putInt(size).putByte(panns.length - off);
for (int i = 0; i < panns.length; ++i) { for (int i = off; i < panns.length; ++i) {
AnnotationWriter aw = panns[i]; AnnotationWriter aw = panns[i];
AnnotationWriter last = null; AnnotationWriter last = null;
int n = 0; int n = 0;
......
...@@ -848,10 +848,10 @@ public class ClassReader { ...@@ -848,10 +848,10 @@ public class ClassReader {
} }
} }
if (ANNOTATIONS && mpanns != 0) { if (ANNOTATIONS && mpanns != 0) {
readParameterAnnotations(mpanns, c, true, mv); readParameterAnnotations(mpanns, desc, c, true, mv);
} }
if (ANNOTATIONS && impanns != 0) { if (ANNOTATIONS && impanns != 0) {
readParameterAnnotations(impanns, c, false, mv); readParameterAnnotations(impanns, desc, c, false, mv);
} }
while (cattrs != null) { while (cattrs != null) {
attr = cattrs.next; attr = cattrs.next;
...@@ -1460,6 +1460,7 @@ public class ClassReader { ...@@ -1460,6 +1460,7 @@ public class ClassReader {
* Reads parameter annotations and makes the given visitor visit them. * Reads parameter annotations and makes the given visitor visit them.
* *
* @param v start offset in {@link #b b} of the annotations to be read. * @param v start offset in {@link #b b} of the annotations to be read.
* @param desc the method descriptor.
* @param buf buffer to be used to call {@link #readUTF8 readUTF8}, * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
* {@link #readClass(int,char[]) readClass} or * {@link #readClass(int,char[]) readClass} or
* {@link #readConst readConst}. * {@link #readConst readConst}.
...@@ -1469,21 +1470,34 @@ public class ClassReader { ...@@ -1469,21 +1470,34 @@ public class ClassReader {
*/ */
private void readParameterAnnotations( private void readParameterAnnotations(
int v, int v,
final String desc,
final char[] buf, final char[] buf,
final boolean visible, final boolean visible,
final MethodVisitor mv) final MethodVisitor mv)
{ {
int i;
int n = b[v++] & 0xFF; int n = b[v++] & 0xFF;
for (int i = 0; i < n; ++i) { // workaround for a bug in javac (javac compiler generates a parameter
// annotation array whose size is equal to the number of parameters in
// the Java source file, while it should generate an array whose size is
// equal to the number of parameters in the method descriptor - which
// includes the synthetic parameters added by the compiler). This work-
// around supposes that the synthetic parameters are the first ones.
int synthetics = Type.getArgumentTypes(desc).length - n;
AnnotationVisitor av;
for (i = 0; i < synthetics; ++i) {
// virtual annotation to detect synthetic parameters in MethodWriter
av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
if (av != null) {
av.visitEnd();
}
}
for (; i < n + synthetics; ++i) {
int j = readUnsignedShort(v); int j = readUnsignedShort(v);
v += 2; v += 2;
for (; j > 0; --j) { for (; j > 0; --j) {
v = readAnnotationValues(v + 2, av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
buf, v = readAnnotationValues(v + 2, buf, true, av);
true,
mv.visitParameterAnnotation(i,
readUTF8(v, buf),
visible));
} }
} }
} }
......
...@@ -208,6 +208,11 @@ class MethodWriter implements MethodVisitor { ...@@ -208,6 +208,11 @@ class MethodWriter implements MethodVisitor {
*/ */
private AnnotationWriter[] ipanns; private AnnotationWriter[] ipanns;
/**
* The number of synthetic parameters of this method.
*/
private int synthetics;
/** /**
* The non standard attributes of the method. * The non standard attributes of the method.
*/ */
...@@ -494,6 +499,12 @@ class MethodWriter implements MethodVisitor { ...@@ -494,6 +499,12 @@ class MethodWriter implements MethodVisitor {
return null; return null;
} }
ByteVector bv = new ByteVector(); ByteVector bv = new ByteVector();
if ("Ljava/lang/Synthetic;".equals(desc)) {
// workaround for a bug in javac with synthetic parameters
// see ClassReader.readParameterAnnotations
synthetics = Math.max(synthetics, parameter + 1);
return new AnnotationWriter(cw, false, bv, null, 0);
}
// write type, and reserve space for values count // write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0); bv.putShort(cw.newUTF8(desc)).putShort(0);
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
...@@ -1844,15 +1855,15 @@ class MethodWriter implements MethodVisitor { ...@@ -1844,15 +1855,15 @@ class MethodWriter implements MethodVisitor {
} }
if (ClassReader.ANNOTATIONS && panns != null) { if (ClassReader.ANNOTATIONS && panns != null) {
cw.newUTF8("RuntimeVisibleParameterAnnotations"); cw.newUTF8("RuntimeVisibleParameterAnnotations");
size += 7 + 2 * panns.length; size += 7 + 2 * (panns.length - synthetics);
for (int i = panns.length - 1; i >= 0; --i) { for (int i = panns.length - 1; i >= synthetics; --i) {
size += panns[i] == null ? 0 : panns[i].getSize(); size += panns[i] == null ? 0 : panns[i].getSize();
} }
} }
if (ClassReader.ANNOTATIONS && ipanns != null) { if (ClassReader.ANNOTATIONS && ipanns != null) {
cw.newUTF8("RuntimeInvisibleParameterAnnotations"); cw.newUTF8("RuntimeInvisibleParameterAnnotations");
size += 7 + 2 * ipanns.length; size += 7 + 2 * (ipanns.length - synthetics);
for (int i = ipanns.length - 1; i >= 0; --i) { for (int i = ipanns.length - 1; i >= synthetics; --i) {
size += ipanns[i] == null ? 0 : ipanns[i].getSize(); size += ipanns[i] == null ? 0 : ipanns[i].getSize();
} }
} }
...@@ -2024,11 +2035,11 @@ class MethodWriter implements MethodVisitor { ...@@ -2024,11 +2035,11 @@ class MethodWriter implements MethodVisitor {
} }
if (ClassReader.ANNOTATIONS && panns != null) { if (ClassReader.ANNOTATIONS && panns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations")); out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
AnnotationWriter.put(panns, out); AnnotationWriter.put(panns, synthetics, out);
} }
if (ClassReader.ANNOTATIONS && ipanns != null) { if (ClassReader.ANNOTATIONS && ipanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations")); out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations"));
AnnotationWriter.put(ipanns, out); AnnotationWriter.put(ipanns, synthetics, out);
} }
if (attrs != null) { if (attrs != null) {
attrs.put(cw, null, 0, -1, -1, out); attrs.put(cw, null, 0, -1, -1, out);
......
...@@ -163,6 +163,7 @@ org/objectweb/asm/MethodWriter.previousBlock=O ...@@ -163,6 +163,7 @@ org/objectweb/asm/MethodWriter.previousBlock=O
org/objectweb/asm/MethodWriter.currentBlock=P org/objectweb/asm/MethodWriter.currentBlock=P
org/objectweb/asm/MethodWriter.stackSize=Q org/objectweb/asm/MethodWriter.stackSize=Q
org/objectweb/asm/MethodWriter.maxStackSize=R org/objectweb/asm/MethodWriter.maxStackSize=R
org/objectweb/asm/MethodWriter.synthetics=S
org/objectweb/asm/Type.sort=a org/objectweb/asm/Type.sort=a
org/objectweb/asm/Type.buf=b org/objectweb/asm/Type.buf=b
...@@ -179,7 +180,7 @@ org/objectweb/asm/signature/SignatureWriter.argumentStack=d ...@@ -179,7 +180,7 @@ org/objectweb/asm/signature/SignatureWriter.argumentStack=d
# method mappings # method mappings
org/objectweb/asm/AnnotationWriter.getSize()I=a org/objectweb/asm/AnnotationWriter.getSize()I=a
org/objectweb/asm/AnnotationWriter.put([Lorg/objectweb/asm/AnnotationWriter;Lorg/objectweb/asm/ByteVector;)V=a org/objectweb/asm/AnnotationWriter.put([Lorg/objectweb/asm/AnnotationWriter;ILorg/objectweb/asm/ByteVector;)V=a
org/objectweb/asm/AnnotationWriter.put(Lorg/objectweb/asm/ByteVector;)V=a org/objectweb/asm/AnnotationWriter.put(Lorg/objectweb/asm/ByteVector;)V=a
org/objectweb/asm/Attribute.getCount()I=a org/objectweb/asm/Attribute.getCount()I=a
...@@ -195,7 +196,7 @@ org/objectweb/asm/ClassReader.readAnnotationValue(I[CLjava/lang/String;Lorg/obje ...@@ -195,7 +196,7 @@ org/objectweb/asm/ClassReader.readAnnotationValue(I[CLjava/lang/String;Lorg/obje
org/objectweb/asm/ClassReader.readAnnotationValues(I[CZLorg/objectweb/asm/AnnotationVisitor;)I=a org/objectweb/asm/ClassReader.readAnnotationValues(I[CZLorg/objectweb/asm/AnnotationVisitor;)I=a
org/objectweb/asm/ClassReader.readAttribute([Lorg/objectweb/asm/Attribute;Ljava/lang/String;II[CI[Lorg/objectweb/asm/Label;)Lorg/objectweb/asm/Attribute;=a org/objectweb/asm/ClassReader.readAttribute([Lorg/objectweb/asm/Attribute;Ljava/lang/String;II[CI[Lorg/objectweb/asm/Label;)Lorg/objectweb/asm/Attribute;=a
org/objectweb/asm/ClassReader.readClass(Ljava/io/InputStream;)[B=a org/objectweb/asm/ClassReader.readClass(Ljava/io/InputStream;)[B=a
org/objectweb/asm/ClassReader.readParameterAnnotations(I[CZLorg/objectweb/asm/MethodVisitor;)V=a org/objectweb/asm/ClassReader.readParameterAnnotations(ILjava/lang/String;[CZLorg/objectweb/asm/MethodVisitor;)V=a
org/objectweb/asm/ClassReader.readUTF(II[C)Ljava/lang/String;=a org/objectweb/asm/ClassReader.readUTF(II[C)Ljava/lang/String;=a
org/objectweb/asm/ClassReader.readFrameType([Ljava/lang/Object;II[C[Lorg/objectweb/asm/Label;)I=a org/objectweb/asm/ClassReader.readFrameType([Ljava/lang/Object;II[C[Lorg/objectweb/asm/Label;)I=a
......
...@@ -293,13 +293,15 @@ public class Annotation extends Generator { ...@@ -293,13 +293,15 @@ public class Annotation extends Generator {
fv.visitEnd(); fv.visitEnd();
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(IIIIIIIIII)V", null, null); mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(IIIIIIIIII)V", null, null);
// visible method anntation // visible method annotation
mv.visitAnnotation(DEPRECATED, true).visitEnd(); mv.visitAnnotation(DEPRECATED, true).visitEnd();
// invisible method annotation // invisible method annotation
av0 = mv.visitAnnotation("Lpkg/Annotation;", false); av0 = mv.visitAnnotation("Lpkg/Annotation;", false);
av0.visitAnnotation("annotationValue", DOC).visitEnd(); av0.visitAnnotation("annotationValue", DOC).visitEnd();
av0.visitEnd(); av0.visitEnd();
// visible parameter annnotation // synthetic parameter annotation
mv.visitParameterAnnotation(0, "Ljava/lang/Synthetic;", false);
// visible parameter annotation
mv.visitParameterAnnotation(8, DEPRECATED, true).visitEnd(); mv.visitParameterAnnotation(8, DEPRECATED, true).visitEnd();
// invisible parameter annotation // invisible parameter annotation
av0 = mv.visitParameterAnnotation(8, "Lpkg/Annotation;", false); av0 = mv.visitParameterAnnotation(8, "Lpkg/Annotation;", false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment