--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -70,7 +70,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -85,7 +85,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public AnnotationVisitor(final int api) {
this(api, null);
@@ -96,13 +96,13 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param av
* the annotation visitor to which this visitor must delegate
* method calls. May be null.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor av) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
@@ -118,7 +118,7 @@
* the actual value, whose type must be {@link Byte},
* {@link Boolean}, {@link Character}, {@link Short},
* {@link Integer} , {@link Long}, {@link Float}, {@link Double},
- * {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+ * {@link String} or {@link Type} of OBJECT or ARRAY sort. This
* value can also be an array of byte, boolean, short, char, int,
* long, float or double values (this is equivalent to using
* {@link #visitArray visitArray} and visiting each array element
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java Thu Nov 02 13:18:23 2017 -0700
@@ -133,7 +133,7 @@
*/
AnnotationWriter(final ClassWriter cw, final boolean named,
final ByteVector bv, final ByteVector parent, final int offset) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
this.cw = cw;
this.named = named;
this.bv = bv;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Thu Nov 02 13:18:23 2017 -0700
@@ -73,31 +73,6 @@
public class ClassReader {
/**
- * True to enable signatures support.
- */
- static final boolean SIGNATURES = true;
-
- /**
- * True to enable annotations support.
- */
- static final boolean ANNOTATIONS = true;
-
- /**
- * True to enable stack map frames support.
- */
- static final boolean FRAMES = true;
-
- /**
- * True to enable bytecode writing support.
- */
- static final boolean WRITER = true;
-
- /**
- * True to enable JSR_W and GOTO_W support.
- */
- static final boolean RESIZE = true;
-
- /**
* Flag to skip method code. If this class is set <code>CODE</code>
* attribute won't be visited. This can be used, for example, to retrieve
* annotations for methods and method parameters.
@@ -134,6 +109,21 @@
public static final int EXPAND_FRAMES = 8;
/**
+ * Flag to expand the ASM pseudo instructions into an equivalent sequence of
+ * standard bytecode instructions. When resolving a forward jump it may
+ * happen that the signed 2 bytes offset reserved for it is not sufficient
+ * to store the bytecode offset. In this case the jump instruction is
+ * replaced with a temporary ASM pseudo instruction using an unsigned 2
+ * bytes offset (see Label#resolve). This internal flag is used to re-read
+ * classes containing such instructions, in order to replace them with
+ * standard instructions. In addition, when this flag is used, GOTO_W and
+ * JSR_W are <i>not</i> converted into GOTO and JSR, to make sure that
+ * infinite loops where a GOTO_W is replaced with a GOTO in ClassReader and
+ * converted back to a GOTO_W in ClassWriter cannot occur.
+ */
+ static final int EXPAND_ASM_INSNS = 256;
+
+ /**
* The class to be parsed. <i>The content of this array must not be
* modified. This field is intended for {@link Attribute} sub classes, and
* is normally not needed by class generators or adapters.</i>
@@ -195,7 +185,7 @@
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
- if (readShort(off + 6) > Opcodes.V1_9) {
+ if (readShort(off + 6) > Opcodes.V9) {
throw new IllegalArgumentException();
}
// parses the constant pool
@@ -234,6 +224,8 @@
// case ClassWriter.CLASS:
// case ClassWriter.STR:
// case ClassWriter.MTYPE
+ // case ClassWriter.PACKAGE:
+ // case ClassWriter.MODULE:
default:
size = 3;
break;
@@ -377,7 +369,9 @@
break;
// case ClassWriter.STR:
// case ClassWriter.CLASS:
- // case ClassWriter.MTYPE
+ // case ClassWriter.MTYPE:
+ // case ClassWriter.MODULE:
+ // case ClassWriter.PACKAGE:
default:
item.set(tag, readUTF8(index, buf), null, null);
break;
@@ -584,11 +578,14 @@
String enclosingOwner = null;
String enclosingName = null;
String enclosingDesc = null;
+ String moduleMainClass = null;
int anns = 0;
int ianns = 0;
int tanns = 0;
int itanns = 0;
int innerClasses = 0;
+ int module = 0;
+ int packages = 0;
Attribute attributes = null;
u = getAttributes();
@@ -607,13 +604,11 @@
enclosingName = readUTF8(items[item], c);
enclosingDesc = readUTF8(items[item] + 2, c);
}
- } else if (SIGNATURES && "Signature".equals(attrName)) {
+ } else if ("Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
- } else if (ANNOTATIONS
- && "RuntimeVisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = u + 8;
} else if ("Deprecated".equals(attrName)) {
access |= Opcodes.ACC_DEPRECATED;
@@ -623,12 +618,16 @@
} else if ("SourceDebugExtension".equals(attrName)) {
int len = readInt(u + 4);
sourceDebug = readUTF(u + 8, len, new char[len]);
- } else if (ANNOTATIONS
- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = u + 8;
+ } else if ("Module".equals(attrName)) {
+ module = u + 8;
+ } else if ("ModuleMainClass".equals(attrName)) {
+ moduleMainClass = readClass(u + 8, c);
+ } else if ("ModulePackages".equals(attrName)) {
+ packages = u + 10;
} else if ("BootstrapMethods".equals(attrName)) {
int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
@@ -657,6 +656,12 @@
classVisitor.visitSource(sourceFile, sourceDebug);
}
+ // visits the module info and associated attributes
+ if (module != 0) {
+ readModule(classVisitor, context, module,
+ moduleMainClass, packages);
+ }
+
// visits the outer class
if (enclosingOwner != null) {
classVisitor.visitOuterClass(enclosingOwner, enclosingName,
@@ -664,19 +669,19 @@
}
// visits the class annotations and type annotations
- if (ANNOTATIONS && anns != 0) {
+ if (anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
classVisitor.visitAnnotation(readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && ianns != 0) {
+ if (ianns != 0) {
for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
classVisitor.visitAnnotation(readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && tanns != 0) {
+ if (tanns != 0) {
for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -684,7 +689,7 @@
context.typePath, readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && itanns != 0) {
+ if (itanns != 0) {
for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -727,6 +732,120 @@
}
/**
+ * Reads the module attribute and visit it.
+ *
+ * @param classVisitor
+ * the current class visitor
+ * @param context
+ * information about the class being parsed.
+ * @param u
+ * start offset of the module attribute in the class file.
+ * @param mainClass
+ * name of the main class of a module or null.
+ * @param packages
+ * start offset of the concealed package attribute.
+ */
+ private void readModule(final ClassVisitor classVisitor,
+ final Context context, int u,
+ final String mainClass, int packages) {
+
+ char[] buffer = context.buffer;
+
+ // reads module name, flags and version
+ String name = readModule(u, buffer);
+ int flags = readUnsignedShort(u + 2);
+ String version = readUTF8(u + 4, buffer);
+ u += 6;
+
+ ModuleVisitor mv = classVisitor.visitModule(name, flags, version);
+ if (mv == null) {
+ return;
+ }
+
+ // module attributes (main class, packages)
+ if (mainClass != null) {
+ mv.visitMainClass(mainClass);
+ }
+
+ if (packages != 0) {
+ for (int i = readUnsignedShort(packages - 2); i > 0; --i) {
+ String packaze = readPackage(packages, buffer);
+ mv.visitPackage(packaze);
+ packages += 2;
+ }
+ }
+
+ // reads requires
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String module = readModule(u, buffer);
+ int access = readUnsignedShort(u + 2);
+ String requireVersion = readUTF8(u + 4, buffer);
+ mv.visitRequire(module, access, requireVersion);
+ u += 6;
+ }
+
+ // reads exports
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String export = readPackage(u, buffer);
+ int access = readUnsignedShort(u + 2);
+ int exportToCount = readUnsignedShort(u + 4);
+ u += 6;
+ String[] tos = null;
+ if (exportToCount != 0) {
+ tos = new String[exportToCount];
+ for (int j = 0; j < tos.length; ++j) {
+ tos[j] = readModule(u, buffer);
+ u += 2;
+ }
+ }
+ mv.visitExport(export, access, tos);
+ }
+
+ // reads opens
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String open = readPackage(u, buffer);
+ int access = readUnsignedShort(u + 2);
+ int openToCount = readUnsignedShort(u + 4);
+ u += 6;
+ String[] tos = null;
+ if (openToCount != 0) {
+ tos = new String[openToCount];
+ for (int j = 0; j < tos.length; ++j) {
+ tos[j] = readModule(u, buffer);
+ u += 2;
+ }
+ }
+ mv.visitOpen(open, access, tos);
+ }
+
+ // read uses
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ mv.visitUse(readClass(u, buffer));
+ u += 2;
+ }
+
+ // read provides
+ u += 2;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ String service = readClass(u, buffer);
+ int provideWithCount = readUnsignedShort(u + 2);
+ u += 4;
+ String[] withs = new String[provideWithCount];
+ for (int j = 0; j < withs.length; ++j) {
+ withs[j] = readClass(u, buffer);
+ u += 2;
+ }
+ mv.visitProvide(service, withs);
+ }
+
+ mv.visitEnd();
+ }
+
+ /**
* Reads a field and makes the given visitor visit it.
*
* @param classVisitor
@@ -762,24 +881,20 @@
if ("ConstantValue".equals(attrName)) {
int item = readUnsignedShort(u + 8);
value = item == 0 ? null : readConst(item, c);
- } else if (SIGNATURES && "Signature".equals(attrName)) {
+ } else if ("Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
} else if ("Deprecated".equals(attrName)) {
access |= Opcodes.ACC_DEPRECATED;
} else if ("Synthetic".equals(attrName)) {
access |= Opcodes.ACC_SYNTHETIC
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
- } else if (ANNOTATIONS
- && "RuntimeVisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = u + 8;
} else {
Attribute attr = readAttribute(context.attrs, attrName, u + 8,
@@ -801,19 +916,19 @@
}
// visits the field annotations and type annotations
- if (ANNOTATIONS && anns != 0) {
+ if (anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
fv.visitAnnotation(readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && ianns != 0) {
+ if (ianns != 0) {
for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
fv.visitAnnotation(readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && tanns != 0) {
+ if (tanns != 0) {
for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -821,7 +936,7 @@
context.typePath, readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && itanns != 0) {
+ if (itanns != 0) {
for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -895,32 +1010,26 @@
exceptions[j] = readClass(exception, c);
exception += 2;
}
- } else if (SIGNATURES && "Signature".equals(attrName)) {
+ } else if ("Signature".equals(attrName)) {
signature = readUTF8(u + 8, c);
} else if ("Deprecated".equals(attrName)) {
context.access |= Opcodes.ACC_DEPRECATED;
- } else if (ANNOTATIONS
- && "RuntimeVisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
anns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = u + 8;
- } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
+ } else if ("AnnotationDefault".equals(attrName)) {
dann = u + 8;
} else if ("Synthetic".equals(attrName)) {
context.access |= Opcodes.ACC_SYNTHETIC
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleParameterAnnotations".equals(attrName)) {
mpanns = u + 8;
- } else if (ANNOTATIONS
- && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleParameterAnnotations".equals(attrName)) {
impanns = u + 8;
} else if ("MethodParameters".equals(attrName)) {
methodParameters = u + 8;
@@ -953,7 +1062,7 @@
* access, name and descriptor can have been changed, this is not
* important since they are not copied as is from the reader).
*/
- if (WRITER && mv instanceof MethodWriter) {
+ if (mv instanceof MethodWriter) {
MethodWriter mw = (MethodWriter) mv;
if (mw.cw.cr == this && signature == mw.signature) {
boolean sameExceptions = false;
@@ -990,26 +1099,26 @@
}
// visits the method annotations
- if (ANNOTATIONS && dann != 0) {
+ if (dann != 0) {
AnnotationVisitor dv = mv.visitAnnotationDefault();
readAnnotationValue(dann, c, null, dv);
if (dv != null) {
dv.visitEnd();
}
}
- if (ANNOTATIONS && anns != 0) {
+ if (anns != 0) {
for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
mv.visitAnnotation(readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && ianns != 0) {
+ if (ianns != 0) {
for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
v = readAnnotationValues(v + 2, c, true,
mv.visitAnnotation(readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && tanns != 0) {
+ if (tanns != 0) {
for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -1017,7 +1126,7 @@
context.typePath, readUTF8(v, c), true));
}
}
- if (ANNOTATIONS && itanns != 0) {
+ if (itanns != 0) {
for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
v = readAnnotationTarget(context, v);
v = readAnnotationValues(v + 2, c, true,
@@ -1025,10 +1134,10 @@
context.typePath, readUTF8(v, c), false));
}
}
- if (ANNOTATIONS && mpanns != 0) {
+ if (mpanns != 0) {
readParameterAnnotations(mv, context, mpanns, true);
}
- if (ANNOTATIONS && impanns != 0) {
+ if (impanns != 0) {
readParameterAnnotations(mv, context, impanns, false);
}
@@ -1075,7 +1184,7 @@
int codeStart = u;
int codeEnd = u + codeLength;
Label[] labels = context.labels = new Label[codeLength + 2];
- readLabel(codeLength + 1, labels);
+ createLabel(codeLength + 1, labels);
while (u < codeEnd) {
int offset = u - codeStart;
int opcode = b[u] & 0xFF;
@@ -1085,11 +1194,16 @@
u += 1;
break;
case ClassWriter.LABEL_INSN:
- readLabel(offset + readShort(u + 1), labels);
+ createLabel(offset + readShort(u + 1), labels);
+ u += 3;
+ break;
+ case ClassWriter.ASM_LABEL_INSN:
+ createLabel(offset + readUnsignedShort(u + 1), labels);
u += 3;
break;
case ClassWriter.LABELW_INSN:
- readLabel(offset + readInt(u + 1), labels);
+ case ClassWriter.ASM_LABELW_INSN:
+ createLabel(offset + readInt(u + 1), labels);
u += 5;
break;
case ClassWriter.WIDE_INSN:
@@ -1104,9 +1218,9 @@
// skips 0 to 3 padding bytes
u = u + 4 - (offset & 3);
// reads instruction
- readLabel(offset + readInt(u), labels);
+ createLabel(offset + readInt(u), labels);
for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
- readLabel(offset + readInt(u + 12), labels);
+ createLabel(offset + readInt(u + 12), labels);
u += 4;
}
u += 12;
@@ -1115,9 +1229,9 @@
// skips 0 to 3 padding bytes
u = u + 4 - (offset & 3);
// reads instruction
- readLabel(offset + readInt(u), labels);
+ createLabel(offset + readInt(u), labels);
for (int i = readInt(u + 4); i > 0; --i) {
- readLabel(offset + readInt(u + 12), labels);
+ createLabel(offset + readInt(u + 12), labels);
u += 8;
}
u += 8;
@@ -1147,9 +1261,9 @@
// reads the try catch entries to find the labels, and also visits them
for (int i = readUnsignedShort(u); i > 0; --i) {
- Label start = readLabel(readUnsignedShort(u + 2), labels);
- Label end = readLabel(readUnsignedShort(u + 4), labels);
- Label handler = readLabel(readUnsignedShort(u + 6), labels);
+ Label start = createLabel(readUnsignedShort(u + 2), labels);
+ Label end = createLabel(readUnsignedShort(u + 4), labels);
+ Label handler = createLabel(readUnsignedShort(u + 6), labels);
String type = readUTF8(items[readUnsignedShort(u + 8)], c);
mv.visitTryCatchBlock(start, end, handler, type);
u += 8;
@@ -1180,13 +1294,9 @@
varTable = u + 8;
for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
int label = readUnsignedShort(v + 10);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
+ createDebugLabel(label, labels);
label += readUnsignedShort(v + 12);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
+ createDebugLabel(label, labels);
v += 10;
}
}
@@ -1196,9 +1306,7 @@
if ((context.flags & SKIP_DEBUG) == 0) {
for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
int label = readUnsignedShort(v + 10);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
+ createDebugLabel(label, labels);
Label l = labels[label];
while (l.line > 0) {
if (l.next == null) {
@@ -1210,17 +1318,15 @@
v += 4;
}
}
- } else if (ANNOTATIONS
- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
tanns = readTypeAnnotations(mv, context, u + 8, true);
ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
: readUnsignedShort(tanns[0] + 1);
- } else if (ANNOTATIONS
- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+ } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
itanns = readTypeAnnotations(mv, context, u + 8, false);
nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
: readUnsignedShort(itanns[0] + 1);
- } else if (FRAMES && "StackMapTable".equals(attrName)) {
+ } else if ("StackMapTable".equals(attrName)) {
if ((context.flags & SKIP_FRAMES) == 0) {
stackMap = u + 10;
stackMapSize = readInt(u + 4);
@@ -1244,7 +1350,7 @@
* this by parsing the stack map table without a full decoding
* (see below).
*/
- } else if (FRAMES && "StackMap".equals(attrName)) {
+ } else if ("StackMap".equals(attrName)) {
if ((context.flags & SKIP_FRAMES) == 0) {
zip = false;
stackMap = u + 10;
@@ -1273,7 +1379,7 @@
u += 2;
// generates the first (implicit) stack map frame
- if (FRAMES && stackMap != 0) {
+ if (stackMap != 0) {
/*
* for the first explicit frame the offset is not offset_delta + 1
* but only offset_delta; setting the implicit frame offset to -1
@@ -1306,14 +1412,31 @@
int v = readUnsignedShort(i + 1);
if (v >= 0 && v < codeLength) {
if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
- readLabel(v, labels);
+ createLabel(v, labels);
}
}
}
}
}
+ if ((context.flags & EXPAND_ASM_INSNS) != 0
+ && (context.flags & EXPAND_FRAMES) != 0) {
+ // Expanding the ASM pseudo instructions can introduce F_INSERT
+ // frames, even if the method does not currently have any frame.
+ // Also these inserted frames must be computed by simulating the
+ // effect of the bytecode instructions one by one, starting from the
+ // first one and the last existing frame (or the implicit first
+ // one). Finally, due to the way MethodWriter computes this (with
+ // the compute = INSERTED_FRAMES option), MethodWriter needs to know
+ // maxLocals before the first instruction is visited. For all these
+ // reasons we always visit the implicit first frame in this case
+ // (passing only maxLocals - the rest can be and is computed in
+ // MethodWriter).
+ mv.visitFrame(Opcodes.F_NEW, maxLocals, null, 0, null);
+ }
// visits the instructions
+ int opcodeDelta = (context.flags & EXPAND_ASM_INSNS) == 0 ? -33 : 0;
+ boolean insertFrame = false;
u = codeStart;
while (u < codeEnd) {
int offset = u - codeStart;
@@ -1334,7 +1457,7 @@
}
// visits the frame for this offset, if any
- while (FRAMES && frame != null
+ while (frame != null
&& (frame.offset == offset || frame.offset == -1)) {
// if there is a frame for this offset, makes the visitor visit
// it, and reads the next frame if there is one.
@@ -1346,6 +1469,9 @@
mv.visitFrame(frame.mode, frame.localDiff, frame.local,
frame.stackCount, frame.stack);
}
+ // if there is already a frame for this offset, there is no
+ // need to insert a new one.
+ insertFrame = false;
}
if (frameCount > 0) {
stackMap = readFrame(stackMap, zip, unzip, frame);
@@ -1354,6 +1480,13 @@
frame = null;
}
}
+ // inserts a frame for this offset, if requested by setting
+ // insertFrame to true during the previous iteration. The actual
+ // frame content will be computed in MethodWriter.
+ if (insertFrame) {
+ mv.visitFrame(ClassWriter.F_INSERT, 0, null, 0, null);
+ insertFrame = false;
+ }
// visits the instruction at this offset
int opcode = b[u] & 0xFF;
@@ -1378,9 +1511,47 @@
u += 3;
break;
case ClassWriter.LABELW_INSN:
- mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
+ mv.visitJumpInsn(opcode + opcodeDelta, labels[offset
+ + readInt(u + 1)]);
u += 5;
break;
+ case ClassWriter.ASM_LABEL_INSN: {
+ // changes temporary opcodes 202 to 217 (inclusive), 218
+ // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+ // IFNONNULL
+ opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+ Label target = labels[offset + readUnsignedShort(u + 1)];
+ // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+ // <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is
+ // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+ // and where <L> designates the instruction just after
+ // the GOTO_W.
+ if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+ mv.visitJumpInsn(opcode + 33, target);
+ } else {
+ opcode = opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+ : opcode ^ 1;
+ Label endif = createLabel(offset + 3, labels);
+ mv.visitJumpInsn(opcode, endif);
+ mv.visitJumpInsn(200, target); // GOTO_W
+ // endif designates the instruction just after GOTO_W,
+ // and is visited as part of the next instruction. Since
+ // it is a jump target, we need to insert a frame here.
+ insertFrame = true;
+ }
+ u += 3;
+ break;
+ }
+ case ClassWriter.ASM_LABELW_INSN: {
+ // replaces the pseudo GOTO_W instruction with a real one.
+ mv.visitJumpInsn(200, labels[offset + readInt(u + 1)]);
+ // The instruction just after is a jump target (because pseudo
+ // GOTO_W are used in patterns IFNOTxxx <L> GOTO_W <l> L:...,
+ // see MethodWriter), so we need to insert a frame here.
+ insertFrame = true;
+ u += 5;
+ break;
+ }
case ClassWriter.WIDE_INSN:
opcode = b[u + 1] & 0xFF;
if (opcode == Opcodes.IINC) {
@@ -1636,8 +1807,8 @@
for (int j = readUnsignedShort(u + 1); j > 0; --j) {
int start = readUnsignedShort(u + 3);
int length = readUnsignedShort(u + 5);
- readLabel(start, context.labels);
- readLabel(start + length, context.labels);
+ createLabel(start, context.labels);
+ createLabel(start + length, context.labels);
u += 6;
}
u += 3;
@@ -1716,8 +1887,8 @@
for (int i = 0; i < n; ++i) {
int start = readUnsignedShort(u);
int length = readUnsignedShort(u + 2);
- context.start[i] = readLabel(start, context.labels);
- context.end[i] = readLabel(start + length, context.labels);
+ context.start[i] = createLabel(start, context.labels);
+ context.end[i] = createLabel(start + length, context.labels);
context.index[i] = readUnsignedShort(u + 4);
u += 6;
}
@@ -2137,7 +2308,7 @@
}
}
frame.offset += delta + 1;
- readLabel(frame.offset, labels);
+ createLabel(frame.offset, labels);
return stackMap;
}
@@ -2190,7 +2361,7 @@
v += 2;
break;
default: // Uninitialized
- frame[index] = readLabel(readUnsignedShort(v), labels);
+ frame[index] = createLabel(readUnsignedShort(v), labels);
v += 2;
}
return v;
@@ -2217,6 +2388,39 @@
}
/**
+ * Creates a label without the Label.DEBUG flag set, for the given offset.
+ * The label is created with a call to {@link #readLabel} and its
+ * Label.DEBUG flag is cleared.
+ *
+ * @param offset
+ * a bytecode offset in a method.
+ * @param labels
+ * the already created labels, indexed by their offset.
+ * @return a Label without the Label.DEBUG flag set.
+ */
+ private Label createLabel(int offset, Label[] labels) {
+ Label label = readLabel(offset, labels);
+ label.status &= ~Label.DEBUG;
+ return label;
+ }
+
+ /**
+ * Creates a label with the Label.DEBUG flag set, if there is no already
+ * existing label for the given offset (otherwise does nothing). The label
+ * is created with a call to {@link #readLabel}.
+ *
+ * @param offset
+ * a bytecode offset in a method.
+ * @param labels
+ * the already created labels, indexed by their offset.
+ */
+ private void createDebugLabel(int offset, Label[] labels) {
+ if (labels[offset] == null) {
+ readLabel(offset, labels).status |= Label.DEBUG;
+ }
+ }
+
+ /**
* Returns the start index of the attribute_info structure of this class.
*
* @return the start index of the attribute_info structure of this class.
@@ -2471,6 +2675,20 @@
}
/**
+ * Read a stringish constant item (CONSTANT_Class, CONSTANT_String,
+ * CONSTANT_MethodType, CONSTANT_Module or CONSTANT_Package
+ * @param index
+ * @param buf
+ * @return
+ */
+ private String readStringish(final int index, final char[] buf) {
+ // computes the start index of the item in b
+ // and reads the CONSTANT_Utf8 item designated by
+ // the first two bytes of this item
+ return readUTF8(items[readUnsignedShort(index)], buf);
+ }
+
+ /**
* Reads a class constant pool item in {@link #b b}. <i>This method is
* intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.</i>
@@ -2484,44 +2702,41 @@
* @return the String corresponding to the specified class item.
*/
public String readClass(final int index, final char[] buf) {
- // computes the start index of the CONSTANT_Class item in b
- // and reads the CONSTANT_Utf8 item designated by
- // the first two bytes of this CONSTANT_Class item
- return readUTF8(items[readUnsignedShort(index)], buf);
+ return readStringish(index, buf);
}
/**
- * Reads a CONSTANT_Module_info item in {@code b}. This method is intended
- * for {@link Attribute} sub classes, and is normally not needed by class
- * generators or adapters.</i>
+ * Reads a module constant pool item in {@link #b b}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.</i>
*
- * @param index
- * the start index of an unsigned short value in {@link #b b},
- * whose value is the index of a module constant pool item.
- * @param buf
- * buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of a module constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
* @return the String corresponding to the specified module item.
*/
- public String readModule(int index, char[] buf) {
- return readUTF8(items[readUnsignedShort(index)], buf);
+ public String readModule(final int index, final char[] buf) {
+ return readStringish(index, buf);
}
/**
- * Reads a CONSTANT_Package_info item in {@code b}. This method is
- * intended for {@link Attribute} sub slasses, and is normally not needed
- * by class generators or adapters.</i>
+ * Reads a module constant pool item in {@link #b b}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.</i>
*
- * @param index
- * the start index of an unsigned short value in {@link #b b},
- * whose value is the index of a package constant pool item.
- * @param buf
- * buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
- * @return the String corresponding to the specified package item.
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of a module constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
+ * @return the String corresponding to the specified module item.
*/
- public String readPackage(int index, char[] buf) {
- return readUTF8(items[readUnsignedShort(index)], buf);
+ public String readPackage(final int index, final char[] buf) {
+ return readStringish(index, buf);
}
/**
@@ -2550,8 +2765,6 @@
case ClassWriter.DOUBLE:
return Double.longBitsToDouble(readLong(index));
case ClassWriter.CLASS:
- case ClassWriter.MODULE:
- case ClassWriter.PACKAGE:
return Type.getObjectType(readUTF8(index, buf));
case ClassWriter.STR:
return readUTF8(index, buf);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -61,7 +61,7 @@
/**
* A visitor to visit a Java class. The methods of this class must be called in
* the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
- * <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
+ * <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
* <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
* <tt>visitEnd</tt>.
@@ -72,7 +72,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -87,7 +87,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public ClassVisitor(final int api) {
this(api, null);
@@ -98,13 +98,13 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param cv
* the class visitor to which this visitor must delegate method
* calls. May be null.
*/
public ClassVisitor(final int api, final ClassVisitor cv) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
@@ -161,6 +161,28 @@
}
/**
+ * Visit the module corresponding to the class.
+ * @param name
+ * module name
+ * @param access
+ * module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+ * and {@code ACC_MANDATED}.
+ * @param version
+ * module version or null.
+ * @return a visitor to visit the module values, or <tt>null</tt> if
+ * this visitor is not interested in visiting this module.
+ */
+ public ModuleVisitor visitModule(String name, int access, String version) {
+ if (api < Opcodes.ASM6) {
+ throw new RuntimeException();
+ }
+ if (cv != null) {
+ return cv.visitModule(name, access, version);
+ }
+ return null;
+ }
+
+ /**
* Visits the enclosing class of the class. This method must be called only
* if the class has an enclosing class.
*
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java Thu Nov 02 13:18:23 2017 -0700
@@ -87,8 +87,8 @@
* {@link MethodVisitor#visitFrame} method are ignored, and the stack map
* frames are recomputed from the methods bytecode. The arguments of the
* {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
- * recomputed from the bytecode. In other words, computeFrames implies
- * computeMaxs.
+ * recomputed from the bytecode. In other words, COMPUTE_FRAMES implies
+ * COMPUTE_MAXS.
*
* @see #ClassWriter(int)
*/
@@ -197,6 +197,27 @@
static final int WIDE_INSN = 17;
/**
+ * The type of the ASM pseudo instructions with an unsigned 2 bytes offset
+ * label (see Label#resolve).
+ */
+ static final int ASM_LABEL_INSN = 18;
+
+ /**
+ * The type of the ASM pseudo instructions with a 4 bytes offset label.
+ */
+ static final int ASM_LABELW_INSN = 19;
+
+ /**
+ * Represents a frame inserted between already existing frames. This kind of
+ * frame can only be used if the frame content can be computed from the
+ * previous existing frame and from the instructions between this existing
+ * frame and the inserted one, without any knowledge of the type hierarchy.
+ * This kind of frame is only used when an unconditional jump is inserted in
+ * a method while expanding an ASM pseudo instruction (see ClassReader).
+ */
+ static final int F_INSERT = 256;
+
+ /**
* The instruction types of all JVM opcodes.
*/
static final byte[] TYPE;
@@ -284,7 +305,7 @@
/**
* The base value for all CONSTANT_MethodHandle constant pool items.
* Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
- * different items.
+ * different items (from 21 to 29).
*/
static final int HANDLE_BASE = 20;
@@ -434,6 +455,11 @@
private ByteVector sourceDebug;
/**
+ * The module attribute of this class.
+ */
+ private ModuleWriter moduleWriter;
+
+ /**
* The constant pool item that contains the name of the enclosing class of
* this class.
*/
@@ -523,25 +549,19 @@
MethodWriter lastMethod;
/**
- * <tt>true</tt> if the maximum stack size and number of local variables
- * must be automatically computed.
+ * Indicates what must be automatically computed.
+ *
+ * @see MethodWriter#compute
*/
- private boolean computeMaxs;
+ private int compute;
/**
- * <tt>true</tt> if the stack map frames must be recomputed from scratch.
+ * <tt>true</tt> if some methods have wide forward jumps using ASM pseudo
+ * instructions, which need to be expanded into sequences of standard
+ * bytecode instructions. In this case the class is re-read and re-written
+ * with a ClassReader -> ClassWriter chain to perform this transformation.
*/
- private boolean computeFrames;
-
- /**
- * <tt>true</tt> if the stack map tables of this class are invalid. The
- * {@link MethodWriter#resizeInstructions} method cannot transform existing
- * stack map tables, and so produces potentially invalid classes when it is
- * executed. In this case the class is reread and rewritten with the
- * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
- * stack map tables when this option is used).
- */
- boolean invalidFrames;
+ boolean hasAsmInsns;
// ------------------------------------------------------------------------
// Static initializer
@@ -552,11 +572,11 @@
*/
static {
int i;
- byte[] b = new byte[220];
+ byte[] b = new byte[221];
String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
+ "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
- + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
+ + "AAAAGGGGGGGHIFBFAAFFAARQJJKKSSSSSSSSSSSSSSSSSST";
for (i = 0; i < b.length; ++i) {
b[i] = (byte) (s.charAt(i) - 'A');
}
@@ -610,8 +630,9 @@
// // temporary opcodes used internally by ASM - see Label and
// MethodWriter
// for (i = 202; i < 220; ++i) {
- // b[i] = LABEL_INSN;
+ // b[i] = ASM_LABEL_INSN;
// }
+ // b[220] = ASM_LABELW_INSN;
//
// // LDC(_W) instructions
// b[Constants.LDC] = LDC_INSN;
@@ -644,7 +665,7 @@
* {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final int flags) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
index = 1;
pool = new ByteVector();
items = new Item[256];
@@ -653,8 +674,9 @@
key2 = new Item();
key3 = new Item();
key4 = new Item();
- this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
- this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
+ this.compute = (flags & COMPUTE_FRAMES) != 0 ? MethodWriter.FRAMES
+ : ((flags & COMPUTE_MAXS) != 0 ? MethodWriter.MAXS
+ : MethodWriter.NOTHING);
}
/**
@@ -684,9 +706,9 @@
* @param flags
* option flags that can be used to modify the default behavior
* of this class. <i>These option flags do not affect methods
- * that are copied as is in the new class. This means that the
- * maximum stack size nor the stack frames will be computed for
- * these methods</i>. See {@link #COMPUTE_MAXS},
+ * that are copied as is in the new class. This means that
+ * neither the maximum stack size nor the stack frames will be
+ * computed for these methods</i>. See {@link #COMPUTE_MAXS},
* {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final ClassReader classReader, final int flags) {
@@ -705,9 +727,9 @@
final String[] interfaces) {
this.version = version;
this.access = access;
- this.name = (name == null) ? 0 : newClass(name);
+ this.name = newClass(name);
thisName = name;
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
this.signature = newUTF8(signature);
}
this.superName = superName == null ? 0 : newClass(superName);
@@ -732,6 +754,14 @@
}
@Override
+ public final ModuleVisitor visitModule(final String name,
+ final int access, final String version) {
+ return moduleWriter = new ModuleWriter(this,
+ newModule(name), access,
+ version == null ? 0 : newUTF8(version));
+ }
+
+ @Override
public final void visitOuterClass(final String owner, final String name,
final String desc) {
enclosingMethodOwner = newClass(owner);
@@ -743,9 +773,6 @@
@Override
public final AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write type, and reserve space for values count
bv.putShort(newUTF8(desc)).putShort(0);
@@ -763,9 +790,6 @@
@Override
public final AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, final String desc, final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -805,7 +829,7 @@
// and equality tests). If so we store the index of this inner class
// entry (plus one) in intVal. This hack allows duplicate detection in
// O(1) time.
- Item nameItem = newClassItem(name);
+ Item nameItem = newStringishItem(CLASS, name);
if (nameItem.intVal == 0) {
++innerClassesCount;
innerClasses.putShort(nameItem.index);
@@ -830,7 +854,7 @@
public final MethodVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
return new MethodWriter(this, access, name, desc, signature,
- exceptions, computeMaxs, computeFrames);
+ exceptions, compute);
}
@Override
@@ -874,7 +898,7 @@
size += 8 + bootstrapMethods.length;
newUTF8("BootstrapMethods");
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
++attributeCount;
size += 8;
newUTF8("Signature");
@@ -912,26 +936,31 @@
size += 8 + innerClasses.length;
newUTF8("InnerClasses");
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
++attributeCount;
size += 8 + anns.getSize();
newUTF8("RuntimeVisibleAnnotations");
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
++attributeCount;
size += 8 + ianns.getSize();
newUTF8("RuntimeInvisibleAnnotations");
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
++attributeCount;
size += 8 + tanns.getSize();
newUTF8("RuntimeVisibleTypeAnnotations");
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
++attributeCount;
size += 8 + itanns.getSize();
newUTF8("RuntimeInvisibleTypeAnnotations");
}
+ if (moduleWriter != null) {
+ attributeCount += 1 + moduleWriter.attributeCount;
+ size += 6 + moduleWriter.size + moduleWriter.attributesSize;
+ newUTF8("Module");
+ }
if (attrs != null) {
attributeCount += attrs.getCount();
size += attrs.getSize(this, null, 0, -1, -1);
@@ -968,7 +997,7 @@
bootstrapMethodsCount);
out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
}
if (sourceFile != 0) {
@@ -979,6 +1008,11 @@
out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
out.putByteArray(sourceDebug.data, 0, len);
}
+ if (moduleWriter != null) {
+ out.putShort(newUTF8("Module"));
+ moduleWriter.put(out);
+ moduleWriter.putAttributes(out);
+ }
if (enclosingMethodOwner != 0) {
out.putShort(newUTF8("EnclosingMethod")).putInt(4);
out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
@@ -997,41 +1031,46 @@
out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
out.putByteArray(innerClasses.data, 0, innerClasses.length);
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
out.putShort(newUTF8("RuntimeVisibleAnnotations"));
anns.put(out);
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out);
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out);
}
if (attrs != null) {
attrs.put(this, null, 0, -1, -1, out);
}
- if (invalidFrames) {
+ if (hasAsmInsns) {
+ boolean hasFrames = false;
+ mb = firstMethod;
+ while (mb != null) {
+ hasFrames |= mb.frameCount > 0;
+ mb = (MethodWriter) mb.mv;
+ }
anns = null;
ianns = null;
attrs = null;
- innerClassesCount = 0;
- innerClasses = null;
- bootstrapMethodsCount = 0;
- bootstrapMethods = null;
+ moduleWriter = null;
firstField = null;
lastField = null;
firstMethod = null;
lastMethod = null;
- computeMaxs = false;
- computeFrames = true;
- invalidFrames = false;
- new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES);
+ compute =
+ hasFrames ? MethodWriter.INSERTED_FRAMES : MethodWriter.NOTHING;
+ hasAsmInsns = false;
+ new ClassReader(out.data).accept(this,
+ (hasFrames ? ClassReader.EXPAND_FRAMES : 0)
+ | ClassReader.EXPAND_ASM_INSNS);
return toByteArray();
}
return out.data;
@@ -1078,16 +1117,16 @@
double val = ((Double) cst).doubleValue();
return newDouble(val);
} else if (cst instanceof String) {
- return newString((String) cst);
+ return newStringishItem(STR, (String) cst);
} else if (cst instanceof Type) {
Type t = (Type) cst;
int s = t.getSort();
if (s == Type.OBJECT) {
- return newClassItem(t.getInternalName());
+ return newStringishItem(CLASS, t.getInternalName());
} else if (s == Type.METHOD) {
- return newMethodTypeItem(t.getDescriptor());
+ return newStringishItem(MTYPE, t.getDescriptor());
} else { // s == primitive type or array
- return newClassItem(t.getDescriptor());
+ return newStringishItem(CLASS, t.getDescriptor());
}
} else if (cst instanceof Handle) {
Handle h = (Handle) cst;
@@ -1136,20 +1175,21 @@
}
/**
- * Adds a class reference to the constant pool of the class being build.
+ * Adds a string reference, a class reference, a method type, a module
+ * or a package to the constant pool of the class being build.
* Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
*
+ * @param type
+ * a type among STR, CLASS, MTYPE, MODULE or PACKAGE
* @param value
- * the internal name of the class.
- * @return a new or already existing class reference item.
+ * string value of the reference.
+ * @return a new or already existing reference item.
*/
- Item newClassItem(final String value) {
- key2.set(CLASS, value, null, null);
+ Item newStringishItem(final int type, final String value) {
+ key2.set(type, value, null, null);
Item result = get(key2);
if (result == null) {
- pool.put12(CLASS, newUTF8(value));
+ pool.put12(type, newUTF8(value));
result = new Item(index++, key2);
put(result);
}
@@ -1167,72 +1207,7 @@
* @return the index of a new or already existing class reference item.
*/
public int newClass(final String value) {
- return newClassItem(value).index;
- }
-
- /**
- * Adds a module name to the constant pool.
- *
- * Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
- *
- * @param value
- * the module name
- * @return the index of a new or already existing module reference item.
- */
- public int newModule(String value) {
- key2.set(MODULE, value, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(MODULE, newUTF8(value));
- result = new Item(index++, key2);
- put(result);
- }
- return result.index;
- }
-
- /**
- * Adds a package name to the constant pool.
- *
- * Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
- *
- * @param value
- * the internal name of the package.
- * @return the index of a new or already existing package reference item.
- */
- public int newPackage(String value) {
- key2.set(PACKAGE, value, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(PACKAGE, newUTF8(value));
- result = new Item(index++, key2);
- put(result);
- }
- return result.index;
- }
-
- /**
- * Adds a method type reference to the constant pool of the class being
- * build. Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
- *
- * @param methodDesc
- * method descriptor of the method type.
- * @return a new or already existing method type reference item.
- */
- Item newMethodTypeItem(final String methodDesc) {
- key2.set(MTYPE, methodDesc, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(MTYPE, newUTF8(methodDesc));
- result = new Item(index++, key2);
- put(result);
- }
- return result;
+ return newStringishItem(CLASS, value).index;
}
/**
@@ -1247,7 +1222,37 @@
* item.
*/
public int newMethodType(final String methodDesc) {
- return newMethodTypeItem(methodDesc).index;
+ return newStringishItem(MTYPE, methodDesc).index;
+ }
+
+ /**
+ * Adds a module reference to the constant pool of the class being
+ * build. Does nothing if the constant pool already contains a similar item.
+ * <i>This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.</i>
+ *
+ * @param moduleName
+ * name of the module.
+ * @return the index of a new or already existing module reference
+ * item.
+ */
+ public int newModule(final String moduleName) {
+ return newStringishItem(MODULE, moduleName).index;
+ }
+
+ /**
+ * Adds a package reference to the constant pool of the class being
+ * build. Does nothing if the constant pool already contains a similar item.
+ * <i>This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.</i>
+ *
+ * @param packageName
+ * name of the package in its internal form.
+ * @return the index of a new or already existing module reference
+ * item.
+ */
+ public int newPackage(final String packageName) {
+ return newStringishItem(PACKAGE, packageName).index;
}
/**
@@ -1629,25 +1634,6 @@
}
/**
- * Adds a string to the constant pool of the class being build. Does nothing
- * if the constant pool already contains a similar item.
- *
- * @param value
- * the String value.
- * @return a new or already existing string item.
- */
- private Item newString(final String value) {
- key2.set(STR, value, null, null);
- Item result = get(key2);
- if (result == null) {
- pool.put12(STR, newUTF8(value));
- result = new Item(index++, key2);
- put(result);
- }
- return result;
- }
-
- /**
* Adds a name and type to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item. <i>This
* method is intended for {@link Attribute} sub classes, and is normally not
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/CurrentFrame.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * Information about the input stack map frame at the "current" instruction of a
+ * method. This is implemented as a Frame subclass for a "basic block"
+ * containing only one instruction.
+ *
+ * @author Eric Bruneton
+ */
+class CurrentFrame extends Frame {
+
+ /**
+ * Sets this CurrentFrame to the input stack map frame of the next "current"
+ * instruction, i.e. the instruction just after the given one. It is assumed
+ * that the value of this object when this method is called is the stack map
+ * frame status just before the given instruction is executed.
+ */
+ @Override
+ void execute(int opcode, int arg, ClassWriter cw, Item item) {
+ super.execute(opcode, arg, cw, item);
+ Frame successor = new Frame();
+ merge(cw, successor, 0);
+ set(successor);
+ owner.inputStackTop = 0;
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -69,7 +69,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -84,7 +84,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public FieldVisitor(final int api) {
this(api, null);
@@ -95,13 +95,13 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param fv
* the field visitor to which this visitor must delegate method
* calls. May be null.
*/
public FieldVisitor(final int api, final FieldVisitor fv) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java Thu Nov 02 13:18:23 2017 -0700
@@ -147,7 +147,7 @@
*/
FieldWriter(final ClassWriter cw, final int access, final String name,
final String desc, final String signature, final Object value) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
if (cw.firstField == null) {
cw.firstField = this;
} else {
@@ -158,7 +158,7 @@
this.access = access;
this.name = cw.newUTF8(name);
this.desc = cw.newUTF8(desc);
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
this.signature = cw.newUTF8(signature);
}
if (value != null) {
@@ -173,9 +173,6 @@
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -193,9 +190,6 @@
@Override
public AnnotationVisitor visitTypeAnnotation(final int typeRef,
final TypePath typePath, final String desc, final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -249,23 +243,23 @@
cw.newUTF8("Deprecated");
size += 6;
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
cw.newUTF8("Signature");
size += 8;
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
cw.newUTF8("RuntimeVisibleAnnotations");
size += 8 + anns.getSize();
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
cw.newUTF8("RuntimeVisibleTypeAnnotations");
size += 8 + tanns.getSize();
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
cw.newUTF8("RuntimeInvisibleTypeAnnotations");
size += 8 + itanns.getSize();
}
@@ -299,19 +293,19 @@
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
++attributeCount;
}
if (attrs != null) {
@@ -331,23 +325,23 @@
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
}
- if (ClassReader.SIGNATURES && signature != 0) {
+ if (signature != 0) {
out.putShort(cw.newUTF8("Signature"));
out.putInt(2).putShort(signature);
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
anns.put(out);
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out);
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out);
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java Thu Nov 02 13:18:23 2017 -0700
@@ -63,7 +63,7 @@
*
* @author Eric Bruneton
*/
-final class Frame {
+class Frame {
/*
* Frames are computed in a two steps process: during the visit of each
@@ -525,7 +525,7 @@
* When the stack map frames are completely computed, this field is the
* actual number of types in {@link #outputStack}.
*/
- private int outputStackTop;
+ int outputStackTop;
/**
* Number of types that are initialized in the basic block.
@@ -550,6 +550,110 @@
private int[] initializations;
/**
+ * Sets this frame to the given value.
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param nLocal
+ * the number of local variables.
+ * @param local
+ * the local variable types. Primitive types are represented by
+ * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+ * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+ * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+ * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+ * represented by a single element). Reference types are
+ * represented by String objects (representing internal names),
+ * and uninitialized types by Label objects (this label
+ * designates the NEW instruction that created this uninitialized
+ * value).
+ * @param nStack
+ * the number of operand stack elements.
+ * @param stack
+ * the operand stack types (same format as the "local" array).
+ */
+ final void set(ClassWriter cw, final int nLocal, final Object[] local,
+ final int nStack, final Object[] stack) {
+ int i = convert(cw, nLocal, local, inputLocals);
+ while (i < local.length) {
+ inputLocals[i++] = TOP;
+ }
+ int nStackTop = 0;
+ for (int j = 0; j < nStack; ++j) {
+ if (stack[j] == Opcodes.LONG || stack[j] == Opcodes.DOUBLE) {
+ ++nStackTop;
+ }
+ }
+ inputStack = new int[nStack + nStackTop];
+ convert(cw, nStack, stack, inputStack);
+ outputStackTop = 0;
+ initializationCount = 0;
+ }
+
+ /**
+ * Converts types from the MethodWriter.visitFrame() format to the Frame
+ * format.
+ *
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param nInput
+ * the number of types to convert.
+ * @param input
+ * the types to convert. Primitive types are represented by
+ * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+ * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+ * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+ * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+ * represented by a single element). Reference types are
+ * represented by String objects (representing internal names),
+ * and uninitialized types by Label objects (this label
+ * designates the NEW instruction that created this uninitialized
+ * value).
+ * @param output
+ * where to store the converted types.
+ * @return the number of output elements.
+ */
+ private static int convert(ClassWriter cw, int nInput, Object[] input,
+ int[] output) {
+ int i = 0;
+ for (int j = 0; j < nInput; ++j) {
+ if (input[j] instanceof Integer) {
+ output[i++] = BASE | ((Integer) input[j]).intValue();
+ if (input[j] == Opcodes.LONG || input[j] == Opcodes.DOUBLE) {
+ output[i++] = TOP;
+ }
+ } else if (input[j] instanceof String) {
+ output[i++] = type(cw, Type.getObjectType((String) input[j])
+ .getDescriptor());
+ } else {
+ output[i++] = UNINITIALIZED
+ | cw.addUninitializedType("",
+ ((Label) input[j]).position);
+ }
+ }
+ return i;
+ }
+
+ /**
+ * Sets this frame to the value of the given frame. WARNING: after this
+ * method is called the two frames share the same data structures. It is
+ * recommended to discard the given frame f to avoid unexpected side
+ * effects.
+ *
+ * @param f
+ * The new frame value.
+ */
+ final void set(final Frame f) {
+ inputLocals = f.inputLocals;
+ inputStack = f.inputStack;
+ outputLocals = f.outputLocals;
+ outputStack = f.outputStack;
+ outputStackTop = f.outputStackTop;
+ initializationCount = f.initializationCount;
+ initializations = f.initializations;
+ }
+
+ /**
* Returns the output frame local variable type at the given index.
*
* @param local
@@ -614,7 +718,7 @@
}
// pushes the type on the output stack
outputStack[outputStackTop++] = type;
- // updates the maximun height reached by the output stack, if needed
+ // updates the maximum height reached by the output stack, if needed
int top = owner.inputStackTop + outputStackTop;
if (top > owner.outputStackMax) {
owner.outputStackMax = top;
@@ -650,7 +754,7 @@
* a type descriptor.
* @return the int encoding of the given type.
*/
- private static int type(final ClassWriter cw, final String desc) {
+ static int type(final ClassWriter cw, final String desc) {
String t;
int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
switch (desc.charAt(index)) {
@@ -838,7 +942,7 @@
* @param maxLocals
* the maximum number of local variables of this method.
*/
- void initInputFrame(final ClassWriter cw, final int access,
+ final void initInputFrame(final ClassWriter cw, final int access,
final Type[] args, final int maxLocals) {
inputLocals = new int[maxLocals];
inputStack = new int[0];
@@ -981,7 +1085,7 @@
case Opcodes.AALOAD:
pop(1);
t1 = pop();
- push(ELEMENT_OF + t1);
+ push(t1 == NULL ? t1 : ELEMENT_OF + t1);
break;
case Opcodes.ISTORE:
case Opcodes.FSTORE:
@@ -1312,7 +1416,7 @@
* @return <tt>true</tt> if the input frame of the given label has been
* changed by this operation.
*/
- boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
+ final boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
boolean changed = false;
int i, s, dim, kind, t;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Item.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Item.java Thu Nov 02 13:18:23 2017 -0700
@@ -80,6 +80,7 @@
* {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
* {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
+ * {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
*
* MethodHandle constant 9 variations are stored using a range of 9 values
@@ -239,12 +240,12 @@
this.strVal3 = strVal3;
switch (type) {
case ClassWriter.CLASS:
- case ClassWriter.MODULE:
- case ClassWriter.PACKAGE:
this.intVal = 0; // intVal of a class must be zero, see visitInnerClass
case ClassWriter.UTF8:
case ClassWriter.STR:
case ClassWriter.MTYPE:
+ case ClassWriter.MODULE:
+ case ClassWriter.PACKAGE:
case ClassWriter.TYPE_NORMAL:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java Thu Nov 02 13:18:23 2017 -0700
@@ -389,13 +389,12 @@
* the position of this label in the bytecode.
* @param data
* the bytecode of the method.
- * @return <tt>true</tt> if a blank that was left for this label was to
+ * @return <tt>true</tt> if a blank that was left for this label was too
* small to store the offset. In such a case the corresponding jump
* instruction is replaced with a pseudo instruction (using unused
* opcodes) using an unsigned two bytes offset. These pseudo
- * instructions will need to be replaced with true instructions with
- * wider offsets (4 bytes instead of 2). This is done in
- * {@link MethodWriter#resizeInstructions}.
+ * instructions will be replaced with standard bytecode instructions
+ * with wider offsets (4 bytes instead of 2), in ClassReader.
* @throws IllegalArgumentException
* if this label has already been resolved, or if it has not
* been created by the given code writer.
@@ -454,7 +453,7 @@
* @return the first label of the series to which this label belongs.
*/
Label getFirst() {
- return !ClassReader.FRAMES || frame == null ? this : frame.owner;
+ return frame == null ? this : frame.owner;
}
// ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -86,7 +86,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -101,7 +101,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public MethodVisitor(final int api) {
this(api, null);
@@ -112,13 +112,13 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this visitor must delegate method
* calls. May be null.
*/
public MethodVisitor(final int api, final MethodVisitor mv) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Thu Nov 02 13:18:23 2017 -0700
@@ -128,7 +128,19 @@
*
* @see #compute
*/
- private static final int FRAMES = 0;
+ static final int FRAMES = 0;
+
+ /**
+ * Indicates that the stack map frames of type F_INSERT must be computed.
+ * The other frames are not (re)computed. They should all be of type F_NEW
+ * and should be sufficient to compute the content of the F_INSERT frames,
+ * together with the bytecode instructions between a F_NEW and a F_INSERT
+ * frame - and without any knowledge of the type hierarchy (by definition of
+ * F_INSERT).
+ *
+ * @see #compute
+ */
+ static final int INSERTED_FRAMES = 1;
/**
* Indicates that the maximum stack size and number of local variables must
@@ -136,14 +148,14 @@
*
* @see #compute
*/
- private static final int MAXS = 1;
+ static final int MAXS = 2;
/**
* Indicates that nothing must be automatically computed.
*
* @see #compute
*/
- private static final int NOTHING = 2;
+ static final int NOTHING = 3;
/**
* The class writer to which this method must be added.
@@ -277,7 +289,7 @@
/**
* Number of stack map frames in the StackMapTable attribute.
*/
- private int frameCount;
+ int frameCount;
/**
* The StackMapTable attribute.
@@ -384,11 +396,6 @@
private Attribute cattrs;
/**
- * Indicates if some jump instructions are too small and need to be resized.
- */
- private boolean resize;
-
- /**
* The number of subroutines in this method.
*/
private int subroutines;
@@ -409,6 +416,7 @@
* Indicates what must be automatically computed.
*
* @see #FRAMES
+ * @see #INSERTED_FRAMES
* @see #MAXS
* @see #NOTHING
*/
@@ -471,18 +479,13 @@
* @param exceptions
* the internal names of the method's exceptions. May be
* <tt>null</tt>.
- * @param computeMaxs
- * <tt>true</tt> if the maximum stack size and number of local
- * variables must be automatically computed.
- * @param computeFrames
- * <tt>true</tt> if the stack map tables must be recomputed from
- * scratch.
+ * @param compute
+ * Indicates what must be automatically computed (see #compute).
*/
MethodWriter(final ClassWriter cw, final int access, final String name,
final String desc, final String signature,
- final String[] exceptions, final boolean computeMaxs,
- final boolean computeFrames) {
- super(Opcodes.ASM5);
+ final String[] exceptions, final int compute) {
+ super(Opcodes.ASM6);
if (cw.firstMethod == null) {
cw.firstMethod = this;
} else {
@@ -497,9 +500,7 @@
this.name = cw.newUTF8(name);
this.desc = cw.newUTF8(desc);
this.descriptor = desc;
- if (ClassReader.SIGNATURES) {
- this.signature = signature;
- }
+ this.signature = signature;
if (exceptions != null && exceptions.length > 0) {
exceptionCount = exceptions.length;
this.exceptions = new int[exceptionCount];
@@ -507,8 +508,8 @@
this.exceptions[i] = cw.newClass(exceptions[i]);
}
}
- this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING);
- if (computeMaxs || computeFrames) {
+ this.compute = compute;
+ if (compute != NOTHING) {
// updates maxLocals
int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -539,9 +540,6 @@
@Override
public AnnotationVisitor visitAnnotationDefault() {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
annd = new ByteVector();
return new AnnotationWriter(cw, false, annd, null, 0);
}
@@ -549,9 +547,6 @@
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -569,9 +564,6 @@
@Override
public AnnotationVisitor visitTypeAnnotation(final int typeRef,
final TypePath typePath, final String desc, final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -592,9 +584,6 @@
@Override
public AnnotationVisitor visitParameterAnnotation(final int parameter,
final String desc, final boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
if ("Ljava/lang/Synthetic;".equals(desc)) {
// workaround for a bug in javac with synthetic parameters
@@ -639,11 +628,33 @@
@Override
public void visitFrame(final int type, final int nLocal,
final Object[] local, final int nStack, final Object[] stack) {
- if (!ClassReader.FRAMES || compute == FRAMES) {
+ if (compute == FRAMES) {
return;
}
- if (type == Opcodes.F_NEW) {
+ if (compute == INSERTED_FRAMES) {
+ if (currentBlock.frame == null) {
+ // This should happen only once, for the implicit first frame
+ // (which is explicitly visited in ClassReader if the
+ // EXPAND_ASM_INSNS option is used).
+ currentBlock.frame = new CurrentFrame();
+ currentBlock.frame.owner = currentBlock;
+ currentBlock.frame.initInputFrame(cw, access,
+ Type.getArgumentTypes(descriptor), nLocal);
+ visitImplicitFirstFrame();
+ } else {
+ if (type == Opcodes.F_NEW) {
+ currentBlock.frame.set(cw, nLocal, local, nStack, stack);
+ } else {
+ // In this case type is equal to F_INSERT by hypothesis, and
+ // currentBlock.frame contains the stack map frame at the
+ // current instruction, computed from the last F_NEW frame
+ // and the bytecode instructions in between (via calls to
+ // CurrentFrame#execute).
+ }
+ visitFrame(currentBlock.frame);
+ }
+ } else if (type == Opcodes.F_NEW) {
if (previousFrame == null) {
visitImplicitFirstFrame();
}
@@ -651,10 +662,10 @@
int frameIndex = startFrame(code.length, nLocal, nStack);
for (int i = 0; i < nLocal; ++i) {
if (local[i] instanceof String) {
- frame[frameIndex++] = Frame.OBJECT
- | cw.addType((String) local[i]);
+ String desc = Type.getObjectType((String) local[i]).getDescriptor();
+ frame[frameIndex++] = Frame.type(cw, desc);
} else if (local[i] instanceof Integer) {
- frame[frameIndex++] = ((Integer) local[i]).intValue();
+ frame[frameIndex++] = Frame.BASE | ((Integer) local[i]).intValue();
} else {
frame[frameIndex++] = Frame.UNINITIALIZED
| cw.addUninitializedType("",
@@ -663,10 +674,10 @@
}
for (int i = 0; i < nStack; ++i) {
if (stack[i] instanceof String) {
- frame[frameIndex++] = Frame.OBJECT
- | cw.addType((String) stack[i]);
+ String desc = Type.getObjectType((String) stack[i]).getDescriptor();
+ frame[frameIndex++] = Frame.type(cw, desc);
} else if (stack[i] instanceof Integer) {
- frame[frameIndex++] = ((Integer) stack[i]).intValue();
+ frame[frameIndex++] = Frame.BASE | ((Integer) stack[i]).intValue();
} else {
frame[frameIndex++] = Frame.UNINITIALIZED
| cw.addUninitializedType("",
@@ -747,7 +758,7 @@
// update currentBlock
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, 0, null, null);
} else {
// updates current and max stack sizes
@@ -770,7 +781,7 @@
lastCodeOffset = code.length;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, operand, null, null);
} else if (opcode != Opcodes.NEWARRAY) {
// updates current and max stack sizes only for NEWARRAY
@@ -795,7 +806,7 @@
lastCodeOffset = code.length;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, var, null, null);
} else {
// updates current and max stack sizes
@@ -852,10 +863,10 @@
@Override
public void visitTypeInsn(final int opcode, final String type) {
lastCodeOffset = code.length;
- Item i = cw.newClassItem(type);
+ Item i = cw.newStringishItem(ClassWriter.CLASS, type);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, code.length, cw, i);
} else if (opcode == Opcodes.NEW) {
// updates current and max stack sizes only if opcode == NEW
@@ -878,7 +889,7 @@
Item i = cw.newFieldItem(owner, name, desc);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, 0, cw, i);
} else {
int size;
@@ -918,7 +929,7 @@
int argSize = i.intVal;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(opcode, 0, cw, i);
} else {
/*
@@ -970,7 +981,7 @@
int argSize = i.intVal;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i);
} else {
/*
@@ -1004,7 +1015,9 @@
}
@Override
- public void visitJumpInsn(final int opcode, final Label label) {
+ public void visitJumpInsn(int opcode, final Label label) {
+ boolean isWide = opcode >= 200; // GOTO_W
+ opcode = isWide ? opcode - 33 : opcode;
lastCodeOffset = code.length;
Label nextInsn = null;
// Label currentBlock = this.currentBlock;
@@ -1019,6 +1032,8 @@
// creates a Label for the next basic block
nextInsn = new Label();
}
+ } else if (compute == INSERTED_FRAMES) {
+ currentBlock.frame.execute(opcode, 0, null, null);
} else {
if (opcode == Opcodes.JSR) {
if ((label.status & Label.SUBROUTINE) == 0) {
@@ -1050,8 +1065,8 @@
/*
* case of a backward jump with an offset < -32768. In this case we
* automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
- * <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is the
- * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <l'>
+ * <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is the
+ * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <L>
* designates the instruction just after the GOTO_W.
*/
if (opcode == Opcodes.GOTO) {
@@ -1067,9 +1082,21 @@
code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
: opcode ^ 1);
code.putShort(8); // jump offset
- code.putByte(200); // GOTO_W
+ // ASM pseudo GOTO_W insn, see ClassReader. We don't use a real
+ // GOTO_W because we might need to insert a frame just after (as
+ // the target of the IFNOTxxx jump instruction).
+ code.putByte(220);
+ cw.hasAsmInsns = true;
}
label.put(this, code, code.length - 1, true);
+ } else if (isWide) {
+ /*
+ * case of a GOTO_W or JSR_W specified by the user (normally
+ * ClassReader when used to resize instructions). In this case we
+ * keep the original instruction.
+ */
+ code.putByte(opcode + 33);
+ label.put(this, code, code.length - 1, true);
} else {
/*
* case of a backward jump with an offset >= -32768, or of a forward
@@ -1097,7 +1124,7 @@
@Override
public void visitLabel(final Label label) {
// resolves previous forward references to label, if any
- resize |= label.resolve(this, code.length, code.data);
+ cw.hasAsmInsns |= label.resolve(this, code.length, code.data);
// updates currentBlock
if ((label.status & Label.DEBUG) != 0) {
return;
@@ -1130,6 +1157,18 @@
previousBlock.successor = label;
}
previousBlock = label;
+ } else if (compute == INSERTED_FRAMES) {
+ if (currentBlock == null) {
+ // This case should happen only once, for the visitLabel call in
+ // the constructor. Indeed, if compute is equal to
+ // INSERTED_FRAMES currentBlock can not be set back to null (see
+ // #noSuccessor).
+ currentBlock = label;
+ } else {
+ // Updates the frame owner so that a correct frame offset is
+ // computed in visitFrame(Frame).
+ currentBlock.frame.owner = label;
+ }
} else if (compute == MAXS) {
if (currentBlock != null) {
// ends current block (with one new successor)
@@ -1155,7 +1194,7 @@
Item i = cw.newConstItem(cst);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(Opcodes.LDC, 0, cw, i);
} else {
int size;
@@ -1187,7 +1226,7 @@
public void visitIincInsn(final int var, final int increment) {
lastCodeOffset = code.length;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(Opcodes.IINC, var, null, null);
}
}
@@ -1271,10 +1310,10 @@
@Override
public void visitMultiANewArrayInsn(final String desc, final int dims) {
lastCodeOffset = code.length;
- Item i = cw.newClassItem(desc);
+ Item i = cw.newStringishItem(ClassWriter.CLASS, desc);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
- if (compute == FRAMES) {
+ if (compute == FRAMES || compute == INSERTED_FRAMES) {
currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i);
} else {
// updates current stack size (max stack size unchanged because
@@ -1289,9 +1328,6 @@
@Override
public AnnotationVisitor visitInsnAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8);
@@ -1331,9 +1367,6 @@
@Override
public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -1387,9 +1420,6 @@
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
TypePath typePath, Label[] start, Label[] end, int[] index,
String desc, boolean visible) {
- if (!ClassReader.ANNOTATIONS) {
- return null;
- }
ByteVector bv = new ByteVector();
// write target_type and target_info
bv.putByte(typeRef >>> 24).putShort(start.length);
@@ -1430,15 +1460,7 @@
@Override
public void visitMaxs(final int maxStack, final int maxLocals) {
- if (resize) {
- // replaces the temporary jump opcodes introduced by Label.resolve.
- if (ClassReader.RESIZE) {
- resizeInstructions();
- } else {
- throw new RuntimeException("Method code too large!");
- }
- }
- if (ClassReader.FRAMES && compute == FRAMES) {
+ if (compute == FRAMES) {
// completes the control flow graph with exception handler blocks
Handler handler = firstHandler;
while (handler != null) {
@@ -1468,8 +1490,8 @@
// creates and visits the first (implicit) frame
Frame f = labels.frame;
- Type[] args = Type.getArgumentTypes(descriptor);
- f.initInputFrame(cw, access, args, this.maxLocals);
+ f.initInputFrame(cw, access, Type.getArgumentTypes(descriptor),
+ this.maxLocals);
visitFrame(f);
/*
@@ -1717,7 +1739,9 @@
} else {
currentBlock.outputStackMax = maxStackSize;
}
- currentBlock = null;
+ if (compute != INSERTED_FRAMES) {
+ currentBlock = null;
+ }
}
// ------------------------------------------------------------------------
@@ -1789,7 +1813,7 @@
if ((access & ACC_CONSTRUCTOR) == 0) {
frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName);
} else {
- frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS;
+ frame[frameIndex++] = Frame.UNINITIALIZED_THIS;
}
}
int i = 1;
@@ -1801,16 +1825,16 @@
case 'B':
case 'S':
case 'I':
- frame[frameIndex++] = 1; // Opcodes.INTEGER;
+ frame[frameIndex++] = Frame.INTEGER;
break;
case 'F':
- frame[frameIndex++] = 2; // Opcodes.FLOAT;
+ frame[frameIndex++] = Frame.FLOAT;
break;
case 'J':
- frame[frameIndex++] = 4; // Opcodes.LONG;
+ frame[frameIndex++] = Frame.LONG;
break;
case 'D':
- frame[frameIndex++] = 3; // Opcodes.DOUBLE;
+ frame[frameIndex++] = Frame.DOUBLE;
break;
case '[':
while (descriptor.charAt(i) == '[') {
@@ -1822,8 +1846,7 @@
++i;
}
}
- frame[frameIndex++] = Frame.OBJECT
- | cw.addType(descriptor.substring(j, ++i));
+ frame[frameIndex++] = Frame.type(cw, descriptor.substring(j, ++i));
break;
case 'L':
while (descriptor.charAt(i) != ';') {
@@ -2083,11 +2106,11 @@
cw.newUTF8(zip ? "StackMapTable" : "StackMap");
size += 8 + stackMap.length;
}
- if (ClassReader.ANNOTATIONS && ctanns != null) {
+ if (ctanns != null) {
cw.newUTF8("RuntimeVisibleTypeAnnotations");
size += 8 + ctanns.getSize();
}
- if (ClassReader.ANNOTATIONS && ictanns != null) {
+ if (ictanns != null) {
cw.newUTF8("RuntimeInvisibleTypeAnnotations");
size += 8 + ictanns.getSize();
}
@@ -2111,7 +2134,7 @@
cw.newUTF8("Deprecated");
size += 6;
}
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
cw.newUTF8("Signature");
cw.newUTF8(signature);
size += 8;
@@ -2120,34 +2143,34 @@
cw.newUTF8("MethodParameters");
size += 7 + methodParameters.length;
}
- if (ClassReader.ANNOTATIONS && annd != null) {
+ if (annd != null) {
cw.newUTF8("AnnotationDefault");
size += 6 + annd.length;
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
cw.newUTF8("RuntimeVisibleAnnotations");
size += 8 + anns.getSize();
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
cw.newUTF8("RuntimeVisibleTypeAnnotations");
size += 8 + tanns.getSize();
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
cw.newUTF8("RuntimeInvisibleTypeAnnotations");
size += 8 + itanns.getSize();
}
- if (ClassReader.ANNOTATIONS && panns != null) {
+ if (panns != null) {
cw.newUTF8("RuntimeVisibleParameterAnnotations");
size += 7 + 2 * (panns.length - synthetics);
for (int i = panns.length - 1; i >= synthetics; --i) {
size += panns[i] == null ? 0 : panns[i].getSize();
}
}
- if (ClassReader.ANNOTATIONS && ipanns != null) {
+ if (ipanns != null) {
cw.newUTF8("RuntimeInvisibleParameterAnnotations");
size += 7 + 2 * (ipanns.length - synthetics);
for (int i = ipanns.length - 1; i >= synthetics; --i) {
@@ -2193,31 +2216,31 @@
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
}
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
++attributeCount;
}
if (methodParameters != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && annd != null) {
+ if (annd != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && panns != null) {
+ if (panns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ipanns != null) {
+ if (ipanns != null) {
++attributeCount;
}
if (attrs != null) {
@@ -2238,10 +2261,10 @@
if (stackMap != null) {
size += 8 + stackMap.length;
}
- if (ClassReader.ANNOTATIONS && ctanns != null) {
+ if (ctanns != null) {
size += 8 + ctanns.getSize();
}
- if (ClassReader.ANNOTATIONS && ictanns != null) {
+ if (ictanns != null) {
size += 8 + ictanns.getSize();
}
if (cattrs != null) {
@@ -2273,10 +2296,10 @@
if (stackMap != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ctanns != null) {
+ if (ctanns != null) {
++attributeCount;
}
- if (ClassReader.ANNOTATIONS && ictanns != null) {
+ if (ictanns != null) {
++attributeCount;
}
if (cattrs != null) {
@@ -2304,11 +2327,11 @@
out.putInt(stackMap.length + 2).putShort(frameCount);
out.putByteArray(stackMap.data, 0, stackMap.length);
}
- if (ClassReader.ANNOTATIONS && ctanns != null) {
+ if (ctanns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
ctanns.put(out);
}
- if (ClassReader.ANNOTATIONS && ictanns != null) {
+ if (ictanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
ictanns.put(out);
}
@@ -2333,7 +2356,7 @@
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
}
- if (ClassReader.SIGNATURES && signature != null) {
+ if (signature != null) {
out.putShort(cw.newUTF8("Signature")).putInt(2)
.putShort(cw.newUTF8(signature));
}
@@ -2343,32 +2366,32 @@
methodParametersCount);
out.putByteArray(methodParameters.data, 0, methodParameters.length);
}
- if (ClassReader.ANNOTATIONS && annd != null) {
+ if (annd != null) {
out.putShort(cw.newUTF8("AnnotationDefault"));
out.putInt(annd.length);
out.putByteArray(annd.data, 0, annd.length);
}
- if (ClassReader.ANNOTATIONS && anns != null) {
+ if (anns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
anns.put(out);
}
- if (ClassReader.ANNOTATIONS && ianns != null) {
+ if (ianns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
- if (ClassReader.ANNOTATIONS && tanns != null) {
+ if (tanns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out);
}
- if (ClassReader.ANNOTATIONS && itanns != null) {
+ if (itanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out);
}
- if (ClassReader.ANNOTATIONS && panns != null) {
+ if (panns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
AnnotationWriter.put(panns, synthetics, out);
}
- if (ClassReader.ANNOTATIONS && ipanns != null) {
+ if (ipanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations"));
AnnotationWriter.put(ipanns, synthetics, out);
}
@@ -2376,569 +2399,4 @@
attrs.put(cw, null, 0, -1, -1, out);
}
}
-
- // ------------------------------------------------------------------------
- // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W)
- // ------------------------------------------------------------------------
-
- /**
- * Resizes and replaces the temporary instructions inserted by
- * {@link Label#resolve} for wide forward jumps, while keeping jump offsets
- * and instruction addresses consistent. This may require to resize other
- * existing instructions, or even to introduce new instructions: for
- * example, increasing the size of an instruction by 2 at the middle of a
- * method can increases the offset of an IFEQ instruction from 32766 to
- * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
- * 32765. This, in turn, may require to increase the size of another jump
- * instruction, and so on... All these operations are handled automatically
- * by this method.
- * <p>
- * <i>This method must be called after all the method that is being built
- * has been visited</i>. In particular, the {@link Label Label} objects used
- * to construct the method are no longer valid after this method has been
- * called.
- */
- private void resizeInstructions() {
- byte[] b = code.data; // bytecode of the method
- int u, v, label; // indexes in b
- int i, j; // loop indexes
- /*
- * 1st step: As explained above, resizing an instruction may require to
- * resize another one, which may require to resize yet another one, and
- * so on. The first step of the algorithm consists in finding all the
- * instructions that need to be resized, without modifying the code.
- * This is done by the following "fix point" algorithm:
- *
- * Parse the code to find the jump instructions whose offset will need
- * more than 2 bytes to be stored (the future offset is computed from
- * the current offset and from the number of bytes that will be inserted
- * or removed between the source and target instructions). For each such
- * instruction, adds an entry in (a copy of) the indexes and sizes
- * arrays (if this has not already been done in a previous iteration!).
- *
- * If at least one entry has been added during the previous step, go
- * back to the beginning, otherwise stop.
- *
- * In fact the real algorithm is complicated by the fact that the size
- * of TABLESWITCH and LOOKUPSWITCH instructions depends on their
- * position in the bytecode (because of padding). In order to ensure the
- * convergence of the algorithm, the number of bytes to be added or
- * removed from these instructions is over estimated during the previous
- * loop, and computed exactly only after the loop is finished (this
- * requires another pass to parse the bytecode of the method).
- */
- int[] allIndexes = new int[0]; // copy of indexes
- int[] allSizes = new int[0]; // copy of sizes
- boolean[] resize; // instructions to be resized
- int newOffset; // future offset of a jump instruction
-
- resize = new boolean[code.length];
-
- // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done
- int state = 3;
- do {
- if (state == 3) {
- state = 2;
- }
- u = 0;
- while (u < b.length) {
- int opcode = b[u] & 0xFF; // opcode of current instruction
- int insert = 0; // bytes to be added after this instruction
-
- switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- case ClassWriter.IMPLVAR_INSN:
- u += 1;
- break;
- case ClassWriter.LABEL_INSN:
- if (opcode > 201) {
- // converts temporary opcodes 202 to 217, 218 and
- // 219 to IFEQ ... JSR (inclusive), IFNULL and
- // IFNONNULL
- opcode = opcode < 218 ? opcode - 49 : opcode - 20;
- label = u + readUnsignedShort(b, u + 1);
- } else {
- label = u + readShort(b, u + 1);
- }
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- if (newOffset < Short.MIN_VALUE
- || newOffset > Short.MAX_VALUE) {
- if (!resize[u]) {
- if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
- // two additional bytes will be required to
- // replace this GOTO or JSR instruction with
- // a GOTO_W or a JSR_W
- insert = 2;
- } else {
- // five additional bytes will be required to
- // replace this IFxxx <l> instruction with
- // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
- // is the "opposite" opcode of IFxxx (i.e.,
- // IFNE for IFEQ) and where <l'> designates
- // the instruction just after the GOTO_W.
- insert = 5;
- }
- resize[u] = true;
- }
- }
- u += 3;
- break;
- case ClassWriter.LABELW_INSN:
- u += 5;
- break;
- case ClassWriter.TABL_INSN:
- if (state == 1) {
- // true number of bytes to be added (or removed)
- // from this instruction = (future number of padding
- // bytes - current number of padding byte) -
- // previously over estimated variation =
- // = ((3 - newOffset%4) - (3 - u%4)) - u%4
- // = (-newOffset%4 + u%4) - u%4
- // = -(newOffset & 3)
- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
- insert = -(newOffset & 3);
- } else if (!resize[u]) {
- // over estimation of the number of bytes to be
- // added to this instruction = 3 - current number
- // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
- insert = u & 3;
- resize[u] = true;
- }
- // skips instruction
- u = u + 4 - (u & 3);
- u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
- break;
- case ClassWriter.LOOK_INSN:
- if (state == 1) {
- // like TABL_INSN
- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
- insert = -(newOffset & 3);
- } else if (!resize[u]) {
- // like TABL_INSN
- insert = u & 3;
- resize[u] = true;
- }
- // skips instruction
- u = u + 4 - (u & 3);
- u += 8 * readInt(b, u + 4) + 8;
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[u + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- u += 6;
- } else {
- u += 4;
- }
- break;
- case ClassWriter.VAR_INSN:
- case ClassWriter.SBYTE_INSN:
- case ClassWriter.LDC_INSN:
- u += 2;
- break;
- case ClassWriter.SHORT_INSN:
- case ClassWriter.LDCW_INSN:
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.TYPE_INSN:
- case ClassWriter.IINC_INSN:
- u += 3;
- break;
- case ClassWriter.ITFMETH_INSN:
- case ClassWriter.INDYMETH_INSN:
- u += 5;
- break;
- // case ClassWriter.MANA_INSN:
- default:
- u += 4;
- break;
- }
- if (insert != 0) {
- // adds a new (u, insert) entry in the allIndexes and
- // allSizes arrays
- int[] newIndexes = new int[allIndexes.length + 1];
- int[] newSizes = new int[allSizes.length + 1];
- System.arraycopy(allIndexes, 0, newIndexes, 0,
- allIndexes.length);
- System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
- newIndexes[allIndexes.length] = u;
- newSizes[allSizes.length] = insert;
- allIndexes = newIndexes;
- allSizes = newSizes;
- if (insert > 0) {
- state = 3;
- }
- }
- }
- if (state < 3) {
- --state;
- }
- } while (state != 0);
-
- // 2nd step:
- // copies the bytecode of the method into a new bytevector, updates the
- // offsets, and inserts (or removes) bytes as requested.
-
- ByteVector newCode = new ByteVector(code.length);
-
- u = 0;
- while (u < code.length) {
- int opcode = b[u] & 0xFF;
- switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- case ClassWriter.IMPLVAR_INSN:
- newCode.putByte(opcode);
- u += 1;
- break;
- case ClassWriter.LABEL_INSN:
- if (opcode > 201) {
- // changes temporary opcodes 202 to 217 (inclusive), 218
- // and 219 to IFEQ ... JSR (inclusive), IFNULL and
- // IFNONNULL
- opcode = opcode < 218 ? opcode - 49 : opcode - 20;
- label = u + readUnsignedShort(b, u + 1);
- } else {
- label = u + readShort(b, u + 1);
- }
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- if (resize[u]) {
- // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
- // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
- // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
- // and where <l'> designates the instruction just after
- // the GOTO_W.
- if (opcode == Opcodes.GOTO) {
- newCode.putByte(200); // GOTO_W
- } else if (opcode == Opcodes.JSR) {
- newCode.putByte(201); // JSR_W
- } else {
- newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
- : opcode ^ 1);
- newCode.putShort(8); // jump offset
- newCode.putByte(200); // GOTO_W
- // newOffset now computed from start of GOTO_W
- newOffset -= 3;
- }
- newCode.putInt(newOffset);
- } else {
- newCode.putByte(opcode);
- newCode.putShort(newOffset);
- }
- u += 3;
- break;
- case ClassWriter.LABELW_INSN:
- label = u + readInt(b, u + 1);
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- newCode.putByte(opcode);
- newCode.putInt(newOffset);
- u += 5;
- break;
- case ClassWriter.TABL_INSN:
- // skips 0 to 3 padding bytes
- v = u;
- u = u + 4 - (v & 3);
- // reads and copies instruction
- newCode.putByte(Opcodes.TABLESWITCH);
- newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- j = readInt(b, u);
- u += 4;
- newCode.putInt(j);
- j = readInt(b, u) - j + 1;
- u += 4;
- newCode.putInt(readInt(b, u - 4));
- for (; j > 0; --j) {
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- }
- break;
- case ClassWriter.LOOK_INSN:
- // skips 0 to 3 padding bytes
- v = u;
- u = u + 4 - (v & 3);
- // reads and copies instruction
- newCode.putByte(Opcodes.LOOKUPSWITCH);
- newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- j = readInt(b, u);
- u += 4;
- newCode.putInt(j);
- for (; j > 0; --j) {
- newCode.putInt(readInt(b, u));
- u += 4;
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- }
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[u + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- newCode.putByteArray(b, u, 6);
- u += 6;
- } else {
- newCode.putByteArray(b, u, 4);
- u += 4;
- }
- break;
- case ClassWriter.VAR_INSN:
- case ClassWriter.SBYTE_INSN:
- case ClassWriter.LDC_INSN:
- newCode.putByteArray(b, u, 2);
- u += 2;
- break;
- case ClassWriter.SHORT_INSN:
- case ClassWriter.LDCW_INSN:
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.TYPE_INSN:
- case ClassWriter.IINC_INSN:
- newCode.putByteArray(b, u, 3);
- u += 3;
- break;
- case ClassWriter.ITFMETH_INSN:
- case ClassWriter.INDYMETH_INSN:
- newCode.putByteArray(b, u, 5);
- u += 5;
- break;
- // case MANA_INSN:
- default:
- newCode.putByteArray(b, u, 4);
- u += 4;
- break;
- }
- }
-
- // updates the stack map frame labels
- if (compute == FRAMES) {
- Label l = labels;
- while (l != null) {
- /*
- * Detects the labels that are just after an IF instruction that
- * has been resized with the IFNOT GOTO_W pattern. These labels
- * are now the target of a jump instruction (the IFNOT
- * instruction). Note that we need the original label position
- * here. getNewOffset must therefore never have been called for
- * this label.
- */
- u = l.position - 3;
- if (u >= 0 && resize[u]) {
- l.status |= Label.TARGET;
- }
- getNewOffset(allIndexes, allSizes, l);
- l = l.successor;
- }
- // Update the offsets in the uninitialized types
- if (cw.typeTable != null) {
- for (i = 0; i < cw.typeTable.length; ++i) {
- Item item = cw.typeTable[i];
- if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
- item.intVal = getNewOffset(allIndexes, allSizes, 0,
- item.intVal);
- }
- }
- }
- // The stack map frames are not serialized yet, so we don't need
- // to update them. They will be serialized in visitMaxs.
- } else if (frameCount > 0) {
- /*
- * Resizing an existing stack map frame table is really hard. Not
- * only the table must be parsed to update the offets, but new
- * frames may be needed for jump instructions that were inserted by
- * this method. And updating the offsets or inserting frames can
- * change the format of the following frames, in case of packed
- * frames. In practice the whole table must be recomputed. For this
- * the frames are marked as potentially invalid. This will cause the
- * whole class to be reread and rewritten with the COMPUTE_FRAMES
- * option (see the ClassWriter.toByteArray method). This is not very
- * efficient but is much easier and requires much less code than any
- * other method I can think of.
- */
- cw.invalidFrames = true;
- }
- // updates the exception handler block labels
- Handler h = firstHandler;
- while (h != null) {
- getNewOffset(allIndexes, allSizes, h.start);
- getNewOffset(allIndexes, allSizes, h.end);
- getNewOffset(allIndexes, allSizes, h.handler);
- h = h.next;
- }
- // updates the instructions addresses in the
- // local var and line number tables
- for (i = 0; i < 2; ++i) {
- ByteVector bv = i == 0 ? localVar : localVarType;
- if (bv != null) {
- b = bv.data;
- u = 0;
- while (u < bv.length) {
- label = readUnsignedShort(b, u);
- newOffset = getNewOffset(allIndexes, allSizes, 0, label);
- writeShort(b, u, newOffset);
- label += readUnsignedShort(b, u + 2);
- newOffset = getNewOffset(allIndexes, allSizes, 0, label)
- - newOffset;
- writeShort(b, u + 2, newOffset);
- u += 10;
- }
- }
- }
- if (lineNumber != null) {
- b = lineNumber.data;
- u = 0;
- while (u < lineNumber.length) {
- writeShort(
- b,
- u,
- getNewOffset(allIndexes, allSizes, 0,
- readUnsignedShort(b, u)));
- u += 4;
- }
- }
- // updates the labels of the other attributes
- Attribute attr = cattrs;
- while (attr != null) {
- Label[] labels = attr.getLabels();
- if (labels != null) {
- for (i = labels.length - 1; i >= 0; --i) {
- getNewOffset(allIndexes, allSizes, labels[i]);
- }
- }
- attr = attr.next;
- }
-
- // replaces old bytecodes with new ones
- code = newCode;
- }
-
- /**
- * Reads an unsigned short value in the given byte array.
- *
- * @param b
- * a byte array.
- * @param index
- * the start index of the value to be read.
- * @return the read value.
- */
- static int readUnsignedShort(final byte[] b, final int index) {
- return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
- }
-
- /**
- * Reads a signed short value in the given byte array.
- *
- * @param b
- * a byte array.
- * @param index
- * the start index of the value to be read.
- * @return the read value.
- */
- static short readShort(final byte[] b, final int index) {
- return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
- }
-
- /**
- * Reads a signed int value in the given byte array.
- *
- * @param b
- * a byte array.
- * @param index
- * the start index of the value to be read.
- * @return the read value.
- */
- static int readInt(final byte[] b, final int index) {
- return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
- | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
- }
-
- /**
- * Writes a short value in the given byte array.
- *
- * @param b
- * a byte array.
- * @param index
- * where the first byte of the short value must be written.
- * @param s
- * the value to be written in the given byte array.
- */
- static void writeShort(final byte[] b, final int index, final int s) {
- b[index] = (byte) (s >>> 8);
- b[index + 1] = (byte) s;
- }
-
- /**
- * Computes the future value of a bytecode offset.
- * <p>
- * Note: it is possible to have several entries for the same instruction in
- * the <tt>indexes</tt> and <tt>sizes</tt>: two entries (index=a,size=b) and
- * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
- *
- * @param indexes
- * current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its <i>last</i>
- * byte, plus one (or, in other words, by the index of the
- * <i>first</i> byte of the <i>next</i> instruction).
- * @param sizes
- * the number of bytes to be <i>added</i> to the above
- * instructions. More precisely, for each i < <tt>len</tt>,
- * <tt>sizes</tt>[i] bytes will be added at the end of the
- * instruction designated by <tt>indexes</tt>[i] or, if
- * <tt>sizes</tt>[i] is negative, the <i>last</i> |
- * <tt>sizes[i]</tt>| bytes of the instruction will be removed
- * (the instruction size <i>must not</i> become negative or
- * null).
- * @param begin
- * index of the first byte of the source instruction.
- * @param end
- * index of the first byte of the target instruction.
- * @return the future value of the given bytecode offset.
- */
- static int getNewOffset(final int[] indexes, final int[] sizes,
- final int begin, final int end) {
- int offset = end - begin;
- for (int i = 0; i < indexes.length; ++i) {
- if (begin < indexes[i] && indexes[i] <= end) {
- // forward jump
- offset += sizes[i];
- } else if (end < indexes[i] && indexes[i] <= begin) {
- // backward jump
- offset -= sizes[i];
- }
- }
- return offset;
- }
-
- /**
- * Updates the offset of the given label.
- *
- * @param indexes
- * current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its <i>last</i>
- * byte, plus one (or, in other words, by the index of the
- * <i>first</i> byte of the <i>next</i> instruction).
- * @param sizes
- * the number of bytes to be <i>added</i> to the above
- * instructions. More precisely, for each i < <tt>len</tt>,
- * <tt>sizes</tt>[i] bytes will be added at the end of the
- * instruction designated by <tt>indexes</tt>[i] or, if
- * <tt>sizes</tt>[i] is negative, the <i>last</i> |
- * <tt>sizes[i]</tt>| bytes of the instruction will be removed
- * (the instruction size <i>must not</i> become negative or
- * null).
- * @param label
- * the label whose offset must be updated.
- */
- static void getNewOffset(final int[] indexes, final int[] sizes,
- final Label label) {
- if ((label.status & Label.RESIZED) == 0) {
- label.position = getNewOffset(indexes, sizes, 0, label.position);
- label.status |= Label.RESIZED;
- }
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,219 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java module. The methods of this class must be called in
+ * the following order: <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> |
+ * <tt>visitRequire</tt> | <tt>visitExport</tt> | <tt>visitOpen</tt> |
+ * <tt>visitUse</tt> | <tt>visitProvide</tt> )* <tt>visitEnd</tt>.
+ *
+ * The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)},
+ * {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)}
+ * take as parameter a package name or a module name. Unlike the other names which are internal names
+ * (names separated by slash), module and package names are qualified names (names separated by dot).
+ *
+ * @author Remi Forax
+ */
+public abstract class ModuleVisitor {
+ /**
+ * The ASM API version implemented by this visitor. The value of this field
+ * must be {@link Opcodes#ASM6}.
+ */
+ protected final int api;
+
+ /**
+ * The module visitor to which this visitor must delegate method calls. May
+ * be null.
+ */
+ protected ModuleVisitor mv;
+
+ /**
+ * Constructs a new {@link ModuleVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+ */
+ public ModuleVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link ModuleVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+ * @param mv
+ * the module visitor to which this visitor must delegate method
+ * calls. May be null.
+ */
+ public ModuleVisitor(final int api, final ModuleVisitor mv) {
+ if (api != Opcodes.ASM6) {
+ throw new IllegalArgumentException();
+ }
+ this.api = api;
+ this.mv = mv;
+ }
+
+ /**
+ * Visit the main class of the current module.
+ *
+ * @param mainClass the internal name of the main class of the current module.
+ */
+ public void visitMainClass(String mainClass) {
+ if (mv != null) {
+ mv.visitMainClass(mainClass);
+ }
+ }
+
+ /**
+ * Visit a package of the current module.
+ *
+ * @param packaze the qualified name of a package.
+ */
+ public void visitPackage(String packaze) {
+ if (mv != null) {
+ mv.visitPackage(packaze);
+ }
+ }
+
+ /**
+ * Visits a dependence of the current module.
+ *
+ * @param module the qualified name of the dependence.
+ * @param access the access flag of the dependence among
+ * ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC
+ * and ACC_MANDATED.
+ * @param version the module version at compile time or null.
+ */
+ public void visitRequire(String module, int access, String version) {
+ if (mv != null) {
+ mv.visitRequire(module, access, version);
+ }
+ }
+
+ /**
+ * Visit an exported package of the current module.
+ *
+ * @param packaze the qualified name of the exported package.
+ * @param access the access flag of the exported package,
+ * valid values are among {@code ACC_SYNTHETIC} and
+ * {@code ACC_MANDATED}.
+ * @param modules the qualified names of the modules that can access to
+ * the public classes of the exported package or
+ * <tt>null</tt>.
+ */
+ public void visitExport(String packaze, int access, String... modules) {
+ if (mv != null) {
+ mv.visitExport(packaze, access, modules);
+ }
+ }
+
+ /**
+ * Visit an open package of the current module.
+ *
+ * @param packaze the qualified name of the opened package.
+ * @param access the access flag of the opened package,
+ * valid values are among {@code ACC_SYNTHETIC} and
+ * {@code ACC_MANDATED}.
+ * @param modules the qualified names of the modules that can use deep
+ * reflection to the classes of the open package or
+ * <tt>null</tt>.
+ */
+ public void visitOpen(String packaze, int access, String... modules) {
+ if (mv != null) {
+ mv.visitOpen(packaze, access, modules);
+ }
+ }
+
+ /**
+ * Visit a service used by the current module.
+ * The name must be the internal name of an interface or a class.
+ *
+ * @param service the internal name of the service.
+ */
+ public void visitUse(String service) {
+ if (mv != null) {
+ mv.visitUse(service);
+ }
+ }
+
+ /**
+ * Visit an implementation of a service.
+ *
+ * @param service the internal name of the service
+ * @param providers the internal names of the implementations
+ * of the service (there is at least one provider).
+ */
+ public void visitProvide(String service, String... providers) {
+ if (mv != null) {
+ mv.visitProvide(service, providers);
+ }
+ }
+
+ /**
+ * Visits the end of the module. This method, which is the last one to be
+ * called, is used to inform the visitor that everything have been visited.
+ */
+ public void visitEnd() {
+ if (mv != null) {
+ mv.visitEnd();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleWriter.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,322 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * @author Remi Forax
+ */
+final class ModuleWriter extends ModuleVisitor {
+ /**
+ * The class writer to which this Module attribute must be added.
+ */
+ private final ClassWriter cw;
+
+ /**
+ * size in byte of the Module attribute.
+ */
+ int size;
+
+ /**
+ * Number of attributes associated with the current module
+ * (Version, ConcealPackages, etc)
+ */
+ int attributeCount;
+
+ /**
+ * Size in bytes of the attributes associated with the current module
+ */
+ int attributesSize;
+
+ /**
+ * module name index in the constant pool
+ */
+ private final int name;
+
+ /**
+ * module access flags
+ */
+ private final int access;
+
+ /**
+ * module version index in the constant pool or 0
+ */
+ private final int version;
+
+ /**
+ * module main class index in the constant pool or 0
+ */
+ private int mainClass;
+
+ /**
+ * number of packages
+ */
+ private int packageCount;
+
+ /**
+ * The packages in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in packageCount
+ */
+ private ByteVector packages;
+
+ /**
+ * number of requires items
+ */
+ private int requireCount;
+
+ /**
+ * The requires items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in requireCount
+ */
+ private ByteVector requires;
+
+ /**
+ * number of exports items
+ */
+ private int exportCount;
+
+ /**
+ * The exports items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in exportCount
+ */
+ private ByteVector exports;
+
+ /**
+ * number of opens items
+ */
+ private int openCount;
+
+ /**
+ * The opens items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in openCount
+ */
+ private ByteVector opens;
+
+ /**
+ * number of uses items
+ */
+ private int useCount;
+
+ /**
+ * The uses items in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in useCount
+ */
+ private ByteVector uses;
+
+ /**
+ * number of provides items
+ */
+ private int provideCount;
+
+ /**
+ * The uses provides in bytecode form. This byte vector only contains
+ * the items themselves, the number of items is store in provideCount
+ */
+ private ByteVector provides;
+
+ ModuleWriter(final ClassWriter cw, final int name,
+ final int access, final int version) {
+ super(Opcodes.ASM6);
+ this.cw = cw;
+ this.size = 16; // name + access + version + 5 counts
+ this.name = name;
+ this.access = access;
+ this.version = version;
+ }
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ if (this.mainClass == 0) { // protect against several calls to visitMainClass
+ cw.newUTF8("ModuleMainClass");
+ attributeCount++;
+ attributesSize += 8;
+ }
+ this.mainClass = cw.newClass(mainClass);
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ if (packages == null) {
+ // protect against several calls to visitPackage
+ cw.newUTF8("ModulePackages");
+ packages = new ByteVector();
+ attributeCount++;
+ attributesSize += 8;
+ }
+ packages.putShort(cw.newPackage(packaze));
+ packageCount++;
+ attributesSize += 2;
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ if (requires == null) {
+ requires = new ByteVector();
+ }
+ requires.putShort(cw.newModule(module))
+ .putShort(access)
+ .putShort(version == null? 0: cw.newUTF8(version));
+ requireCount++;
+ size += 6;
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ if (exports == null) {
+ exports = new ByteVector();
+ }
+ exports.putShort(cw.newPackage(packaze)).putShort(access);
+ if (modules == null) {
+ exports.putShort(0);
+ size += 6;
+ } else {
+ exports.putShort(modules.length);
+ for(String module: modules) {
+ exports.putShort(cw.newModule(module));
+ }
+ size += 6 + 2 * modules.length;
+ }
+ exportCount++;
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ if (opens == null) {
+ opens = new ByteVector();
+ }
+ opens.putShort(cw.newPackage(packaze)).putShort(access);
+ if (modules == null) {
+ opens.putShort(0);
+ size += 6;
+ } else {
+ opens.putShort(modules.length);
+ for(String module: modules) {
+ opens.putShort(cw.newModule(module));
+ }
+ size += 6 + 2 * modules.length;
+ }
+ openCount++;
+ }
+
+ @Override
+ public void visitUse(String service) {
+ if (uses == null) {
+ uses = new ByteVector();
+ }
+ uses.putShort(cw.newClass(service));
+ useCount++;
+ size += 2;
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ if (provides == null) {
+ provides = new ByteVector();
+ }
+ provides.putShort(cw.newClass(service));
+ provides.putShort(providers.length);
+ for(String provider: providers) {
+ provides.putShort(cw.newClass(provider));
+ }
+ provideCount++;
+ size += 4 + 2 * providers.length;
+ }
+
+ @Override
+ public void visitEnd() {
+ // empty
+ }
+
+ void putAttributes(ByteVector out) {
+ if (mainClass != 0) {
+ out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass);
+ }
+ if (packages != null) {
+ out.putShort(cw.newUTF8("ModulePackages"))
+ .putInt(2 + 2 * packageCount)
+ .putShort(packageCount)
+ .putByteArray(packages.data, 0, packages.length);
+ }
+ }
+
+ void put(ByteVector out) {
+ out.putInt(size);
+ out.putShort(name).putShort(access).putShort(version);
+ out.putShort(requireCount);
+ if (requires != null) {
+ out.putByteArray(requires.data, 0, requires.length);
+ }
+ out.putShort(exportCount);
+ if (exports != null) {
+ out.putByteArray(exports.data, 0, exports.length);
+ }
+ out.putShort(openCount);
+ if (opens != null) {
+ out.putByteArray(opens.data, 0, opens.length);
+ }
+ out.putShort(useCount);
+ if (uses != null) {
+ out.putByteArray(uses.data, 0, uses.length);
+ }
+ out.putShort(provideCount);
+ if (provides != null) {
+ out.putByteArray(provides.data, 0, provides.length);
+ }
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java Thu Nov 02 13:18:23 2017 -0700
@@ -70,13 +70,13 @@
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
-@SuppressWarnings("deprecation") // for Integer(int) constructor
public interface Opcodes {
// ASM API versions
int ASM4 = 4 << 16 | 0 << 8 | 0;
int ASM5 = 5 << 16 | 0 << 8 | 0;
+ int ASM6 = 6 << 16 | 0 << 8 | 0;
// versions
@@ -88,7 +88,7 @@
int V1_6 = 0 << 16 | 50;
int V1_7 = 0 << 16 | 51;
int V1_8 = 0 << 16 | 52;
- int V1_9 = 0 << 16 | 53;
+ int V9 = 0 << 16 | 53;
// access flags
@@ -99,18 +99,23 @@
int ACC_FINAL = 0x0010; // class, field, method, parameter
int ACC_SUPER = 0x0020; // class
int ACC_SYNCHRONIZED = 0x0020; // method
+ int ACC_OPEN = 0x0020; // module
+ int ACC_TRANSITIVE = 0x0020; // module requires
int ACC_VOLATILE = 0x0040; // field
int ACC_BRIDGE = 0x0040; // method
+ int ACC_STATIC_PHASE = 0x0040; // module requires
int ACC_VARARGS = 0x0080; // method
int ACC_TRANSIENT = 0x0080; // field
int ACC_NATIVE = 0x0100; // method
int ACC_INTERFACE = 0x0200; // class
int ACC_ABSTRACT = 0x0400; // class, method
int ACC_STRICT = 0x0800; // method
- int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
+ int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
int ACC_ANNOTATION = 0x2000; // class
int ACC_ENUM = 0x4000; // class(?) field inner
- int ACC_MANDATED = 0x8000; // parameter
+ int ACC_MANDATED = 0x8000; // parameter, module, module *
+ int ACC_MODULE = 0x8000; // class
+
// ASM specific pseudo access flags
@@ -177,15 +182,17 @@
*/
int F_SAME1 = 4;
- // For reference comparison purposes, construct new instances
- // instead of using valueOf() or autoboxing.
- Integer TOP = new Integer(0);
- Integer INTEGER = new Integer(1);
- Integer FLOAT = new Integer(2);
- Integer DOUBLE = new Integer(3);
- Integer LONG = new Integer(4);
- Integer NULL = new Integer(5);
- Integer UNINITIALIZED_THIS = new Integer(6);
+ // Do not try to change the following code to use auto-boxing,
+ // these values are compared by reference and not by value
+ // The constructor of Integer was deprecated in 9
+ // but we are stuck with it by backward compatibility
+ @SuppressWarnings("deprecation") Integer TOP = new Integer(0);
+ @SuppressWarnings("deprecation") Integer INTEGER = new Integer(1);
+ @SuppressWarnings("deprecation") Integer FLOAT = new Integer(2);
+ @SuppressWarnings("deprecation") Integer DOUBLE = new Integer(3);
+ @SuppressWarnings("deprecation") Integer LONG = new Integer(4);
+ @SuppressWarnings("deprecation") Integer NULL = new Integer(5);
+ @SuppressWarnings("deprecation") Integer UNINITIALIZED_THIS = new Integer(6);
// opcodes // visit method (- = idem)
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java Thu Nov 02 13:18:23 2017 -0700
@@ -406,7 +406,16 @@
*/
public static Type getReturnType(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray();
- return getType(buf, methodDescriptor.indexOf(')') + 1);
+ int off = 1;
+ while (true) {
+ char car = buf[off++];
+ if (car == ')') {
+ return getType(buf, off);
+ } else if (car == 'L') {
+ while (buf[off++] != ';') {
+ }
+ }
+ }
}
/**
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -112,7 +112,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this adapter delegates calls.
* @param access
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -170,7 +170,7 @@
*/
public AnalyzerAdapter(final String owner, final int access,
final String name, final String desc, final MethodVisitor mv) {
- this(Opcodes.ASM5, owner, access, name, desc, mv);
+ this(Opcodes.ASM6, owner, access, name, desc, mv);
if (getClass() != AnalyzerAdapter.class) {
throw new IllegalStateException();
}
@@ -181,7 +181,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param owner
* the owner's class name.
* @param access
@@ -690,6 +690,8 @@
t1 = pop();
if (t1 instanceof String) {
pushDesc(((String) t1).substring(1));
+ } else if (t1 == Opcodes.NULL) {
+ push(t1);
} else {
push("java/lang/Object");
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java Thu Nov 02 13:18:23 2017 -0700
@@ -73,7 +73,7 @@
public AnnotationRemapper(final AnnotationVisitor av,
final Remapper remapper) {
- this(Opcodes.ASM5, av, remapper);
+ this(Opcodes.ASM6, av, remapper);
}
protected AnnotationRemapper(final int api, final AnnotationVisitor av,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java Thu Nov 02 13:18:23 2017 -0700
@@ -59,10 +59,14 @@
package jdk.internal.org.objectweb.asm.commons;
+import java.util.List;
+
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
+import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -78,7 +82,7 @@
protected String className;
public ClassRemapper(final ClassVisitor cv, final Remapper remapper) {
- this(Opcodes.ASM5, cv, remapper);
+ this(Opcodes.ASM6, cv, remapper);
}
protected ClassRemapper(final int api, final ClassVisitor cv,
@@ -97,6 +101,12 @@
}
@Override
+ public ModuleVisitor visitModule(String name, int flags, String version) {
+ ModuleVisitor mv = super.visitModule(remapper.mapModuleName(name), flags, version);
+ return mv == null ? null : createModuleRemapper(mv);
+ }
+
+ @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
visible);
@@ -112,6 +122,18 @@
}
@Override
+ public void visitAttribute(Attribute attr) {
+ if (attr instanceof ModuleHashesAttribute) {
+ ModuleHashesAttribute hashesAttr = new ModuleHashesAttribute();
+ List<String> modules = hashesAttr.modules;
+ for(int i = 0; i < modules.size(); i++) {
+ modules.set(i, remapper.mapModuleName(modules.get(i)));
+ }
+ }
+ super.visitAttribute(attr);
+ }
+
+ @Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
FieldVisitor fv = super.visitField(access,
@@ -158,4 +180,8 @@
protected AnnotationVisitor createAnnotationRemapper(AnnotationVisitor av) {
return new AnnotationRemapper(av, remapper);
}
+
+ protected ModuleVisitor createModuleRemapper(ModuleVisitor mv) {
+ return new ModuleRemapper(mv, remapper);
+ }
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java Thu Nov 02 13:18:23 2017 -0700
@@ -75,7 +75,7 @@
private int maxSize;
public CodeSizeEvaluator(final MethodVisitor mv) {
- this(Opcodes.ASM5, mv);
+ this(Opcodes.ASM6, mv);
}
protected CodeSizeEvaluator(final int api, final MethodVisitor mv) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java Thu Nov 02 13:18:23 2017 -0700
@@ -74,7 +74,7 @@
private final Remapper remapper;
public FieldRemapper(final FieldVisitor fv, final Remapper remapper) {
- this(Opcodes.ASM5, fv, remapper);
+ this(Opcodes.ASM6, fv, remapper);
}
protected FieldRemapper(final int api, final FieldVisitor fv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -289,7 +289,7 @@
*/
public GeneratorAdapter(final MethodVisitor mv, final int access,
final String name, final String desc) {
- this(Opcodes.ASM5, mv, access, name, desc);
+ this(Opcodes.ASM6, mv, access, name, desc);
if (getClass() != GeneratorAdapter.class) {
throw new IllegalStateException();
}
@@ -300,7 +300,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this adapter delegates calls.
* @param access
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -86,7 +86,7 @@
* If a subclass calls this constructor.
*/
public InstructionAdapter(final MethodVisitor mv) {
- this(Opcodes.ASM5, mv);
+ this(Opcodes.ASM6, mv);
if (getClass() != InstructionAdapter.class) {
throw new IllegalStateException();
}
@@ -97,7 +97,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this adapter delegates calls.
*/
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -142,7 +142,7 @@
public JSRInlinerAdapter(final MethodVisitor mv, final int access,
final String name, final String desc, final String signature,
final String[] exceptions) {
- this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
+ this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
if (getClass() != JSRInlinerAdapter.class) {
throw new IllegalStateException();
}
@@ -153,7 +153,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param mv
* the <code>MethodVisitor</code> to send the resulting inlined
* method code to (use <code>null</code> for none).
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java Thu Nov 02 13:18:23 2017 -0700
@@ -120,7 +120,7 @@
*/
public LocalVariablesSorter(final int access, final String desc,
final MethodVisitor mv) {
- this(Opcodes.ASM5, access, desc, mv);
+ this(Opcodes.ASM6, access, desc, mv);
if (getClass() != LocalVariablesSorter.class) {
throw new IllegalStateException();
}
@@ -131,7 +131,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param access
* access flags of the adapted method.
* @param desc
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java Thu Nov 02 13:18:23 2017 -0700
@@ -76,7 +76,7 @@
protected final Remapper remapper;
public MethodRemapper(final MethodVisitor mv, final Remapper remapper) {
- this(Opcodes.ASM5, mv, remapper);
+ this(Opcodes.ASM6, mv, remapper);
}
protected MethodRemapper(final int api, final MethodVisitor mv,
@@ -122,18 +122,20 @@
}
private Object[] remapEntries(int n, Object[] entries) {
- for (int i = 0; i < n; i++) {
- if (entries[i] instanceof String) {
- Object[] newEntries = new Object[n];
- if (i > 0) {
- System.arraycopy(entries, 0, newEntries, 0, i);
+ if (entries != null) {
+ for (int i = 0; i < n; i++) {
+ if (entries[i] instanceof String) {
+ Object[] newEntries = new Object[n];
+ if (i > 0) {
+ System.arraycopy(entries, 0, newEntries, 0, i);
+ }
+ do {
+ Object t = entries[i];
+ newEntries[i++] = t instanceof String ? remapper
+ .mapType((String) t) : t;
+ } while (i < n);
+ return newEntries;
}
- do {
- Object t = entries[i];
- newEntries[i++] = t instanceof String ? remapper
- .mapType((String) t) : t;
- } while (i < n);
- return newEntries;
}
}
return entries;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleHashesAttribute.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,155 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleHashes attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleHashesAttribute extends Attribute {
+ public String algorithm;
+ public List<String> modules;
+ public List<byte[]> hashes;
+
+ /**
+ * Creates an attribute with a hashing algorithm, a list of module names,
+ * and a list of the same length of hashes.
+ * @param algorithm the hashing algorithm name.
+ * @param modules a list of module name
+ * @param hashes a list of hash, one for each module name.
+ */
+ public ModuleHashesAttribute(final String algorithm,
+ final List<String> modules, final List<byte[]> hashes) {
+ super("ModuleHashes");
+ this.algorithm = algorithm;
+ this.modules = modules;
+ this.hashes = hashes;
+ }
+
+ /**
+ * Creates an empty attribute that can be used as prototype
+ * to be passed as argument of the method
+ * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+ */
+ public ModuleHashesAttribute() {
+ this(null, null, null);
+ }
+
+ @Override
+ protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+ int codeOff, Label[] labels) {
+ String hashAlgorithm = cr.readUTF8(off, buf);
+
+ int count = cr.readUnsignedShort(off + 2);
+ ArrayList<String> modules = new ArrayList<String>(count);
+ ArrayList<byte[]> hashes = new ArrayList<byte[]>(count);
+ off += 4;
+
+ for (int i = 0; i < count; i++) {
+ String module = cr.readModule(off, buf);
+ int hashLength = cr.readUnsignedShort(off + 2);
+ off += 4;
+
+ byte[] hash = new byte[hashLength];
+ for (int j = 0; j < hashLength; j++) {
+ hash[j] = (byte) (cr.readByte(off + j) & 0xff);
+ }
+ off += hashLength;
+
+ modules.add(module);
+ hashes.add(hash);
+ }
+ return new ModuleHashesAttribute(hashAlgorithm, modules, hashes);
+ }
+
+ @Override
+ protected ByteVector write(ClassWriter cw, byte[] code, int len,
+ int maxStack, int maxLocals) {
+ ByteVector v = new ByteVector();
+ int index = cw.newUTF8(algorithm);
+ v.putShort(index);
+
+ int count = (modules == null)? 0: modules.size();
+ v.putShort(count);
+
+ for(int i = 0; i < count; i++) {
+ String module = modules.get(i);
+ v.putShort(cw.newModule(module));
+
+ byte[] hash = hashes.get(i);
+ v.putShort(hash.length);
+ for(byte b: hash) {
+ v.putByte(b);
+ }
+ }
+ return v;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleRemapper.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,135 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} adapter for type remapping.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRemapper extends ModuleVisitor {
+ private final Remapper remapper;
+
+ public ModuleRemapper(final ModuleVisitor mv, final Remapper remapper) {
+ this(Opcodes.ASM6, mv, remapper);
+ }
+
+ protected ModuleRemapper(final int api, final ModuleVisitor mv,
+ final Remapper remapper) {
+ super(api, mv);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ super.visitMainClass(remapper.mapType(mainClass));
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ super.visitPackage(remapper.mapPackageName(packaze));
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ super.visitRequire(remapper.mapModuleName(module), access, version);
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ String[] newModules = null;
+ if (modules != null) {
+ newModules = new String[modules.length];
+ for (int i = 0 ; i < modules.length; i++) {
+ newModules[i] = remapper.mapModuleName(modules[i]);
+ }
+ }
+ super.visitExport(remapper.mapPackageName(packaze), access, newModules);
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ String[] newModules = null;
+ if (modules != null) {
+ newModules = new String[modules.length];
+ for (int i = 0 ; i < modules.length; i++) {
+ newModules[i] = remapper.mapModuleName(modules[i]);
+ }
+ }
+ super.visitOpen(remapper.mapPackageName(packaze), access, newModules);
+ }
+
+ @Override
+ public void visitUse(String service) {
+ super.visitUse(remapper.mapType(service));
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ String[] newProviders = new String[providers.length];
+ for (int i = 0 ; i < providers.length; i++) {
+ newProviders[i] = remapper.mapType(providers[i]);
+ }
+ super.visitProvide(remapper.mapType(service), newProviders);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleResolutionAttribute.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,135 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleResolution_attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleResolutionAttribute extends Attribute {
+ /**
+ * Resolution state of a module meaning that the module is not available
+ * from the class-path by default.
+ */
+ public static final int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1;
+
+ /**
+ * Resolution state of a module meaning the module is marked as deprecated.
+ */
+ public static final int RESOLUTION_WARN_DEPRECATED = 2;
+
+ /**
+ * Resolution state of a module meaning the module is marked as deprecated
+ * and will be removed in a future release.
+ */
+ public static final int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4;
+
+ /**
+ * Resolution state of a module meaning the module is not yet standardized,
+ * so in incubating mode.
+ */
+ public static final int RESOLUTION_WARN_INCUBATING = 8;
+
+ public int resolution;
+
+ /**
+ * Creates an attribute with a resolution state value.
+ * @param resolution the resolution state among
+ * {@link #RESOLUTION_WARN_DEPRECATED},
+ * {@link #RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL}, and
+ * {@link #RESOLUTION_WARN_INCUBATING}.
+ */
+ public ModuleResolutionAttribute(final int resolution) {
+ super("ModuleResolution");
+ this.resolution = resolution;
+ }
+
+ /**
+ * Creates an empty attribute that can be used as prototype
+ * to be passed as argument of the method
+ * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+ */
+ public ModuleResolutionAttribute() {
+ this(0);
+ }
+
+ @Override
+ protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+ int codeOff, Label[] labels) {
+ int resolution = cr.readUnsignedShort(off);
+ return new ModuleResolutionAttribute(resolution);
+ }
+
+ @Override
+ protected ByteVector write(ClassWriter cw, byte[] code, int len,
+ int maxStack, int maxLocals) {
+ ByteVector v = new ByteVector();
+ v.putShort(resolution);
+ return v;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleTargetAttribute.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,110 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleTarget attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleTargetAttribute extends Attribute {
+ public String platform;
+
+ /**
+ * Creates an attribute with a platform name.
+ * @param platform the platform name on which the module can run.
+ */
+ public ModuleTargetAttribute(final String platform) {
+ super("ModuleTarget");
+ this.platform = platform;
+ }
+
+ /**
+ * Creates an empty attribute that can be used as prototype
+ * to be passed as argument of the method
+ * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+ */
+ public ModuleTargetAttribute() {
+ this(null);
+ }
+
+ @Override
+ protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+ int codeOff, Label[] labels) {
+ String platform = cr.readUTF8(off, buf);
+ return new ModuleTargetAttribute(platform);
+ }
+
+ @Override
+ protected ByteVector write(ClassWriter cw, byte[] code, int len,
+ int maxStack, int maxLocals) {
+ ByteVector v = new ByteVector();
+ int index = (platform == null)? 0: cw.newUTF8(platform);
+ v.putShort(index);
+ return v;
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java Thu Nov 02 13:18:23 2017 -0700
@@ -255,6 +255,28 @@
}
/**
+ * Map package name to the new name. Subclasses can override.
+ *
+ * @param name name of the package
+ * @return new name of the package
+ */
+ public String mapPackageName(String name) {
+ String fakeName = map(name + ".FakeClassName");
+ int index;
+ return fakeName == null || (index = fakeName.lastIndexOf('.')) == -1 ? name: fakeName.substring(0, index);
+ }
+
+ /**
+ * Map module name to the new name. Subclasses can override.
+ *
+ * @param name name of the module
+ * @return new name of the module
+ */
+ public String mapModuleName(String name) {
+ return name;
+ }
+
+ /**
* Map type name to the new name. Subclasses can override.
*
* @param typeName
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -75,7 +75,7 @@
public RemappingAnnotationAdapter(final AnnotationVisitor av,
final Remapper remapper) {
- this(Opcodes.ASM5, av, remapper);
+ this(Opcodes.ASM6, av, remapper);
}
protected RemappingAnnotationAdapter(final int api,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -63,6 +63,7 @@
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -80,7 +81,7 @@
protected String className;
public RemappingClassAdapter(final ClassVisitor cv, final Remapper remapper) {
- this(Opcodes.ASM5, cv, remapper);
+ this(Opcodes.ASM6, cv, remapper);
}
protected RemappingClassAdapter(final int api, final ClassVisitor cv,
@@ -99,6 +100,11 @@
}
@Override
+ public ModuleVisitor visitModule(String name, int flags, String version) {
+ throw new RuntimeException("RemappingClassAdapter is deprecated, use ClassRemapper instead");
+ }
+
+ @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
visible);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -76,7 +76,7 @@
private final Remapper remapper;
public RemappingFieldAdapter(final FieldVisitor fv, final Remapper remapper) {
- this(Opcodes.ASM5, fv, remapper);
+ this(Opcodes.ASM6, fv, remapper);
}
protected RemappingFieldAdapter(final int api, final FieldVisitor fv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -79,7 +79,7 @@
public RemappingMethodAdapter(final int access, final String desc,
final MethodVisitor mv, final Remapper remapper) {
- this(Opcodes.ASM5, access, desc, mv, remapper);
+ this(Opcodes.ASM6, access, desc, mv, remapper);
}
protected RemappingMethodAdapter(final int api, final int access,
@@ -125,18 +125,20 @@
}
private Object[] remapEntries(int n, Object[] entries) {
- for (int i = 0; i < n; i++) {
- if (entries[i] instanceof String) {
- Object[] newEntries = new Object[n];
- if (i > 0) {
- System.arraycopy(entries, 0, newEntries, 0, i);
+ if (entries != null) {
+ for (int i = 0; i < n; i++) {
+ if (entries[i] instanceof String) {
+ Object[] newEntries = new Object[n];
+ if (i > 0) {
+ System.arraycopy(entries, 0, newEntries, 0, i);
+ }
+ do {
+ Object t = entries[i];
+ newEntries[i++] = t instanceof String ? remapper
+ .mapType((String) t) : t;
+ } while (i < n);
+ return newEntries;
}
- do {
- Object t = entries[i];
- newEntries[i++] = t instanceof String ? remapper
- .mapType((String) t) : t;
- } while (i < n);
- return newEntries;
}
}
return entries;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -79,7 +79,7 @@
public RemappingSignatureAdapter(final SignatureVisitor v,
final Remapper remapper) {
- this(Opcodes.ASM5, v, remapper);
+ this(Opcodes.ASM6, v, remapper);
}
protected RemappingSignatureAdapter(final int api,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java Thu Nov 02 13:18:23 2017 -0700
@@ -80,7 +80,7 @@
* ClassWriter cw = new ClassWriter(...);
* ClassVisitor sv = new SerialVersionUIDAdder(cw);
* ClassVisitor ca = new MyClassAdapter(sv);
- * new ClassReader(originalClass).accept(ca, false);
+ * new ClassReader(orginalClass).accept(ca, false);
* </pre>
*
* The SVUID algorithm can be found <a href=
@@ -199,7 +199,7 @@
* If a subclass calls this constructor.
*/
public SerialVersionUIDAdder(final ClassVisitor cv) {
- this(Opcodes.ASM5, cv);
+ this(Opcodes.ASM6, cv);
if (getClass() != SerialVersionUIDAdder.class) {
throw new IllegalStateException();
}
@@ -210,7 +210,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param cv
* a {@link ClassVisitor} to which this visitor will delegate
* calls.
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java Thu Nov 02 13:18:23 2017 -0700
@@ -78,7 +78,7 @@
private Stack<String> classNames = new Stack<String>();
public SignatureRemapper(final SignatureVisitor v, final Remapper remapper) {
- this(Opcodes.ASM5, v, remapper);
+ this(Opcodes.ASM6, v, remapper);
}
protected SignatureRemapper(final int api, final SignatureVisitor v,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java Thu Nov 02 13:18:23 2017 -0700
@@ -78,7 +78,7 @@
private int counter;
public StaticInitMerger(final String prefix, final ClassVisitor cv) {
- this(Opcodes.ASM5, prefix, cv);
+ this(Opcodes.ASM6, prefix, cv);
}
protected StaticInitMerger(final int api, final String prefix,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java Thu Nov 02 13:18:23 2017 -0700
@@ -86,7 +86,7 @@
public TryCatchBlockSorter(final MethodVisitor mv, final int access,
final String name, final String desc, final String signature,
final String[] exceptions) {
- this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
+ this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
}
protected TryCatchBlockSorter(final int api, final MethodVisitor mv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -102,7 +102,7 @@
/**
* The ASM API version implemented by this visitor. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -111,10 +111,10 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public SignatureVisitor(final int api) {
- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java Thu Nov 02 13:18:23 2017 -0700
@@ -95,7 +95,7 @@
* Constructs a new {@link SignatureWriter} object.
*/
public SignatureWriter() {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
}
// ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -65,7 +65,7 @@
import jdk.internal.org.objectweb.asm.Opcodes;
/**
- * A node that represents an annotationn.
+ * A node that represents an annotation.
*
* @author Eric Bruneton
*/
@@ -81,8 +81,8 @@
* as two consecutive elements in the list. The name is a {@link String},
* and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
* {@link Short}, {@link Integer}, {@link Long}, {@link Float},
- * {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or an
- * two elements String array (for enumeration values), a
+ * {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or a
+ * two elements String array (for enumeration values), an
* {@link AnnotationNode}, or a {@link List} of values of one of the
* preceding types. The list may be <tt>null</tt> if there is no name value
* pair.
@@ -100,7 +100,7 @@
* If a subclass calls this constructor.
*/
public AnnotationNode(final String desc) {
- this(Opcodes.ASM5, desc);
+ this(Opcodes.ASM6, desc);
if (getClass() != AnnotationNode.class) {
throw new IllegalStateException();
}
@@ -111,7 +111,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param desc
* the class descriptor of the annotation class.
*/
@@ -127,7 +127,7 @@
* where the visited values must be stored.
*/
AnnotationNode(final List<Object> values) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
this.values = values;
}
@@ -143,7 +143,65 @@
if (this.desc != null) {
values.add(name);
}
- values.add(value);
+ if (value instanceof byte[]) {
+ byte[] v = (byte[]) value;
+ ArrayList<Byte> l = new ArrayList<Byte>(v.length);
+ for (byte b : v) {
+ l.add(b);
+ }
+ values.add(l);
+ } else if (value instanceof boolean[]) {
+ boolean[] v = (boolean[]) value;
+ ArrayList<Boolean> l = new ArrayList<Boolean>(v.length);
+ for (boolean b : v) {
+ l.add(b);
+ }
+ values.add(l);
+ } else if (value instanceof short[]) {
+ short[] v = (short[]) value;
+ ArrayList<Short> l = new ArrayList<Short>(v.length);
+ for (short s : v) {
+ l.add(s);
+ }
+ values.add(l);
+ } else if (value instanceof char[]) {
+ char[] v = (char[]) value;
+ ArrayList<Character> l = new ArrayList<Character>(v.length);
+ for (char c : v) {
+ l.add(c);
+ }
+ values.add(l);
+ } else if (value instanceof int[]) {
+ int[] v = (int[]) value;
+ ArrayList<Integer> l = new ArrayList<Integer>(v.length);
+ for (int i : v) {
+ l.add(i);
+ }
+ values.add(l);
+ } else if (value instanceof long[]) {
+ long[] v = (long[]) value;
+ ArrayList<Long> l = new ArrayList<Long>(v.length);
+ for (long lng : v) {
+ l.add(lng);
+ }
+ values.add(l);
+ } else if (value instanceof float[]) {
+ float[] v = (float[]) value;
+ ArrayList<Float> l = new ArrayList<Float>(v.length);
+ for (float f : v) {
+ l.add(f);
+ }
+ values.add(l);
+ } else if (value instanceof double[]) {
+ double[] v = (double[]) value;
+ ArrayList<Double> l = new ArrayList<Double>(v.length);
+ for (double d : v) {
+ l.add(d);
+ }
+ values.add(l);
+ } else {
+ values.add(value);
+ }
}
@Override
@@ -200,8 +258,8 @@
* versions of the ASM API than the given version.
*
* @param api
- * an ASM API version. Must be one of {@link Opcodes#ASM4} or
- * {@link Opcodes#ASM5}.
+ * an ASM API version. Must be one of {@link Opcodes#ASM4},
+ * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public void check(final int api) {
// nothing to do
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -67,6 +67,7 @@
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -127,6 +128,11 @@
public String sourceDebug;
/**
+ * Module information. May be <tt>null</tt>.
+ */
+ public ModuleNode module;
+
+ /**
* The internal name of the enclosing class of the class. May be
* <tt>null</tt>.
*/
@@ -221,7 +227,7 @@
* If a subclass calls this constructor.
*/
public ClassNode() {
- this(Opcodes.ASM5);
+ this(Opcodes.ASM6);
if (getClass() != ClassNode.class) {
throw new IllegalStateException();
}
@@ -232,7 +238,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public ClassNode(final int api) {
super(api);
@@ -267,6 +273,12 @@
}
@Override
+ public ModuleVisitor visitModule(final String name, final int access,
+ final String version) {
+ return module = new ModuleNode(name, access, version);
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
outerClass = owner;
@@ -358,11 +370,16 @@
* API than the given version.
*
* @param api
- * an ASM API version. Must be one of {@link Opcodes#ASM4} or
- * {@link Opcodes#ASM5}.
+ * an ASM API version. Must be one of {@link Opcodes#ASM4},
+ * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public void check(final int api) {
- if (api == Opcodes.ASM4) {
+ if (api < Opcodes.ASM6) {
+ if (module != null) {
+ throw new RuntimeException();
+ }
+ }
+ if (api < Opcodes.ASM5) {
if (visibleTypeAnnotations != null
&& visibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
@@ -371,12 +388,31 @@
&& invisibleTypeAnnotations.size() > 0) {
throw new RuntimeException();
}
- for (FieldNode f : fields) {
- f.check(api);
- }
- for (MethodNode m : methods) {
- m.check(api);
- }
+ }
+ // checks attributes
+ int i, n;
+ n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ visibleAnnotations.get(i).check(api);
+ }
+ n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ invisibleAnnotations.get(i).check(api);
+ }
+ n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ visibleTypeAnnotations.get(i).check(api);
+ }
+ n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+ .size();
+ for (i = 0; i < n; ++i) {
+ invisibleTypeAnnotations.get(i).check(api);
+ }
+ for (FieldNode f : fields) {
+ f.check(api);
+ }
+ for (MethodNode m : methods) {
+ m.check(api);
}
}
@@ -395,6 +431,10 @@
if (sourceFile != null || sourceDebug != null) {
cv.visitSource(sourceFile, sourceDebug);
}
+ // visits module
+ if (module != null) {
+ module.accept(cv);
+ }
// visits outer class
if (outerClass != null) {
cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -173,7 +173,7 @@
*/
public FieldNode(final int access, final String name, final String desc,
final String signature, final Object value) {
- this(Opcodes.ASM5, access, name, desc, signature, value);
+ this(Opcodes.ASM6, access, name, desc, signature, value);
if (getClass() != FieldNode.class) {
throw new IllegalStateException();
}
@@ -276,8 +276,8 @@
* API than the given version.
*
* @param api
- * an ASM API version. Must be one of {@link Opcodes#ASM4} or
- * {@link Opcodes#ASM5}.
+ * an ASM API version. Must be one of {@link Opcodes#ASM4},
+ * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public void check(final int api) {
if (api == Opcodes.ASM4) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java Thu Nov 02 13:18:23 2017 -0700
@@ -634,14 +634,28 @@
}
public void add(Object o) {
- InsnList.this.insertBefore(next, (AbstractInsnNode) o);
+ if (next != null) {
+ InsnList.this.insertBefore(next, (AbstractInsnNode) o);
+ } else if (prev != null) {
+ InsnList.this.insert(prev, (AbstractInsnNode) o);
+ } else {
+ InsnList.this.add((AbstractInsnNode) o);
+ }
prev = (AbstractInsnNode) o;
remove = null;
}
public void set(Object o) {
- InsnList.this.set(next.prev, (AbstractInsnNode) o);
- prev = (AbstractInsnNode) o;
+ if (remove != null) {
+ InsnList.this.set(remove, (AbstractInsnNode) o);
+ if (remove == prev) {
+ prev = (AbstractInsnNode) o;
+ } else {
+ next = (AbstractInsnNode) o;
+ }
+ } else {
+ throw new IllegalStateException();
+ }
}
}
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -122,7 +122,7 @@
*/
public LocalVariableAnnotationNode(int typeRef, TypePath typePath,
LabelNode[] start, LabelNode[] end, int[] index, String desc) {
- this(Opcodes.ASM5, typeRef, typePath, start, end, index, desc);
+ this(Opcodes.ASM6, typeRef, typePath, start, end, index, desc);
}
/**
@@ -130,7 +130,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param typeRef
* a reference to the annotated type. See {@link TypeReference}.
* @param start
@@ -181,6 +181,6 @@
index[i] = this.index.get(i);
}
accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
- index, desc, true));
+ index, desc, visible));
}
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -249,7 +249,7 @@
* If a subclass calls this constructor.
*/
public MethodNode() {
- this(Opcodes.ASM5);
+ this(Opcodes.ASM6);
if (getClass() != MethodNode.class) {
throw new IllegalStateException();
}
@@ -260,7 +260,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public MethodNode(final int api) {
super(api);
@@ -291,7 +291,7 @@
*/
public MethodNode(final int access, final String name, final String desc,
final String signature, final String[] exceptions) {
- this(Opcodes.ASM5, access, name, desc, signature, exceptions);
+ this(Opcodes.ASM6, access, name, desc, signature, exceptions);
if (getClass() != MethodNode.class) {
throw new IllegalStateException();
}
@@ -302,7 +302,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param access
* the method's access flags (see {@link Opcodes}). This
* parameter also indicates if the method is synthetic and/or
@@ -688,8 +688,8 @@
* versions of the ASM API than the given version.
*
* @param api
- * an ASM API version. Must be one of {@link Opcodes#ASM4} or
- * {@link Opcodes#ASM5}.
+ * an ASM API version. Must be one of {@link Opcodes#ASM4},
+ * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public void check(final int api) {
if (api == Opcodes.ASM4) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleExportNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,111 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an exported package with its name and the module that can access to it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleExportNode {
+ /**
+ * The package name.
+ */
+ public String packaze;
+
+ /**
+ * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+ * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ */
+ public int access;
+
+ /**
+ * A list of modules that can access to this exported package.
+ * May be <tt>null</tt>.
+ */
+ public List<String> modules;
+
+ /**
+ * Constructs a new {@link ModuleExportNode}.
+ *
+ * @param packaze
+ * the parameter's name.
+ * @param modules
+ * a list of modules that can access to this exported package.
+ */
+ public ModuleExportNode(final String packaze, final int access, final List<String> modules) {
+ this.packaze = packaze;
+ this.access = access;
+ this.modules = modules;
+ }
+
+ /**
+ * Makes the given module visitor visit this export declaration.
+ *
+ * @param mv
+ * a module visitor.
+ */
+ public void accept(final ModuleVisitor mv) {
+ mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,280 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a module declaration.
+ *
+ * @author Remi Forax
+ */
+public class ModuleNode extends ModuleVisitor {
+ /**
+ * Module name
+ */
+ public String name;
+
+ /**
+ * Module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+ * and {@code ACC_MANDATED}.
+ */
+ public int access;
+
+ /**
+ * Version of the module.
+ * May be <tt>null</tt>.
+ */
+ public String version;
+
+ /**
+ * Name of the main class in internal form
+ * May be <tt>null</tt>.
+ */
+ public String mainClass;
+
+ /**
+ * A list of packages that are declared by the current module.
+ * May be <tt>null</tt>.
+ */
+ public List<String> packages;
+
+ /**
+ * A list of modules can are required by the current module.
+ * May be <tt>null</tt>.
+ */
+ public List<ModuleRequireNode> requires;
+
+ /**
+ * A list of packages that are exported by the current module.
+ * May be <tt>null</tt>.
+ */
+ public List<ModuleExportNode> exports;
+
+ /**
+ * A list of packages that are opened by the current module.
+ * May be <tt>null</tt>.
+ */
+ public List<ModuleOpenNode> opens;
+
+ /**
+ * A list of classes in their internal forms that are used
+ * as a service by the current module. May be <tt>null</tt>.
+ */
+ public List<String> uses;
+
+ /**
+ * A list of services along with their implementations provided
+ * by the current module. May be <tt>null</tt>.
+ */
+ public List<ModuleProvideNode> provides;
+
+ public ModuleNode(final String name, final int access,
+ final String version) {
+ super(Opcodes.ASM6);
+ this.name = name;
+ this.access = access;
+ this.version = version;
+ }
+
+ public ModuleNode(final int api,
+ final String name,
+ final int access,
+ final String version,
+ final List<ModuleRequireNode> requires,
+ final List<ModuleExportNode> exports,
+ final List<ModuleOpenNode> opens,
+ final List<String> uses,
+ final List<ModuleProvideNode> provides) {
+ super(api);
+ this.name = name;
+ this.access = access;
+ this.version = version;
+ this.requires = requires;
+ this.exports = exports;
+ this.opens = opens;
+ this.uses = uses;
+ this.provides = provides;
+ if (getClass() != ModuleNode.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ this.mainClass = mainClass;
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ if (packages == null) {
+ packages = new ArrayList<String>(5);
+ }
+ packages.add(packaze);
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ if (requires == null) {
+ requires = new ArrayList<ModuleRequireNode>(5);
+ }
+ requires.add(new ModuleRequireNode(module, access, version));
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ if (exports == null) {
+ exports = new ArrayList<ModuleExportNode>(5);
+ }
+ List<String> moduleList = null;
+ if (modules != null) {
+ moduleList = new ArrayList<String>(modules.length);
+ for (int i = 0; i < modules.length; i++) {
+ moduleList.add(modules[i]);
+ }
+ }
+ exports.add(new ModuleExportNode(packaze, access, moduleList));
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ if (opens == null) {
+ opens = new ArrayList<ModuleOpenNode>(5);
+ }
+ List<String> moduleList = null;
+ if (modules != null) {
+ moduleList = new ArrayList<String>(modules.length);
+ for (int i = 0; i < modules.length; i++) {
+ moduleList.add(modules[i]);
+ }
+ }
+ opens.add(new ModuleOpenNode(packaze, access, moduleList));
+ }
+
+ @Override
+ public void visitUse(String service) {
+ if (uses == null) {
+ uses = new ArrayList<String>(5);
+ }
+ uses.add(service);
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ if (provides == null) {
+ provides = new ArrayList<ModuleProvideNode>(5);
+ }
+ ArrayList<String> providerList =
+ new ArrayList<String>(providers.length);
+ for (int i = 0; i < providers.length; i++) {
+ providerList.add(providers[i]);
+ }
+ provides.add(new ModuleProvideNode(service, providerList));
+ }
+
+ @Override
+ public void visitEnd() {
+ }
+
+ public void accept(final ClassVisitor cv) {
+ ModuleVisitor mv = cv.visitModule(name, access, version);
+ if (mv == null) {
+ return;
+ }
+ if (mainClass != null) {
+ mv.visitMainClass(mainClass);
+ }
+ if (packages != null) {
+ for (int i = 0; i < packages.size(); i++) {
+ mv.visitPackage(packages.get(i));
+ }
+ }
+
+ if (requires != null) {
+ for (int i = 0; i < requires.size(); i++) {
+ requires.get(i).accept(mv);
+ }
+ }
+ if (exports != null) {
+ for (int i = 0; i < exports.size(); i++) {
+ exports.get(i).accept(mv);
+ }
+ }
+ if (opens != null) {
+ for (int i = 0; i < opens.size(); i++) {
+ opens.get(i).accept(mv);
+ }
+ }
+ if (uses != null) {
+ for (int i = 0; i < uses.size(); i++) {
+ mv.visitUse(uses.get(i));
+ }
+ }
+ if (provides != null) {
+ for (int i = 0; i < provides.size(); i++) {
+ provides.get(i).accept(mv);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleOpenNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,111 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an opened package with its name and the module that can access to it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleOpenNode {
+ /**
+ * The package name.
+ */
+ public String packaze;
+
+ /**
+ * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+ * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ */
+ public int access;
+
+ /**
+ * A list of modules that can access to this exported package.
+ * May be <tt>null</tt>.
+ */
+ public List<String> modules;
+
+ /**
+ * Constructs a new {@link ModuleOpenNode}.
+ *
+ * @param packaze
+ * the parameter's name.
+ * @param modules
+ * a list of modules that can access to this open package.
+ */
+ public ModuleOpenNode(final String packaze, final int access, final List<String> modules) {
+ this.packaze = packaze;
+ this.access = access;
+ this.modules = modules;
+ }
+
+ /**
+ * Makes the given module visitor visit this open declaration.
+ *
+ * @param mv
+ * a module visitor.
+ */
+ public void accept(final ModuleVisitor mv) {
+ mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleProvideNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,103 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a service and its implementation provided by the current module.
+ *
+ * @author Remi Forax
+ */
+public class ModuleProvideNode {
+ /**
+ * The service name (in its internal form).
+ */
+ public String service;
+
+ /**
+ * The service provider names (in their internal form).
+ */
+ public List<String> providers;
+
+ /**
+ * Constructs a new {@link ModuleProvideNode}.
+ *
+ * @param service
+ * the service name (in its internal form).
+ * @param providers
+ * the service provider names (in their internal form).
+ */
+ public ModuleProvideNode(final String service, final List<String> providers) {
+ this.service = service;
+ this.providers = providers;
+ }
+
+ /**
+ * Makes the given module visitor visit this require declaration.
+ *
+ * @param mv
+ * a module visitor.
+ */
+ public void accept(final ModuleVisitor mv) {
+ mv.visitProvide(service, providers.toArray(new String[0]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleRequireNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,116 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a required module with its name and access of a module descriptor.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRequireNode {
+ /**
+ * The name of the required module.
+ */
+ public String module;
+
+ /**
+ * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+ * Valid values are <tt>ACC_TRANSITIVE</tt>, <tt>ACC_STATIC_PHASE</tt>,
+ * <tt>ACC_SYNTHETIC</tt> and <tt>ACC_MANDATED</tt>.
+ */
+ public int access;
+
+ /**
+ * Version at compile time of the required module or null.
+ */
+ public String version;
+
+ /**
+ * Constructs a new {@link ModuleRequireNode}.
+ *
+ * @param module
+ * the name of the required module.
+ * @param access
+ * The access flags. Valid values are
+ * <tt>ACC_TRANSITIVE</tt>, <tt>ACC_STATIC_PHASE</tt>,
+ * <tt>ACC_SYNTHETIC</tt> and <tt>ACC_MANDATED</tt>
+ * (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+ * @param version
+ * Version of the required module at compile time,
+ * null if not defined.
+ */
+ public ModuleRequireNode(final String module, final int access,
+ final String version) {
+ this.module = module;
+ this.access = access;
+ this.version = version;
+ }
+
+ /**
+ * Makes the given module visitor visit this require directive.
+ *
+ * @param mv
+ * a module visitor.
+ */
+ public void accept(final ModuleVisitor mv) {
+ mv.visitRequire(module, access, version);
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java Thu Nov 02 13:18:23 2017 -0700
@@ -99,7 +99,7 @@
*/
public TypeAnnotationNode(final int typeRef, final TypePath typePath,
final String desc) {
- this(Opcodes.ASM5, typeRef, typePath, desc);
+ this(Opcodes.ASM6, typeRef, typePath, desc);
if (getClass() != TypeAnnotationNode.class) {
throw new IllegalStateException();
}
@@ -110,7 +110,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param typeRef
* a reference to the annotated type. See {@link TypeReference}.
* @param typePath
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java Thu Nov 02 13:18:23 2017 -0700
@@ -82,7 +82,7 @@
Opcodes {
public BasicInterpreter() {
- super(ASM5);
+ super(ASM6);
}
protected BasicInterpreter(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java Thu Nov 02 13:18:23 2017 -0700
@@ -76,7 +76,7 @@
public class BasicVerifier extends BasicInterpreter {
public BasicVerifier() {
- super(ASM5);
+ super(ASM6);
}
protected BasicVerifier(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java Thu Nov 02 13:18:23 2017 -0700
@@ -136,7 +136,7 @@
public SimpleVerifier(final Type currentClass,
final Type currentSuperClass,
final List<Type> currentClassInterfaces, final boolean isInterface) {
- this(ASM5, currentClass, currentSuperClass, currentClassInterfaces,
+ this(ASM6, currentClass, currentSuperClass, currentClassInterfaces,
isInterface);
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java Thu Nov 02 13:18:23 2017 -0700
@@ -79,7 +79,7 @@
Opcodes {
public SourceInterpreter() {
- super(ASM5);
+ super(ASM6);
}
protected SourceInterpreter(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java Thu Nov 02 13:18:23 2017 -0700
@@ -110,6 +110,11 @@
private static final int ACCESS_INNER = 1048576;
/**
+ * Pseudo access flag used to distinguish module requires/exports flags.
+ */
+ private static final int ACCESS_MODULE = 2097152;
+
+ /**
* Constructs a new {@link ASMifier}. <i>Subclasses must not use this
* constructor</i>. Instead, they must use the
* {@link #ASMifier(int, String, int)} version.
@@ -118,7 +123,7 @@
* If a subclass calls this constructor.
*/
public ASMifier() {
- this(Opcodes.ASM5, "cw", 0);
+ this(Opcodes.ASM6, "cw", 0);
if (getClass() != ASMifier.class) {
throw new IllegalStateException();
}
@@ -129,7 +134,7 @@
*
* @param api
* the ASM API version implemented by this class. Must be one of
- * {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param name
* the name of the visitor variable in the produced code.
* @param id
@@ -196,13 +201,17 @@
final String signature, final String superName,
final String[] interfaces) {
String simpleName;
- int n = name.lastIndexOf('/');
- if (n == -1) {
- simpleName = name;
+ if (name == null) {
+ simpleName = "module-info";
} else {
- text.add("package asm." + name.substring(0, n).replace('/', '.')
- + ";\n");
- simpleName = name.substring(n + 1);
+ int n = name.lastIndexOf('/');
+ if (n == -1) {
+ simpleName = name;
+ } else {
+ text.add("package asm." + name.substring(0, n).replace('/', '.')
+ + ";\n");
+ simpleName = name.substring(n + 1).replace('-', '_');
+ }
}
text.add("import java.util.*;\n");
text.add("import jdk.internal.org.objectweb.asm.*;\n");
@@ -237,6 +246,12 @@
case Opcodes.V1_7:
buf.append("V1_7");
break;
+ case Opcodes.V1_8:
+ buf.append("V1_8");
+ break;
+ case Opcodes.V9:
+ buf.append("V9");
+ break;
default:
buf.append(version);
break;
@@ -276,6 +291,24 @@
}
@Override
+ public Printer visitModule(final String name, final int flags,
+ final String version) {
+ buf.setLength(0);
+ buf.append("ModuleVisitor mdv = cw.visitModule(");
+ appendConstant(name);
+ buf.append(", ");
+ appendAccess(flags | ACCESS_MODULE);
+ buf.append(", ");
+ appendConstant(version);
+ buf.append(");\n\n");
+ text.add(buf.toString());
+ ASMifier a = createASMifier("mdv", 0);
+ text.add(a.getText());
+ text.add("}\n");
+ return a;
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
buf.setLength(0);
@@ -386,6 +419,108 @@
}
// ------------------------------------------------------------------------
+ // Module
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ buf.setLength(0);
+ buf.append("mdv.visitMainClass(");
+ appendConstant(buf, mainClass);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ buf.setLength(0);
+ buf.append("mdv.visitPackage(");
+ appendConstant(buf, packaze);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ buf.setLength(0);
+ buf.append("mdv.visitRequire(");
+ appendConstant(buf, module);
+ buf.append(", ");
+ appendAccess(access | ACCESS_MODULE);
+ buf.append(", ");
+ appendConstant(buf, version);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ buf.setLength(0);
+ buf.append("mdv.visitExport(");
+ appendConstant(buf, packaze);
+ buf.append(", ");
+ appendAccess(access | ACCESS_MODULE);
+ if (modules != null && modules.length > 0) {
+ buf.append(", new String[] {");
+ for (int i = 0; i < modules.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(modules[i]);
+ }
+ buf.append(" }");
+ }
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ buf.setLength(0);
+ buf.append("mdv.visitOpen(");
+ appendConstant(buf, packaze);
+ buf.append(", ");
+ appendAccess(access | ACCESS_MODULE);
+ if (modules != null && modules.length > 0) {
+ buf.append(", new String[] {");
+ for (int i = 0; i < modules.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(modules[i]);
+ }
+ buf.append(" }");
+ }
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitUse(String service) {
+ buf.setLength(0);
+ buf.append("mdv.visitUse(");
+ appendConstant(buf, service);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ buf.setLength(0);
+ buf.append("mdv.visitProvide(");
+ appendConstant(buf, service);
+ buf.append(", new String[] {");
+ for (int i = 0; i < providers.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(providers[i]);
+ }
+ buf.append(" });\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitModuleEnd() {
+ text.add("mdv.visitEnd();\n");
+ }
+
+
+ // ------------------------------------------------------------------------
// Annotations
// ------------------------------------------------------------------------
@@ -972,7 +1107,7 @@
// ------------------------------------------------------------------------
protected ASMifier createASMifier(final String name, final int id) {
- return new ASMifier(Opcodes.ASM5, name, id);
+ return new ASMifier(Opcodes.ASM6, name, id);
}
/**
@@ -1000,7 +1135,11 @@
if (!first) {
buf.append(" + ");
}
- buf.append("ACC_FINAL");
+ if ((access & ACCESS_MODULE) == 0) {
+ buf.append("ACC_FINAL");
+ } else {
+ buf.append("ACC_TRANSITIVE");
+ }
first = false;
}
if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -1010,31 +1149,35 @@
buf.append("ACC_STATIC");
first = false;
}
- if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
+ if ((access & (Opcodes.ACC_SYNCHRONIZED | Opcodes.ACC_SUPER | Opcodes.ACC_TRANSITIVE)) != 0) {
if (!first) {
buf.append(" + ");
}
if ((access & ACCESS_CLASS) == 0) {
- buf.append("ACC_SYNCHRONIZED");
+ if ((access & ACCESS_MODULE) == 0) {
+ buf.append("ACC_SYNCHRONIZED");
+ } else {
+ buf.append("ACC_TRANSITIVE");
+ }
} else {
buf.append("ACC_SUPER");
}
first = false;
}
- if ((access & Opcodes.ACC_VOLATILE) != 0
- && (access & ACCESS_FIELD) != 0) {
+ if ((access & (Opcodes.ACC_VOLATILE | Opcodes.ACC_BRIDGE | Opcodes.ACC_STATIC_PHASE)) != 0) {
if (!first) {
buf.append(" + ");
}
- buf.append("ACC_VOLATILE");
- first = false;
- }
- if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0
- && (access & ACCESS_FIELD) == 0) {
- if (!first) {
- buf.append(" + ");
+ if ((access & ACCESS_FIELD) == 0) {
+ if ((access & ACCESS_MODULE) == 0) {
+ buf.append("ACC_BRIDGE");
+ } else {
+ buf.append("ACC_STATIC_PHASE");
+ }
+ } else {
+ buf.append("ACC_VOLATILE");
}
- buf.append("ACC_BRIDGE");
+
first = false;
}
if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0
@@ -1113,11 +1256,15 @@
buf.append("ACC_DEPRECATED");
first = false;
}
- if ((access & Opcodes.ACC_MANDATED) != 0) {
+ if ((access & (Opcodes.ACC_MANDATED | Opcodes.ACC_MODULE)) != 0) {
if (!first) {
buf.append(" + ");
}
- buf.append("ACC_MANDATED");
+ if ((access & ACCESS_CLASS) == 0) {
+ buf.append("ACC_MANDATED");
+ } else {
+ buf.append("ACC_MODULE");
+ }
first = false;
}
if (first) {
@@ -1163,7 +1310,8 @@
.append(", \"");
buf.append(h.getOwner()).append("\", \"");
buf.append(h.getName()).append("\", \"");
- buf.append(h.getDesc()).append("\")");
+ buf.append(h.getDesc()).append("\", ");
+ buf.append(h.isInterface()).append(")");
} else if (cst instanceof Byte) {
buf.append("new Byte((byte)").append(cst).append(')');
} else if (cst instanceof Boolean) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -78,7 +78,7 @@
}
CheckAnnotationAdapter(final AnnotationVisitor av, final boolean named) {
- super(Opcodes.ASM5, av);
+ super(Opcodes.ASM6, av);
this.named = named;
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -73,6 +73,7 @@
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -181,6 +182,11 @@
private boolean end;
/**
+ * <tt>true</tt> if the visitModule method has been called.
+ */
+ private boolean module;
+
+ /**
* The already visited labels. This map associate Integer values to Label
* keys.
*/
@@ -363,7 +369,7 @@
* If a subclass calls this constructor.
*/
public CheckClassAdapter(final ClassVisitor cv, final boolean checkDataFlow) {
- this(Opcodes.ASM5, cv, checkDataFlow);
+ this(Opcodes.ASM6, cv, checkDataFlow);
if (getClass() != CheckClassAdapter.class) {
throw new IllegalStateException();
}
@@ -374,7 +380,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param cv
* the class visitor to which this adapter must delegate calls.
* @param checkDataFlow
@@ -407,8 +413,12 @@
+ Opcodes.ACC_SUPER + Opcodes.ACC_INTERFACE
+ Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC
+ Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM
- + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
- if (name == null || !name.endsWith("package-info")) {
+ + Opcodes.ACC_DEPRECATED + Opcodes.ACC_MODULE
+ + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+ if (name == null) {
+ throw new IllegalArgumentException("Illegal class name (null)");
+ }
+ if (!name.endsWith("package-info")) {
CheckMethodAdapter.checkInternalName(name, "class name");
}
if ("java/lang/Object".equals(name)) {
@@ -450,6 +460,22 @@
}
@Override
+ public ModuleVisitor visitModule(String name, int access, String version) {
+ checkState();
+ if (module) {
+ throw new IllegalStateException(
+ "visitModule can be called only once.");
+ }
+ module = true;
+ if (name == null) {
+ throw new IllegalArgumentException("Illegal module name (null)");
+ }
+ checkAccess(access, Opcodes.ACC_OPEN | Opcodes.ACC_SYNTHETIC);
+ return new CheckModuleAdapter(super.visitModule(name, access, version),
+ (access & Opcodes.ACC_OPEN) != 0);
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
checkState();
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -83,7 +83,7 @@
* If a subclass calls this constructor.
*/
public CheckFieldAdapter(final FieldVisitor fv) {
- this(Opcodes.ASM5, fv);
+ this(Opcodes.ASM6, fv);
if (getClass() != CheckFieldAdapter.class) {
throw new IllegalStateException();
}
@@ -94,7 +94,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param fv
* the field visitor to which this adapter must delegate calls.
*/
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -426,7 +426,7 @@
*/
public CheckMethodAdapter(final MethodVisitor mv,
final Map<Label, Integer> labels) {
- this(Opcodes.ASM5, mv, labels);
+ this(Opcodes.ASM6, mv, labels);
if (getClass() != CheckMethodAdapter.class) {
throw new IllegalStateException();
}
@@ -439,7 +439,8 @@
*
* @param api
* the ASM API version implemented by this CheckMethodAdapter.
- * Must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5}
+ * or {@link Opcodes#ASM6}.
* @param mv
* the method visitor to which this adapter must delegate calls.
* @param labels
@@ -756,6 +757,12 @@
throw new IllegalArgumentException(
"INVOKEINTERFACE can't be used with classes");
}
+ if (opcode == Opcodes.INVOKESPECIAL && itf
+ && (version & 0xFFFF) < Opcodes.V1_8) {
+ throw new IllegalArgumentException(
+ "INVOKESPECIAL can't be used with interfaces prior to Java 8");
+ }
+
// Calling super.visitMethodInsn requires to call the correct version
// depending on this.api (otherwise infinite loops can occur). To
// simplify and to make it easier to automatically remove the backward
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckModuleAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,180 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.util;
+
+import java.util.HashSet;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * @author Remi Forax
+ */
+public final class CheckModuleAdapter extends ModuleVisitor {
+ private boolean end;
+ private final boolean isOpen;
+
+ private final HashSet<String> requireNames = new HashSet<String>();
+ private final HashSet<String> exportNames = new HashSet<String>();
+ private final HashSet<String> openNames = new HashSet<String>();
+ private final HashSet<String> useNames = new HashSet<String>();
+ private final HashSet<String> provideNames = new HashSet<String>();
+
+ public CheckModuleAdapter(final ModuleVisitor mv, final boolean isOpen) {
+ super(Opcodes.ASM6, mv);
+ this.isOpen = isOpen;
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ checkEnd();
+ if (module == null) {
+ throw new IllegalArgumentException("require cannot be null");
+ }
+ checkDeclared("requires", requireNames, module);
+ CheckClassAdapter.checkAccess(access, Opcodes.ACC_STATIC_PHASE
+ + Opcodes.ACC_TRANSITIVE + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_MANDATED);
+ super.visitRequire(module, access, version);
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ checkEnd();
+ if (packaze == null) {
+ throw new IllegalArgumentException("packaze cannot be null");
+ }
+ CheckMethodAdapter.checkInternalName(packaze, "package name");
+ checkDeclared("exports", exportNames, packaze);
+ CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC
+ + Opcodes.ACC_MANDATED);
+ if (modules != null) {
+ for (int i = 0; i < modules.length; i++) {
+ if (modules[i] == null) {
+ throw new IllegalArgumentException("module at index " + i + " cannot be null");
+ }
+ }
+ }
+ super.visitExport(packaze, access, modules);
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ checkEnd();
+ if (isOpen) {
+ throw new IllegalArgumentException("an open module can not use open directive");
+ }
+ if (packaze == null) {
+ throw new IllegalArgumentException("packaze cannot be null");
+ }
+ CheckMethodAdapter.checkInternalName(packaze, "package name");
+ checkDeclared("opens", openNames, packaze);
+ CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC
+ + Opcodes.ACC_MANDATED);
+ if (modules != null) {
+ for (int i = 0; i < modules.length; i++) {
+ if (modules[i] == null) {
+ throw new IllegalArgumentException("module at index " + i + " cannot be null");
+ }
+ }
+ }
+ super.visitOpen(packaze, access, modules);
+ }
+
+ @Override
+ public void visitUse(String service) {
+ checkEnd();
+ CheckMethodAdapter.checkInternalName(service, "service");
+ checkDeclared("uses", useNames, service);
+ super.visitUse(service);
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ checkEnd();
+ CheckMethodAdapter.checkInternalName(service, "service");
+ checkDeclared("provides", provideNames, service);
+ if (providers == null || providers.length == 0) {
+ throw new IllegalArgumentException("providers cannot be null or empty");
+ }
+ for (int i = 0; i < providers.length; i++) {
+ CheckMethodAdapter.checkInternalName(providers[i], "provider");
+ }
+ super.visitProvide(service, providers);
+ }
+
+ @Override
+ public void visitEnd() {
+ checkEnd();
+ end = true;
+ super.visitEnd();
+ }
+
+ private void checkEnd() {
+ if (end) {
+ throw new IllegalStateException(
+ "Cannot call a visit method after visitEnd has been called");
+ }
+ }
+
+ private static void checkDeclared(String directive, HashSet<String> names, String name) {
+ if (!names.add(name)) {
+ throw new IllegalArgumentException(directive + " " + name + " already declared");
+ }
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java Thu Nov 02 13:18:23 2017 -0700
@@ -142,7 +142,7 @@
* <tt>null</tt>.
*/
public CheckSignatureAdapter(final int type, final SignatureVisitor sv) {
- this(Opcodes.ASM5, type, sv);
+ this(Opcodes.ASM6, type, sv);
}
/**
@@ -150,7 +150,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param type
* the type of signature to be checked. See
* {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
@@ -175,7 +175,7 @@
|| (state != EMPTY && state != FORMAL && state != BOUND)) {
throw new IllegalStateException();
}
- CheckMethodAdapter.checkIdentifier(name, "formal type parameter");
+ checkIdentifier(name, "formal type parameter");
state = FORMAL;
if (sv != null) {
sv.visitFormalTypeParameter(name);
@@ -284,7 +284,7 @@
if (type != TYPE_SIGNATURE || state != EMPTY) {
throw new IllegalStateException();
}
- CheckMethodAdapter.checkIdentifier(name, "type variable");
+ checkIdentifier(name, "type variable");
state = SIMPLE_TYPE;
if (sv != null) {
sv.visitTypeVariable(name);
@@ -306,7 +306,7 @@
if (type != TYPE_SIGNATURE || state != EMPTY) {
throw new IllegalStateException();
}
- CheckMethodAdapter.checkInternalName(name, "class name");
+ checkClassName(name, "class name");
state = CLASS_TYPE;
if (sv != null) {
sv.visitClassType(name);
@@ -318,7 +318,7 @@
if (state != CLASS_TYPE) {
throw new IllegalStateException();
}
- CheckMethodAdapter.checkIdentifier(name, "inner class name");
+ checkIdentifier(name, "inner class name");
if (sv != null) {
sv.visitInnerClassType(name);
}
@@ -356,4 +356,30 @@
sv.visitEnd();
}
}
+
+ private void checkClassName(final String name, final String msg) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not be null or empty)");
+ }
+ for (int i = 0; i < name.length(); ++i) {
+ if (".;[<>:".indexOf(name.charAt(i)) != -1) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not contain . ; [ < > or :): " + name);
+ }
+ }
+ }
+
+ private void checkIdentifier(final String name, final String msg) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not be null or empty)");
+ }
+ for (int i = 0; i < name.length(); ++i) {
+ if (".;[/<>:".indexOf(name.charAt(i)) != -1) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not contain . ; [ / < > or :): " + name);
+ }
+ }
+ }
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java Thu Nov 02 13:18:23 2017 -0700
@@ -146,7 +146,7 @@
/**
* The ASM API version implemented by this class. The value of this field
- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected final int api;
@@ -174,7 +174,7 @@
*
* @param api
* the ASM API version implemented by this printer. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected Printer(final int api) {
this.api = api;
@@ -226,6 +226,24 @@
*/
public abstract void visitSource(final String source, final String debug);
+
+ /**
+ * Module.
+ * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitModule(String, int)}.
+ *
+ * @param name
+ * module name.
+ * @param access
+ * module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+ * and {@code ACC_MANDATED}.
+ * @param version
+ * module version or null.
+ * @return
+ */
+ public Printer visitModule(String name, int access, String version) {
+ throw new RuntimeException("Must be overriden");
+ }
+
/**
* Class outer class.
* See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitOuterClass}.
@@ -376,6 +394,45 @@
public abstract void visitClassEnd();
// ------------------------------------------------------------------------
+ // Module
+ // ------------------------------------------------------------------------
+
+ public void visitMainClass(String mainClass) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitPackage(String packaze) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitRequire(String module, int access, String version) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitExport(String packaze, int access, String... modules) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitOpen(String packaze, int access, String... modules) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitUse(String service) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ public void visitProvide(String service, String... providers) {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ /**
+ * Module end. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitEnd}.
+ */
+ public void visitModuleEnd() {
+ throw new RuntimeException("Must be overriden");
+ }
+
+ // ------------------------------------------------------------------------
// Annotations
// ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Thu Nov 02 13:18:23 2017 -0700
@@ -182,7 +182,7 @@
* If a subclass calls this constructor.
*/
public Textifier() {
- this(Opcodes.ASM5);
+ this(Opcodes.ASM6);
if (getClass() != Textifier.class) {
throw new IllegalStateException();
}
@@ -193,7 +193,7 @@
*
* @param api
* the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
protected Textifier(final int api) {
super(api);
@@ -250,6 +250,10 @@
public void visit(final int version, final int access, final String name,
final String signature, final String superName,
final String[] interfaces) {
+ if ((access & Opcodes.ACC_MODULE) != 0) {
+ // visitModule will print the module
+ return;
+ }
this.access = access;
int major = version & 0xFFFF;
int minor = version >>> 16;
@@ -271,7 +275,7 @@
.append(sv.getDeclaration()).append('\n');
}
- appendAccess(access & ~Opcodes.ACC_SUPER);
+ appendAccess(access & ~(Opcodes.ACC_SUPER | Opcodes.ACC_MODULE));
if ((access & Opcodes.ACC_ANNOTATION) != 0) {
buf.append("@interface ");
} else if ((access & Opcodes.ACC_INTERFACE) != 0) {
@@ -315,6 +319,24 @@
}
@Override
+ public Printer visitModule(final String name, final int access,
+ final String version) {
+ buf.setLength(0);
+ if ((access & Opcodes.ACC_OPEN) != 0) {
+ buf.append("open ");
+ }
+ buf.append("module ")
+ .append(name)
+ .append(" { ")
+ .append(version == null ? "" : "// " + version)
+ .append("\n\n");
+ text.add(buf.toString());
+ Textifier t = createTextifier();
+ text.add(t.getText());
+ return t;
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
buf.setLength(0);
@@ -443,7 +465,7 @@
}
buf.append(tab);
- appendAccess(access & ~Opcodes.ACC_VOLATILE);
+ appendAccess(access & ~(Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT));
if ((access & Opcodes.ACC_NATIVE) != 0) {
buf.append("native ");
}
@@ -483,6 +505,118 @@
}
// ------------------------------------------------------------------------
+ // Module
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ buf.setLength(0);
+ buf.append(" // main class ").append(mainClass).append('\n');
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ buf.setLength(0);
+ buf.append(" // package ").append(packaze).append('\n');
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitRequire(String require, int access, String version) {
+ buf.setLength(0);
+ buf.append(tab).append("requires ");
+ if ((access & Opcodes.ACC_TRANSITIVE) != 0) {
+ buf.append("transitive ");
+ }
+ if ((access & Opcodes.ACC_STATIC_PHASE) != 0) {
+ buf.append("static ");
+ }
+ buf.append(require)
+ .append("; // access flags 0x")
+ .append(Integer.toHexString(access).toUpperCase())
+ .append('\n');
+ if (version != null) {
+ buf.append(" // version ")
+ .append(version)
+ .append('\n');
+ }
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitExport(String export, int access, String... modules) {
+ buf.setLength(0);
+ buf.append(tab).append("exports ");
+ buf.append(export);
+ if (modules != null && modules.length > 0) {
+ buf.append(" to");
+ } else {
+ buf.append(';');
+ }
+ buf.append(" // access flags 0x")
+ .append(Integer.toHexString(access).toUpperCase())
+ .append('\n');
+ if (modules != null && modules.length > 0) {
+ for (int i = 0; i < modules.length; ++i) {
+ buf.append(tab2).append(modules[i]);
+ buf.append(i != modules.length - 1 ? ",\n": ";\n");
+ }
+ }
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitOpen(String export, int access, String... modules) {
+ buf.setLength(0);
+ buf.append(tab).append("opens ");
+ buf.append(export);
+ if (modules != null && modules.length > 0) {
+ buf.append(" to");
+ } else {
+ buf.append(';');
+ }
+ buf.append(" // access flags 0x")
+ .append(Integer.toHexString(access).toUpperCase())
+ .append('\n');
+ if (modules != null && modules.length > 0) {
+ for (int i = 0; i < modules.length; ++i) {
+ buf.append(tab2).append(modules[i]);
+ buf.append(i != modules.length - 1 ? ",\n": ";\n");
+ }
+ }
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitUse(String use) {
+ buf.setLength(0);
+ buf.append(tab).append("uses ");
+ appendDescriptor(INTERNAL_NAME, use);
+ buf.append(";\n");
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitProvide(String provide, String... providers) {
+ buf.setLength(0);
+ buf.append(tab).append("provides ");
+ appendDescriptor(INTERNAL_NAME, provide);
+ buf.append(" with\n");
+ for (int i = 0; i < providers.length; ++i) {
+ buf.append(tab2);
+ appendDescriptor(INTERNAL_NAME, providers[i]);
+ buf.append(i != providers.length - 1 ? ",\n": ";\n");
+ }
+ text.add(buf.toString());
+ }
+
+ @Override
+ public void visitModuleEnd() {
+ // empty
+ }
+
+ // ------------------------------------------------------------------------
// Annotations
// ------------------------------------------------------------------------
@@ -1296,13 +1430,16 @@
appendDescriptor(INTERNAL_NAME, h.getOwner());
buf.append('.');
buf.append(h.getName());
- if(!isMethodHandle){
+ if (!isMethodHandle) {
buf.append('(');
}
appendDescriptor(HANDLE_DESCRIPTOR, h.getDesc());
- if(!isMethodHandle){
+ if (!isMethodHandle) {
buf.append(')');
}
+ if (h.isInterface()) {
+ buf.append(" itf");
+ }
}
/**
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -76,7 +76,7 @@
}
public TraceAnnotationVisitor(final AnnotationVisitor av, final Printer p) {
- super(Opcodes.ASM5, av);
+ super(Opcodes.ASM6, av);
this.p = p;
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -65,6 +65,7 @@
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
@@ -160,7 +161,7 @@
*/
public TraceClassVisitor(final ClassVisitor cv, final Printer p,
final PrintWriter pw) {
- super(Opcodes.ASM5, cv);
+ super(Opcodes.ASM6, cv);
this.pw = pw;
this.p = p;
}
@@ -180,6 +181,14 @@
}
@Override
+ public ModuleVisitor visitModule(String name, int flags,
+ String version) {
+ Printer p = this.p.visitModule(name, flags, version);
+ ModuleVisitor mv = super.visitModule(name, flags, version);
+ return new TraceModuleVisitor(mv, p);
+ }
+
+ @Override
public void visitOuterClass(final String owner, final String name,
final String desc) {
p.visitOuterClass(owner, name, desc);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -79,7 +79,7 @@
}
public TraceFieldVisitor(final FieldVisitor fv, final Printer p) {
- super(Opcodes.ASM5, fv);
+ super(Opcodes.ASM6, fv);
this.p = p;
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -81,7 +81,7 @@
}
public TraceMethodVisitor(final MethodVisitor mv, final Printer p) {
- super(Opcodes.ASM5, mv);
+ super(Opcodes.ASM6, mv);
this.p = p;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceModuleVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,130 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.util;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} that prints the fields it visits with a
+ * {@link Printer}.
+ *
+ * @author Remi Forax
+ */
+public final class TraceModuleVisitor extends ModuleVisitor {
+
+ public final Printer p;
+
+ public TraceModuleVisitor(final Printer p) {
+ this(null, p);
+ }
+
+ public TraceModuleVisitor(final ModuleVisitor mv, final Printer p) {
+ super(Opcodes.ASM6, mv);
+ this.p = p;
+ }
+
+ @Override
+ public void visitMainClass(String mainClass) {
+ p.visitMainClass(mainClass);
+ super.visitMainClass(mainClass);
+ }
+
+ @Override
+ public void visitPackage(String packaze) {
+ p.visitPackage(packaze);
+ super.visitPackage(packaze);
+ }
+
+ @Override
+ public void visitRequire(String module, int access, String version) {
+ p.visitRequire(module, access, version);
+ super.visitRequire(module, access, version);
+ }
+
+ @Override
+ public void visitExport(String packaze, int access, String... modules) {
+ p.visitExport(packaze, access, modules);
+ super.visitExport(packaze, access, modules);
+ }
+
+ @Override
+ public void visitOpen(String packaze, int access, String... modules) {
+ p.visitOpen(packaze, access, modules);
+ super.visitOpen(packaze, access, modules);
+ }
+
+ @Override
+ public void visitUse(String use) {
+ p.visitUse(use);
+ super.visitUse(use);
+ }
+
+ @Override
+ public void visitProvide(String service, String... providers) {
+ p.visitProvide(service, providers);
+ super.visitProvide(service, providers);
+ }
+
+ @Override
+ public void visitEnd() {
+ p.visitModuleEnd();
+ super.visitEnd();
+ }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java Thu Nov 02 13:18:23 2017 -0700
@@ -104,13 +104,13 @@
private String separator = "";
public TraceSignatureVisitor(final int access) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
this.declaration = new StringBuilder();
}
private TraceSignatureVisitor(final StringBuilder buf) {
- super(Opcodes.ASM5);
+ super(Opcodes.ASM6);
this.declaration = buf;
}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt Thu Nov 02 13:18:23 2017 -0700
@@ -1,12 +1,4 @@
-Path: .
-Working Copy Root Path: /hudson/jobs/objectweb-init/workspace/asm-svn-2016-01-25
-URL: file:///svnroot/asm/trunk/asm
-Repository Root: file:///svnroot/asm
-Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
-Revision: 1795
-Node Kind: directory
-Schedule: normal
-Last Changed Author: ebruneton
-Last Changed Rev: 1795
-Last Changed Date: 2016-01-24 14:17:10 +0100 (Sun, 24 Jan 2016)
+ASM_6_0-11-gac81f5f
+origin https://gitlab.ow2.org/asm/asm.git (fetch)
+ac81f5f Merge branch 'add-class-dump-tool-for-unit-tests' into 'master'
--- a/test/hotspot/jtreg/runtime/constantPool/ConstModule.java Thu Nov 02 15:09:13 2017 -0700
+++ b/test/hotspot/jtreg/runtime/constantPool/ConstModule.java Thu Nov 02 13:18:23 2017 -0700
@@ -47,13 +47,13 @@
// Test that the JVM throws CFE for constant pool CONSTANT_Module type, for
// class file version 53, when ACC_MODULE is not set in the access_flags.
- ConstModule.write_and_load(Opcodes.V1_9,
+ ConstModule.write_and_load(Opcodes.V9,
Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC,
"jdk.fooMod", "FooMod", MODULE_TEST, CFE_EXCEPTION);
// Test that the JVM throws NCDFE for constant pool CONSTANT_Module type,
// for class file version 53, when ACC_MODULE is set in the access_flags.
- ConstModule.write_and_load(Opcodes.V1_9,
+ ConstModule.write_and_load(Opcodes.V9,
Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
"jdk.fooModACC", "FooModACC", MODULE_TEST, NCDFE_EXCEPTION);
@@ -65,13 +65,13 @@
// Test that the JVM throws CFE for constant pool CONSTANT_Package type, for
// class file version 53, when ACC_MODULE is not set in the access_flags.
- ConstModule.write_and_load(Opcodes.V1_9,
+ ConstModule.write_and_load(Opcodes.V9,
Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC,
"jdk.fooPkg", "FooPkg", PACKAGE_TEST, CFE_EXCEPTION);
// Test that the JVM throws NCDFE for constant pool CONSTANT_Package type,
// for class file version 53, when ACC_MODULE is set in the access_flags.
- ConstModule.write_and_load(Opcodes.V1_9,
+ ConstModule.write_and_load(Opcodes.V9,
Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
"jdk.fooModACC", "FooModACC", PACKAGE_TEST, NCDFE_EXCEPTION);
--- a/test/jdk/java/lang/ModuleTests/AnnotationsTest.java Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/java/lang/ModuleTests/AnnotationsTest.java Thu Nov 02 13:18:23 2017 -0700
@@ -34,13 +34,13 @@
import java.util.List;
import java.util.Set;
-import jdk.internal.module.ClassFileAttributes;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@@ -48,6 +48,7 @@
/**
* @test
* @modules java.base/jdk.internal.org.objectweb.asm
+ * java.base/jdk.internal.org.objectweb.asm.commons
* java.base/jdk.internal.module
* java.xml
* @run testng AnnotationsTest
@@ -113,14 +114,11 @@
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) { };
+ ClassVisitor cv = new ClassVisitor(Opcodes.ASM6, cw) { };
ClassReader cr = new ClassReader(in);
-
List<Attribute> attrs = new ArrayList<>();
- attrs.add(new ClassFileAttributes.ModuleAttribute());
- attrs.add(new ClassFileAttributes.ModulePackagesAttribute());
- attrs.add(new ClassFileAttributes.ModuleTargetAttribute());
+ attrs.add(new ModuleTargetAttribute());
cr.accept(cv, attrs.toArray(new Attribute[0]), 0);
AnnotationVisitor annotationVisitor
--- a/test/jdk/java/lang/invoke/DefineClassTest.java Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/java/lang/invoke/DefineClassTest.java Thu Nov 02 13:18:23 2017 -0700
@@ -243,7 +243,7 @@
byte[] generateClass(String className) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- cw.visit(V1_9,
+ cw.visit(V9,
ACC_PUBLIC + ACC_SUPER,
className.replace(".", "/"),
null,
@@ -272,7 +272,7 @@
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- cw.visit(V1_9,
+ cw.visit(V9,
ACC_PUBLIC + ACC_SUPER,
className.replace(".", "/"),
null,
@@ -309,7 +309,7 @@
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- cw.visit(V1_9,
+ cw.visit(V9,
ACC_PUBLIC + ACC_SUPER,
className.replace(".", "/"),
null,
--- a/test/jdk/java/util/ServiceLoader/BadProvidersTest.java Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/java/util/ServiceLoader/BadProvidersTest.java Thu Nov 02 13:18:23 2017 -0700
@@ -209,7 +209,7 @@
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ ClassWriter.COMPUTE_FRAMES);
- cw.visit(V1_9,
+ cw.visit(V9,
ACC_PUBLIC + ACC_SUPER,
"p/ProviderFactory",
null,
--- a/test/jdk/lib/testlibrary/ModuleTargetHelper.java Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/lib/testlibrary/ModuleTargetHelper.java Thu Nov 02 13:18:23 2017 -0700
@@ -29,13 +29,9 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
public class ModuleTargetHelper {
private ModuleTargetHelper() {}
@@ -60,29 +56,12 @@
}
public static ModuleTarget read(InputStream in) throws IOException {
- ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
- @Override
- public void visitAttribute(Attribute attr) {
- if (attr instanceof ModuleTargetAttribute) {
- modTargets[0] = (ModuleTargetAttribute)attr;
- }
- }
- };
-
- // prototype of attributes that should be parsed
- Attribute[] attrs = new Attribute[] {
- new ModuleTargetAttribute()
- };
-
- // parse module-info.class
- ClassReader cr = new ClassReader(in);
- cr.accept(cv, attrs, 0);
- if (modTargets[0] != null) {
- return new ModuleTarget(modTargets[0].targetPlatform());
+ ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+ if (attrs.target() != null) {
+ return new ModuleTarget(attrs.target().targetPlatform());
+ } else {
+ return null;
}
-
- return null;
}
public static ModuleTarget read(ModuleReference modRef) throws IOException {
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m1/p1/Main.java Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m1/p1/Main.java Thu Nov 02 13:18:23 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,35 +34,13 @@
import java.util.Collections;
import java.util.Set;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
public class Main {
private static boolean hasModuleTarget(InputStream in) throws IOException {
- ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
- @Override
- public void visitAttribute(Attribute attr) {
- if (attr instanceof ModuleTargetAttribute) {
- modTargets[0] = (ModuleTargetAttribute)attr;
- }
- }
- };
-
- // prototype of attributes that should be parsed
- Attribute[] attrs = new Attribute[] {
- new ModuleTargetAttribute()
- };
-
- // parse module-info.class
- ClassReader cr = new ClassReader(in);
- cr.accept(cv, attrs, 0);
- return modTargets[0] != null && modTargets[0].targetPlatform() != null;
+ ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+ return attrs.target() != null;
}
public static void main(String... args) throws Exception {
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java Thu Nov 02 13:18:23 2017 -0700
@@ -35,35 +35,13 @@
import java.util.Map;
import java.util.Set;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
public class Main {
private static boolean hasModuleTarget(InputStream in) throws IOException {
- ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
- ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
- @Override
- public void visitAttribute(Attribute attr) {
- if (attr instanceof ModuleTargetAttribute) {
- modTargets[0] = (ModuleTargetAttribute)attr;
- }
- }
- };
-
- // prototype of attributes that should be parsed
- Attribute[] attrs = new Attribute[] {
- new ModuleTargetAttribute()
- };
-
- // parse module-info.class
- ClassReader cr = new ClassReader(in);
- cr.accept(cv, attrs, 0);
- return modTargets[0] != null && modTargets[0].targetPlatform() != null;
+ ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+ return attrs.target() != null;
}
private static boolean hasModuleTarget(String modName) throws IOException {