8190287: Update JDK's internal ASM to ASMv6
Reviewed-by: alanb, mchung, sundar
This commit is contained in:
parent
41f1222db0
commit
105a51b96d
@ -70,7 +70,7 @@ public abstract class AnnotationVisitor {
|
||||
|
||||
/**
|
||||
* 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 @@ public abstract class AnnotationVisitor {
|
||||
*
|
||||
* @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 @@ public abstract class AnnotationVisitor {
|
||||
*
|
||||
* @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 @@ public abstract class AnnotationVisitor {
|
||||
* 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
|
||||
|
@ -133,7 +133,7 @@ final class AnnotationWriter extends AnnotationVisitor {
|
||||
*/
|
||||
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;
|
||||
|
@ -72,31 +72,6 @@ import java.io.InputStream;
|
||||
*/
|
||||
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
|
||||
@ -133,6 +108,21 @@ public class ClassReader {
|
||||
*/
|
||||
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
|
||||
@ -195,7 +185,7 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
// case ClassWriter.CLASS:
|
||||
// case ClassWriter.STR:
|
||||
// case ClassWriter.MTYPE
|
||||
// case ClassWriter.PACKAGE:
|
||||
// case ClassWriter.MODULE:
|
||||
default:
|
||||
size = 3;
|
||||
break;
|
||||
@ -377,7 +369,9 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
} 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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
}
|
||||
|
||||
// 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 @@ public class ClassReader {
|
||||
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,
|
||||
@ -726,6 +731,120 @@ public class ClassReader {
|
||||
classVisitor.visitEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@ -762,24 +881,20 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
}
|
||||
|
||||
// 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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
* 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 @@ public class ClassReader {
|
||||
}
|
||||
|
||||
// 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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
// 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 @@ public class ClassReader {
|
||||
// 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 @@ public class ClassReader {
|
||||
|
||||
// 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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
* 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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
}
|
||||
|
||||
// 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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
}
|
||||
}
|
||||
frame.offset += delta + 1;
|
||||
readLabel(frame.offset, labels);
|
||||
createLabel(frame.offset, labels);
|
||||
return stackMap;
|
||||
}
|
||||
|
||||
@ -2190,7 +2361,7 @@ public class ClassReader {
|
||||
v += 2;
|
||||
break;
|
||||
default: // Uninitialized
|
||||
frame[index] = readLabel(readUnsignedShort(v), labels);
|
||||
frame[index] = createLabel(readUnsignedShort(v), labels);
|
||||
v += 2;
|
||||
}
|
||||
return v;
|
||||
@ -2216,6 +2387,39 @@ public class ClassReader {
|
||||
return labels[offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@ -2470,6 +2674,20 @@ public class ClassReader {
|
||||
return new String(buf, 0, strLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -2484,44 +2702,41 @@ public class ClassReader {
|
||||
* @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 @@ public class ClassReader {
|
||||
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);
|
||||
|
@ -61,7 +61,7 @@ package jdk.internal.org.objectweb.asm;
|
||||
/**
|
||||
* 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 @@ public abstract class ClassVisitor {
|
||||
|
||||
/**
|
||||
* 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 @@ public abstract class ClassVisitor {
|
||||
*
|
||||
* @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 @@ public abstract class ClassVisitor {
|
||||
*
|
||||
* @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;
|
||||
@ -160,6 +160,28 @@ public abstract class ClassVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -87,8 +87,8 @@ public class ClassWriter extends ClassVisitor {
|
||||
* {@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)
|
||||
*/
|
||||
@ -196,6 +196,27 @@ public class ClassWriter extends ClassVisitor {
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@ -284,7 +305,7 @@ public class ClassWriter extends ClassVisitor {
|
||||
/**
|
||||
* 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;
|
||||
|
||||
@ -433,6 +454,11 @@ public class ClassWriter extends ClassVisitor {
|
||||
*/
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
*/
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
// // 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 @@ public class ClassWriter extends ClassVisitor {
|
||||
* {@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 @@ public class ClassWriter extends ClassVisitor {
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
* @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 @@ public class ClassWriter extends ClassVisitor {
|
||||
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);
|
||||
@ -731,6 +753,14 @@ public class ClassWriter extends ClassVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
@ -743,9 +773,6 @@ public class ClassWriter extends ClassVisitor {
|
||||
@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 @@ public class ClassWriter extends ClassVisitor {
|
||||
@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 @@ public class ClassWriter extends ClassVisitor {
|
||||
// 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 class ClassWriter extends ClassVisitor {
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
size += 8 + bootstrapMethods.length;
|
||||
newUTF8("BootstrapMethods");
|
||||
}
|
||||
if (ClassReader.SIGNATURES && signature != 0) {
|
||||
if (signature != 0) {
|
||||
++attributeCount;
|
||||
size += 8;
|
||||
newUTF8("Signature");
|
||||
@ -912,26 +936,31 @@ public class ClassWriter extends ClassVisitor {
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
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 @@ public class ClassWriter extends ClassVisitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public class ClassWriter extends ClassVisitor {
|
||||
* @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 @@ public class ClassWriter extends ClassVisitor {
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1628,25 +1633,6 @@ public class ClassWriter extends ClassVisitor {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -69,7 +69,7 @@ public abstract class FieldVisitor {
|
||||
|
||||
/**
|
||||
* 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 @@ public abstract class FieldVisitor {
|
||||
*
|
||||
* @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 @@ public abstract class FieldVisitor {
|
||||
*
|
||||
* @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;
|
||||
|
@ -147,7 +147,7 @@ final class FieldWriter extends FieldVisitor {
|
||||
*/
|
||||
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 @@ final class FieldWriter extends FieldVisitor {
|
||||
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 @@ final class FieldWriter extends FieldVisitor {
|
||||
@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 @@ final class FieldWriter extends FieldVisitor {
|
||||
@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 @@ final class FieldWriter extends FieldVisitor {
|
||||
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 @@ final class FieldWriter extends FieldVisitor {
|
||||
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 @@ final class FieldWriter extends FieldVisitor {
|
||||
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);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ package jdk.internal.org.objectweb.asm;
|
||||
*
|
||||
* @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 @@ final class Frame {
|
||||
* 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.
|
||||
@ -549,6 +549,110 @@ final class Frame {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -614,7 +718,7 @@ final class Frame {
|
||||
}
|
||||
// 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 @@ final class Frame {
|
||||
* 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 @@ final class Frame {
|
||||
* @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 @@ final class Frame {
|
||||
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 @@ final class Frame {
|
||||
* @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;
|
||||
|
||||
|
@ -80,6 +80,7 @@ final class Item {
|
||||
* {@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 @@ final class Item {
|
||||
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;
|
||||
|
@ -389,13 +389,12 @@ public class Label {
|
||||
* 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 @@ public class Label {
|
||||
* @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;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -86,7 +86,7 @@ public abstract class MethodVisitor {
|
||||
|
||||
/**
|
||||
* 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 @@ public abstract class MethodVisitor {
|
||||
*
|
||||
* @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 @@ public abstract class MethodVisitor {
|
||||
*
|
||||
* @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;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -70,13 +70,13 @@ package jdk.internal.org.objectweb.asm;
|
||||
* @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 @@ public interface Opcodes {
|
||||
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 @@ public interface Opcodes {
|
||||
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 @@ public interface Opcodes {
|
||||
*/
|
||||
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)
|
||||
|
||||
|
@ -406,7 +406,16 @@ public class Type {
|
||||
*/
|
||||
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++] != ';') {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,7 +112,7 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
|
||||
*
|
||||
* @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
|
||||
|
@ -170,7 +170,7 @@ public class AnalyzerAdapter extends MethodVisitor {
|
||||
*/
|
||||
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 @@ public class AnalyzerAdapter extends MethodVisitor {
|
||||
*
|
||||
* @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 @@ public class AnalyzerAdapter extends MethodVisitor {
|
||||
t1 = pop();
|
||||
if (t1 instanceof String) {
|
||||
pushDesc(((String) t1).substring(1));
|
||||
} else if (t1 == Opcodes.NULL) {
|
||||
push(t1);
|
||||
} else {
|
||||
push("java/lang/Object");
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public class AnnotationRemapper extends AnnotationVisitor {
|
||||
|
||||
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,
|
||||
|
@ -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 @@ public class ClassRemapper extends ClassVisitor {
|
||||
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,
|
||||
@ -96,6 +100,12 @@ public class ClassRemapper extends ClassVisitor {
|
||||
interfaces == null ? null : remapper.mapTypes(interfaces));
|
||||
}
|
||||
|
||||
@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),
|
||||
@ -111,6 +121,18 @@ public class ClassRemapper extends ClassVisitor {
|
||||
return av == null ? null : createAnnotationRemapper(av);
|
||||
}
|
||||
|
||||
@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) {
|
||||
@ -158,4 +180,8 @@ public class ClassRemapper extends ClassVisitor {
|
||||
protected AnnotationVisitor createAnnotationRemapper(AnnotationVisitor av) {
|
||||
return new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
|
||||
protected ModuleVisitor createModuleRemapper(ModuleVisitor mv) {
|
||||
return new ModuleRemapper(mv, remapper);
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
|
||||
private int maxSize;
|
||||
|
||||
public CodeSizeEvaluator(final MethodVisitor mv) {
|
||||
this(Opcodes.ASM5, mv);
|
||||
this(Opcodes.ASM6, mv);
|
||||
}
|
||||
|
||||
protected CodeSizeEvaluator(final int api, final MethodVisitor mv) {
|
||||
|
@ -74,7 +74,7 @@ public class FieldRemapper extends FieldVisitor {
|
||||
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,
|
||||
|
@ -289,7 +289,7 @@ public class GeneratorAdapter extends LocalVariablesSorter {
|
||||
*/
|
||||
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 @@ public class GeneratorAdapter extends LocalVariablesSorter {
|
||||
*
|
||||
* @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
|
||||
|
@ -86,7 +86,7 @@ public class InstructionAdapter extends MethodVisitor {
|
||||
* 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 @@ public class InstructionAdapter extends MethodVisitor {
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
|
@ -142,7 +142,7 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
|
||||
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 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
|
||||
*
|
||||
* @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).
|
||||
|
@ -120,7 +120,7 @@ public class LocalVariablesSorter extends MethodVisitor {
|
||||
*/
|
||||
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 @@ public class LocalVariablesSorter extends MethodVisitor {
|
||||
*
|
||||
* @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
|
||||
|
@ -76,7 +76,7 @@ public class MethodRemapper extends MethodVisitor {
|
||||
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 @@ public class MethodRemapper extends MethodVisitor {
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -254,6 +254,28 @@ public abstract class Remapper {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -75,7 +75,7 @@ public class RemappingAnnotationAdapter extends AnnotationVisitor {
|
||||
|
||||
public RemappingAnnotationAdapter(final AnnotationVisitor av,
|
||||
final Remapper remapper) {
|
||||
this(Opcodes.ASM5, av, remapper);
|
||||
this(Opcodes.ASM6, av, remapper);
|
||||
}
|
||||
|
||||
protected RemappingAnnotationAdapter(final int api,
|
||||
|
@ -63,6 +63,7 @@ import jdk.internal.org.objectweb.asm.AnnotationVisitor;
|
||||
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 @@ public class RemappingClassAdapter extends ClassVisitor {
|
||||
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,
|
||||
@ -98,6 +99,11 @@ public class RemappingClassAdapter extends ClassVisitor {
|
||||
interfaces == null ? null : remapper.mapTypes(interfaces));
|
||||
}
|
||||
|
||||
@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),
|
||||
|
@ -76,7 +76,7 @@ public class RemappingFieldAdapter extends FieldVisitor {
|
||||
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,
|
||||
|
@ -79,7 +79,7 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
|
||||
|
||||
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 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -79,7 +79,7 @@ public class RemappingSignatureAdapter extends SignatureVisitor {
|
||||
|
||||
public RemappingSignatureAdapter(final SignatureVisitor v,
|
||||
final Remapper remapper) {
|
||||
this(Opcodes.ASM5, v, remapper);
|
||||
this(Opcodes.ASM6, v, remapper);
|
||||
}
|
||||
|
||||
protected RemappingSignatureAdapter(final int api,
|
||||
|
@ -80,7 +80,7 @@ import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
* 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 @@ public class SerialVersionUIDAdder extends ClassVisitor {
|
||||
* 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 @@ public class SerialVersionUIDAdder extends ClassVisitor {
|
||||
*
|
||||
* @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.
|
||||
|
@ -78,7 +78,7 @@ public class SignatureRemapper extends SignatureVisitor {
|
||||
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,
|
||||
|
@ -78,7 +78,7 @@ public class StaticInitMerger extends ClassVisitor {
|
||||
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,
|
||||
|
@ -86,7 +86,7 @@ public class TryCatchBlockSorter extends MethodNode {
|
||||
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,
|
||||
|
@ -102,7 +102,7 @@ public abstract class SignatureVisitor {
|
||||
|
||||
/**
|
||||
* 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 @@ public abstract class SignatureVisitor {
|
||||
*
|
||||
* @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;
|
||||
|
@ -95,7 +95,7 @@ public class SignatureWriter extends SignatureVisitor {
|
||||
* Constructs a new {@link SignatureWriter} object.
|
||||
*/
|
||||
public SignatureWriter() {
|
||||
super(Opcodes.ASM5);
|
||||
super(Opcodes.ASM6);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -65,7 +65,7 @@ import jdk.internal.org.objectweb.asm.AnnotationVisitor;
|
||||
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 @@ public class AnnotationNode extends AnnotationVisitor {
|
||||
* 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 @@ public class AnnotationNode extends AnnotationVisitor {
|
||||
* 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 @@ public class AnnotationNode extends AnnotationVisitor {
|
||||
*
|
||||
* @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 @@ public class AnnotationNode extends AnnotationVisitor {
|
||||
* 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 @@ public class AnnotationNode extends AnnotationVisitor {
|
||||
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 @@ public class AnnotationNode extends AnnotationVisitor {
|
||||
* 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
|
||||
|
@ -67,6 +67,7 @@ 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;
|
||||
|
||||
@ -126,6 +127,11 @@ public class ClassNode extends ClassVisitor {
|
||||
*/
|
||||
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 @@ public class ClassNode extends ClassVisitor {
|
||||
* 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 @@ public class ClassNode extends ClassVisitor {
|
||||
*
|
||||
* @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);
|
||||
@ -266,6 +272,12 @@ public class ClassNode extends ClassVisitor {
|
||||
sourceDebug = debug;
|
||||
}
|
||||
|
||||
@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) {
|
||||
@ -358,11 +370,16 @@ public class ClassNode extends ClassVisitor {
|
||||
* 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 @@ public class ClassNode extends ClassVisitor {
|
||||
&& 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 @@ public class ClassNode extends ClassVisitor {
|
||||
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);
|
||||
|
@ -173,7 +173,7 @@ public class FieldNode extends FieldVisitor {
|
||||
*/
|
||||
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 @@ public class FieldNode extends FieldVisitor {
|
||||
* 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) {
|
||||
|
@ -634,14 +634,28 @@ public class InsnList {
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ public class LocalVariableAnnotationNode extends TypeAnnotationNode {
|
||||
*/
|
||||
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 @@ public class LocalVariableAnnotationNode extends TypeAnnotationNode {
|
||||
*
|
||||
* @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 @@ public class LocalVariableAnnotationNode extends TypeAnnotationNode {
|
||||
index[i] = this.index.get(i);
|
||||
}
|
||||
accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
|
||||
index, desc, true));
|
||||
index, desc, visible));
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ public class MethodNode extends MethodVisitor {
|
||||
* 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 @@ public class MethodNode extends MethodVisitor {
|
||||
*
|
||||
* @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 class MethodNode extends MethodVisitor {
|
||||
*/
|
||||
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 @@ public class MethodNode extends MethodVisitor {
|
||||
*
|
||||
* @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 @@ public class MethodNode extends MethodVisitor {
|
||||
* 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) {
|
||||
|
@ -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]));
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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]));
|
||||
}
|
||||
}
|
@ -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]));
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -99,7 +99,7 @@ public class TypeAnnotationNode extends AnnotationNode {
|
||||
*/
|
||||
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 @@ public class TypeAnnotationNode extends AnnotationNode {
|
||||
*
|
||||
* @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
|
||||
|
@ -82,7 +82,7 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements
|
||||
Opcodes {
|
||||
|
||||
public BasicInterpreter() {
|
||||
super(ASM5);
|
||||
super(ASM6);
|
||||
}
|
||||
|
||||
protected BasicInterpreter(final int api) {
|
||||
|
@ -76,7 +76,7 @@ import jdk.internal.org.objectweb.asm.tree.MethodInsnNode;
|
||||
public class BasicVerifier extends BasicInterpreter {
|
||||
|
||||
public BasicVerifier() {
|
||||
super(ASM5);
|
||||
super(ASM6);
|
||||
}
|
||||
|
||||
protected BasicVerifier(final int api) {
|
||||
|
@ -136,7 +136,7 @@ public class SimpleVerifier extends BasicVerifier {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ public class SourceInterpreter extends Interpreter<SourceValue> implements
|
||||
Opcodes {
|
||||
|
||||
public SourceInterpreter() {
|
||||
super(ASM5);
|
||||
super(ASM6);
|
||||
}
|
||||
|
||||
protected SourceInterpreter(final int api) {
|
||||
|
@ -109,6 +109,11 @@ public class ASMifier extends Printer {
|
||||
*/
|
||||
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
|
||||
@ -118,7 +123,7 @@ public class ASMifier extends Printer {
|
||||
* 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 @@ public class ASMifier extends Printer {
|
||||
*
|
||||
* @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 @@ public class ASMifier extends Printer {
|
||||
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 @@ public class ASMifier extends Printer {
|
||||
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;
|
||||
@ -275,6 +290,24 @@ public class ASMifier extends Printer {
|
||||
text.add(buf.toString());
|
||||
}
|
||||
|
||||
@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) {
|
||||
@ -385,6 +418,108 @@ public class ASMifier extends Printer {
|
||||
text.add("}\n");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 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 @@ public class ASMifier extends Printer {
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
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 @@ public class ASMifier extends Printer {
|
||||
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 @@ public class ASMifier extends Printer {
|
||||
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 @@ public class ASMifier extends Printer {
|
||||
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 @@ public class ASMifier extends Printer {
|
||||
.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) {
|
||||
|
@ -78,7 +78,7 @@ public class CheckAnnotationAdapter extends AnnotationVisitor {
|
||||
}
|
||||
|
||||
CheckAnnotationAdapter(final AnnotationVisitor av, final boolean named) {
|
||||
super(Opcodes.ASM5, av);
|
||||
super(Opcodes.ASM6, av);
|
||||
this.named = named;
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@ import jdk.internal.org.objectweb.asm.ClassVisitor;
|
||||
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;
|
||||
@ -180,6 +181,11 @@ public class CheckClassAdapter extends ClassVisitor {
|
||||
*/
|
||||
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 @@ public class CheckClassAdapter extends ClassVisitor {
|
||||
* 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 @@ public class CheckClassAdapter extends ClassVisitor {
|
||||
*
|
||||
* @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 @@ public class CheckClassAdapter extends ClassVisitor {
|
||||
+ 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)) {
|
||||
@ -449,6 +459,22 @@ public class CheckClassAdapter extends ClassVisitor {
|
||||
super.visitSource(file, debug);
|
||||
}
|
||||
|
||||
@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) {
|
||||
|
@ -83,7 +83,7 @@ public class CheckFieldAdapter extends FieldVisitor {
|
||||
* 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 @@ public class CheckFieldAdapter extends FieldVisitor {
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
|
@ -426,7 +426,7 @@ public class CheckMethodAdapter extends MethodVisitor {
|
||||
*/
|
||||
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 @@ public class CheckMethodAdapter extends MethodVisitor {
|
||||
*
|
||||
* @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 @@ public class CheckMethodAdapter extends MethodVisitor {
|
||||
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
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@ -142,7 +142,7 @@ public class CheckSignatureAdapter extends SignatureVisitor {
|
||||
* <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 @@ public class CheckSignatureAdapter extends SignatureVisitor {
|
||||
*
|
||||
* @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 @@ public class CheckSignatureAdapter extends SignatureVisitor {
|
||||
|| (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 @@ public class CheckSignatureAdapter extends SignatureVisitor {
|
||||
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 @@ public class CheckSignatureAdapter extends SignatureVisitor {
|
||||
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 @@ public class CheckSignatureAdapter extends SignatureVisitor {
|
||||
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 @@ public class CheckSignatureAdapter extends SignatureVisitor {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ public abstract class Printer {
|
||||
|
||||
/**
|
||||
* 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 @@ public abstract class Printer {
|
||||
*
|
||||
* @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 class Printer {
|
||||
*/
|
||||
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}.
|
||||
@ -375,6 +393,45 @@ public abstract class Printer {
|
||||
*/
|
||||
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
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -182,7 +182,7 @@ public class Textifier extends Printer {
|
||||
* 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 @@ public class Textifier extends Printer {
|
||||
*
|
||||
* @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 class Textifier extends Printer {
|
||||
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 @@ public class Textifier extends Printer {
|
||||
.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) {
|
||||
@ -314,6 +318,24 @@ public class Textifier extends Printer {
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
@ -443,7 +465,7 @@ public class Textifier extends Printer {
|
||||
}
|
||||
|
||||
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 ");
|
||||
}
|
||||
@ -482,6 +504,118 @@ public class Textifier extends Printer {
|
||||
text.add("}\n");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 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 @@ public class Textifier extends Printer {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +76,7 @@ public final class TraceAnnotationVisitor extends AnnotationVisitor {
|
||||
}
|
||||
|
||||
public TraceAnnotationVisitor(final AnnotationVisitor av, final Printer p) {
|
||||
super(Opcodes.ASM5, av);
|
||||
super(Opcodes.ASM6, av);
|
||||
this.p = p;
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@ 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;
|
||||
|
||||
@ -160,7 +161,7 @@ public final class TraceClassVisitor extends ClassVisitor {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -179,6 +180,14 @@ public final class TraceClassVisitor extends ClassVisitor {
|
||||
super.visitSource(file, debug);
|
||||
}
|
||||
|
||||
@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) {
|
||||
|
@ -79,7 +79,7 @@ public final class TraceFieldVisitor extends FieldVisitor {
|
||||
}
|
||||
|
||||
public TraceFieldVisitor(final FieldVisitor fv, final Printer p) {
|
||||
super(Opcodes.ASM5, fv);
|
||||
super(Opcodes.ASM6, fv);
|
||||
this.p = p;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ public final class TraceMethodVisitor extends MethodVisitor {
|
||||
}
|
||||
|
||||
public TraceMethodVisitor(final MethodVisitor mv, final Printer p) {
|
||||
super(Opcodes.ASM5, mv);
|
||||
super(Opcodes.ASM6, mv);
|
||||
this.p = p;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -104,13 +104,13 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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'
|
||||
|
||||
|
@ -47,13 +47,13 @@ public class ConstModule {
|
||||
|
||||
// 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 @@ public class ConstModule {
|
||||
|
||||
// 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);
|
||||
|
||||
|
@ -34,13 +34,13 @@ import java.util.ArrayList;
|
||||
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 @@ import static org.testng.Assert.*;
|
||||
/**
|
||||
* @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 @@ public class AnnotationsTest {
|
||||
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
|
||||
|
@ -243,7 +243,7 @@ public class DefineClassTest {
|
||||
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 @@ public class DefineClassTest {
|
||||
|
||||
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 @@ public class DefineClassTest {
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
|
||||
+ ClassWriter.COMPUTE_FRAMES);
|
||||
cw.visit(V1_9,
|
||||
cw.visit(V9,
|
||||
ACC_PUBLIC + ACC_SUPER,
|
||||
className.replace(".", "/"),
|
||||
null,
|
||||
|
@ -209,7 +209,7 @@ public class BadProvidersTest {
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
|
||||
+ ClassWriter.COMPUTE_FRAMES);
|
||||
cw.visit(V1_9,
|
||||
cw.visit(V9,
|
||||
ACC_PUBLIC + ACC_SUPER,
|
||||
"p/ProviderFactory",
|
||||
null,
|
||||
|
@ -29,13 +29,9 @@ import java.net.URI;
|
||||
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 class ModuleTargetHelper {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -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.nio.file.Path;
|
||||
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 {
|
||||
|
@ -35,35 +35,13 @@ import java.nio.file.Path;
|
||||
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 {
|
||||
|
Loading…
Reference in New Issue
Block a user