Commit c75ddc2b authored by Eric Bruneton's avatar Eric Bruneton

Add unit tests cases for ConstantDynamic and fix bugs found with them.

parent cccd4980
Pipeline #1439 passed with stage
in 3 minutes and 56 seconds
......@@ -61,7 +61,7 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
* use this constructor</i>. Instead, they must use the {@link #BasicInterpreter(int)} version.
*/
public BasicInterpreter() {
super(ASM6);
super(ASM7);
if (getClass() != BasicInterpreter.class) {
throw new IllegalStateException();
}
......@@ -71,8 +71,7 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
* Constructs a new {@link BasicInterpreter}.
*
* @param api the ASM API version supported by this interpreter. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
*/
protected BasicInterpreter(final int api) {
super(api);
......
......@@ -48,7 +48,7 @@ public class BasicVerifier extends BasicInterpreter {
* this constructor</i>. Instead, they must use the {@link #BasicVerifier(int)} version.
*/
public BasicVerifier() {
super(ASM6);
super(ASM7);
if (getClass() != BasicVerifier.class) {
throw new IllegalStateException();
}
......@@ -58,8 +58,8 @@ public class BasicVerifier extends BasicInterpreter {
* Constructs a new {@link BasicVerifier}.
*
* @param api the ASM API version supported by this interpreter. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7}.
*/
protected BasicVerifier(final int api) {
super(api);
......
......@@ -46,8 +46,8 @@ public abstract class Interpreter<V extends Value> {
/**
* The ASM API version supported by this interpreter. The value of this field must be one of
* {@link org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* {@link org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7}.
*/
protected final int api;
......@@ -55,8 +55,8 @@ public abstract class Interpreter<V extends Value> {
* Constructs a new {@link Interpreter}.
*
* @param api the ASM API version supported by this interpreter. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7}.
*/
protected Interpreter(final int api) {
this.api = api;
......
......@@ -94,7 +94,7 @@ public class SimpleVerifier extends BasicVerifier {
final Type currentSuperClass,
final List<Type> currentClassInterfaces,
final boolean isInterface) {
this(ASM6, currentClass, currentSuperClass, currentClassInterfaces, isInterface);
this(ASM7, currentClass, currentSuperClass, currentClassInterfaces, isInterface);
if (getClass() != SimpleVerifier.class) {
throw new IllegalStateException();
}
......@@ -105,8 +105,8 @@ public class SimpleVerifier extends BasicVerifier {
* loaded into the JVM since it may be incorrect.
*
* @param api the ASM API version supported by this verifier. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7}.
* @param currentClass the type of the class to be verified.
* @param currentSuperClass the type of the super class of the class to be verified.
* @param currentClassInterfaces the types of the interfaces directly implemented by the class to
......
......@@ -51,7 +51,7 @@ public class SourceInterpreter extends Interpreter<SourceValue> implements Opcod
* use this constructor</i>. Instead, they must use the {@link #SourceInterpreter(int)} version.
*/
public SourceInterpreter() {
super(ASM6);
super(ASM7);
if (getClass() != SourceInterpreter.class) {
throw new IllegalStateException();
}
......@@ -61,8 +61,7 @@ public class SourceInterpreter extends Interpreter<SourceValue> implements Opcod
* Constructs a new {@link SourceInterpreter}.
*
* @param api the ASM API version supported by this interpreter. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
*/
protected SourceInterpreter(final int api) {
super(api);
......
......@@ -89,7 +89,7 @@ public class BasicInterpreterTest extends AsmTest {
for (MethodNode methodNode : classNode.methods) {
Analyzer<BasicValue> analyzer =
new Analyzer<BasicValue>(
new BasicInterpreter(Opcodes.ASM6) {
new BasicInterpreter(Opcodes.ASM7) {
@Override
public BasicValue merge(final BasicValue value1, final BasicValue value2) {
return new BasicValue(super.merge(value1, value2).getType());
......
......@@ -478,7 +478,7 @@ public class SimpleVerifierTest extends AsmTest implements Opcodes {
Type baseType = Type.getObjectType("C");
Type superType = Type.getObjectType("D");
Type interfaceType = Type.getObjectType("I");
new SimpleVerifier(ASM6, baseType, superType, Arrays.asList(interfaceType), false) {
new SimpleVerifier(ASM7, baseType, superType, Arrays.asList(interfaceType), false) {
void test() {
assertTrue(isAssignableFrom(baseType, baseType));
......@@ -496,7 +496,7 @@ public class SimpleVerifierTest extends AsmTest implements Opcodes {
}
}.test();
new SimpleVerifier(ASM6, interfaceType, null, null, true) {
new SimpleVerifier(ASM7, interfaceType, null, null, true) {
void test() {
assertTrue(isAssignableFrom(interfaceType, baseType));
......@@ -523,7 +523,12 @@ public class SimpleVerifierTest extends AsmTest implements Opcodes {
ClassNode classNode = new ClassNode();
new ClassReader(classParameter.getBytes()).accept(classNode, 0);
for (MethodNode methodNode : classNode.methods) {
Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(new SimpleVerifier());
Analyzer<BasicValue> analyzer =
new Analyzer<BasicValue>(
new SimpleVerifier(
Type.getObjectType(classNode.name),
Type.getObjectType(classNode.superName),
(classNode.access & Opcodes.ACC_INTERFACE) != 0));
analyzer.analyze(classNode.name, methodNode);
}
}
......
......@@ -77,7 +77,7 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
* Constructs a new {@link AdviceAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param mv the method visitor to which this adapter delegates calls.
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
......
......@@ -116,7 +116,7 @@ public class AnalyzerAdapter extends MethodVisitor {
final String name,
final String desc,
final MethodVisitor mv) {
this(Opcodes.ASM6, owner, access, name, desc, mv);
this(Opcodes.ASM7, owner, access, name, desc, mv);
if (getClass() != AnalyzerAdapter.class) {
throw new IllegalStateException();
}
......@@ -126,7 +126,7 @@ public class AnalyzerAdapter extends MethodVisitor {
* Constructs a new {@link AnalyzerAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param owner the owner's class name.
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
......
......@@ -41,7 +41,7 @@ public class AnnotationRemapper extends AnnotationVisitor {
protected final Remapper remapper;
public AnnotationRemapper(final AnnotationVisitor av, final Remapper remapper) {
this(Opcodes.ASM6, av, remapper);
this(Opcodes.ASM7, av, remapper);
}
protected AnnotationRemapper(final int api, final AnnotationVisitor av, final Remapper remapper) {
......
......@@ -51,7 +51,7 @@ public class ClassRemapper extends ClassVisitor {
protected String className;
public ClassRemapper(final ClassVisitor cv, final Remapper remapper) {
this(Opcodes.ASM6, cv, remapper);
this(Opcodes.ASM7, cv, remapper);
}
protected ClassRemapper(final int api, final ClassVisitor cv, final Remapper remapper) {
......
......@@ -44,7 +44,7 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
private int maxSize;
public CodeSizeEvaluator(final MethodVisitor mv) {
this(Opcodes.ASM6, mv);
this(Opcodes.ASM7, mv);
}
protected CodeSizeEvaluator(final int api, final MethodVisitor mv) {
......
......@@ -43,7 +43,7 @@ public class FieldRemapper extends FieldVisitor {
private final Remapper remapper;
public FieldRemapper(final FieldVisitor fv, final Remapper remapper) {
this(Opcodes.ASM6, fv, remapper);
this(Opcodes.ASM7, fv, remapper);
}
protected FieldRemapper(final int api, final FieldVisitor fv, final Remapper remapper) {
......
......@@ -198,7 +198,7 @@ public class GeneratorAdapter extends LocalVariablesSorter {
*/
public GeneratorAdapter(
final MethodVisitor mv, final int access, final String name, final String desc) {
this(Opcodes.ASM6, mv, access, name, desc);
this(Opcodes.ASM7, mv, access, name, desc);
if (getClass() != GeneratorAdapter.class) {
throw new IllegalStateException();
}
......@@ -208,7 +208,7 @@ public class GeneratorAdapter extends LocalVariablesSorter {
* Constructs a new {@link GeneratorAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param mv the method visitor to which this adapter delegates calls.
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
......
......@@ -28,6 +28,7 @@
package org.objectweb.asm.commons;
import org.objectweb.asm.Condy;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
......@@ -51,7 +52,7 @@ public class InstructionAdapter extends MethodVisitor {
* @throws IllegalStateException If a subclass calls this constructor.
*/
public InstructionAdapter(final MethodVisitor mv) {
this(Opcodes.ASM6, mv);
this(Opcodes.ASM7, mv);
if (getClass() != InstructionAdapter.class) {
throw new IllegalStateException();
}
......@@ -61,7 +62,7 @@ public class InstructionAdapter extends MethodVisitor {
* Constructs a new {@link InstructionAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param mv the method visitor to which this adapter delegates calls.
*/
protected InstructionAdapter(final int api, final MethodVisitor mv) {
......@@ -628,6 +629,9 @@ public class InstructionAdapter extends MethodVisitor {
|| (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
throw new UnsupportedOperationException();
}
if (api < Opcodes.ASM7 && value instanceof Condy) {
throw new UnsupportedOperationException();
}
if (value instanceof Integer) {
int val = ((Integer) value).intValue();
iconst(val);
......@@ -658,6 +662,8 @@ public class InstructionAdapter extends MethodVisitor {
tconst((Type) value);
} else if (value instanceof Handle) {
hconst((Handle) value);
} else if (value instanceof Condy) {
cconst((Condy) value);
} else {
throw new IllegalArgumentException();
}
......@@ -744,6 +750,10 @@ public class InstructionAdapter extends MethodVisitor {
mv.visitLdcInsn(handle);
}
public void cconst(final Condy condy) {
mv.visitLdcInsn(condy);
}
public void load(final int var, final Type type) {
mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), var);
}
......
......@@ -102,7 +102,7 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
final String desc,
final String signature,
final String[] exceptions) {
this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
this(Opcodes.ASM7, mv, access, name, desc, signature, exceptions);
if (getClass() != JSRInlinerAdapter.class) {
throw new IllegalStateException();
}
......@@ -112,7 +112,7 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
* Constructs a new JSRInliner.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param mv the <code>MethodVisitor</code> to send the resulting inlined method code to (use
* <code>null</code> for none).
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
......
......@@ -76,7 +76,7 @@ public class LocalVariablesSorter extends MethodVisitor {
* @throws IllegalStateException If a subclass calls this constructor.
*/
public LocalVariablesSorter(final int access, final String desc, final MethodVisitor mv) {
this(Opcodes.ASM6, access, desc, mv);
this(Opcodes.ASM7, access, desc, mv);
if (getClass() != LocalVariablesSorter.class) {
throw new IllegalStateException();
}
......@@ -86,7 +86,7 @@ public class LocalVariablesSorter extends MethodVisitor {
* Constructs a new {@link LocalVariablesSorter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param access access flags of the adapted method.
* @param desc the method's descriptor (see {@link Type Type}).
* @param mv the method visitor to which this adapter delegates calls.
......
......@@ -45,7 +45,7 @@ public class MethodRemapper extends MethodVisitor {
protected final Remapper remapper;
public MethodRemapper(final MethodVisitor mv, final Remapper remapper) {
this(Opcodes.ASM6, mv, remapper);
this(Opcodes.ASM7, mv, remapper);
}
protected MethodRemapper(final int api, final MethodVisitor mv, final Remapper remapper) {
......
......@@ -40,7 +40,7 @@ public class ModuleRemapper extends ModuleVisitor {
private final Remapper remapper;
public ModuleRemapper(final ModuleVisitor mv, final Remapper remapper) {
this(Opcodes.ASM6, mv, remapper);
this(Opcodes.ASM7, mv, remapper);
}
protected ModuleRemapper(final int api, final ModuleVisitor mv, final Remapper remapper) {
......
......@@ -145,7 +145,7 @@ public class SerialVersionUIDAdder extends ClassVisitor {
* @throws IllegalStateException If a subclass calls this constructor.
*/
public SerialVersionUIDAdder(final ClassVisitor cv) {
this(Opcodes.ASM6, cv);
this(Opcodes.ASM7, cv);
if (getClass() != SerialVersionUIDAdder.class) {
throw new IllegalStateException();
}
......@@ -155,7 +155,7 @@ public class SerialVersionUIDAdder extends ClassVisitor {
* Constructs a new {@link SerialVersionUIDAdder}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param cv a {@link ClassVisitor} to which this visitor will delegate calls.
*/
protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) {
......
......@@ -47,7 +47,7 @@ public class SignatureRemapper extends SignatureVisitor {
private Stack<String> classNames = new Stack<String>();
public SignatureRemapper(final SignatureVisitor v, final Remapper remapper) {
this(Opcodes.ASM6, v, remapper);
this(Opcodes.ASM7, v, remapper);
}
protected SignatureRemapper(final int api, final SignatureVisitor v, final Remapper remapper) {
......
......@@ -47,7 +47,7 @@ public class StaticInitMerger extends ClassVisitor {
private int counter;
public StaticInitMerger(final String prefix, final ClassVisitor cv) {
this(Opcodes.ASM6, prefix, cv);
this(Opcodes.ASM7, prefix, cv);
}
protected StaticInitMerger(final int api, final String prefix, final ClassVisitor cv) {
......
......@@ -57,7 +57,7 @@ public class TryCatchBlockSorter extends MethodNode {
final String desc,
final String signature,
final String[] exceptions) {
this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
this(Opcodes.ASM7, mv, access, name, desc, signature, exceptions);
}
protected TryCatchBlockSorter(
......
......@@ -132,7 +132,7 @@ public class AnalyzerAdapterTest extends AsmTest {
private boolean hasOriginalFrame;
public AnalyzedFramesInserter(MethodVisitor mv) {
super(Opcodes.ASM6, mv);
super(Opcodes.ASM7, mv);
}
@Override
......
......@@ -807,7 +807,7 @@ public class GeneratorAdapterTest {
textifier = new Textifier();
generatorAdapter =
new GeneratorAdapter(
Opcodes.ASM6, new TraceMethodVisitor(textifier), access, name, descriptor);
Opcodes.ASM7, new TraceMethodVisitor(textifier), access, name, descriptor);
}
public String push(final boolean value) {
......
......@@ -90,7 +90,7 @@ public class LocalVariablesSorterTest extends AsmTest {
new ClassReader(new FileInputStream("src/test/resources/Issue317586.class"));
ClassWriter classWriter = new ClassWriter(0);
ClassVisitor classVisitor =
new ClassVisitor(Opcodes.ASM6, classWriter) {
new ClassVisitor(Opcodes.ASM7, classWriter) {
@Override
public MethodVisitor visitMethod(
final int access,
......
......@@ -49,7 +49,7 @@ import java.util.stream.Stream;
/**
* Base class for the ASM tests. ASM can be used to read, write or transform any Java class, ranging
* from very old (e.g. JDK 1.3) to very recent classes, containing all possible class file
* structures. ASM can also be used with different variants of its API (ASM4, ASM5 or ASM6). In
* structures. ASM can also be used with different variants of its API (ASM4, ASM5, ASM6, etc). In
* order to test it thoroughly, it is therefore necessary to run read, write and transform tests,
* for each API version, and for each class in a set of classes containing all possible class file
* structures. The purpose of this class is to automate this process. For this it relies on:
......@@ -65,8 +65,8 @@ import java.util.stream.Stream;
* API) tuple.
* </ul>
*
* For instance, to run a test on all the precompiled classes, with both the ASM5 and the ASM6 API,
* use a subclass such as the following:
* <p>For instance, to run a test on all the precompiled classes, with all the APIs, use a subclass
* such as the following:
*
* <pre>
* public class MyParameterizedTest extends AsmTest {
......@@ -124,7 +124,8 @@ public abstract class AsmTest {
JDK8_ARTIFICIAL_STRUCTURES("jdk8.ArtificialStructures"),
JDK8_INNER_CLASS("jdk8.AllStructures$InnerClass"),
JDK8_LARGE_METHOD("jdk8.LargeMethod"),
JDK9_MODULE("jdk9.module-info");
JDK9_MODULE("jdk9.module-info"),
JDK11_ALL_STRUCTURES("jdk11.AllStructures");
private final String name;
......@@ -151,10 +152,13 @@ public abstract class AsmTest {
* @return whether this class was compiled with a JDK which is more recent than api.
*/
public boolean isMoreRecentThan(final Api api) {
if (name.startsWith("jdk8") && api.value() < Api.ASM5.value()) {
if (name.startsWith("jdk8.") && api.value() < Api.ASM5.value()) {
return true;
}
return name.startsWith("jdk9") && api.value() < Api.ASM6.value();
if (name.startsWith("jdk9.") && api.value() < Api.ASM6.value()) {
return true;
}
return name.startsWith("jdk11.") && api.value() < Api.ASM7.value();
}
/**
......@@ -165,9 +169,12 @@ public abstract class AsmTest {
* less than 9.
*/
public boolean isMoreRecentThanCurrentJdk() {
if (name.startsWith("jdk9")) {
if (name.startsWith("jdk9.")) {
return getMajorJavaVersion() < 9;
}
if (name.startsWith("jdk11.")) {
return getMajorJavaVersion() < 11;
}
return false;
}
......@@ -222,7 +229,8 @@ public abstract class AsmTest {
public enum Api {
ASM4("ASM4", 4 << 16),
ASM5("ASM5", 5 << 16),
ASM6("ASM6", 6 << 16);
ASM6("ASM6", 6 << 16),
ASM7("ASM7", 7 << 16);
private final String name;
private final int value;
......@@ -235,7 +243,7 @@ public abstract class AsmTest {
/**
* Returns the int value of this version, as expected by ASM.
*
* @return one of the ASM4, ASM5 or ASM6 constants from the ASM Opcodes interface.
* @return one of the ASM4, ASM5, ASM6 or ASM7 constants from the ASM Opcodes interface.
*/
public int value() {
return value;
......@@ -244,7 +252,7 @@ public abstract class AsmTest {
/**
* Returns a human readable symbol corresponding to this version.
*
* @return one of "ASM4", "ASM5" or "ASM6".
* @return one of "ASM4", "ASM5", "ASM6" or "ASM7".
*/
@Override
public String toString() {
......@@ -269,10 +277,10 @@ public abstract class AsmTest {
* with <tt>@MethodSource("allClassesAndLatestApi")</tt> will be executed on all the precompiled
* classes, with the latest api.
*
* @return all the possible (precompiledClass, ASM6) pairs, for all the precompiled classes.
* @return all the possible (precompiledClass, ASM7) pairs, for all the precompiled classes.
*/
public static Stream<Arguments> allClassesAndLatestApi() {
return classesAndApis(Api.ASM6);
return classesAndApis(Api.ASM7);
}
private static Stream<Arguments> classesAndApis(final Api... apis) {
......
......@@ -150,7 +150,7 @@ class ClassDump {
builder.add("magic: ", parser.u4());
builder.add("minor_version: ", parser.u2());
int majorVersion = parser.u2();
if (majorVersion >= /* V10 = */ 54) {
if (majorVersion > /* V11 = */ 55) {
throw new IOException("Unsupported class version");
}
builder.add("major_version: ", majorVersion);
......@@ -235,8 +235,10 @@ class ClassDump {
return new ConstantMethodHandleInfo(parser, classContext);
case 16:
return new ConstantMethodTypeInfo(parser, classContext);
case 17:
return new ConstantDynamicInfo(parser, classContext);
case 18:
return new ConstantInvokeDynamicInfo(parser, classContext);
return new ConstantDynamicCallSiteInfo(parser, classContext);
case 19:
return new ConstantModuleInfo(parser, classContext);
case 20:
......@@ -640,23 +642,23 @@ class ClassDump {
}
/**
* A CONSTANT_InvokeDynamic_info item.
* A CONSTANT_DynamicCallSite_info item.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.10">JVMS
* 4.4.10</a>
*/
private static class ConstantInvokeDynamicInfo extends CpInfo {
private static class ConstantDynamicCallSiteInfo extends CpInfo {
private final int bootstrapMethodAttrIndex;
private final int nameAndTypeIndex;
/**
* Parses a CONSTANT_InvokeDynamic_info item.
* Parses a CONSTANT_DynamicCallSite_info item.
*
* @param parser a class parser.
* @param classContext a context to lookup constant pool items from their index.
* @throws IOException if the class can't be parsed.
*/
ConstantInvokeDynamicInfo(final Parser parser, final ClassContext classContext) throws IOException {
ConstantDynamicCallSiteInfo(final Parser parser, final ClassContext classContext) throws IOException {
super(classContext);
this.bootstrapMethodAttrIndex = parser.u2();
this.nameAndTypeIndex = parser.u2();
......@@ -724,6 +726,37 @@ class ClassDump {
}
}
/**
* A CONSTANT_Dynamic_info item.
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.10">JVMS
* 4.4.13</a>
*/
private static class ConstantDynamicInfo extends CpInfo {
private final int bootstrapMethodAttrIndex;
private final int nameAndTypeIndex;
/**
* Parses a CONSTANT_Dynamic_info item.
*
* @param parser a class parser.
* @param classContext a context to lookup constant pool items from their index.
* @throws IOException if the class can't be parsed.
*/
ConstantDynamicInfo(final Parser parser, final ClassContext classContext) throws IOException {
super(classContext);
this.bootstrapMethodAttrIndex = parser.u2();
this.nameAndTypeIndex = parser.u2();
}
@Override
String dump() {
return bootstrapMethodAttrIndex
+ "."
+ getCpInfo(nameAndTypeIndex, ConstantNameAndTypeInfo.class).dump();
}
}
/**
* Parses and dumps a field_info structure.
*
......
// 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 jdk11;
import java.io.FileOutputStream;
import java.io.IOException;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Condy;
import org.objectweb.asm.Handle;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Generates classes with all the JDK11 specific class file features.
*
* <p>TODO: remove this and use the JDK11 to compile equivalent classes, when it is released.
*
* @author Eric Bruneton
*/
public class DumpAllStructures implements Opcodes {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("AllStructures.class");
fileOutputStream.write(dumpAllStructures());
fileOutputStream.close();
}
private static byte[] dumpAllStructures() {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
classWriter.visit(