8339115: Rename TypeKind enum constants to follow code style

Reviewed-by: asotona
This commit is contained in:
Chen Liang 2024-08-30 17:28:28 +00:00
parent fef1ef7dfe
commit 25e03b5209
38 changed files with 725 additions and 638 deletions

View File

@ -106,7 +106,8 @@ public class JSpec implements Taglet {
this.idPrefix = idPrefix; this.idPrefix = idPrefix;
} }
private static final Pattern TAG_PATTERN = Pattern.compile("(?s)(.+ )?(?<chapter>[1-9][0-9]*)(?<section>[0-9.]*)( .*)?$"); // Note: Matches special cases like @jvms 6.5.checkcast
private static final Pattern TAG_PATTERN = Pattern.compile("(?s)(.+ )?(?<chapter>[1-9][0-9]*)(?<section>[0-9a-z_.]*)( .*)?$");
/** /**
* Returns the set of locations in which the tag may be used. * Returns the set of locations in which the tag may be used.

View File

@ -102,7 +102,9 @@ public sealed interface AnnotationValue {
* {@return the constant pool entry backing this constant element} * {@return the constant pool entry backing this constant element}
* *
* @apiNote * @apiNote
* Different types of constant values may share the same type of entry. * Different types of constant values may share the same type of entry
* because they have the same {@linkplain TypeKind##computational-type
* computational type}.
* For example, {@link OfInt} and {@link OfChar} are both * For example, {@link OfInt} and {@link OfChar} are both
* backed by {@link IntegerEntry}. Use {@link #resolvedValue * backed by {@link IntegerEntry}. Use {@link #resolvedValue
* resolvedValue()} for a value of accurate type. * resolvedValue()} for a value of accurate type.

View File

@ -262,7 +262,7 @@ public sealed interface CodeBuilder
*/ */
default CodeBuilder ifThen(Opcode opcode, default CodeBuilder ifThen(Opcode opcode,
Consumer<BlockCodeBuilder> thenHandler) { Consumer<BlockCodeBuilder> thenHandler) {
if (opcode.kind() != Opcode.Kind.BRANCH || opcode.primaryTypeKind() == TypeKind.VoidType) { if (opcode.kind() != Opcode.Kind.BRANCH || opcode.primaryTypeKind() == TypeKind.VOID) {
throw new IllegalArgumentException("Illegal branch opcode: " + opcode); throw new IllegalArgumentException("Illegal branch opcode: " + opcode);
} }
@ -312,7 +312,7 @@ public sealed interface CodeBuilder
default CodeBuilder ifThenElse(Opcode opcode, default CodeBuilder ifThenElse(Opcode opcode,
Consumer<BlockCodeBuilder> thenHandler, Consumer<BlockCodeBuilder> thenHandler,
Consumer<BlockCodeBuilder> elseHandler) { Consumer<BlockCodeBuilder> elseHandler) {
if (opcode.kind() != Opcode.Kind.BRANCH || opcode.primaryTypeKind() == TypeKind.VoidType) { if (opcode.kind() != Opcode.Kind.BRANCH || opcode.primaryTypeKind() == TypeKind.VOID) {
throw new IllegalArgumentException("Illegal branch opcode: " + opcode); throw new IllegalArgumentException("Illegal branch opcode: " + opcode);
} }
@ -550,66 +550,58 @@ public sealed interface CodeBuilder
* @param fromType the source type * @param fromType the source type
* @param toType the target type * @param toType the target type
* @return this builder * @return this builder
* @throws IllegalArgumentException for conversions of {@code VoidType} or {@code ReferenceType} * @throws IllegalArgumentException for conversions of {@link TypeKind#VOID void} or
* {@link TypeKind#REFERENCE reference}
* @since 23 * @since 23
*/ */
default CodeBuilder conversion(TypeKind fromType, TypeKind toType) { default CodeBuilder conversion(TypeKind fromType, TypeKind toType) {
return switch (fromType) { var computationalFrom = fromType.asLoadable();
case IntType, ByteType, CharType, ShortType, BooleanType -> var computationalTo = toType.asLoadable();
if (computationalFrom != computationalTo) {
switch (computationalTo) {
case INT -> {
switch (computationalFrom) {
case FLOAT -> f2i();
case LONG -> l2i();
case DOUBLE -> d2i();
default -> throw BytecodeHelpers.cannotConvertException(fromType, toType);
}
}
case FLOAT -> {
switch (computationalFrom) {
case INT -> i2f();
case LONG -> l2f();
case DOUBLE -> d2f();
default -> throw BytecodeHelpers.cannotConvertException(fromType, toType);
}
}
case LONG -> {
switch (computationalFrom) {
case INT -> i2l();
case FLOAT -> f2l();
case DOUBLE -> d2l();
default -> throw BytecodeHelpers.cannotConvertException(fromType, toType);
}
}
case DOUBLE -> {
switch (computationalFrom) {
case INT -> i2d();
case FLOAT -> f2d();
case LONG -> l2d();
default -> throw BytecodeHelpers.cannotConvertException(fromType, toType);
}
}
}
}
if (computationalTo == TypeKind.INT && toType != TypeKind.INT) {
switch (toType) { switch (toType) {
case IntType -> this; case BOOLEAN -> iconst_1().iand();
case LongType -> i2l(); case BYTE -> i2b();
case DoubleType -> i2d(); case CHAR -> i2c();
case FloatType -> i2f(); case SHORT -> i2s();
case ByteType -> i2b(); }
case CharType -> i2c(); }
case ShortType -> i2s(); return this;
case BooleanType -> iconst_1().iand();
case VoidType, ReferenceType ->
throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
};
case LongType ->
switch (toType) {
case IntType -> l2i();
case LongType -> this;
case DoubleType -> l2d();
case FloatType -> l2f();
case ByteType -> l2i().i2b();
case CharType -> l2i().i2c();
case ShortType -> l2i().i2s();
case BooleanType -> l2i().iconst_1().iand();
case VoidType, ReferenceType ->
throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
};
case DoubleType ->
switch (toType) {
case IntType -> d2i();
case LongType -> d2l();
case DoubleType -> this;
case FloatType -> d2f();
case ByteType -> d2i().i2b();
case CharType -> d2i().i2c();
case ShortType -> d2i().i2s();
case BooleanType -> d2i().iconst_1().iand();
case VoidType, ReferenceType ->
throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
};
case FloatType ->
switch (toType) {
case IntType -> f2i();
case LongType -> f2l();
case DoubleType -> f2d();
case FloatType -> this;
case ByteType -> f2i().i2b();
case CharType -> f2i().i2c();
case ShortType -> f2i().i2s();
case BooleanType -> f2i().iconst_1().iand();
case VoidType, ReferenceType ->
throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
};
case VoidType, ReferenceType ->
throw new IllegalArgumentException(String.format("convert %s -> %s", fromType, toType));
};
} }
/** /**
@ -842,7 +834,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder aaload() { default CodeBuilder aaload() {
return arrayLoad(TypeKind.ReferenceType); return arrayLoad(TypeKind.REFERENCE);
} }
/** /**
@ -850,7 +842,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder aastore() { default CodeBuilder aastore() {
return arrayStore(TypeKind.ReferenceType); return arrayStore(TypeKind.REFERENCE);
} }
/** /**
@ -863,7 +855,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder aload(int slot) { default CodeBuilder aload(int slot) {
return loadLocal(TypeKind.ReferenceType, slot); return loadLocal(TypeKind.REFERENCE, slot);
} }
/** /**
@ -890,7 +882,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder areturn() { default CodeBuilder areturn() {
return return_(TypeKind.ReferenceType); return return_(TypeKind.REFERENCE);
} }
/** /**
@ -911,7 +903,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder astore(int slot) { default CodeBuilder astore(int slot) {
return storeLocal(TypeKind.ReferenceType, slot); return storeLocal(TypeKind.REFERENCE, slot);
} }
/** /**
@ -927,7 +919,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder baload() { default CodeBuilder baload() {
return arrayLoad(TypeKind.ByteType); return arrayLoad(TypeKind.BYTE);
} }
/** /**
@ -935,7 +927,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder bastore() { default CodeBuilder bastore() {
return arrayStore(TypeKind.ByteType); return arrayStore(TypeKind.BYTE);
} }
/** /**
@ -952,7 +944,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder caload() { default CodeBuilder caload() {
return arrayLoad(TypeKind.CharType); return arrayLoad(TypeKind.CHAR);
} }
/** /**
@ -960,7 +952,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder castore() { default CodeBuilder castore() {
return arrayStore(TypeKind.CharType); return arrayStore(TypeKind.CHAR);
} }
/** /**
@ -1019,7 +1011,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder daload() { default CodeBuilder daload() {
return arrayLoad(TypeKind.DoubleType); return arrayLoad(TypeKind.DOUBLE);
} }
/** /**
@ -1027,7 +1019,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder dastore() { default CodeBuilder dastore() {
return arrayStore(TypeKind.DoubleType); return arrayStore(TypeKind.DOUBLE);
} }
/** /**
@ -1080,7 +1072,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder dload(int slot) { default CodeBuilder dload(int slot) {
return loadLocal(TypeKind.DoubleType, slot); return loadLocal(TypeKind.DOUBLE, slot);
} }
/** /**
@ -1112,7 +1104,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder dreturn() { default CodeBuilder dreturn() {
return return_(TypeKind.DoubleType); return return_(TypeKind.DOUBLE);
} }
/** /**
@ -1125,7 +1117,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder dstore(int slot) { default CodeBuilder dstore(int slot) {
return storeLocal(TypeKind.DoubleType, slot); return storeLocal(TypeKind.DOUBLE, slot);
} }
/** /**
@ -1223,7 +1215,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder faload() { default CodeBuilder faload() {
return arrayLoad(TypeKind.FloatType); return arrayLoad(TypeKind.FLOAT);
} }
/** /**
@ -1231,7 +1223,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder fastore() { default CodeBuilder fastore() {
return arrayStore(TypeKind.FloatType); return arrayStore(TypeKind.FLOAT);
} }
/** /**
@ -1292,7 +1284,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder fload(int slot) { default CodeBuilder fload(int slot) {
return loadLocal(TypeKind.FloatType, slot); return loadLocal(TypeKind.FLOAT, slot);
} }
/** /**
@ -1324,7 +1316,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder freturn() { default CodeBuilder freturn() {
return return_(TypeKind.FloatType); return return_(TypeKind.FLOAT);
} }
/** /**
@ -1337,7 +1329,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder fstore(int slot) { default CodeBuilder fstore(int slot) {
return storeLocal(TypeKind.FloatType, slot); return storeLocal(TypeKind.FLOAT, slot);
} }
/** /**
@ -1478,7 +1470,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder iaload() { default CodeBuilder iaload() {
return arrayLoad(TypeKind.IntType); return arrayLoad(TypeKind.INT);
} }
/** /**
@ -1494,7 +1486,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder iastore() { default CodeBuilder iastore() {
return arrayStore(TypeKind.IntType); return arrayStore(TypeKind.INT);
} }
/** /**
@ -1725,7 +1717,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder iload(int slot) { default CodeBuilder iload(int slot) {
return loadLocal(TypeKind.IntType, slot); return loadLocal(TypeKind.INT, slot);
} }
/** /**
@ -1954,7 +1946,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder ireturn() { default CodeBuilder ireturn() {
return return_(TypeKind.IntType); return return_(TypeKind.INT);
} }
/** /**
@ -1983,7 +1975,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder istore(int slot) { default CodeBuilder istore(int slot) {
return storeLocal(TypeKind.IntType, slot); return storeLocal(TypeKind.INT, slot);
} }
/** /**
@ -2057,7 +2049,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder laload() { default CodeBuilder laload() {
return arrayLoad(TypeKind.LongType); return arrayLoad(TypeKind.LONG);
} }
/** /**
@ -2073,7 +2065,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder lastore() { default CodeBuilder lastore() {
return arrayStore(TypeKind.LongType); return arrayStore(TypeKind.LONG);
} }
/** /**
@ -2145,7 +2137,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder lload(int slot) { default CodeBuilder lload(int slot) {
return loadLocal(TypeKind.LongType, slot); return loadLocal(TypeKind.LONG, slot);
} }
/** /**
@ -2185,7 +2177,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder lreturn() { default CodeBuilder lreturn() {
return return_(TypeKind.LongType); return return_(TypeKind.LONG);
} }
/** /**
@ -2214,7 +2206,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder lstore(int slot) { default CodeBuilder lstore(int slot) {
return storeLocal(TypeKind.LongType, slot); return storeLocal(TypeKind.LONG, slot);
} }
/** /**
@ -2384,7 +2376,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder return_() { default CodeBuilder return_() {
return return_(TypeKind.VoidType); return return_(TypeKind.VOID);
} }
/** /**
@ -2392,7 +2384,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder saload() { default CodeBuilder saload() {
return arrayLoad(TypeKind.ShortType); return arrayLoad(TypeKind.SHORT);
} }
/** /**
@ -2400,7 +2392,7 @@ public sealed interface CodeBuilder
* @return this builder * @return this builder
*/ */
default CodeBuilder sastore() { default CodeBuilder sastore() {
return arrayStore(TypeKind.ShortType); return arrayStore(TypeKind.SHORT);
} }
/** /**

View File

@ -45,55 +45,55 @@ public enum Opcode {
NOP(ClassFile.NOP, 1, Kind.NOP), NOP(ClassFile.NOP, 1, Kind.NOP),
/** Push null */ /** Push null */
ACONST_NULL(ClassFile.ACONST_NULL, 1, Kind.CONSTANT, TypeKind.ReferenceType, 0, ConstantDescs.NULL), ACONST_NULL(ClassFile.ACONST_NULL, 1, Kind.CONSTANT, TypeKind.REFERENCE, 0, ConstantDescs.NULL),
/** Push int constant -1 */ /** Push int constant -1 */
ICONST_M1(ClassFile.ICONST_M1, 1, Kind.CONSTANT, TypeKind.IntType, 0, -1), ICONST_M1(ClassFile.ICONST_M1, 1, Kind.CONSTANT, TypeKind.INT, 0, -1),
/** Push int constant 0 */ /** Push int constant 0 */
ICONST_0(ClassFile.ICONST_0, 1, Kind.CONSTANT, TypeKind.IntType, 0, 0), ICONST_0(ClassFile.ICONST_0, 1, Kind.CONSTANT, TypeKind.INT, 0, 0),
/** Push int constant 1 */ /** Push int constant 1 */
ICONST_1(ClassFile.ICONST_1, 1, Kind.CONSTANT, TypeKind.IntType, 0, 1), ICONST_1(ClassFile.ICONST_1, 1, Kind.CONSTANT, TypeKind.INT, 0, 1),
/** Push int constant 2 */ /** Push int constant 2 */
ICONST_2(ClassFile.ICONST_2, 1, Kind.CONSTANT, TypeKind.IntType, 0, 2), ICONST_2(ClassFile.ICONST_2, 1, Kind.CONSTANT, TypeKind.INT, 0, 2),
/** Push int constant 3 */ /** Push int constant 3 */
ICONST_3(ClassFile.ICONST_3, 1, Kind.CONSTANT, TypeKind.IntType, 0, 3), ICONST_3(ClassFile.ICONST_3, 1, Kind.CONSTANT, TypeKind.INT, 0, 3),
/** Push int constant 4 */ /** Push int constant 4 */
ICONST_4(ClassFile.ICONST_4, 1, Kind.CONSTANT, TypeKind.IntType, 0, 4), ICONST_4(ClassFile.ICONST_4, 1, Kind.CONSTANT, TypeKind.INT, 0, 4),
/** Push int constant 5 */ /** Push int constant 5 */
ICONST_5(ClassFile.ICONST_5, 1, Kind.CONSTANT, TypeKind.IntType, 0, 5), ICONST_5(ClassFile.ICONST_5, 1, Kind.CONSTANT, TypeKind.INT, 0, 5),
/** Push long constant 0 */ /** Push long constant 0 */
LCONST_0(ClassFile.LCONST_0, 1, Kind.CONSTANT, TypeKind.LongType, 0, 0L), LCONST_0(ClassFile.LCONST_0, 1, Kind.CONSTANT, TypeKind.LONG, 0, 0L),
/** Push long constant 1 */ /** Push long constant 1 */
LCONST_1(ClassFile.LCONST_1, 1, Kind.CONSTANT, TypeKind.LongType, 0, 1L), LCONST_1(ClassFile.LCONST_1, 1, Kind.CONSTANT, TypeKind.LONG, 0, 1L),
/** Push float constant 0 */ /** Push float constant 0 */
FCONST_0(ClassFile.FCONST_0, 1, Kind.CONSTANT, TypeKind.FloatType, 0, 0.0f), FCONST_0(ClassFile.FCONST_0, 1, Kind.CONSTANT, TypeKind.FLOAT, 0, 0.0f),
/** Push float constant 1 */ /** Push float constant 1 */
FCONST_1(ClassFile.FCONST_1, 1, Kind.CONSTANT, TypeKind.FloatType, 0, 1.0f), FCONST_1(ClassFile.FCONST_1, 1, Kind.CONSTANT, TypeKind.FLOAT, 0, 1.0f),
/** Push float constant 2 */ /** Push float constant 2 */
FCONST_2(ClassFile.FCONST_2, 1, Kind.CONSTANT, TypeKind.FloatType, 0, 2.0f), FCONST_2(ClassFile.FCONST_2, 1, Kind.CONSTANT, TypeKind.FLOAT, 0, 2.0f),
/** Push double constant 0 */ /** Push double constant 0 */
DCONST_0(ClassFile.DCONST_0, 1, Kind.CONSTANT, TypeKind.DoubleType, 0, 0.0d), DCONST_0(ClassFile.DCONST_0, 1, Kind.CONSTANT, TypeKind.DOUBLE, 0, 0.0d),
/** Push double constant 1 */ /** Push double constant 1 */
DCONST_1(ClassFile.DCONST_1, 1, Kind.CONSTANT, TypeKind.DoubleType, 0, 1.0d), DCONST_1(ClassFile.DCONST_1, 1, Kind.CONSTANT, TypeKind.DOUBLE, 0, 1.0d),
/** Push byte */ /** Push byte */
BIPUSH(ClassFile.BIPUSH, 2, Kind.CONSTANT, TypeKind.ByteType), BIPUSH(ClassFile.BIPUSH, 2, Kind.CONSTANT, TypeKind.BYTE),
/** Push short */ /** Push short */
SIPUSH(ClassFile.SIPUSH, 3, Kind.CONSTANT, TypeKind.ShortType), SIPUSH(ClassFile.SIPUSH, 3, Kind.CONSTANT, TypeKind.SHORT),
/** Push item from run-time constant pool */ /** Push item from run-time constant pool */
LDC(ClassFile.LDC, 2, Kind.CONSTANT), LDC(ClassFile.LDC, 2, Kind.CONSTANT),
@ -105,202 +105,202 @@ public enum Opcode {
LDC2_W(ClassFile.LDC2_W, 3, Kind.CONSTANT), LDC2_W(ClassFile.LDC2_W, 3, Kind.CONSTANT),
/** Load int from local variable */ /** Load int from local variable */
ILOAD(ClassFile.ILOAD, 2, Kind.LOAD, TypeKind.IntType, -1), ILOAD(ClassFile.ILOAD, 2, Kind.LOAD, TypeKind.INT, -1),
/** Load long from local variable */ /** Load long from local variable */
LLOAD(ClassFile.LLOAD, 2, Kind.LOAD, TypeKind.LongType, -1), LLOAD(ClassFile.LLOAD, 2, Kind.LOAD, TypeKind.LONG, -1),
/** Load float from local variable */ /** Load float from local variable */
FLOAD(ClassFile.FLOAD, 2, Kind.LOAD, TypeKind.FloatType, -1), FLOAD(ClassFile.FLOAD, 2, Kind.LOAD, TypeKind.FLOAT, -1),
/** Load double from local variable */ /** Load double from local variable */
DLOAD(ClassFile.DLOAD, 2, Kind.LOAD, TypeKind.DoubleType, -1), DLOAD(ClassFile.DLOAD, 2, Kind.LOAD, TypeKind.DOUBLE, -1),
/** Load reference from local variable */ /** Load reference from local variable */
ALOAD(ClassFile.ALOAD, 2, Kind.LOAD, TypeKind.ReferenceType, -1), ALOAD(ClassFile.ALOAD, 2, Kind.LOAD, TypeKind.REFERENCE, -1),
/** Load int from local variable 0 */ /** Load int from local variable 0 */
ILOAD_0(ClassFile.ILOAD_0, 1, Kind.LOAD, TypeKind.IntType, 0), ILOAD_0(ClassFile.ILOAD_0, 1, Kind.LOAD, TypeKind.INT, 0),
/** Load int from local variable 1 */ /** Load int from local variable 1 */
ILOAD_1(ClassFile.ILOAD_1, 1, Kind.LOAD, TypeKind.IntType, 1), ILOAD_1(ClassFile.ILOAD_1, 1, Kind.LOAD, TypeKind.INT, 1),
/** Load int from local variable 2 */ /** Load int from local variable 2 */
ILOAD_2(ClassFile.ILOAD_2, 1, Kind.LOAD, TypeKind.IntType, 2), ILOAD_2(ClassFile.ILOAD_2, 1, Kind.LOAD, TypeKind.INT, 2),
/** Load int from local variable3 */ /** Load int from local variable3 */
ILOAD_3(ClassFile.ILOAD_3, 1, Kind.LOAD, TypeKind.IntType, 3), ILOAD_3(ClassFile.ILOAD_3, 1, Kind.LOAD, TypeKind.INT, 3),
/** Load long from local variable 0 */ /** Load long from local variable 0 */
LLOAD_0(ClassFile.LLOAD_0, 1, Kind.LOAD, TypeKind.LongType, 0), LLOAD_0(ClassFile.LLOAD_0, 1, Kind.LOAD, TypeKind.LONG, 0),
/** Load long from local variable 1 */ /** Load long from local variable 1 */
LLOAD_1(ClassFile.LLOAD_1, 1, Kind.LOAD, TypeKind.LongType, 1), LLOAD_1(ClassFile.LLOAD_1, 1, Kind.LOAD, TypeKind.LONG, 1),
/** Load long from local variable 2 */ /** Load long from local variable 2 */
LLOAD_2(ClassFile.LLOAD_2, 1, Kind.LOAD, TypeKind.LongType, 2), LLOAD_2(ClassFile.LLOAD_2, 1, Kind.LOAD, TypeKind.LONG, 2),
/** Load long from local variable 3 */ /** Load long from local variable 3 */
LLOAD_3(ClassFile.LLOAD_3, 1, Kind.LOAD, TypeKind.LongType, 3), LLOAD_3(ClassFile.LLOAD_3, 1, Kind.LOAD, TypeKind.LONG, 3),
/** Load float from local variable 0 */ /** Load float from local variable 0 */
FLOAD_0(ClassFile.FLOAD_0, 1, Kind.LOAD, TypeKind.FloatType, 0), FLOAD_0(ClassFile.FLOAD_0, 1, Kind.LOAD, TypeKind.FLOAT, 0),
/** Load float from local variable 1 */ /** Load float from local variable 1 */
FLOAD_1(ClassFile.FLOAD_1, 1, Kind.LOAD, TypeKind.FloatType, 1), FLOAD_1(ClassFile.FLOAD_1, 1, Kind.LOAD, TypeKind.FLOAT, 1),
/** Load float from local variable 2 */ /** Load float from local variable 2 */
FLOAD_2(ClassFile.FLOAD_2, 1, Kind.LOAD, TypeKind.FloatType, 2), FLOAD_2(ClassFile.FLOAD_2, 1, Kind.LOAD, TypeKind.FLOAT, 2),
/** Load float from local variable 3 */ /** Load float from local variable 3 */
FLOAD_3(ClassFile.FLOAD_3, 1, Kind.LOAD, TypeKind.FloatType, 3), FLOAD_3(ClassFile.FLOAD_3, 1, Kind.LOAD, TypeKind.FLOAT, 3),
/** Load double from local variable 0 */ /** Load double from local variable 0 */
DLOAD_0(ClassFile.DLOAD_0, 1, Kind.LOAD, TypeKind.DoubleType, 0), DLOAD_0(ClassFile.DLOAD_0, 1, Kind.LOAD, TypeKind.DOUBLE, 0),
/** Load double from local variable 1 */ /** Load double from local variable 1 */
DLOAD_1(ClassFile.DLOAD_1, 1, Kind.LOAD, TypeKind.DoubleType, 1), DLOAD_1(ClassFile.DLOAD_1, 1, Kind.LOAD, TypeKind.DOUBLE, 1),
/** Load double from local variable 2 */ /** Load double from local variable 2 */
DLOAD_2(ClassFile.DLOAD_2, 1, Kind.LOAD, TypeKind.DoubleType, 2), DLOAD_2(ClassFile.DLOAD_2, 1, Kind.LOAD, TypeKind.DOUBLE, 2),
/** Load double from local variable 3 */ /** Load double from local variable 3 */
DLOAD_3(ClassFile.DLOAD_3, 1, Kind.LOAD, TypeKind.DoubleType, 3), DLOAD_3(ClassFile.DLOAD_3, 1, Kind.LOAD, TypeKind.DOUBLE, 3),
/** Load reference from local variable 0 */ /** Load reference from local variable 0 */
ALOAD_0(ClassFile.ALOAD_0, 1, Kind.LOAD, TypeKind.ReferenceType, 0), ALOAD_0(ClassFile.ALOAD_0, 1, Kind.LOAD, TypeKind.REFERENCE, 0),
/** Load reference from local variable 1 */ /** Load reference from local variable 1 */
ALOAD_1(ClassFile.ALOAD_1, 1, Kind.LOAD, TypeKind.ReferenceType, 1), ALOAD_1(ClassFile.ALOAD_1, 1, Kind.LOAD, TypeKind.REFERENCE, 1),
/** Load reference from local variable 2 */ /** Load reference from local variable 2 */
ALOAD_2(ClassFile.ALOAD_2, 1, Kind.LOAD, TypeKind.ReferenceType, 2), ALOAD_2(ClassFile.ALOAD_2, 1, Kind.LOAD, TypeKind.REFERENCE, 2),
/** Load reference from local variable 3 */ /** Load reference from local variable 3 */
ALOAD_3(ClassFile.ALOAD_3, 1, Kind.LOAD, TypeKind.ReferenceType, 3), ALOAD_3(ClassFile.ALOAD_3, 1, Kind.LOAD, TypeKind.REFERENCE, 3),
/** Load int from array */ /** Load int from array */
IALOAD(ClassFile.IALOAD, 1, Kind.ARRAY_LOAD, TypeKind.IntType), IALOAD(ClassFile.IALOAD, 1, Kind.ARRAY_LOAD, TypeKind.INT),
/** Load long from array */ /** Load long from array */
LALOAD(ClassFile.LALOAD, 1, Kind.ARRAY_LOAD, TypeKind.LongType), LALOAD(ClassFile.LALOAD, 1, Kind.ARRAY_LOAD, TypeKind.LONG),
/** Load float from array */ /** Load float from array */
FALOAD(ClassFile.FALOAD, 1, Kind.ARRAY_LOAD, TypeKind.FloatType), FALOAD(ClassFile.FALOAD, 1, Kind.ARRAY_LOAD, TypeKind.FLOAT),
/** Load double from array */ /** Load double from array */
DALOAD(ClassFile.DALOAD, 1, Kind.ARRAY_LOAD, TypeKind.DoubleType), DALOAD(ClassFile.DALOAD, 1, Kind.ARRAY_LOAD, TypeKind.DOUBLE),
/** Load reference from array */ /** Load reference from array */
AALOAD(ClassFile.AALOAD, 1, Kind.ARRAY_LOAD, TypeKind.ReferenceType), AALOAD(ClassFile.AALOAD, 1, Kind.ARRAY_LOAD, TypeKind.REFERENCE),
/** Load byte from array */ /** Load byte or boolean from array */
BALOAD(ClassFile.BALOAD, 1, Kind.ARRAY_LOAD, TypeKind.ByteType), BALOAD(ClassFile.BALOAD, 1, Kind.ARRAY_LOAD, TypeKind.BYTE),
/** Load char from array */ /** Load char from array */
CALOAD(ClassFile.CALOAD, 1, Kind.ARRAY_LOAD, TypeKind.CharType), CALOAD(ClassFile.CALOAD, 1, Kind.ARRAY_LOAD, TypeKind.CHAR),
/** Load short from array */ /** Load short from array */
SALOAD(ClassFile.SALOAD, 1, Kind.ARRAY_LOAD, TypeKind.ShortType), SALOAD(ClassFile.SALOAD, 1, Kind.ARRAY_LOAD, TypeKind.SHORT),
/** Store int into local variable */ /** Store int into local variable */
ISTORE(ClassFile.ISTORE, 2, Kind.STORE, TypeKind.IntType, -1), ISTORE(ClassFile.ISTORE, 2, Kind.STORE, TypeKind.INT, -1),
/** Store long into local variable */ /** Store long into local variable */
LSTORE(ClassFile.LSTORE, 2, Kind.STORE, TypeKind.LongType, -1), LSTORE(ClassFile.LSTORE, 2, Kind.STORE, TypeKind.LONG, -1),
/** Store float into local variable */ /** Store float into local variable */
FSTORE(ClassFile.FSTORE, 2, Kind.STORE, TypeKind.FloatType, -1), FSTORE(ClassFile.FSTORE, 2, Kind.STORE, TypeKind.FLOAT, -1),
/** Store double into local variable */ /** Store double into local variable */
DSTORE(ClassFile.DSTORE, 2, Kind.STORE, TypeKind.DoubleType, -1), DSTORE(ClassFile.DSTORE, 2, Kind.STORE, TypeKind.DOUBLE, -1),
/** Store reference into local variable */ /** Store reference into local variable */
ASTORE(ClassFile.ASTORE, 2, Kind.STORE, TypeKind.ReferenceType, -1), ASTORE(ClassFile.ASTORE, 2, Kind.STORE, TypeKind.REFERENCE, -1),
/** Store int into local variable 0 */ /** Store int into local variable 0 */
ISTORE_0(ClassFile.ISTORE_0, 1, Kind.STORE, TypeKind.IntType, 0), ISTORE_0(ClassFile.ISTORE_0, 1, Kind.STORE, TypeKind.INT, 0),
/** Store int into local variable 1 */ /** Store int into local variable 1 */
ISTORE_1(ClassFile.ISTORE_1, 1, Kind.STORE, TypeKind.IntType, 1), ISTORE_1(ClassFile.ISTORE_1, 1, Kind.STORE, TypeKind.INT, 1),
/** Store int into local variable 2 */ /** Store int into local variable 2 */
ISTORE_2(ClassFile.ISTORE_2, 1, Kind.STORE, TypeKind.IntType, 2), ISTORE_2(ClassFile.ISTORE_2, 1, Kind.STORE, TypeKind.INT, 2),
/** Store int into local variable 3 */ /** Store int into local variable 3 */
ISTORE_3(ClassFile.ISTORE_3, 1, Kind.STORE, TypeKind.IntType, 3), ISTORE_3(ClassFile.ISTORE_3, 1, Kind.STORE, TypeKind.INT, 3),
/** Store long into local variable 0 */ /** Store long into local variable 0 */
LSTORE_0(ClassFile.LSTORE_0, 1, Kind.STORE, TypeKind.LongType, 0), LSTORE_0(ClassFile.LSTORE_0, 1, Kind.STORE, TypeKind.LONG, 0),
/** Store long into local variable 1 */ /** Store long into local variable 1 */
LSTORE_1(ClassFile.LSTORE_1, 1, Kind.STORE, TypeKind.LongType, 1), LSTORE_1(ClassFile.LSTORE_1, 1, Kind.STORE, TypeKind.LONG, 1),
/** Store long into local variable 2 */ /** Store long into local variable 2 */
LSTORE_2(ClassFile.LSTORE_2, 1, Kind.STORE, TypeKind.LongType, 2), LSTORE_2(ClassFile.LSTORE_2, 1, Kind.STORE, TypeKind.LONG, 2),
/** Store long into local variable 3 */ /** Store long into local variable 3 */
LSTORE_3(ClassFile.LSTORE_3, 1, Kind.STORE, TypeKind.LongType, 3), LSTORE_3(ClassFile.LSTORE_3, 1, Kind.STORE, TypeKind.LONG, 3),
/** Store float into local variable 0 */ /** Store float into local variable 0 */
FSTORE_0(ClassFile.FSTORE_0, 1, Kind.STORE, TypeKind.FloatType, 0), FSTORE_0(ClassFile.FSTORE_0, 1, Kind.STORE, TypeKind.FLOAT, 0),
/** Store float into local variable 1 */ /** Store float into local variable 1 */
FSTORE_1(ClassFile.FSTORE_1, 1, Kind.STORE, TypeKind.FloatType, 1), FSTORE_1(ClassFile.FSTORE_1, 1, Kind.STORE, TypeKind.FLOAT, 1),
/** Store float into local variable 2 */ /** Store float into local variable 2 */
FSTORE_2(ClassFile.FSTORE_2, 1, Kind.STORE, TypeKind.FloatType, 2), FSTORE_2(ClassFile.FSTORE_2, 1, Kind.STORE, TypeKind.FLOAT, 2),
/** Store float into local variable 3 */ /** Store float into local variable 3 */
FSTORE_3(ClassFile.FSTORE_3, 1, Kind.STORE, TypeKind.FloatType, 3), FSTORE_3(ClassFile.FSTORE_3, 1, Kind.STORE, TypeKind.FLOAT, 3),
/** Store double into local variable 0 */ /** Store double into local variable 0 */
DSTORE_0(ClassFile.DSTORE_0, 1, Kind.STORE, TypeKind.DoubleType, 0), DSTORE_0(ClassFile.DSTORE_0, 1, Kind.STORE, TypeKind.DOUBLE, 0),
/** Store double into local variable 1 */ /** Store double into local variable 1 */
DSTORE_1(ClassFile.DSTORE_1, 1, Kind.STORE, TypeKind.DoubleType, 1), DSTORE_1(ClassFile.DSTORE_1, 1, Kind.STORE, TypeKind.DOUBLE, 1),
/** Store double into local variable 2 */ /** Store double into local variable 2 */
DSTORE_2(ClassFile.DSTORE_2, 1, Kind.STORE, TypeKind.DoubleType, 2), DSTORE_2(ClassFile.DSTORE_2, 1, Kind.STORE, TypeKind.DOUBLE, 2),
/** Store double into local variable 3 */ /** Store double into local variable 3 */
DSTORE_3(ClassFile.DSTORE_3, 1, Kind.STORE, TypeKind.DoubleType, 3), DSTORE_3(ClassFile.DSTORE_3, 1, Kind.STORE, TypeKind.DOUBLE, 3),
/** Store reference into local variable 0 */ /** Store reference into local variable 0 */
ASTORE_0(ClassFile.ASTORE_0, 1, Kind.STORE, TypeKind.ReferenceType, 0), ASTORE_0(ClassFile.ASTORE_0, 1, Kind.STORE, TypeKind.REFERENCE, 0),
/** Store reference into local variable 1 */ /** Store reference into local variable 1 */
ASTORE_1(ClassFile.ASTORE_1, 1, Kind.STORE, TypeKind.ReferenceType, 1), ASTORE_1(ClassFile.ASTORE_1, 1, Kind.STORE, TypeKind.REFERENCE, 1),
/** Store reference into local variable 2 */ /** Store reference into local variable 2 */
ASTORE_2(ClassFile.ASTORE_2, 1, Kind.STORE, TypeKind.ReferenceType, 2), ASTORE_2(ClassFile.ASTORE_2, 1, Kind.STORE, TypeKind.REFERENCE, 2),
/** Store reference into local variable 3 */ /** Store reference into local variable 3 */
ASTORE_3(ClassFile.ASTORE_3, 1, Kind.STORE, TypeKind.ReferenceType, 3), ASTORE_3(ClassFile.ASTORE_3, 1, Kind.STORE, TypeKind.REFERENCE, 3),
/** Store into int array */ /** Store into int array */
IASTORE(ClassFile.IASTORE, 1, Kind.ARRAY_STORE, TypeKind.IntType), IASTORE(ClassFile.IASTORE, 1, Kind.ARRAY_STORE, TypeKind.INT),
/** Store into long array */ /** Store into long array */
LASTORE(ClassFile.LASTORE, 1, Kind.ARRAY_STORE, TypeKind.LongType), LASTORE(ClassFile.LASTORE, 1, Kind.ARRAY_STORE, TypeKind.LONG),
/** Store into float array */ /** Store into float array */
FASTORE(ClassFile.FASTORE, 1, Kind.ARRAY_STORE, TypeKind.FloatType), FASTORE(ClassFile.FASTORE, 1, Kind.ARRAY_STORE, TypeKind.FLOAT),
/** Store into double array */ /** Store into double array */
DASTORE(ClassFile.DASTORE, 1, Kind.ARRAY_STORE, TypeKind.DoubleType), DASTORE(ClassFile.DASTORE, 1, Kind.ARRAY_STORE, TypeKind.DOUBLE),
/** Store into reference array */ /** Store into reference array */
AASTORE(ClassFile.AASTORE, 1, Kind.ARRAY_STORE, TypeKind.ReferenceType), AASTORE(ClassFile.AASTORE, 1, Kind.ARRAY_STORE, TypeKind.REFERENCE),
/** Store into byte array */ /** Store into byte or boolean array */
BASTORE(ClassFile.BASTORE, 1, Kind.ARRAY_STORE, TypeKind.ByteType), BASTORE(ClassFile.BASTORE, 1, Kind.ARRAY_STORE, TypeKind.BYTE),
/** Store into char array */ /** Store into char array */
CASTORE(ClassFile.CASTORE, 1, Kind.ARRAY_STORE, TypeKind.CharType), CASTORE(ClassFile.CASTORE, 1, Kind.ARRAY_STORE, TypeKind.CHAR),
/** Store into short array */ /** Store into short array */
SASTORE(ClassFile.SASTORE, 1, Kind.ARRAY_STORE, TypeKind.ShortType), SASTORE(ClassFile.SASTORE, 1, Kind.ARRAY_STORE, TypeKind.SHORT),
/** Pop the top operand stack value */ /** Pop the top operand stack value */
POP(ClassFile.POP, 1, Kind.STACK), POP(ClassFile.POP, 1, Kind.STACK),
@ -330,220 +330,220 @@ public enum Opcode {
SWAP(ClassFile.SWAP, 1, Kind.STACK), SWAP(ClassFile.SWAP, 1, Kind.STACK),
/** Add int */ /** Add int */
IADD(ClassFile.IADD, 1, Kind.OPERATOR, TypeKind.IntType), IADD(ClassFile.IADD, 1, Kind.OPERATOR, TypeKind.INT),
/** Add long */ /** Add long */
LADD(ClassFile.LADD, 1, Kind.OPERATOR, TypeKind.LongType), LADD(ClassFile.LADD, 1, Kind.OPERATOR, TypeKind.LONG),
/** Add float */ /** Add float */
FADD(ClassFile.FADD, 1, Kind.OPERATOR, TypeKind.FloatType), FADD(ClassFile.FADD, 1, Kind.OPERATOR, TypeKind.FLOAT),
/** Add double */ /** Add double */
DADD(ClassFile.DADD, 1, Kind.OPERATOR, TypeKind.DoubleType), DADD(ClassFile.DADD, 1, Kind.OPERATOR, TypeKind.DOUBLE),
/** Subtract int */ /** Subtract int */
ISUB(ClassFile.ISUB, 1, Kind.OPERATOR, TypeKind.IntType), ISUB(ClassFile.ISUB, 1, Kind.OPERATOR, TypeKind.INT),
/** Subtract long */ /** Subtract long */
LSUB(ClassFile.LSUB, 1, Kind.OPERATOR, TypeKind.LongType), LSUB(ClassFile.LSUB, 1, Kind.OPERATOR, TypeKind.LONG),
/** Subtract float */ /** Subtract float */
FSUB(ClassFile.FSUB, 1, Kind.OPERATOR, TypeKind.FloatType), FSUB(ClassFile.FSUB, 1, Kind.OPERATOR, TypeKind.FLOAT),
/** Subtract double */ /** Subtract double */
DSUB(ClassFile.DSUB, 1, Kind.OPERATOR, TypeKind.DoubleType), DSUB(ClassFile.DSUB, 1, Kind.OPERATOR, TypeKind.DOUBLE),
/** Multiply int */ /** Multiply int */
IMUL(ClassFile.IMUL, 1, Kind.OPERATOR, TypeKind.IntType), IMUL(ClassFile.IMUL, 1, Kind.OPERATOR, TypeKind.INT),
/** Multiply long */ /** Multiply long */
LMUL(ClassFile.LMUL, 1, Kind.OPERATOR, TypeKind.LongType), LMUL(ClassFile.LMUL, 1, Kind.OPERATOR, TypeKind.LONG),
/** Multiply float */ /** Multiply float */
FMUL(ClassFile.FMUL, 1, Kind.OPERATOR, TypeKind.FloatType), FMUL(ClassFile.FMUL, 1, Kind.OPERATOR, TypeKind.FLOAT),
/** Multiply double */ /** Multiply double */
DMUL(ClassFile.DMUL, 1, Kind.OPERATOR, TypeKind.DoubleType), DMUL(ClassFile.DMUL, 1, Kind.OPERATOR, TypeKind.DOUBLE),
/** Divide int */ /** Divide int */
IDIV(ClassFile.IDIV, 1, Kind.OPERATOR, TypeKind.IntType), IDIV(ClassFile.IDIV, 1, Kind.OPERATOR, TypeKind.INT),
/** Divide long */ /** Divide long */
LDIV(ClassFile.LDIV, 1, Kind.OPERATOR, TypeKind.LongType), LDIV(ClassFile.LDIV, 1, Kind.OPERATOR, TypeKind.LONG),
/** Divide float */ /** Divide float */
FDIV(ClassFile.FDIV, 1, Kind.OPERATOR, TypeKind.FloatType), FDIV(ClassFile.FDIV, 1, Kind.OPERATOR, TypeKind.FLOAT),
/** Divide double */ /** Divide double */
DDIV(ClassFile.DDIV, 1, Kind.OPERATOR, TypeKind.DoubleType), DDIV(ClassFile.DDIV, 1, Kind.OPERATOR, TypeKind.DOUBLE),
/** Remainder int */ /** Remainder int */
IREM(ClassFile.IREM, 1, Kind.OPERATOR, TypeKind.IntType), IREM(ClassFile.IREM, 1, Kind.OPERATOR, TypeKind.INT),
/** Remainder long */ /** Remainder long */
LREM(ClassFile.LREM, 1, Kind.OPERATOR, TypeKind.LongType), LREM(ClassFile.LREM, 1, Kind.OPERATOR, TypeKind.LONG),
/** Remainder float */ /** Remainder float */
FREM(ClassFile.FREM, 1, Kind.OPERATOR, TypeKind.FloatType), FREM(ClassFile.FREM, 1, Kind.OPERATOR, TypeKind.FLOAT),
/** Remainder double */ /** Remainder double */
DREM(ClassFile.DREM, 1, Kind.OPERATOR, TypeKind.DoubleType), DREM(ClassFile.DREM, 1, Kind.OPERATOR, TypeKind.DOUBLE),
/** Negate int */ /** Negate int */
INEG(ClassFile.INEG, 1, Kind.OPERATOR, TypeKind.IntType), INEG(ClassFile.INEG, 1, Kind.OPERATOR, TypeKind.INT),
/** Negate long */ /** Negate long */
LNEG(ClassFile.LNEG, 1, Kind.OPERATOR, TypeKind.LongType), LNEG(ClassFile.LNEG, 1, Kind.OPERATOR, TypeKind.LONG),
/** Negate float */ /** Negate float */
FNEG(ClassFile.FNEG, 1, Kind.OPERATOR, TypeKind.FloatType), FNEG(ClassFile.FNEG, 1, Kind.OPERATOR, TypeKind.FLOAT),
/** Negate double */ /** Negate double */
DNEG(ClassFile.DNEG, 1, Kind.OPERATOR, TypeKind.DoubleType), DNEG(ClassFile.DNEG, 1, Kind.OPERATOR, TypeKind.DOUBLE),
/** Shift left int */ /** Shift left int */
ISHL(ClassFile.ISHL, 1, Kind.OPERATOR, TypeKind.IntType), ISHL(ClassFile.ISHL, 1, Kind.OPERATOR, TypeKind.INT),
/** Shift left long */ /** Shift left long */
LSHL(ClassFile.LSHL, 1, Kind.OPERATOR, TypeKind.LongType), LSHL(ClassFile.LSHL, 1, Kind.OPERATOR, TypeKind.LONG),
/** Shift right int */ /** Shift right int */
ISHR(ClassFile.ISHR, 1, Kind.OPERATOR, TypeKind.IntType), ISHR(ClassFile.ISHR, 1, Kind.OPERATOR, TypeKind.INT),
/** Shift right long */ /** Shift right long */
LSHR(ClassFile.LSHR, 1, Kind.OPERATOR, TypeKind.LongType), LSHR(ClassFile.LSHR, 1, Kind.OPERATOR, TypeKind.LONG),
/** Logical shift right int */ /** Logical shift right int */
IUSHR(ClassFile.IUSHR, 1, Kind.OPERATOR, TypeKind.IntType), IUSHR(ClassFile.IUSHR, 1, Kind.OPERATOR, TypeKind.INT),
/** Logical shift right long */ /** Logical shift right long */
LUSHR(ClassFile.LUSHR, 1, Kind.OPERATOR, TypeKind.LongType), LUSHR(ClassFile.LUSHR, 1, Kind.OPERATOR, TypeKind.LONG),
/** Boolean AND int */ /** Boolean AND int */
IAND(ClassFile.IAND, 1, Kind.OPERATOR, TypeKind.IntType), IAND(ClassFile.IAND, 1, Kind.OPERATOR, TypeKind.INT),
/** Boolean AND long */ /** Boolean AND long */
LAND(ClassFile.LAND, 1, Kind.OPERATOR, TypeKind.LongType), LAND(ClassFile.LAND, 1, Kind.OPERATOR, TypeKind.LONG),
/** Boolean OR int */ /** Boolean OR int */
IOR(ClassFile.IOR, 1, Kind.OPERATOR, TypeKind.IntType), IOR(ClassFile.IOR, 1, Kind.OPERATOR, TypeKind.INT),
/** Boolean OR long */ /** Boolean OR long */
LOR(ClassFile.LOR, 1, Kind.OPERATOR, TypeKind.LongType), LOR(ClassFile.LOR, 1, Kind.OPERATOR, TypeKind.LONG),
/** Boolean XOR int */ /** Boolean XOR int */
IXOR(ClassFile.IXOR, 1, Kind.OPERATOR, TypeKind.IntType), IXOR(ClassFile.IXOR, 1, Kind.OPERATOR, TypeKind.INT),
/** Boolean XOR long */ /** Boolean XOR long */
LXOR(ClassFile.LXOR, 1, Kind.OPERATOR, TypeKind.LongType), LXOR(ClassFile.LXOR, 1, Kind.OPERATOR, TypeKind.LONG),
/** Increment local variable by constant */ /** Increment local variable by constant */
IINC(ClassFile.IINC, 3, Kind.INCREMENT, TypeKind.IntType, -1), IINC(ClassFile.IINC, 3, Kind.INCREMENT, TypeKind.INT, -1),
/** Convert int to long */ /** Convert int to long */
I2L(ClassFile.I2L, 1, Kind.CONVERT, TypeKind.IntType, TypeKind.LongType), I2L(ClassFile.I2L, 1, Kind.CONVERT, TypeKind.INT, TypeKind.LONG),
/** Convert int to float */ /** Convert int to float */
I2F(ClassFile.I2F, 1, Kind.CONVERT, TypeKind.IntType, TypeKind.FloatType), I2F(ClassFile.I2F, 1, Kind.CONVERT, TypeKind.INT, TypeKind.FLOAT),
/** Convert int to double */ /** Convert int to double */
I2D(ClassFile.I2D, 1, Kind.CONVERT, TypeKind.IntType, TypeKind.DoubleType), I2D(ClassFile.I2D, 1, Kind.CONVERT, TypeKind.INT, TypeKind.DOUBLE),
/** Convert long to int */ /** Convert long to int */
L2I(ClassFile.L2I, 1, Kind.CONVERT, TypeKind.LongType, TypeKind.IntType), L2I(ClassFile.L2I, 1, Kind.CONVERT, TypeKind.LONG, TypeKind.INT),
/** Convert long to float */ /** Convert long to float */
L2F(ClassFile.L2F, 1, Kind.CONVERT, TypeKind.LongType, TypeKind.FloatType), L2F(ClassFile.L2F, 1, Kind.CONVERT, TypeKind.LONG, TypeKind.FLOAT),
/** Convert long to double */ /** Convert long to double */
L2D(ClassFile.L2D, 1, Kind.CONVERT, TypeKind.LongType, TypeKind.DoubleType), L2D(ClassFile.L2D, 1, Kind.CONVERT, TypeKind.LONG, TypeKind.DOUBLE),
/** Convert float to int */ /** Convert float to int */
F2I(ClassFile.F2I, 1, Kind.CONVERT, TypeKind.FloatType, TypeKind.IntType), F2I(ClassFile.F2I, 1, Kind.CONVERT, TypeKind.FLOAT, TypeKind.INT),
/** Convert float to long */ /** Convert float to long */
F2L(ClassFile.F2L, 1, Kind.CONVERT, TypeKind.FloatType, TypeKind.LongType), F2L(ClassFile.F2L, 1, Kind.CONVERT, TypeKind.FLOAT, TypeKind.LONG),
/** Convert float to double */ /** Convert float to double */
F2D(ClassFile.F2D, 1, Kind.CONVERT, TypeKind.FloatType, TypeKind.DoubleType), F2D(ClassFile.F2D, 1, Kind.CONVERT, TypeKind.FLOAT, TypeKind.DOUBLE),
/** Convert double to int */ /** Convert double to int */
D2I(ClassFile.D2I, 1, Kind.CONVERT, TypeKind.DoubleType, TypeKind.IntType), D2I(ClassFile.D2I, 1, Kind.CONVERT, TypeKind.DOUBLE, TypeKind.INT),
/** Convert double to long */ /** Convert double to long */
D2L(ClassFile.D2L, 1, Kind.CONVERT, TypeKind.DoubleType, TypeKind.LongType), D2L(ClassFile.D2L, 1, Kind.CONVERT, TypeKind.DOUBLE, TypeKind.LONG),
/** Convert double to float */ /** Convert double to float */
D2F(ClassFile.D2F, 1, Kind.CONVERT, TypeKind.DoubleType, TypeKind.FloatType), D2F(ClassFile.D2F, 1, Kind.CONVERT, TypeKind.DOUBLE, TypeKind.FLOAT),
/** Convert int to byte */ /** Convert int to byte */
I2B(ClassFile.I2B, 1, Kind.CONVERT, TypeKind.IntType, TypeKind.ByteType), I2B(ClassFile.I2B, 1, Kind.CONVERT, TypeKind.INT, TypeKind.BYTE),
/** Convert int to char */ /** Convert int to char */
I2C(ClassFile.I2C, 1, Kind.CONVERT, TypeKind.IntType, TypeKind.CharType), I2C(ClassFile.I2C, 1, Kind.CONVERT, TypeKind.INT, TypeKind.CHAR),
/** Convert int to short */ /** Convert int to short */
I2S(ClassFile.I2S, 1, Kind.CONVERT, TypeKind.IntType, TypeKind.ShortType), I2S(ClassFile.I2S, 1, Kind.CONVERT, TypeKind.INT, TypeKind.SHORT),
/** Compare long */ /** Compare long */
LCMP(ClassFile.LCMP, 1, Kind.OPERATOR, TypeKind.LongType), LCMP(ClassFile.LCMP, 1, Kind.OPERATOR, TypeKind.LONG),
/** Compare float */ /** Compare float */
FCMPL(ClassFile.FCMPL, 1, Kind.OPERATOR, TypeKind.FloatType), FCMPL(ClassFile.FCMPL, 1, Kind.OPERATOR, TypeKind.FLOAT),
/** Compare float */ /** Compare float */
FCMPG(ClassFile.FCMPG, 1, Kind.OPERATOR, TypeKind.FloatType), FCMPG(ClassFile.FCMPG, 1, Kind.OPERATOR, TypeKind.FLOAT),
/** Compare double */ /** Compare double */
DCMPL(ClassFile.DCMPL, 1, Kind.OPERATOR, TypeKind.DoubleType), DCMPL(ClassFile.DCMPL, 1, Kind.OPERATOR, TypeKind.DOUBLE),
/** Compare double */ /** Compare double */
DCMPG(ClassFile.DCMPG, 1, Kind.OPERATOR, TypeKind.DoubleType), DCMPG(ClassFile.DCMPG, 1, Kind.OPERATOR, TypeKind.DOUBLE),
/** Branch if int comparison with zero succeeds */ /** Branch if int comparison with zero succeeds */
IFEQ(ClassFile.IFEQ, 3, Kind.BRANCH, TypeKind.IntType), IFEQ(ClassFile.IFEQ, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison with zero succeeds */ /** Branch if int comparison with zero succeeds */
IFNE(ClassFile.IFNE, 3, Kind.BRANCH, TypeKind.IntType), IFNE(ClassFile.IFNE, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison with zero succeeds */ /** Branch if int comparison with zero succeeds */
IFLT(ClassFile.IFLT, 3, Kind.BRANCH, TypeKind.IntType), IFLT(ClassFile.IFLT, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison with zero succeeds */ /** Branch if int comparison with zero succeeds */
IFGE(ClassFile.IFGE, 3, Kind.BRANCH, TypeKind.IntType), IFGE(ClassFile.IFGE, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison with zero succeeds */ /** Branch if int comparison with zero succeeds */
IFGT(ClassFile.IFGT, 3, Kind.BRANCH, TypeKind.IntType), IFGT(ClassFile.IFGT, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison with zero succeeds */ /** Branch if int comparison with zero succeeds */
IFLE(ClassFile.IFLE, 3, Kind.BRANCH, TypeKind.IntType), IFLE(ClassFile.IFLE, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison succeeds */ /** Branch if int comparison succeeds */
IF_ICMPEQ(ClassFile.IF_ICMPEQ, 3, Kind.BRANCH, TypeKind.IntType), IF_ICMPEQ(ClassFile.IF_ICMPEQ, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison succeeds */ /** Branch if int comparison succeeds */
IF_ICMPNE(ClassFile.IF_ICMPNE, 3, Kind.BRANCH, TypeKind.IntType), IF_ICMPNE(ClassFile.IF_ICMPNE, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison succeeds */ /** Branch if int comparison succeeds */
IF_ICMPLT(ClassFile.IF_ICMPLT, 3, Kind.BRANCH, TypeKind.IntType), IF_ICMPLT(ClassFile.IF_ICMPLT, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison succeeds */ /** Branch if int comparison succeeds */
IF_ICMPGE(ClassFile.IF_ICMPGE, 3, Kind.BRANCH, TypeKind.IntType), IF_ICMPGE(ClassFile.IF_ICMPGE, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison succeeds */ /** Branch if int comparison succeeds */
IF_ICMPGT(ClassFile.IF_ICMPGT, 3, Kind.BRANCH, TypeKind.IntType), IF_ICMPGT(ClassFile.IF_ICMPGT, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if int comparison succeeds */ /** Branch if int comparison succeeds */
IF_ICMPLE(ClassFile.IF_ICMPLE, 3, Kind.BRANCH, TypeKind.IntType), IF_ICMPLE(ClassFile.IF_ICMPLE, 3, Kind.BRANCH, TypeKind.INT),
/** Branch if reference comparison succeeds */ /** Branch if reference comparison succeeds */
IF_ACMPEQ(ClassFile.IF_ACMPEQ, 3, Kind.BRANCH, TypeKind.ReferenceType), IF_ACMPEQ(ClassFile.IF_ACMPEQ, 3, Kind.BRANCH, TypeKind.REFERENCE),
/** Branch if reference comparison succeeds */ /** Branch if reference comparison succeeds */
IF_ACMPNE(ClassFile.IF_ACMPNE, 3, Kind.BRANCH, TypeKind.ReferenceType), IF_ACMPNE(ClassFile.IF_ACMPNE, 3, Kind.BRANCH, TypeKind.REFERENCE),
/** Branch always */ /** Branch always */
GOTO(ClassFile.GOTO, 3, Kind.BRANCH, TypeKind.VoidType), GOTO(ClassFile.GOTO, 3, Kind.BRANCH, TypeKind.VOID),
/** /**
* Jump subroutine is discontinued opcode * Jump subroutine is discontinued opcode
@ -564,22 +564,22 @@ public enum Opcode {
LOOKUPSWITCH(ClassFile.LOOKUPSWITCH, -1, Kind.LOOKUP_SWITCH), LOOKUPSWITCH(ClassFile.LOOKUPSWITCH, -1, Kind.LOOKUP_SWITCH),
/** Return int from method */ /** Return int from method */
IRETURN(ClassFile.IRETURN, 1, Kind.RETURN, TypeKind.IntType), IRETURN(ClassFile.IRETURN, 1, Kind.RETURN, TypeKind.INT),
/** Return long from method */ /** Return long from method */
LRETURN(ClassFile.LRETURN, 1, Kind.RETURN, TypeKind.LongType), LRETURN(ClassFile.LRETURN, 1, Kind.RETURN, TypeKind.LONG),
/** Return float from method */ /** Return float from method */
FRETURN(ClassFile.FRETURN, 1, Kind.RETURN, TypeKind.FloatType), FRETURN(ClassFile.FRETURN, 1, Kind.RETURN, TypeKind.FLOAT),
/** Return double from method */ /** Return double from method */
DRETURN(ClassFile.DRETURN, 1, Kind.RETURN, TypeKind.DoubleType), DRETURN(ClassFile.DRETURN, 1, Kind.RETURN, TypeKind.DOUBLE),
/** Return reference from method */ /** Return reference from method */
ARETURN(ClassFile.ARETURN, 1, Kind.RETURN, TypeKind.ReferenceType), ARETURN(ClassFile.ARETURN, 1, Kind.RETURN, TypeKind.REFERENCE),
/** Return void from method */ /** Return void from method */
RETURN(ClassFile.RETURN, 1, Kind.RETURN, TypeKind.VoidType), RETURN(ClassFile.RETURN, 1, Kind.RETURN, TypeKind.VOID),
/** Get static field from class */ /** Get static field from class */
GETSTATIC(ClassFile.GETSTATIC, 3, Kind.FIELD_ACCESS), GETSTATIC(ClassFile.GETSTATIC, 3, Kind.FIELD_ACCESS),
@ -621,7 +621,7 @@ public enum Opcode {
ANEWARRAY(ClassFile.ANEWARRAY, 3, Kind.NEW_REF_ARRAY), ANEWARRAY(ClassFile.ANEWARRAY, 3, Kind.NEW_REF_ARRAY),
/** Get length of array */ /** Get length of array */
ARRAYLENGTH(ClassFile.ARRAYLENGTH, 1, Kind.OPERATOR, TypeKind.IntType), ARRAYLENGTH(ClassFile.ARRAYLENGTH, 1, Kind.OPERATOR, TypeKind.INT),
/** Throw exception or error */ /** Throw exception or error */
ATHROW(ClassFile.ATHROW, 1, Kind.THROW_EXCEPTION), ATHROW(ClassFile.ATHROW, 1, Kind.THROW_EXCEPTION),
@ -642,13 +642,13 @@ public enum Opcode {
MULTIANEWARRAY(ClassFile.MULTIANEWARRAY, 4, Kind.NEW_MULTI_ARRAY), MULTIANEWARRAY(ClassFile.MULTIANEWARRAY, 4, Kind.NEW_MULTI_ARRAY),
/** Branch if reference is null */ /** Branch if reference is null */
IFNULL(ClassFile.IFNULL, 3, Kind.BRANCH, TypeKind.ReferenceType), IFNULL(ClassFile.IFNULL, 3, Kind.BRANCH, TypeKind.REFERENCE),
/** Branch if reference not null */ /** Branch if reference not null */
IFNONNULL(ClassFile.IFNONNULL, 3, Kind.BRANCH, TypeKind.ReferenceType), IFNONNULL(ClassFile.IFNONNULL, 3, Kind.BRANCH, TypeKind.REFERENCE),
/** Branch always (wide index) */ /** Branch always (wide index) */
GOTO_W(ClassFile.GOTO_W, 5, Kind.BRANCH, TypeKind.VoidType), GOTO_W(ClassFile.GOTO_W, 5, Kind.BRANCH, TypeKind.VOID),
/** /**
* Jump subroutine (wide index) is discontinued opcode * Jump subroutine (wide index) is discontinued opcode
@ -657,34 +657,34 @@ public enum Opcode {
JSR_W(ClassFile.JSR_W, 5, Kind.DISCONTINUED_JSR), JSR_W(ClassFile.JSR_W, 5, Kind.DISCONTINUED_JSR),
/** Load int from local variable (wide index) */ /** Load int from local variable (wide index) */
ILOAD_W((ClassFile.WIDE << 8) | ClassFile.ILOAD, 4, Kind.LOAD, TypeKind.IntType, -1), ILOAD_W((ClassFile.WIDE << 8) | ClassFile.ILOAD, 4, Kind.LOAD, TypeKind.INT, -1),
/** Load long from local variable (wide index) */ /** Load long from local variable (wide index) */
LLOAD_W((ClassFile.WIDE << 8) | ClassFile.LLOAD, 4, Kind.LOAD, TypeKind.LongType, -1), LLOAD_W((ClassFile.WIDE << 8) | ClassFile.LLOAD, 4, Kind.LOAD, TypeKind.LONG, -1),
/** Load float from local variable (wide index) */ /** Load float from local variable (wide index) */
FLOAD_W((ClassFile.WIDE << 8) | ClassFile.FLOAD, 4, Kind.LOAD, TypeKind.FloatType, -1), FLOAD_W((ClassFile.WIDE << 8) | ClassFile.FLOAD, 4, Kind.LOAD, TypeKind.FLOAT, -1),
/** Load double from local variable (wide index) */ /** Load double from local variable (wide index) */
DLOAD_W((ClassFile.WIDE << 8) | ClassFile.DLOAD, 4, Kind.LOAD, TypeKind.DoubleType, -1), DLOAD_W((ClassFile.WIDE << 8) | ClassFile.DLOAD, 4, Kind.LOAD, TypeKind.DOUBLE, -1),
/** Load reference from local variable (wide index) */ /** Load reference from local variable (wide index) */
ALOAD_W((ClassFile.WIDE << 8) | ClassFile.ALOAD, 4, Kind.LOAD, TypeKind.ReferenceType, -1), ALOAD_W((ClassFile.WIDE << 8) | ClassFile.ALOAD, 4, Kind.LOAD, TypeKind.REFERENCE, -1),
/** Store int into local variable (wide index) */ /** Store int into local variable (wide index) */
ISTORE_W((ClassFile.WIDE << 8) | ClassFile.ISTORE, 4, Kind.STORE, TypeKind.IntType, -1), ISTORE_W((ClassFile.WIDE << 8) | ClassFile.ISTORE, 4, Kind.STORE, TypeKind.INT, -1),
/** Store long into local variable (wide index) */ /** Store long into local variable (wide index) */
LSTORE_W((ClassFile.WIDE << 8) | ClassFile.LSTORE, 4, Kind.STORE, TypeKind.LongType, -1), LSTORE_W((ClassFile.WIDE << 8) | ClassFile.LSTORE, 4, Kind.STORE, TypeKind.LONG, -1),
/** Store float into local variable (wide index) */ /** Store float into local variable (wide index) */
FSTORE_W((ClassFile.WIDE << 8) | ClassFile.FSTORE, 4, Kind.STORE, TypeKind.FloatType, -1), FSTORE_W((ClassFile.WIDE << 8) | ClassFile.FSTORE, 4, Kind.STORE, TypeKind.FLOAT, -1),
/** Store double into local variable (wide index) */ /** Store double into local variable (wide index) */
DSTORE_W((ClassFile.WIDE << 8) | ClassFile.DSTORE, 4, Kind.STORE, TypeKind.DoubleType, -1), DSTORE_W((ClassFile.WIDE << 8) | ClassFile.DSTORE, 4, Kind.STORE, TypeKind.DOUBLE, -1),
/** Store reference into local variable (wide index) */ /** Store reference into local variable (wide index) */
ASTORE_W((ClassFile.WIDE << 8) | ClassFile.ASTORE, 4, Kind.STORE, TypeKind.ReferenceType, -1), ASTORE_W((ClassFile.WIDE << 8) | ClassFile.ASTORE, 4, Kind.STORE, TypeKind.REFERENCE, -1),
/** /**
* Return from subroutine (wide index) is discontinued opcode * Return from subroutine (wide index) is discontinued opcode
@ -693,7 +693,7 @@ public enum Opcode {
RET_W((ClassFile.WIDE << 8) | ClassFile.RET, 4, Kind.DISCONTINUED_RET), RET_W((ClassFile.WIDE << 8) | ClassFile.RET, 4, Kind.DISCONTINUED_RET),
/** Increment local variable by constant (wide index) */ /** Increment local variable by constant (wide index) */
IINC_W((ClassFile.WIDE << 8) | ClassFile.IINC, 6, Kind.INCREMENT, TypeKind.IntType, -1); IINC_W((ClassFile.WIDE << 8) | ClassFile.IINC, 6, Kind.INCREMENT, TypeKind.INT, -1);
/** /**
* Kinds of opcodes. * Kinds of opcodes.

View File

@ -25,107 +25,197 @@
package java.lang.classfile; package java.lang.classfile;
import java.lang.classfile.instruction.DiscontinuedInstruction;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.invoke.TypeDescriptor; import java.lang.invoke.TypeDescriptor;
import jdk.internal.javac.PreviewFeature; import jdk.internal.javac.PreviewFeature;
import jdk.internal.vm.annotation.Stable;
/** /**
* Describes the types that can be part of a field or method descriptor. * Describes the data types Java Virtual Machine operates on.
* This omits {@code returnAddress} (JVMS {@jvms 2.3.3}),
* which is only used by discontinued {@link
* DiscontinuedInstruction.JsrInstruction jsr} and {@link
* DiscontinuedInstruction.RetInstruction ret} instructions,
* and includes {@link #VOID void} (JVMS {@jvms 4.3.3}), which
* appears as a method return type.
* *
* <h2 id="computational-type">Computational Type</h2>
* In the {@code class} file format, local variables (JVMS {@jvms 2.6.1}),
* and the operand stack (JVMS {@jvms 2.6.2}) of the Java Virtual Machine,
* {@link #BOOLEAN boolean}, {@link #BYTE byte}, {@link #CHAR char},
* {@link #SHORT short} types do not exist and are {@linkplain
* #asLoadable() represented} by the {@link #INT int} computational type.
* {@link #INT int}, {@link #FLOAT float}, {@link #REFERENCE reference},
* {@code returnAddress}, {@link #LONG long}, and {@link #DOUBLE doule}
* are the computational types of the Java Virtual Machine.
*
* @jvms 2.2 Data Types
* @jvms 2.11.1 Types and the Java Virtual Machine
* @since 22 * @since 22
*/ */
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public enum TypeKind { public enum TypeKind {
/** the primitive type byte */ // Elements are grouped so frequently used switch ranges such as
ByteType("byte", "B", 8), // primitives (boolean - double) and computational (int - void) are together.
/** the primitive type short */ // This also follows the order of typed opcodes
ShortType("short", "S", 9), // Begin primitive types
/** the primitive type int */ /**
IntType("int", "I", 10), * The primitive type {@code boolean}. Its {@linkplain ##computational-type
/** the primitive type float */ * computational type} is {@link #INT int}. {@code 0} represents {@code false},
FloatType("float", "F", 6), * and {@code 1} represents {@code true}. It is zero-extended to an {@code int}
/** the primitive type long */ * when loaded onto the operand stack and narrowed by taking the bitwise AND
LongType("long", "J", 11), * with {@code 1} when stored.
/** the primitive type double */ *
DoubleType("double", "D", 7), * @jvms 2.3.4 The {@code boolean} Type
/** a reference type */ */
ReferenceType("reference type", "L", -1), BOOLEAN(1, 4),
/** the primitive type char */ /**
CharType("char", "C", 5), * The primitive type {@code byte}. Its {@linkplain ##computational-type
/** the primitive type boolean */ * computational type} is {@link #INT int}. It is sign-extended to an
BooleanType("boolean", "Z", 4), * {@code int} when loaded onto the operand stack and truncated when
/** void */ * stored.
VoidType("void", "V", -1); */
BYTE(1, 8),
/**
* The primitive type {@code char}. Its {@linkplain ##computational-type
* computational type} is {@link #INT int}. It is zero-extended to an
* {@code int} when loaded onto the operand stack and truncated when
* stored.
*/
CHAR(1, 5),
/**
* The primitive type {@code short}. Its {@linkplain ##computational-type
* computational type} is {@link #INT int}. It is sign-extended to an
* {@code int} when loaded onto the operand stack and truncated when
* stored.
*/
SHORT(1, 9),
// Begin computational types
/**
* The primitive type {@code int}.
*/
INT(1, 10),
/**
* The primitive type {@code long}. It is of {@linkplain #slotSize() category} 2.
*/
LONG(2, 11),
/**
* The primitive type {@code float}.
*/
FLOAT(1, 6),
/**
* The primitive type {@code double}. It is of {@linkplain #slotSize() category} 2.
*/
DOUBLE(2, 7),
// End primitive types
/**
* A reference type.
* @jvms 2.4 Reference Types and Values
*/
REFERENCE(1, -1),
/**
* The {@code void} type, for absence of a value. While this is not a data type,
* this can be a method return type indicating no change in {@linkplain #slotSize()
* operand stack depth}.
*
* @jvms 4.3.3 Method Descriptors
*/
VOID(0, -1);
// End computational types
private final String name; private @Stable ClassDesc upperBound;
private final String descriptor; private final int slots;
private final int newarrayCode; private final int newarrayCode;
/** {@return the human-readable name corresponding to this type} */ TypeKind(int slots, int newarrayCode) {
public String typeName() { return name; } this.slots = slots;
this.newarrayCode = newarrayCode;
/** {@return the field descriptor character corresponding to this type} */ }
public String descriptor() { return descriptor; }
/** /**
* {@return the code used by the {@code newarray} opcode corresponding to this type} * {@return the most specific upper bound field descriptor that can store any value
* of this type} This is the primitive class descriptor for primitive types and
* {@link #VOID void} and {@link ConstantDescs#CD_Object Object} descriptor for
* {@link #REFERENCE reference}.
*/
public ClassDesc upperBound() {
var upper = this.upperBound;
if (upper == null)
return this.upperBound = fetchUpperBound();
return upper;
}
private ClassDesc fetchUpperBound() {
return switch (this) {
case BOOLEAN -> ConstantDescs.CD_boolean;
case BYTE -> ConstantDescs.CD_byte;
case CHAR -> ConstantDescs.CD_char;
case SHORT -> ConstantDescs.CD_short;
case INT -> ConstantDescs.CD_int;
case FLOAT -> ConstantDescs.CD_float;
case LONG -> ConstantDescs.CD_long;
case DOUBLE -> ConstantDescs.CD_double;
case REFERENCE -> ConstantDescs.CD_Object;
case VOID -> ConstantDescs.CD_void;
};
}
/**
* {@return the code used by the {@link Opcode#NEWARRAY newarray} instruction to create an array
* of this component type, or {@code -1} if this type is not supported by {@code newarray}}
* @since 23 * @since 23
* @jvms 6.5.newarray <i>newarray</i>
*/ */
public int newarrayCode() { public int newarrayCode() {
return newarrayCode; return newarrayCode;
} }
/** /**
* {@return the number of local variable slots consumed by this type} * {@return the number of local variable index or operand stack depth consumed by this type}
* This is also the category of this type for instructions operating on the operand stack without
* regard to type (JVMS {@jvms 2.11.1}), such as {@link Opcode#POP pop} versus {@link Opcode#POP2
* pop2}.
* @jvms 2.6.1 Local Variables
* @jvms 2.6.2 Operand Stacks
*/ */
public int slotSize() { public int slotSize() {
return switch (this) { return this.slots;
case VoidType -> 0;
case LongType, DoubleType -> 2;
default -> 1;
};
} }
/** /**
* Erase this type kind to the type which will be used for xLOAD, xSTORE, * {@return the {@linkplain ##computational-type computational type} for this type, or {@link #VOID void}
* and xRETURN bytecodes * for {@code void}}
* @return the erased type kind
*/ */
public TypeKind asLoadable() { public TypeKind asLoadable() {
return switch (this) { return ordinal() < 4 ? INT : this;
case BooleanType, ByteType, CharType, ShortType -> TypeKind.IntType;
default -> this;
};
}
TypeKind(String name, String descriptor, int newarrayCode) {
this.name = name;
this.descriptor = descriptor;
this.newarrayCode = newarrayCode;
} }
/** /**
* {@return the type kind associated with the array type described by the * {@return the component type described by the array code used as an operand to {@link Opcode#NEWARRAY
* array code used as an operand to {@code newarray}} * newarray}}
* @param newarrayCode the operand of the {@code newarray} instruction * @param newarrayCode the operand of the {@code newarray} instruction
* @throws IllegalArgumentException if the code is invalid * @throws IllegalArgumentException if the code is invalid
* @since 23 * @since 23
* @jvms 6.5.newarray <i>newarray</i>
*/ */
public static TypeKind fromNewarrayCode(int newarrayCode) { public static TypeKind fromNewarrayCode(int newarrayCode) {
return switch (newarrayCode) { return switch (newarrayCode) {
case 4 -> TypeKind.BooleanType; case 4 -> BOOLEAN;
case 5 -> TypeKind.CharType; case 5 -> CHAR;
case 6 -> TypeKind.FloatType; case 6 -> FLOAT;
case 7 -> TypeKind.DoubleType; case 7 -> DOUBLE;
case 8 -> TypeKind.ByteType; case 8 -> BYTE;
case 9 -> TypeKind.ShortType; case 9 -> SHORT;
case 10 -> TypeKind.IntType; case 10 -> INT;
case 11 -> TypeKind.LongType; case 11 -> LONG;
default -> throw new IllegalArgumentException("Bad newarray code: " + newarrayCode); default -> throw new IllegalArgumentException("Bad newarray code: " + newarrayCode);
}; };
} }
/** /**
* {@return the type kind associated with the specified field descriptor} * {@return the type associated with the specified field descriptor}
* @param s the field descriptor * @param s the field descriptor
* @throws IllegalArgumentException only if the descriptor is not valid * @throws IllegalArgumentException only if the descriptor is not valid
*/ */
@ -134,27 +224,27 @@ public enum TypeKind {
throw new IllegalArgumentException("Empty descriptor"); throw new IllegalArgumentException("Empty descriptor");
} }
return switch (s.charAt(0)) { return switch (s.charAt(0)) {
case '[', 'L' -> TypeKind.ReferenceType; case '[', 'L' -> REFERENCE;
case 'B' -> TypeKind.ByteType; case 'B' -> BYTE;
case 'C' -> TypeKind.CharType; case 'C' -> CHAR;
case 'Z' -> TypeKind.BooleanType; case 'Z' -> BOOLEAN;
case 'S' -> TypeKind.ShortType; case 'S' -> SHORT;
case 'I' -> TypeKind.IntType; case 'I' -> INT;
case 'F' -> TypeKind.FloatType; case 'F' -> FLOAT;
case 'J' -> TypeKind.LongType; case 'J' -> LONG;
case 'D' -> TypeKind.DoubleType; case 'D' -> DOUBLE;
case 'V' -> TypeKind.VoidType; case 'V' -> VOID;
default -> throw new IllegalArgumentException("Bad type: " + s); default -> throw new IllegalArgumentException("Bad type: " + s);
}; };
} }
/** /**
* {@return the type kind associated with the specified field descriptor} * {@return the type associated with the specified field descriptor}
* @param descriptor the field descriptor * @param descriptor the field descriptor
*/ */
public static TypeKind from(TypeDescriptor.OfField<?> descriptor) { public static TypeKind from(TypeDescriptor.OfField<?> descriptor) {
return descriptor.isPrimitive() // implicit null check return descriptor.isPrimitive() // implicit null check
? fromDescriptor(descriptor.descriptorString()) ? fromDescriptor(descriptor.descriptorString())
: TypeKind.ReferenceType; : REFERENCE;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -181,7 +181,7 @@ class PackageSnippets {
var storeStack = new ArrayDeque<StoreInstruction>(); var storeStack = new ArrayDeque<StoreInstruction>();
int slot = 0; int slot = 0;
if (!mm.flags().has(AccessFlag.STATIC)) if (!mm.flags().has(AccessFlag.STATIC))
storeStack.push(StoreInstruction.of(TypeKind.ReferenceType, slot++)); storeStack.push(StoreInstruction.of(TypeKind.REFERENCE, slot++));
for (var pt : mm.methodTypeSymbol().parameterList()) { for (var pt : mm.methodTypeSymbol().parameterList()) {
var tk = TypeKind.from(pt); var tk = TypeKind.from(pt);
storeStack.push(StoreInstruction.of(tk, slot)); storeStack.push(StoreInstruction.of(tk, slot));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -50,6 +50,6 @@ public sealed interface DoubleEntry
*/ */
@Override @Override
default TypeKind typeKind() { default TypeKind typeKind() {
return TypeKind.DoubleType; return TypeKind.DOUBLE;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,6 +51,6 @@ public sealed interface FloatEntry
*/ */
@Override @Override
default TypeKind typeKind() { default TypeKind typeKind() {
return TypeKind.FloatType; return TypeKind.FLOAT;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -50,6 +50,6 @@ public sealed interface IntegerEntry
*/ */
@Override @Override
default TypeKind typeKind() { default TypeKind typeKind() {
return TypeKind.IntType; return TypeKind.INT;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -48,6 +48,6 @@ public sealed interface LoadableConstantEntry extends PoolEntry
* {@return the type of the constant} * {@return the type of the constant}
*/ */
default TypeKind typeKind() { default TypeKind typeKind() {
return TypeKind.ReferenceType; return TypeKind.REFERENCE;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -50,6 +50,6 @@ public sealed interface LongEntry
*/ */
@Override @Override
default TypeKind typeKind() { default TypeKind typeKind() {
return TypeKind.LongType; return TypeKind.LONG;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -45,7 +45,9 @@ import jdk.internal.javac.PreviewFeature;
public sealed interface ArrayLoadInstruction extends Instruction public sealed interface ArrayLoadInstruction extends Instruction
permits AbstractInstruction.UnboundArrayLoadInstruction { permits AbstractInstruction.UnboundArrayLoadInstruction {
/** /**
* {@return the component type of the array} * {@return the component type of the array} The {@link TypeKind#BYTE byte}
* type load instruction {@link Opcode#BALOAD baload} also operates on
* {@link TypeKind#BOOLEAN boolean} arrays.
*/ */
TypeKind typeKind(); TypeKind typeKind();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -45,7 +45,9 @@ import jdk.internal.javac.PreviewFeature;
public sealed interface ArrayStoreInstruction extends Instruction public sealed interface ArrayStoreInstruction extends Instruction
permits AbstractInstruction.UnboundArrayStoreInstruction { permits AbstractInstruction.UnboundArrayStoreInstruction {
/** /**
* {@return the component type of the array} * {@return the component type of the array} The {@link TypeKind#BYTE byte}
* type store instruction {@link Opcode#BASTORE bastore} also operates on
* {@link TypeKind#BOOLEAN boolean} arrays.
*/ */
TypeKind typeKind(); TypeKind typeKind();

View File

@ -57,7 +57,7 @@ public sealed interface NewPrimitiveArrayInstruction extends Instruction
static NewPrimitiveArrayInstruction of(TypeKind typeKind) { static NewPrimitiveArrayInstruction of(TypeKind typeKind) {
// Implicit null-check: // Implicit null-check:
if (typeKind.newarrayCode() < 0) { if (typeKind.newarrayCode() < 0) {
throw new IllegalArgumentException("Illegal component type: " + typeKind.typeName()); throw new IllegalArgumentException("Illegal component type for primitive array: " + typeKind.name());
} }
return new AbstractInstruction.UnboundNewPrimitiveArrayInstruction(typeKind); return new AbstractInstruction.UnboundNewPrimitiveArrayInstruction(typeKind);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -381,7 +381,7 @@ class PackageSnippets {
var storeStack = new ArrayDeque<StoreInstruction>(); var storeStack = new ArrayDeque<StoreInstruction>();
int slot = 0; int slot = 0;
if (!mm.flags().has(AccessFlag.STATIC)) if (!mm.flags().has(AccessFlag.STATIC))
storeStack.push(StoreInstruction.of(TypeKind.ReferenceType, slot++)); storeStack.push(StoreInstruction.of(TypeKind.REFERENCE, slot++));
for (var pt : mm.methodTypeSymbol().parameterList()) { for (var pt : mm.methodTypeSymbol().parameterList()) {
var tk = TypeKind.from(pt); var tk = TypeKind.from(pt);
storeStack.push(StoreInstruction.of(tk, slot)); storeStack.push(StoreInstruction.of(tk, slot));

View File

@ -368,9 +368,9 @@ class InvokerBytecodeGenerator {
*/ */
private void emitUnboxing(CodeBuilder cob, TypeKind target) { private void emitUnboxing(CodeBuilder cob, TypeKind target) {
switch (target) { switch (target) {
case BooleanType -> emitReferenceCast(cob, Boolean.class, null); case BOOLEAN -> emitReferenceCast(cob, Boolean.class, null);
case CharType -> emitReferenceCast(cob, Character.class, null); case CHAR -> emitReferenceCast(cob, Character.class, null);
case ByteType, DoubleType, FloatType, IntType, LongType, ShortType -> case BYTE, DOUBLE, FLOAT, INT, LONG, SHORT ->
emitReferenceCast(cob, Number.class, null); emitReferenceCast(cob, Number.class, null);
default -> {} default -> {}
} }
@ -443,7 +443,7 @@ class InvokerBytecodeGenerator {
} }
if (writeBack != null) { if (writeBack != null) {
cob.dup(); cob.dup();
emitStoreInsn(cob, TypeKind.ReferenceType, writeBack.index()); emitStoreInsn(cob, TypeKind.REFERENCE, writeBack.index());
} }
} }
@ -901,7 +901,7 @@ class InvokerBytecodeGenerator {
// invoke selectAlternativeName.arguments[1] // invoke selectAlternativeName.arguments[1]
Class<?>[] preForkClasses = localClasses.clone(); Class<?>[] preForkClasses = localClasses.clone();
emitPushArgument(cob, selectAlternativeName, 1); // get 2nd argument of selectAlternative emitPushArgument(cob, selectAlternativeName, 1); // get 2nd argument of selectAlternative
emitStoreInsn(cob, TypeKind.ReferenceType, receiver.index()); // store the MH in the receiver slot emitStoreInsn(cob, TypeKind.REFERENCE, receiver.index()); // store the MH in the receiver slot
emitStaticInvoke(cob, invokeBasicName); emitStaticInvoke(cob, invokeBasicName);
// goto L_done // goto L_done
@ -913,7 +913,7 @@ class InvokerBytecodeGenerator {
// invoke selectAlternativeName.arguments[2] // invoke selectAlternativeName.arguments[2]
System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length); System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);
emitPushArgument(cob, selectAlternativeName, 2); // get 3rd argument of selectAlternative emitPushArgument(cob, selectAlternativeName, 2); // get 3rd argument of selectAlternative
emitStoreInsn(cob, TypeKind.ReferenceType, receiver.index()); // store the MH in the receiver slot emitStoreInsn(cob, TypeKind.REFERENCE, receiver.index()); // store the MH in the receiver slot
emitStaticInvoke(cob, invokeBasicName); emitStaticInvoke(cob, invokeBasicName);
// L_done: // L_done:
@ -1151,7 +1151,7 @@ class InvokerBytecodeGenerator {
emitPushArgument(cob, invoker, 2); // push cases emitPushArgument(cob, invoker, 2); // push cases
cob.getfield(CD_CasesHolder, "cases", CD_MethodHandle_array); cob.getfield(CD_CasesHolder, "cases", CD_MethodHandle_array);
int casesLocal = extendLocalsMap(new Class<?>[] { MethodHandle[].class }); int casesLocal = extendLocalsMap(new Class<?>[] { MethodHandle[].class });
emitStoreInsn(cob, TypeKind.ReferenceType, casesLocal); emitStoreInsn(cob, TypeKind.REFERENCE, casesLocal);
Label endLabel = cob.newLabel(); Label endLabel = cob.newLabel();
Label defaultLabel = cob.newLabel(); Label defaultLabel = cob.newLabel();
@ -1172,7 +1172,7 @@ class InvokerBytecodeGenerator {
for (int i = 0; i < numCases; i++) { for (int i = 0; i < numCases; i++) {
cob.labelBinding(cases.get(i).target()); cob.labelBinding(cases.get(i).target());
// Load the particular case: // Load the particular case:
emitLoadInsn(cob, TypeKind.ReferenceType, casesLocal); emitLoadInsn(cob, TypeKind.REFERENCE, casesLocal);
cob.loadConstant(i); cob.loadConstant(i);
cob.aaload(); cob.aaload();
@ -1311,7 +1311,7 @@ class InvokerBytecodeGenerator {
// PREINIT: // PREINIT:
emitPushArgument(cob, MethodHandleImpl.LoopClauses.class, invoker.arguments[1]); emitPushArgument(cob, MethodHandleImpl.LoopClauses.class, invoker.arguments[1]);
cob.getfield(CD_LoopClauses, "clauses", CD_MethodHandle_array2); cob.getfield(CD_LoopClauses, "clauses", CD_MethodHandle_array2);
emitStoreInsn(cob, TypeKind.ReferenceType, clauseDataIndex); emitStoreInsn(cob, TypeKind.REFERENCE, clauseDataIndex);
// INIT: // INIT:
for (int c = 0, state = 0; c < nClauses; ++c) { for (int c = 0, state = 0; c < nClauses; ++c) {
@ -1398,7 +1398,7 @@ class InvokerBytecodeGenerator {
} }
private void emitPushClauseArray(CodeBuilder cob, int clauseDataSlot, int which) { private void emitPushClauseArray(CodeBuilder cob, int clauseDataSlot, int which) {
emitLoadInsn(cob, TypeKind.ReferenceType, clauseDataSlot); emitLoadInsn(cob, TypeKind.REFERENCE, clauseDataSlot);
cob.loadConstant(which - 1); cob.loadConstant(which - 1);
cob.aaload(); cob.aaload();
} }
@ -1497,7 +1497,7 @@ class InvokerBytecodeGenerator {
// long - l2i,i2b l2i,i2s l2i,i2c l2i <-> l2f l2d // long - l2i,i2b l2i,i2s l2i,i2c l2i <-> l2f l2d
// float - f2i,i2b f2i,i2s f2i,i2c f2i f2l <-> f2d // float - f2i,i2b f2i,i2s f2i,i2c f2i f2l <-> f2d
// double - d2i,i2b d2i,i2s d2i,i2c d2i d2l d2f <-> // double - d2i,i2b d2i,i2s d2i,i2c d2i d2l d2f <->
if (from != to && from != TypeKind.BooleanType) try { if (from != to && from != TypeKind.BOOLEAN) try {
cob.conversion(from, to); cob.conversion(from, to);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new IllegalStateException("unhandled prim cast: " + from + "2" + to); throw new IllegalStateException("unhandled prim cast: " + from + "2" + to);

View File

@ -138,12 +138,12 @@ class LambdaForm {
public static final int VOID_RESULT = -1, LAST_RESULT = -2; public static final int VOID_RESULT = -1, LAST_RESULT = -2;
enum BasicType { enum BasicType {
L_TYPE('L', Object.class, Wrapper.OBJECT, TypeKind.ReferenceType), // all reference types L_TYPE('L', Object.class, Wrapper.OBJECT, TypeKind.REFERENCE), // all reference types
I_TYPE('I', int.class, Wrapper.INT, TypeKind.IntType), I_TYPE('I', int.class, Wrapper.INT, TypeKind.INT),
J_TYPE('J', long.class, Wrapper.LONG, TypeKind.LongType), J_TYPE('J', long.class, Wrapper.LONG, TypeKind.LONG),
F_TYPE('F', float.class, Wrapper.FLOAT, TypeKind.FloatType), F_TYPE('F', float.class, Wrapper.FLOAT, TypeKind.FLOAT),
D_TYPE('D', double.class, Wrapper.DOUBLE, TypeKind.DoubleType), // all primitive types D_TYPE('D', double.class, Wrapper.DOUBLE, TypeKind.DOUBLE), // all primitive types
V_TYPE('V', void.class, Wrapper.VOID, TypeKind.VoidType); // not valid in all contexts V_TYPE('V', void.class, Wrapper.VOID, TypeKind.VOID); // not valid in all contexts
static final @Stable BasicType[] ALL_TYPES = BasicType.values(); static final @Stable BasicType[] ALL_TYPES = BasicType.values();
static final @Stable BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1); static final @Stable BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1);

View File

@ -49,8 +49,6 @@ import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc; import java.lang.constant.MethodTypeDesc;
import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodHandles.Lookup;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@ -1419,11 +1417,11 @@ public final class StringConcatFactory {
// Compute parameter variable slots // Compute parameter variable slots
int paramCount = concatArgs.parameterCount(), int paramCount = concatArgs.parameterCount(),
thisSlot = cb.receiverSlot(), thisSlot = cb.receiverSlot(),
lengthSlot = cb.allocateLocal(TypeKind.IntType), lengthSlot = cb.allocateLocal(TypeKind.INT),
coderSlot = cb.allocateLocal(TypeKind.ByteType), coderSlot = cb.allocateLocal(TypeKind.BYTE),
bufSlot = cb.allocateLocal(TypeKind.ReferenceType), bufSlot = cb.allocateLocal(TypeKind.REFERENCE),
constantsSlot = cb.allocateLocal(TypeKind.ReferenceType), constantsSlot = cb.allocateLocal(TypeKind.REFERENCE),
suffixSlot = cb.allocateLocal(TypeKind.ReferenceType); suffixSlot = cb.allocateLocal(TypeKind.REFERENCE);
/* /*
* Types other than int/long/char/boolean require local variables to store the result of stringOf. * Types other than int/long/char/boolean require local variables to store the result of stringOf.
@ -1447,7 +1445,7 @@ public final class StringConcatFactory {
} else { } else {
methodTypeDesc = MTD_String_Object; methodTypeDesc = MTD_String_Object;
} }
stringSlots[i] = cb.allocateLocal(TypeKind.ReferenceType); stringSlots[i] = cb.allocateLocal(TypeKind.REFERENCE);
cb.loadLocal(TypeKind.from(cl), cb.parameterSlot(i)) cb.loadLocal(TypeKind.from(cl), cb.parameterSlot(i))
.invokestatic(CD_StringConcatHelper, "stringOf", methodTypeDesc) .invokestatic(CD_StringConcatHelper, "stringOf", methodTypeDesc)
.astore(stringSlots[i]); .astore(stringSlots[i]);
@ -1464,7 +1462,7 @@ public final class StringConcatFactory {
var cl = concatArgs.parameterType(i); var cl = concatArgs.parameterType(i);
if (maybeUTF16(cl)) { if (maybeUTF16(cl)) {
if (cl == char.class) { if (cl == char.class) {
cb.loadLocal(TypeKind.CharType, cb.parameterSlot(i)); cb.loadLocal(TypeKind.CHAR, cb.parameterSlot(i));
} else { } else {
cb.aload(stringSlots[i]); cb.aload(stringSlots[i]);
} }
@ -1531,7 +1529,7 @@ public final class StringConcatFactory {
var kind = TypeKind.from(cl); var kind = TypeKind.from(cl);
if (needStringOf(cl)) { if (needStringOf(cl)) {
paramSlot = stringSlots[i]; paramSlot = stringSlots[i];
kind = TypeKind.ReferenceType; kind = TypeKind.REFERENCE;
} }
cb.loadLocal(kind, paramSlot); cb.loadLocal(kind, paramSlot);
} }
@ -1682,7 +1680,7 @@ public final class StringConcatFactory {
} else if (cl == CD_char) { } else if (cl == CD_char) {
methodTypeDesc = PREPEND_char; methodTypeDesc = PREPEND_char;
} else { } else {
kind = TypeKind.ReferenceType; kind = TypeKind.REFERENCE;
methodTypeDesc = PREPEND_String; methodTypeDesc = PREPEND_String;
} }

View File

@ -69,14 +69,14 @@ class TypeConvertingMethodAdapter {
} }
private static TypeKind primitiveTypeKindFromClass(Class<?> type) { private static TypeKind primitiveTypeKindFromClass(Class<?> type) {
if (type == Integer.class) return TypeKind.IntType; if (type == Integer.class) return TypeKind.INT;
if (type == Long.class) return TypeKind.LongType; if (type == Long.class) return TypeKind.LONG;
if (type == Boolean.class) return TypeKind.BooleanType; if (type == Boolean.class) return TypeKind.BOOLEAN;
if (type == Short.class) return TypeKind.ShortType; if (type == Short.class) return TypeKind.SHORT;
if (type == Byte.class) return TypeKind.ByteType; if (type == Byte.class) return TypeKind.BYTE;
if (type == Character.class) return TypeKind.CharType; if (type == Character.class) return TypeKind.CHAR;
if (type == Float.class) return TypeKind.FloatType; if (type == Float.class) return TypeKind.FLOAT;
if (type == Double.class) return TypeKind.DoubleType; if (type == Double.class) return TypeKind.DOUBLE;
return null; return null;
} }
@ -94,27 +94,27 @@ class TypeConvertingMethodAdapter {
static void box(CodeBuilder cob, TypeKind tk) { static void box(CodeBuilder cob, TypeKind tk) {
switch (tk) { switch (tk) {
case BooleanType -> cob.invokestatic(BoxHolder.BOX_BOOLEAN); case BOOLEAN -> cob.invokestatic(BoxHolder.BOX_BOOLEAN);
case ByteType -> cob.invokestatic(BoxHolder.BOX_BYTE); case BYTE -> cob.invokestatic(BoxHolder.BOX_BYTE);
case CharType -> cob.invokestatic(BoxHolder.BOX_CHAR); case CHAR -> cob.invokestatic(BoxHolder.BOX_CHAR);
case DoubleType -> cob.invokestatic(BoxHolder.BOX_DOUBLE); case DOUBLE -> cob.invokestatic(BoxHolder.BOX_DOUBLE);
case FloatType -> cob.invokestatic(BoxHolder.BOX_FLOAT); case FLOAT -> cob.invokestatic(BoxHolder.BOX_FLOAT);
case IntType -> cob.invokestatic(BoxHolder.BOX_INT); case INT -> cob.invokestatic(BoxHolder.BOX_INT);
case LongType -> cob.invokestatic(BoxHolder.BOX_LONG); case LONG -> cob.invokestatic(BoxHolder.BOX_LONG);
case ShortType -> cob.invokestatic(BoxHolder.BOX_SHORT); case SHORT -> cob.invokestatic(BoxHolder.BOX_SHORT);
} }
} }
static void unbox(CodeBuilder cob, TypeKind to) { static void unbox(CodeBuilder cob, TypeKind to) {
switch (to) { switch (to) {
case BooleanType -> cob.invokevirtual(BoxHolder.UNBOX_BOOLEAN); case BOOLEAN -> cob.invokevirtual(BoxHolder.UNBOX_BOOLEAN);
case ByteType -> cob.invokevirtual(BoxHolder.UNBOX_BYTE); case BYTE -> cob.invokevirtual(BoxHolder.UNBOX_BYTE);
case CharType -> cob.invokevirtual(BoxHolder.UNBOX_CHAR); case CHAR -> cob.invokevirtual(BoxHolder.UNBOX_CHAR);
case DoubleType -> cob.invokevirtual(BoxHolder.UNBOX_DOUBLE); case DOUBLE -> cob.invokevirtual(BoxHolder.UNBOX_DOUBLE);
case FloatType -> cob.invokevirtual(BoxHolder.UNBOX_FLOAT); case FLOAT -> cob.invokevirtual(BoxHolder.UNBOX_FLOAT);
case IntType -> cob.invokevirtual(BoxHolder.UNBOX_INT); case INT -> cob.invokevirtual(BoxHolder.UNBOX_INT);
case LongType -> cob.invokevirtual(BoxHolder.UNBOX_LONG); case LONG -> cob.invokevirtual(BoxHolder.UNBOX_LONG);
case ShortType -> cob.invokevirtual(BoxHolder.UNBOX_SHORT); case SHORT -> cob.invokevirtual(BoxHolder.UNBOX_SHORT);
} }
} }

View File

@ -50,124 +50,128 @@ public class BytecodeHelpers {
private BytecodeHelpers() { private BytecodeHelpers() {
} }
public static IllegalArgumentException cannotConvertException(TypeKind from, TypeKind to) {
return new IllegalArgumentException(String.format("convert %s -> %s", from, to));
}
public static Opcode loadOpcode(TypeKind tk, int slot) { public static Opcode loadOpcode(TypeKind tk, int slot) {
return switch (tk) { return switch (tk) {
case IntType, ShortType, ByteType, CharType, BooleanType -> switch (slot) { case INT, SHORT, BYTE, CHAR, BOOLEAN -> switch (slot) {
case 0 -> Opcode.ILOAD_0; case 0 -> Opcode.ILOAD_0;
case 1 -> Opcode.ILOAD_1; case 1 -> Opcode.ILOAD_1;
case 2 -> Opcode.ILOAD_2; case 2 -> Opcode.ILOAD_2;
case 3 -> Opcode.ILOAD_3; case 3 -> Opcode.ILOAD_3;
default -> (slot < 256) ? Opcode.ILOAD : Opcode.ILOAD_W; default -> (slot < 256) ? Opcode.ILOAD : Opcode.ILOAD_W;
}; };
case LongType -> switch (slot) { case LONG -> switch (slot) {
case 0 -> Opcode.LLOAD_0; case 0 -> Opcode.LLOAD_0;
case 1 -> Opcode.LLOAD_1; case 1 -> Opcode.LLOAD_1;
case 2 -> Opcode.LLOAD_2; case 2 -> Opcode.LLOAD_2;
case 3 -> Opcode.LLOAD_3; case 3 -> Opcode.LLOAD_3;
default -> (slot < 256) ? Opcode.LLOAD : Opcode.LLOAD_W; default -> (slot < 256) ? Opcode.LLOAD : Opcode.LLOAD_W;
}; };
case DoubleType -> switch (slot) { case DOUBLE -> switch (slot) {
case 0 -> Opcode.DLOAD_0; case 0 -> Opcode.DLOAD_0;
case 1 -> Opcode.DLOAD_1; case 1 -> Opcode.DLOAD_1;
case 2 -> Opcode.DLOAD_2; case 2 -> Opcode.DLOAD_2;
case 3 -> Opcode.DLOAD_3; case 3 -> Opcode.DLOAD_3;
default -> (slot < 256) ? Opcode.DLOAD : Opcode.DLOAD_W; default -> (slot < 256) ? Opcode.DLOAD : Opcode.DLOAD_W;
}; };
case FloatType -> switch (slot) { case FLOAT -> switch (slot) {
case 0 -> Opcode.FLOAD_0; case 0 -> Opcode.FLOAD_0;
case 1 -> Opcode.FLOAD_1; case 1 -> Opcode.FLOAD_1;
case 2 -> Opcode.FLOAD_2; case 2 -> Opcode.FLOAD_2;
case 3 -> Opcode.FLOAD_3; case 3 -> Opcode.FLOAD_3;
default -> (slot < 256) ? Opcode.FLOAD : Opcode.FLOAD_W; default -> (slot < 256) ? Opcode.FLOAD : Opcode.FLOAD_W;
}; };
case ReferenceType -> switch (slot) { case REFERENCE -> switch (slot) {
case 0 -> Opcode.ALOAD_0; case 0 -> Opcode.ALOAD_0;
case 1 -> Opcode.ALOAD_1; case 1 -> Opcode.ALOAD_1;
case 2 -> Opcode.ALOAD_2; case 2 -> Opcode.ALOAD_2;
case 3 -> Opcode.ALOAD_3; case 3 -> Opcode.ALOAD_3;
default -> (slot < 256) ? Opcode.ALOAD : Opcode.ALOAD_W; default -> (slot < 256) ? Opcode.ALOAD : Opcode.ALOAD_W;
}; };
case VoidType -> throw new IllegalArgumentException("void"); case VOID -> throw new IllegalArgumentException("void");
}; };
} }
public static Opcode storeOpcode(TypeKind tk, int slot) { public static Opcode storeOpcode(TypeKind tk, int slot) {
return switch (tk) { return switch (tk) {
case IntType, ShortType, ByteType, CharType, BooleanType -> switch (slot) { case INT, SHORT, BYTE, CHAR, BOOLEAN -> switch (slot) {
case 0 -> Opcode.ISTORE_0; case 0 -> Opcode.ISTORE_0;
case 1 -> Opcode.ISTORE_1; case 1 -> Opcode.ISTORE_1;
case 2 -> Opcode.ISTORE_2; case 2 -> Opcode.ISTORE_2;
case 3 -> Opcode.ISTORE_3; case 3 -> Opcode.ISTORE_3;
default -> (slot < 256) ? Opcode.ISTORE : Opcode.ISTORE_W; default -> (slot < 256) ? Opcode.ISTORE : Opcode.ISTORE_W;
}; };
case LongType -> switch (slot) { case LONG -> switch (slot) {
case 0 -> Opcode.LSTORE_0; case 0 -> Opcode.LSTORE_0;
case 1 -> Opcode.LSTORE_1; case 1 -> Opcode.LSTORE_1;
case 2 -> Opcode.LSTORE_2; case 2 -> Opcode.LSTORE_2;
case 3 -> Opcode.LSTORE_3; case 3 -> Opcode.LSTORE_3;
default -> (slot < 256) ? Opcode.LSTORE : Opcode.LSTORE_W; default -> (slot < 256) ? Opcode.LSTORE : Opcode.LSTORE_W;
}; };
case DoubleType -> switch (slot) { case DOUBLE -> switch (slot) {
case 0 -> Opcode.DSTORE_0; case 0 -> Opcode.DSTORE_0;
case 1 -> Opcode.DSTORE_1; case 1 -> Opcode.DSTORE_1;
case 2 -> Opcode.DSTORE_2; case 2 -> Opcode.DSTORE_2;
case 3 -> Opcode.DSTORE_3; case 3 -> Opcode.DSTORE_3;
default -> (slot < 256) ? Opcode.DSTORE : Opcode.DSTORE_W; default -> (slot < 256) ? Opcode.DSTORE : Opcode.DSTORE_W;
}; };
case FloatType -> switch (slot) { case FLOAT -> switch (slot) {
case 0 -> Opcode.FSTORE_0; case 0 -> Opcode.FSTORE_0;
case 1 -> Opcode.FSTORE_1; case 1 -> Opcode.FSTORE_1;
case 2 -> Opcode.FSTORE_2; case 2 -> Opcode.FSTORE_2;
case 3 -> Opcode.FSTORE_3; case 3 -> Opcode.FSTORE_3;
default -> (slot < 256) ? Opcode.FSTORE : Opcode.FSTORE_W; default -> (slot < 256) ? Opcode.FSTORE : Opcode.FSTORE_W;
}; };
case ReferenceType -> switch (slot) { case REFERENCE -> switch (slot) {
case 0 -> Opcode.ASTORE_0; case 0 -> Opcode.ASTORE_0;
case 1 -> Opcode.ASTORE_1; case 1 -> Opcode.ASTORE_1;
case 2 -> Opcode.ASTORE_2; case 2 -> Opcode.ASTORE_2;
case 3 -> Opcode.ASTORE_3; case 3 -> Opcode.ASTORE_3;
default -> (slot < 256) ? Opcode.ASTORE : Opcode.ASTORE_W; default -> (slot < 256) ? Opcode.ASTORE : Opcode.ASTORE_W;
}; };
case VoidType -> throw new IllegalArgumentException("void"); case VOID -> throw new IllegalArgumentException("void");
}; };
} }
public static Opcode returnOpcode(TypeKind tk) { public static Opcode returnOpcode(TypeKind tk) {
return switch (tk) { return switch (tk) {
case ByteType, ShortType, IntType, CharType, BooleanType -> Opcode.IRETURN; case BYTE, SHORT, INT, CHAR, BOOLEAN -> Opcode.IRETURN;
case FloatType -> Opcode.FRETURN; case FLOAT -> Opcode.FRETURN;
case LongType -> Opcode.LRETURN; case LONG -> Opcode.LRETURN;
case DoubleType -> Opcode.DRETURN; case DOUBLE -> Opcode.DRETURN;
case ReferenceType -> Opcode.ARETURN; case REFERENCE -> Opcode.ARETURN;
case VoidType -> Opcode.RETURN; case VOID -> Opcode.RETURN;
}; };
} }
public static Opcode arrayLoadOpcode(TypeKind tk) { public static Opcode arrayLoadOpcode(TypeKind tk) {
return switch (tk) { return switch (tk) {
case ByteType, BooleanType -> Opcode.BALOAD; case BYTE, BOOLEAN -> Opcode.BALOAD;
case ShortType -> Opcode.SALOAD; case SHORT -> Opcode.SALOAD;
case IntType -> Opcode.IALOAD; case INT -> Opcode.IALOAD;
case FloatType -> Opcode.FALOAD; case FLOAT -> Opcode.FALOAD;
case LongType -> Opcode.LALOAD; case LONG -> Opcode.LALOAD;
case DoubleType -> Opcode.DALOAD; case DOUBLE -> Opcode.DALOAD;
case ReferenceType -> Opcode.AALOAD; case REFERENCE -> Opcode.AALOAD;
case CharType -> Opcode.CALOAD; case CHAR -> Opcode.CALOAD;
case VoidType -> throw new IllegalArgumentException("void not an allowable array type"); case VOID -> throw new IllegalArgumentException("void not an allowable array type");
}; };
} }
public static Opcode arrayStoreOpcode(TypeKind tk) { public static Opcode arrayStoreOpcode(TypeKind tk) {
return switch (tk) { return switch (tk) {
case ByteType, BooleanType -> Opcode.BASTORE; case BYTE, BOOLEAN -> Opcode.BASTORE;
case ShortType -> Opcode.SASTORE; case SHORT -> Opcode.SASTORE;
case IntType -> Opcode.IASTORE; case INT -> Opcode.IASTORE;
case FloatType -> Opcode.FASTORE; case FLOAT -> Opcode.FASTORE;
case LongType -> Opcode.LASTORE; case LONG -> Opcode.LASTORE;
case DoubleType -> Opcode.DASTORE; case DOUBLE -> Opcode.DASTORE;
case ReferenceType -> Opcode.AASTORE; case REFERENCE -> Opcode.AASTORE;
case CharType -> Opcode.CASTORE; case CHAR -> Opcode.CASTORE;
case VoidType -> throw new IllegalArgumentException("void not an allowable array type"); case VOID -> throw new IllegalArgumentException("void not an allowable array type");
}; };
} }
@ -195,38 +199,38 @@ public class BytecodeHelpers {
public static Opcode convertOpcode(TypeKind from, TypeKind to) { public static Opcode convertOpcode(TypeKind from, TypeKind to) {
return switch (from) { return switch (from) {
case IntType -> case INT ->
switch (to) { switch (to) {
case LongType -> Opcode.I2L; case LONG -> Opcode.I2L;
case FloatType -> Opcode.I2F; case FLOAT -> Opcode.I2F;
case DoubleType -> Opcode.I2D; case DOUBLE -> Opcode.I2D;
case ByteType -> Opcode.I2B; case BYTE -> Opcode.I2B;
case CharType -> Opcode.I2C; case CHAR -> Opcode.I2C;
case ShortType -> Opcode.I2S; case SHORT -> Opcode.I2S;
default -> throw new IllegalArgumentException(String.format("convert %s -> %s", from, to)); default -> throw cannotConvertException(from, to);
}; };
case LongType -> case LONG ->
switch (to) { switch (to) {
case FloatType -> Opcode.L2F; case FLOAT -> Opcode.L2F;
case DoubleType -> Opcode.L2D; case DOUBLE -> Opcode.L2D;
case IntType -> Opcode.L2I; case INT -> Opcode.L2I;
default -> throw new IllegalArgumentException(String.format("convert %s -> %s", from, to)); default -> throw cannotConvertException(from, to);
}; };
case DoubleType -> case DOUBLE ->
switch (to) { switch (to) {
case FloatType -> Opcode.D2F; case FLOAT -> Opcode.D2F;
case LongType -> Opcode.D2L; case LONG -> Opcode.D2L;
case IntType -> Opcode.D2I; case INT -> Opcode.D2I;
default -> throw new IllegalArgumentException(String.format("convert %s -> %s", from, to)); default -> throw cannotConvertException(from, to);
}; };
case FloatType -> case FLOAT ->
switch (to) { switch (to) {
case LongType -> Opcode.F2L; case LONG -> Opcode.F2L;
case DoubleType -> Opcode.F2D; case DOUBLE -> Opcode.F2D;
case IntType -> Opcode.F2I; case INT -> Opcode.F2I;
default -> throw new IllegalArgumentException(String.format("convert %s -> %s", from, to)); default -> throw cannotConvertException(from, to);
}; };
default -> throw new IllegalArgumentException(String.format("convert %s -> %s", from, to)); default -> throw cannotConvertException(from, to);
}; };
} }

View File

@ -851,7 +851,7 @@ public final class ClassPrinterImpl {
"type", newo.className().name().stringValue())); "type", newo.className().name().stringValue()));
case NewPrimitiveArrayInstruction newa -> in.with(leafs( case NewPrimitiveArrayInstruction newa -> in.with(leafs(
"dimensions", 1, "dimensions", 1,
"descriptor", newa.typeKind().typeName())); "descriptor", newa.typeKind().upperBound().displayName()));
case NewReferenceArrayInstruction newa -> in.with(leafs( case NewReferenceArrayInstruction newa -> in.with(leafs(
"dimensions", 1, "dimensions", 1,
"descriptor", newa.componentType().name().stringValue())); "descriptor", newa.componentType().name().stringValue()));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -59,7 +59,7 @@ public final class CodeLocalsShifterImpl implements CodeLocalsShifter {
shift(cob, si.slot(), si.typeKind())); shift(cob, si.slot(), si.typeKind()));
case IncrementInstruction ii -> case IncrementInstruction ii ->
cob.iinc( cob.iinc(
shift(cob, ii.slot(), TypeKind.IntType), shift(cob, ii.slot(), TypeKind.INT),
ii.constant()); ii.constant());
case LocalVariable lv -> case LocalVariable lv ->
cob.localVariable( cob.localVariable(
@ -73,7 +73,7 @@ public final class CodeLocalsShifterImpl implements CodeLocalsShifter {
shift(cob, lvt.slot(), shift(cob, lvt.slot(),
(lvt.signatureSymbol() instanceof Signature.BaseTypeSig bsig) (lvt.signatureSymbol() instanceof Signature.BaseTypeSig bsig)
? TypeKind.fromDescriptor(bsig.signatureString()) ? TypeKind.fromDescriptor(bsig.signatureString())
: TypeKind.ReferenceType), : TypeKind.REFERENCE),
lvt.name(), lvt.name(),
lvt.signature(), lvt.signature(),
lvt.startScope(), lvt.startScope(),
@ -83,7 +83,7 @@ public final class CodeLocalsShifterImpl implements CodeLocalsShifter {
} }
private int shift(CodeBuilder cob, int slot, TypeKind tk) { private int shift(CodeBuilder cob, int slot, TypeKind tk) {
if (tk == TypeKind.VoidType) throw new IllegalArgumentException("Illegal local void type"); if (tk == TypeKind.VOID) throw new IllegalArgumentException("Illegal local void type");
if (slot >= fixed) { if (slot >= fixed) {
int key = 2*slot - fixed + tk.slotSize() - 1; int key = 2*slot - fixed + tk.slotSize() - 1;
if (key >= locals.length) locals = Arrays.copyOf(locals, key + 20); if (key >= locals.length) locals = Arrays.copyOf(locals, key + 20);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -146,7 +146,7 @@ public final class CodeStackTrackerImpl implements CodeStackTracker {
private void push(TypeKind type) { private void push(TypeKind type) {
if (stack != null) { if (stack != null) {
if (type != TypeKind.VoidType) stack.push(type); if (type != TypeKind.VOID) stack.push(type);
} else { } else {
maxSize = null; maxSize = null;
} }
@ -228,15 +228,15 @@ public final class CodeStackTrackerImpl implements CodeStackTracker {
case MonitorInstruction i -> case MonitorInstruction i ->
pop(1); pop(1);
case NewMultiArrayInstruction i -> { case NewMultiArrayInstruction i -> {
pop(i.dimensions());push(TypeKind.ReferenceType); pop(i.dimensions());push(TypeKind.REFERENCE);
} }
case NewObjectInstruction i -> case NewObjectInstruction i ->
push(TypeKind.ReferenceType); push(TypeKind.REFERENCE);
case NewPrimitiveArrayInstruction i -> { case NewPrimitiveArrayInstruction i -> {
pop(1);push(TypeKind.ReferenceType); pop(1);push(TypeKind.REFERENCE);
} }
case NewReferenceArrayInstruction i -> { case NewReferenceArrayInstruction i -> {
pop(1);push(TypeKind.ReferenceType); pop(1);push(TypeKind.REFERENCE);
} }
case NopInstruction i -> {} case NopInstruction i -> {}
case OperatorInstruction i -> { case OperatorInstruction i -> {
@ -329,15 +329,15 @@ public final class CodeStackTrackerImpl implements CodeStackTracker {
case TypeCheckInstruction i -> { case TypeCheckInstruction i -> {
switch (i.opcode()) { switch (i.opcode()) {
case CHECKCAST -> { case CHECKCAST -> {
pop(1);push(TypeKind.ReferenceType); pop(1);push(TypeKind.REFERENCE);
} }
case INSTANCEOF -> { case INSTANCEOF -> {
pop(1);push(TypeKind.IntType); pop(1);push(TypeKind.INT);
} }
} }
} }
case ExceptionCatch i -> case ExceptionCatch i ->
map.put(i.handler(), new Stack(new Item(TypeKind.ReferenceType, null), 1, 1)); map.put(i.handler(), new Stack(new Item(TypeKind.REFERENCE, null), 1, 1));
case LabelTarget i -> case LabelTarget i ->
stack = map.getOrDefault(i.label(), stack); stack = map.getOrDefault(i.label(), stack);
default -> {} default -> {}

View File

@ -1436,7 +1436,7 @@ public final class DirectCodeBuilder
public CodeBuilder newarray(TypeKind typeKind) { public CodeBuilder newarray(TypeKind typeKind) {
int atype = typeKind.newarrayCode(); // implicit null check int atype = typeKind.newarrayCode(); // implicit null check
if (atype < 0) if (atype < 0)
throw new IllegalArgumentException("Illegal component type: " + typeKind.typeName()); throw new IllegalArgumentException("Illegal component type: ".concat(typeKind.upperBound().displayName()));
writeNewPrimitiveArray(atype); writeNewPrimitiveArray(atype);
return this; return this;
} }

View File

@ -230,12 +230,12 @@ public record ParserVerifier(ClassModel classModel) {
ClassDesc type = ((FieldModel)ae).fieldTypeSymbol(); ClassDesc type = ((FieldModel)ae).fieldTypeSymbol();
ConstantValueEntry cve = cva.constant(); ConstantValueEntry cve = cva.constant();
if (!switch (TypeKind.from(type)) { if (!switch (TypeKind.from(type)) {
case BooleanType, ByteType, CharType, IntType, ShortType -> cve instanceof IntegerEntry; case BOOLEAN, BYTE, CHAR, INT, SHORT -> cve instanceof IntegerEntry;
case DoubleType -> cve instanceof DoubleEntry; case DOUBLE -> cve instanceof DoubleEntry;
case FloatType -> cve instanceof FloatEntry; case FLOAT -> cve instanceof FloatEntry;
case LongType -> cve instanceof LongEntry; case LONG -> cve instanceof LongEntry;
case ReferenceType -> type.equals(ConstantDescs.CD_String) && cve instanceof StringEntry; case REFERENCE -> type.equals(ConstantDescs.CD_String) && cve instanceof StringEntry;
case VoidType -> false; case VOID -> false;
}) { }) {
errors.add(new VerifyError("Bad constant value type in %s".formatted(toString(ae)))); errors.add(new VerifyError("Bad constant value type in %s".formatted(toString(ae))));
} }

View File

@ -273,10 +273,10 @@ public class BindingSpecializer {
int numScopes = 0; int numScopes = 0;
for (int i = 0; i < callerMethodType.parameterCount(); i++) { for (int i = 0; i < callerMethodType.parameterCount(); i++) {
if (shouldAcquire(i)) { if (shouldAcquire(i)) {
int scopeLocal = cb.allocateLocal(ReferenceType); int scopeLocal = cb.allocateLocal(REFERENCE);
initialScopeSlots[numScopes++] = scopeLocal; initialScopeSlots[numScopes++] = scopeLocal;
cb.loadConstant(null); cb.loadConstant(null);
cb.storeLocal(ReferenceType, scopeLocal); // need to initialize all scope locals here in case an exception occurs cb.storeLocal(REFERENCE, scopeLocal); // need to initialize all scope locals here in case an exception occurs
} }
} }
scopeSlots = Arrays.copyOf(initialScopeSlots, numScopes); // fit to size scopeSlots = Arrays.copyOf(initialScopeSlots, numScopes); // fit to size
@ -292,16 +292,16 @@ public class BindingSpecializer {
} else { } else {
cb.getstatic(CD_SharedUtils, "DUMMY_ARENA", CD_Arena); cb.getstatic(CD_SharedUtils, "DUMMY_ARENA", CD_Arena);
} }
contextIdx = cb.allocateLocal(ReferenceType); contextIdx = cb.allocateLocal(REFERENCE);
cb.storeLocal(ReferenceType, contextIdx); cb.storeLocal(REFERENCE, contextIdx);
// in case the call needs a return buffer, allocate it here. // in case the call needs a return buffer, allocate it here.
// for upcalls the VM wrapper stub allocates the buffer. // for upcalls the VM wrapper stub allocates the buffer.
if (callingSequence.needsReturnBuffer() && callingSequence.forDowncall()) { if (callingSequence.needsReturnBuffer() && callingSequence.forDowncall()) {
emitLoadInternalAllocator(); emitLoadInternalAllocator();
emitAllocateCall(callingSequence.returnBufferSize(), 1); emitAllocateCall(callingSequence.returnBufferSize(), 1);
returnBufferIdx = cb.allocateLocal(ReferenceType); returnBufferIdx = cb.allocateLocal(REFERENCE);
cb.storeLocal(ReferenceType, returnBufferIdx); cb.storeLocal(REFERENCE, returnBufferIdx);
} }
Label tryStart = cb.newLabel(); Label tryStart = cb.newLabel();
@ -324,7 +324,7 @@ public class BindingSpecializer {
// for downcalls, recipes have an input value, which we set up here // for downcalls, recipes have an input value, which we set up here
if (callingSequence.needsReturnBuffer() && i == 0) { if (callingSequence.needsReturnBuffer() && i == 0) {
assert returnBufferIdx != -1; assert returnBufferIdx != -1;
cb.loadLocal(ReferenceType, returnBufferIdx); cb.loadLocal(REFERENCE, returnBufferIdx);
pushType(MemorySegment.class); pushType(MemorySegment.class);
} else { } else {
emitGetInput(); emitGetInput();
@ -339,8 +339,8 @@ public class BindingSpecializer {
if (callingSequence.needsReturnBuffer() && i == 0) { if (callingSequence.needsReturnBuffer() && i == 0) {
// return buffer ptr is wrapped in a MemorySegment above, but not passed to the leaf handle // return buffer ptr is wrapped in a MemorySegment above, but not passed to the leaf handle
popType(MemorySegment.class); popType(MemorySegment.class);
returnBufferIdx = cb.allocateLocal(ReferenceType); returnBufferIdx = cb.allocateLocal(REFERENCE);
cb.storeLocal(ReferenceType, returnBufferIdx); cb.storeLocal(REFERENCE, returnBufferIdx);
} else { } else {
// for upcalls the recipe result is an argument to the leaf handle // for upcalls the recipe result is an argument to the leaf handle
emitSetOutput(typeStack.pop()); emitSetOutput(typeStack.pop());
@ -355,7 +355,7 @@ public class BindingSpecializer {
if (callingSequence.forDowncall()) { if (callingSequence.forDowncall()) {
cb.loadConstant(CLASS_DATA_DESC); cb.loadConstant(CLASS_DATA_DESC);
} else { } else {
cb.loadLocal(ReferenceType, 0); // load target arg cb.loadLocal(REFERENCE, 0); // load target arg
} }
cb.checkcast(CD_MethodHandle); cb.checkcast(CD_MethodHandle);
// load all the leaf args // load all the leaf args
@ -506,7 +506,7 @@ public class BindingSpecializer {
boolean hasOtherScopes = curScopeLocalIdx != 0; boolean hasOtherScopes = curScopeLocalIdx != 0;
for (int i = 0; i < curScopeLocalIdx; i++) { for (int i = 0; i < curScopeLocalIdx; i++) {
cb.dup(); // dup for comparison cb.dup(); // dup for comparison
cb.loadLocal(ReferenceType, scopeSlots[i]); cb.loadLocal(REFERENCE, scopeSlots[i]);
cb.if_acmpeq(skipAcquire); cb.if_acmpeq(skipAcquire);
} }
@ -515,7 +515,7 @@ public class BindingSpecializer {
int nextScopeLocal = scopeSlots[curScopeLocalIdx++]; int nextScopeLocal = scopeSlots[curScopeLocalIdx++];
// call acquire first here. So that if it fails, we don't call release // call acquire first here. So that if it fails, we don't call release
cb.invokevirtual(CD_MemorySessionImpl, "acquire0", MTD_ACQUIRE0); // call acquire on the other cb.invokevirtual(CD_MemorySessionImpl, "acquire0", MTD_ACQUIRE0); // call acquire on the other
cb.storeLocal(ReferenceType, nextScopeLocal); // store off one to release later cb.storeLocal(REFERENCE, nextScopeLocal); // store off one to release later
if (hasOtherScopes) { // avoid ASM generating a bunch of nops for the dead code if (hasOtherScopes) { // avoid ASM generating a bunch of nops for the dead code
cb.goto_(end); cb.goto_(end);
@ -529,9 +529,9 @@ public class BindingSpecializer {
private void emitReleaseScopes() { private void emitReleaseScopes() {
for (int scopeLocal : scopeSlots) { for (int scopeLocal : scopeSlots) {
cb.loadLocal(ReferenceType, scopeLocal); cb.loadLocal(REFERENCE, scopeLocal);
cb.ifThen(Opcode.IFNONNULL, ifCb -> { cb.ifThen(Opcode.IFNONNULL, ifCb -> {
ifCb.loadLocal(ReferenceType, scopeLocal); ifCb.loadLocal(REFERENCE, scopeLocal);
ifCb.invokevirtual(CD_MemorySessionImpl, "release0", MTD_RELEASE0); ifCb.invokevirtual(CD_MemorySessionImpl, "release0", MTD_RELEASE0);
}); });
} }
@ -551,7 +551,7 @@ public class BindingSpecializer {
private void emitLoadInternalSession() { private void emitLoadInternalSession() {
assert contextIdx != -1; assert contextIdx != -1;
cb.loadLocal(ReferenceType, contextIdx); cb.loadLocal(REFERENCE, contextIdx);
cb.checkcast(CD_Arena); cb.checkcast(CD_Arena);
cb.invokeinterface(CD_Arena, "scope", MTD_SCOPE); cb.invokeinterface(CD_Arena, "scope", MTD_SCOPE);
cb.checkcast(CD_MemorySessionImpl); cb.checkcast(CD_MemorySessionImpl);
@ -559,12 +559,12 @@ public class BindingSpecializer {
private void emitLoadInternalAllocator() { private void emitLoadInternalAllocator() {
assert contextIdx != -1; assert contextIdx != -1;
cb.loadLocal(ReferenceType, contextIdx); cb.loadLocal(REFERENCE, contextIdx);
} }
private void emitCloseContext() { private void emitCloseContext() {
assert contextIdx != -1; assert contextIdx != -1;
cb.loadLocal(ReferenceType, contextIdx); cb.loadLocal(REFERENCE, contextIdx);
cb.checkcast(CD_Arena); cb.checkcast(CD_Arena);
cb.invokeinterface(CD_Arena, "close", MTD_CLOSE); cb.invokeinterface(CD_Arena, "close", MTD_CLOSE);
} }
@ -585,7 +585,7 @@ public class BindingSpecializer {
private void emitAllocBuffer(Allocate binding) { private void emitAllocBuffer(Allocate binding) {
if (callingSequence.forDowncall()) { if (callingSequence.forDowncall()) {
assert returnAllocatorIdx != -1; assert returnAllocatorIdx != -1;
cb.loadLocal(ReferenceType, returnAllocatorIdx); cb.loadLocal(REFERENCE, returnAllocatorIdx);
} else { } else {
emitLoadInternalAllocator(); emitLoadInternalAllocator();
} }
@ -618,10 +618,10 @@ public class BindingSpecializer {
} else { } else {
assert storeType == long.class; // chunking only for int and long assert storeType == long.class; // chunking only for int and long
} }
int longValueIdx = cb.allocateLocal(LongType); int longValueIdx = cb.allocateLocal(LONG);
cb.storeLocal(LongType, longValueIdx); cb.storeLocal(LONG, longValueIdx);
int writeAddrIdx = cb.allocateLocal(ReferenceType); int writeAddrIdx = cb.allocateLocal(REFERENCE);
cb.storeLocal(ReferenceType, writeAddrIdx); cb.storeLocal(REFERENCE, writeAddrIdx);
int remaining = byteWidth; int remaining = byteWidth;
int chunkOffset = 0; int chunkOffset = 0;
@ -648,7 +648,7 @@ public class BindingSpecializer {
//int writeChunk = (int) (((0xFFFF_FFFFL << shiftAmount) & longValue) >>> shiftAmount); //int writeChunk = (int) (((0xFFFF_FFFFL << shiftAmount) & longValue) >>> shiftAmount);
int shiftAmount = chunkOffset * Byte.SIZE; int shiftAmount = chunkOffset * Byte.SIZE;
mask = mask << shiftAmount; mask = mask << shiftAmount;
cb.loadLocal(LongType, longValueIdx); cb.loadLocal(LONG, longValueIdx);
cb.loadConstant(mask); cb.loadConstant(mask);
cb.land(); cb.land();
if (shiftAmount != 0) { if (shiftAmount != 0) {
@ -662,7 +662,7 @@ public class BindingSpecializer {
// chunk done, now write it // chunk done, now write it
//writeAddress.set(JAVA_SHORT_UNALIGNED, offset, writeChunk); //writeAddress.set(JAVA_SHORT_UNALIGNED, offset, writeChunk);
cb.loadLocal(ReferenceType, writeAddrIdx); cb.loadLocal(REFERENCE, writeAddrIdx);
ClassDesc valueLayoutType = emitLoadLayoutConstant(chunkStoreType); ClassDesc valueLayoutType = emitLoadLayoutConstant(chunkStoreType);
long writeOffset = offset + SharedUtils.pickChunkOffset(chunkOffset, byteWidth, chunkSize); long writeOffset = offset + SharedUtils.pickChunkOffset(chunkOffset, byteWidth, chunkSize);
cb.loadConstant(writeOffset); cb.loadConstant(writeOffset);
@ -694,7 +694,7 @@ public class BindingSpecializer {
cb.storeLocal(storeTypeKind, valueIdx); // store away the stored value, need it later cb.storeLocal(storeTypeKind, valueIdx); // store away the stored value, need it later
assert returnBufferIdx != -1; assert returnBufferIdx != -1;
cb.loadLocal(ReferenceType, returnBufferIdx); cb.loadLocal(REFERENCE, returnBufferIdx);
ClassDesc valueLayoutType = emitLoadLayoutConstant(storeType); ClassDesc valueLayoutType = emitLoadLayoutConstant(storeType);
cb.loadConstant(retBufOffset); cb.loadConstant(retBufOffset);
cb.loadLocal(storeTypeKind, valueIdx); cb.loadLocal(storeTypeKind, valueIdx);
@ -714,7 +714,7 @@ public class BindingSpecializer {
emitRestoreReturnValue(loadType); emitRestoreReturnValue(loadType);
} else { } else {
assert returnBufferIdx != -1; assert returnBufferIdx != -1;
cb.loadLocal(ReferenceType, returnBufferIdx); cb.loadLocal(REFERENCE, returnBufferIdx);
ClassDesc valueLayoutType = emitLoadLayoutConstant(loadType); ClassDesc valueLayoutType = emitLoadLayoutConstant(loadType);
cb.loadConstant(retBufOffset); cb.loadConstant(retBufOffset);
MethodTypeDesc descriptor = MethodTypeDesc.of(classDesc(loadType), valueLayoutType, CD_long); MethodTypeDesc descriptor = MethodTypeDesc.of(classDesc(loadType), valueLayoutType, CD_long);
@ -814,12 +814,12 @@ public class BindingSpecializer {
cb.invokeinterface(CD_MemorySegment, "get", descriptor); cb.invokeinterface(CD_MemorySegment, "get", descriptor);
} else { } else {
// chunked // chunked
int readAddrIdx = cb.allocateLocal(ReferenceType); int readAddrIdx = cb.allocateLocal(REFERENCE);
cb.storeLocal(ReferenceType, readAddrIdx); cb.storeLocal(REFERENCE, readAddrIdx);
cb.loadConstant(0L); // result cb.loadConstant(0L); // result
int resultIdx = cb.allocateLocal(LongType); int resultIdx = cb.allocateLocal(LONG);
cb.storeLocal(LongType, resultIdx); cb.storeLocal(LONG, resultIdx);
int remaining = byteWidth; int remaining = byteWidth;
int chunkOffset = 0; int chunkOffset = 0;
@ -848,7 +848,7 @@ public class BindingSpecializer {
throw new IllegalStateException("Unexpected chunk size for chunked write: " + chunkSize); throw new IllegalStateException("Unexpected chunk size for chunked write: " + chunkSize);
} }
// read from segment // read from segment
cb.loadLocal(ReferenceType, readAddrIdx); cb.loadLocal(REFERENCE, readAddrIdx);
ClassDesc valueLayoutType = emitLoadLayoutConstant(chunkType); ClassDesc valueLayoutType = emitLoadLayoutConstant(chunkType);
MethodTypeDesc descriptor = MethodTypeDesc.of(classDesc(chunkType), valueLayoutType, CD_long); MethodTypeDesc descriptor = MethodTypeDesc.of(classDesc(chunkType), valueLayoutType, CD_long);
long readOffset = offset + SharedUtils.pickChunkOffset(chunkOffset, byteWidth, chunkSize); long readOffset = offset + SharedUtils.pickChunkOffset(chunkOffset, byteWidth, chunkSize);
@ -863,15 +863,15 @@ public class BindingSpecializer {
cb.lshl(); cb.lshl();
} }
// add to result // add to result
cb.loadLocal(LongType, resultIdx); cb.loadLocal(LONG, resultIdx);
cb.lor(); cb.lor();
cb.storeLocal(LongType, resultIdx); cb.storeLocal(LONG, resultIdx);
remaining -= chunkSize; remaining -= chunkSize;
chunkOffset += chunkSize; chunkOffset += chunkSize;
} while (remaining != 0); } while (remaining != 0);
cb.loadLocal(LongType, resultIdx); cb.loadLocal(LONG, resultIdx);
if (loadType == int.class) { if (loadType == int.class) {
cb.l2i(); cb.l2i();
} else { } else {
@ -897,13 +897,13 @@ public class BindingSpecializer {
emitLoadInternalAllocator(); emitLoadInternalAllocator();
emitAllocateCall(size, alignment); emitAllocateCall(size, alignment);
cb.dup(); cb.dup();
int storeIdx = cb.allocateLocal(ReferenceType); int storeIdx = cb.allocateLocal(REFERENCE);
cb.storeLocal(ReferenceType, storeIdx); cb.storeLocal(REFERENCE, storeIdx);
cb.loadConstant(0L); cb.loadConstant(0L);
cb.loadConstant(size); cb.loadConstant(size);
cb.invokestatic(CD_MemorySegment, "copy", MTD_COPY, true); cb.invokestatic(CD_MemorySegment, "copy", MTD_COPY, true);
cb.loadLocal(ReferenceType, storeIdx); cb.loadLocal(REFERENCE, storeIdx);
pushType(MemorySegment.class); pushType(MemorySegment.class);
} }
@ -982,11 +982,11 @@ public class BindingSpecializer {
private void emitConstZero(TypeKind kind) { private void emitConstZero(TypeKind kind) {
switch (kind) { switch (kind) {
case BooleanType, ByteType, ShortType, CharType, IntType -> cb.iconst_0(); case BOOLEAN, BYTE, SHORT, CHAR, INT -> cb.iconst_0();
case LongType -> cb.lconst_0(); case LONG -> cb.lconst_0();
case FloatType -> cb.fconst_0(); case FLOAT -> cb.fconst_0();
case DoubleType -> cb.dconst_0(); case DOUBLE -> cb.dconst_0();
case ReferenceType -> cb.aconst_null(); case REFERENCE -> cb.aconst_null();
} }
} }
} }

View File

@ -155,7 +155,7 @@ public class CodeWriter extends BasicWriter {
case NewObjectInstruction instr -> case NewObjectInstruction instr ->
printConstantPoolRef(instr.className()); printConstantPoolRef(instr.className());
case NewPrimitiveArrayInstruction instr -> case NewPrimitiveArrayInstruction instr ->
print(" " + instr.typeKind().typeName()); print(" " + instr.typeKind().upperBound().displayName());
case NewReferenceArrayInstruction instr -> case NewReferenceArrayInstruction instr ->
printConstantPoolRef(instr.componentType()); printConstantPoolRef(instr.componentType());
case TableSwitchInstruction instr -> { case TableSwitchInstruction instr -> {

View File

@ -1562,7 +1562,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
cob.aload(BUILDER_VAR) cob.aload(BUILDER_VAR)
.loadConstant(name) .loadConstant(name)
.loadConstant(hash.length) .loadConstant(hash.length)
.newarray(TypeKind.ByteType); .newarray(TypeKind.BYTE);
for (int i = 0; i < hash.length; i++) { for (int i = 0; i < hash.length; i++) {
cob.dup() // arrayref cob.dup() // arrayref
.loadConstant(i) .loadConstant(i)

View File

@ -85,10 +85,10 @@ class AdvancedTransformationsTest {
mb.transformCode(com, new CodeTransform() { mb.transformCode(com, new CodeTransform() {
@Override @Override
public void atStart(CodeBuilder builder) { public void atStart(CodeBuilder builder) {
builder.allocateLocal(TypeKind.ReferenceType); builder.allocateLocal(TypeKind.REFERENCE);
builder.allocateLocal(TypeKind.LongType); builder.allocateLocal(TypeKind.LONG);
builder.allocateLocal(TypeKind.IntType); builder.allocateLocal(TypeKind.INT);
builder.allocateLocal(TypeKind.DoubleType); builder.allocateLocal(TypeKind.DOUBLE);
} }
@Override @Override
public void accept(CodeBuilder builder, CodeElement element) { public void accept(CodeBuilder builder, CodeElement element) {
@ -324,7 +324,7 @@ class AdvancedTransformationsTest {
var storeStack = new ArrayDeque<StoreInstruction>(); var storeStack = new ArrayDeque<StoreInstruction>();
int slot = 0; int slot = 0;
if (!mm.flags().has(AccessFlag.STATIC)) if (!mm.flags().has(AccessFlag.STATIC))
storeStack.push(StoreInstruction.of(TypeKind.ReferenceType, slot++)); storeStack.push(StoreInstruction.of(TypeKind.REFERENCE, slot++));
for (var pt : mm.methodTypeSymbol().parameterList()) { for (var pt : mm.methodTypeSymbol().parameterList()) {
var tk = TypeKind.from(pt); var tk = TypeKind.from(pt);
storeStack.push(StoreInstruction.of(tk, slot)); storeStack.push(StoreInstruction.of(tk, slot));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -88,7 +88,7 @@ class ArrayTest {
case 4: { case 4: {
NewPrimitiveArrayInstruction nai = (NewPrimitiveArrayInstruction) im; NewPrimitiveArrayInstruction nai = (NewPrimitiveArrayInstruction) im;
assertEquals(nai.opcode(), Opcode.NEWARRAY); assertEquals(nai.opcode(), Opcode.NEWARRAY);
assertEquals(nai.typeKind(), TypeKind.DoubleType); assertEquals(nai.typeKind(), TypeKind.DOUBLE);
break; break;
} }
} }

View File

@ -259,9 +259,9 @@ class BuilderBlockTest {
ClassFile.of().build(ClassDesc.of("Foo"), cb -> { ClassFile.of().build(ClassDesc.of("Foo"), cb -> {
cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), ClassFile.ACC_STATIC, cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), ClassFile.ACC_STATIC,
mb -> mb.withCode(xb -> { mb -> mb.withCode(xb -> {
int slot1 = xb.allocateLocal(TypeKind.IntType); int slot1 = xb.allocateLocal(TypeKind.INT);
int slot2 = xb.allocateLocal(TypeKind.LongType); int slot2 = xb.allocateLocal(TypeKind.LONG);
int slot3 = xb.allocateLocal(TypeKind.IntType); int slot3 = xb.allocateLocal(TypeKind.INT);
assertEquals(slot1, 4); assertEquals(slot1, 4);
assertEquals(slot2, 5); assertEquals(slot2, 5);
@ -277,15 +277,15 @@ class BuilderBlockTest {
cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), ClassFile.ACC_STATIC, cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), ClassFile.ACC_STATIC,
mb -> mb.withCode(xb -> { mb -> mb.withCode(xb -> {
xb.block(bb -> { xb.block(bb -> {
int slot1 = bb.allocateLocal(TypeKind.IntType); int slot1 = bb.allocateLocal(TypeKind.INT);
int slot2 = bb.allocateLocal(TypeKind.LongType); int slot2 = bb.allocateLocal(TypeKind.LONG);
int slot3 = bb.allocateLocal(TypeKind.IntType); int slot3 = bb.allocateLocal(TypeKind.INT);
assertEquals(slot1, 4); assertEquals(slot1, 4);
assertEquals(slot2, 5); assertEquals(slot2, 5);
assertEquals(slot3, 7); assertEquals(slot3, 7);
}); });
int slot4 = xb.allocateLocal(TypeKind.IntType); int slot4 = xb.allocateLocal(TypeKind.INT);
assertEquals(slot4, 4); assertEquals(slot4, 4);
xb.return_(); xb.return_();
})); }));
@ -299,20 +299,20 @@ class BuilderBlockTest {
mb -> mb.withCode(xb -> { mb -> mb.withCode(xb -> {
xb.iconst_0(); xb.iconst_0();
xb.ifThenElse(bb -> { xb.ifThenElse(bb -> {
int slot1 = bb.allocateLocal(TypeKind.IntType); int slot1 = bb.allocateLocal(TypeKind.INT);
int slot2 = bb.allocateLocal(TypeKind.LongType); int slot2 = bb.allocateLocal(TypeKind.LONG);
int slot3 = bb.allocateLocal(TypeKind.IntType); int slot3 = bb.allocateLocal(TypeKind.INT);
assertEquals(slot1, 4); assertEquals(slot1, 4);
assertEquals(slot2, 5); assertEquals(slot2, 5);
assertEquals(slot3, 7); assertEquals(slot3, 7);
}, },
bb -> { bb -> {
int slot1 = bb.allocateLocal(TypeKind.IntType); int slot1 = bb.allocateLocal(TypeKind.INT);
assertEquals(slot1, 4); assertEquals(slot1, 4);
}); });
int slot4 = xb.allocateLocal(TypeKind.IntType); int slot4 = xb.allocateLocal(TypeKind.INT);
assertEquals(slot4, 4); assertEquals(slot4, 4);
xb.return_(); xb.return_();
})); }));
@ -335,7 +335,7 @@ class BuilderBlockTest {
&& se.utf8().equalsString("Output")) { && se.utf8().equalsString("Output")) {
assertFalse(foundItem); assertFalse(foundItem);
foundItem = true; foundItem = true;
var i = cob.allocateLocal(TypeKind.IntType); var i = cob.allocateLocal(TypeKind.INT);
assertEquals(7, i, "Allocated new int slot"); assertEquals(7, i, "Allocated new int slot");
} }
} }
@ -373,8 +373,8 @@ class BuilderBlockTest {
ClassTransform bufferingTransform = (clb, cle) -> { ClassTransform bufferingTransform = (clb, cle) -> {
if (cle instanceof MethodModel mm && mm.methodName().equalsString("work")) { if (cle instanceof MethodModel mm && mm.methodName().equalsString("work")) {
clb.withMethodBody(mm.methodName(), mm.methodType(), mm.flags().flagsMask(), cob -> { clb.withMethodBody(mm.methodName(), mm.methodType(), mm.flags().flagsMask(), cob -> {
int d = cob.allocateLocal(TypeKind.IntType); int d = cob.allocateLocal(TypeKind.INT);
int e = cob.allocateLocal(TypeKind.IntType); int e = cob.allocateLocal(TypeKind.INT);
assertEquals(5, d); assertEquals(5, d);
assertEquals(6, e); assertEquals(6, e);

View File

@ -187,7 +187,7 @@ class BuilderTryCatchTest {
cb.withMethod("main", MethodTypeDesc.of(CD_String, CD_String.arrayType()), cb.withMethod("main", MethodTypeDesc.of(CD_String, CD_String.arrayType()),
ACC_PUBLIC | ACC_STATIC, mb -> { ACC_PUBLIC | ACC_STATIC, mb -> {
mb.withCode(xb -> { mb.withCode(xb -> {
int stringSlot = xb.allocateLocal(TypeKind.ReferenceType); int stringSlot = xb.allocateLocal(TypeKind.REFERENCE);
xb.loadConstant("S"); xb.loadConstant("S");
xb.astore(stringSlot); xb.astore(stringSlot);
@ -218,12 +218,12 @@ class BuilderTryCatchTest {
cb.withMethod("main", MethodTypeDesc.of(CD_String, CD_String.arrayType()), cb.withMethod("main", MethodTypeDesc.of(CD_String, CD_String.arrayType()),
ACC_PUBLIC | ACC_STATIC, mb -> { ACC_PUBLIC | ACC_STATIC, mb -> {
mb.withCode(xb -> { mb.withCode(xb -> {
int stringSlot = xb.allocateLocal(TypeKind.ReferenceType); int stringSlot = xb.allocateLocal(TypeKind.REFERENCE);
xb.loadConstant("S"); xb.loadConstant("S");
xb.astore(stringSlot); xb.astore(stringSlot);
xb.trying(tb -> { xb.trying(tb -> {
int intSlot = tb.allocateLocal(TypeKind.IntType); int intSlot = tb.allocateLocal(TypeKind.INT);
tb.aload(0); tb.aload(0);
tb.loadConstant(0); tb.loadConstant(0);
@ -240,7 +240,7 @@ class BuilderTryCatchTest {
catchBuilder.catching(CD_IOOBE, tb -> { catchBuilder.catching(CD_IOOBE, tb -> {
tb.pop(); tb.pop();
int doubleSlot = tb.allocateLocal(TypeKind.DoubleType); int doubleSlot = tb.allocateLocal(TypeKind.DOUBLE);
tb.loadConstant(Math.PI); tb.loadConstant(Math.PI);
tb.dstore(doubleSlot); tb.dstore(doubleSlot);
@ -250,7 +250,7 @@ class BuilderTryCatchTest {
}).catchingAll(tb -> { }).catchingAll(tb -> {
tb.pop(); tb.pop();
int refSlot = tb.allocateLocal(TypeKind.ReferenceType); int refSlot = tb.allocateLocal(TypeKind.REFERENCE);
tb.loadConstant("REF"); tb.loadConstant("REF");
tb.astore(refSlot); tb.astore(refSlot);
@ -281,7 +281,7 @@ class BuilderTryCatchTest {
cb.withMethod("main", MethodTypeDesc.of(CD_String, CD_String.arrayType()), cb.withMethod("main", MethodTypeDesc.of(CD_String, CD_String.arrayType()),
ACC_PUBLIC | ACC_STATIC, mb -> { ACC_PUBLIC | ACC_STATIC, mb -> {
mb.withCode(xb -> { mb.withCode(xb -> {
int stringSlot = xb.allocateLocal(TypeKind.ReferenceType); int stringSlot = xb.allocateLocal(TypeKind.REFERENCE);
xb.loadConstant("S"); xb.loadConstant("S");
xb.astore(stringSlot); xb.astore(stringSlot);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -45,29 +45,29 @@ class StackTrackerTest {
void testStackTracker() { void testStackTracker() {
ClassFile.of().build(ClassDesc.of("Foo"), clb -> ClassFile.of().build(ClassDesc.of("Foo"), clb ->
clb.withMethodBody("m", MethodTypeDesc.of(ConstantDescs.CD_Void), 0, cob -> { clb.withMethodBody("m", MethodTypeDesc.of(ConstantDescs.CD_Void), 0, cob -> {
var stackTracker = CodeStackTracker.of(DoubleType, FloatType); //initial stack tracker pre-set var stackTracker = CodeStackTracker.of(DOUBLE, FLOAT); //initial stack tracker pre-set
cob.transforming(stackTracker, stcb -> { cob.transforming(stackTracker, stcb -> {
assertIterableEquals(stackTracker.stack().get(), List.of(DoubleType, FloatType)); assertIterableEquals(stackTracker.stack().get(), List.of(DOUBLE, FLOAT));
stcb.aload(0); stcb.aload(0);
assertIterableEquals(stackTracker.stack().get(), List.of(ReferenceType, DoubleType, FloatType)); assertIterableEquals(stackTracker.stack().get(), List.of(REFERENCE, DOUBLE, FLOAT));
stcb.lconst_0(); stcb.lconst_0();
assertIterableEquals(stackTracker.stack().get(), List.of(LongType, ReferenceType, DoubleType, FloatType)); assertIterableEquals(stackTracker.stack().get(), List.of(LONG, REFERENCE, DOUBLE, FLOAT));
stcb.trying(tryb -> { stcb.trying(tryb -> {
assertIterableEquals(stackTracker.stack().get(), List.of(LongType, ReferenceType, DoubleType, FloatType)); assertIterableEquals(stackTracker.stack().get(), List.of(LONG, REFERENCE, DOUBLE, FLOAT));
tryb.iconst_1(); tryb.iconst_1();
assertIterableEquals(stackTracker.stack().get(), List.of(IntType, LongType, ReferenceType, DoubleType, FloatType)); assertIterableEquals(stackTracker.stack().get(), List.of(INT, LONG, REFERENCE, DOUBLE, FLOAT));
tryb.ifThen(thb -> { tryb.ifThen(thb -> {
assertIterableEquals(stackTracker.stack().get(), List.of(LongType, ReferenceType, DoubleType, FloatType)); assertIterableEquals(stackTracker.stack().get(), List.of(LONG, REFERENCE, DOUBLE, FLOAT));
thb.loadConstant(ClassDesc.of("Phee")); thb.loadConstant(ClassDesc.of("Phee"));
assertIterableEquals(stackTracker.stack().get(), List.of(ReferenceType, LongType, ReferenceType, DoubleType, FloatType)); assertIterableEquals(stackTracker.stack().get(), List.of(REFERENCE, LONG, REFERENCE, DOUBLE, FLOAT));
thb.athrow(); thb.athrow();
assertFalse(stackTracker.stack().isPresent()); assertFalse(stackTracker.stack().isPresent());
}); });
assertIterableEquals(stackTracker.stack().get(), List.of(LongType, ReferenceType, DoubleType, FloatType)); assertIterableEquals(stackTracker.stack().get(), List.of(LONG, REFERENCE, DOUBLE, FLOAT));
tryb.return_(); tryb.return_();
assertFalse(stackTracker.stack().isPresent()); assertFalse(stackTracker.stack().isPresent());
}, catchb -> catchb.catching(ClassDesc.of("Phee"), cb -> { }, catchb -> catchb.catching(ClassDesc.of("Phee"), cb -> {
assertIterableEquals(stackTracker.stack().get(), List.of(ReferenceType)); assertIterableEquals(stackTracker.stack().get(), List.of(REFERENCE));
cb.athrow(); cb.athrow();
assertFalse(stackTracker.stack().isPresent()); assertFalse(stackTracker.stack().isPresent());
})); }));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -38,8 +38,6 @@ import static helpers.TestConstants.MTD_VOID;
import static java.lang.constant.ConstantDescs.CD_Object; import static java.lang.constant.ConstantDescs.CD_Object;
import static java.lang.constant.ConstantDescs.CD_void; import static java.lang.constant.ConstantDescs.CD_void;
import java.lang.constant.MethodTypeDesc; import java.lang.constant.MethodTypeDesc;
import static java.lang.classfile.Opcode.INVOKESPECIAL;
import static java.lang.classfile.TypeKind.VoidType;
class TempConstantPoolBuilderTest { class TempConstantPoolBuilderTest {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -47,7 +47,6 @@ import java.util.stream.Stream;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import static java.lang.constant.ConstantDescs.CD_void; import static java.lang.constant.ConstantDescs.CD_void;
import static java.lang.classfile.TypeKind.VoidType;
class Utf8EntryTest { class Utf8EntryTest {

View File

@ -520,7 +520,7 @@ public record ClassRecord(
yield new ConstantPoolEntryRecord.CpClassRecord("[" + type).hashCode() + 1; yield new ConstantPoolEntryRecord.CpClassRecord("[" + type).hashCode() + 1;
} }
case NewPrimitiveArrayInstruction cins -> case NewPrimitiveArrayInstruction cins ->
new ConstantPoolEntryRecord.CpClassRecord("[" + cins.typeKind().descriptor()).hashCode() + 1; new ConstantPoolEntryRecord.CpClassRecord("[" + cins.typeKind().upperBound().descriptorString()).hashCode() + 1;
case TypeCheckInstruction cins -> case TypeCheckInstruction cins ->
ConstantPoolEntryRecord.ofCPEntry(cins.type()).hashCode(); ConstantPoolEntryRecord.ofCPEntry(cins.type()).hashCode();
case ConstantInstruction.LoadConstantInstruction cins -> { case ConstantInstruction.LoadConstantInstruction cins -> {

View File

@ -219,27 +219,27 @@ class RebuildingTransformation {
switch (coe) { switch (coe) {
case ArrayLoadInstruction i -> { case ArrayLoadInstruction i -> {
switch (i.typeKind()) { switch (i.typeKind()) {
case ByteType -> cob.baload(); case BYTE -> cob.baload();
case ShortType -> cob.saload(); case SHORT -> cob.saload();
case IntType -> cob.iaload(); case INT -> cob.iaload();
case FloatType -> cob.faload(); case FLOAT -> cob.faload();
case LongType -> cob.laload(); case LONG -> cob.laload();
case DoubleType -> cob.daload(); case DOUBLE -> cob.daload();
case ReferenceType -> cob.aaload(); case REFERENCE -> cob.aaload();
case CharType -> cob.caload(); case CHAR -> cob.caload();
default -> throw new AssertionError("Should not reach here"); default -> throw new AssertionError("Should not reach here");
} }
} }
case ArrayStoreInstruction i -> { case ArrayStoreInstruction i -> {
switch (i.typeKind()) { switch (i.typeKind()) {
case ByteType -> cob.bastore(); case BYTE -> cob.bastore();
case ShortType -> cob.sastore(); case SHORT -> cob.sastore();
case IntType -> cob.iastore(); case INT -> cob.iastore();
case FloatType -> cob.fastore(); case FLOAT -> cob.fastore();
case LongType -> cob.lastore(); case LONG -> cob.lastore();
case DoubleType -> cob.dastore(); case DOUBLE -> cob.dastore();
case ReferenceType -> cob.aastore(); case REFERENCE -> cob.aastore();
case CharType -> cob.castore(); case CHAR -> cob.castore();
default -> throw new AssertionError("Should not reach here"); default -> throw new AssertionError("Should not reach here");
} }
} }
@ -304,38 +304,38 @@ class RebuildingTransformation {
} }
case ConvertInstruction i -> { case ConvertInstruction i -> {
switch (i.fromType()) { switch (i.fromType()) {
case DoubleType -> { case DOUBLE -> {
switch (i.toType()) { switch (i.toType()) {
case FloatType -> cob.d2f(); case FLOAT -> cob.d2f();
case IntType -> cob.d2i(); case INT -> cob.d2i();
case LongType -> cob.d2l(); case LONG -> cob.d2l();
default -> throw new AssertionError("Should not reach here"); default -> throw new AssertionError("Should not reach here");
} }
} }
case FloatType -> { case FLOAT -> {
switch (i.toType()) { switch (i.toType()) {
case DoubleType -> cob.f2d(); case DOUBLE -> cob.f2d();
case IntType -> cob.f2i(); case INT -> cob.f2i();
case LongType -> cob.f2l(); case LONG -> cob.f2l();
default -> throw new AssertionError("Should not reach here"); default -> throw new AssertionError("Should not reach here");
} }
} }
case IntType -> { case INT -> {
switch (i.toType()) { switch (i.toType()) {
case ByteType -> cob.i2b(); case BYTE -> cob.i2b();
case CharType -> cob.i2c(); case CHAR -> cob.i2c();
case DoubleType -> cob.i2d(); case DOUBLE -> cob.i2d();
case FloatType -> cob.i2f(); case FLOAT -> cob.i2f();
case LongType -> cob.i2l(); case LONG -> cob.i2l();
case ShortType -> cob.i2s(); case SHORT -> cob.i2s();
default -> throw new AssertionError("Should not reach here"); default -> throw new AssertionError("Should not reach here");
} }
} }
case LongType -> { case LONG -> {
switch (i.toType()) { switch (i.toType()) {
case DoubleType -> cob.l2d(); case DOUBLE -> cob.l2d();
case FloatType -> cob.l2f(); case FLOAT -> cob.l2f();
case IntType -> cob.l2i(); case INT -> cob.l2i();
default -> throw new AssertionError("Should not reach here"); default -> throw new AssertionError("Should not reach here");
} }
} }
@ -410,21 +410,21 @@ class RebuildingTransformation {
} }
case LoadInstruction i -> { case LoadInstruction i -> {
switch (i.typeKind()) { switch (i.typeKind()) {
case IntType -> cob.iload(i.slot()); case INT -> cob.iload(i.slot());
case FloatType -> cob.fload(i.slot()); case FLOAT -> cob.fload(i.slot());
case LongType -> cob.lload(i.slot()); case LONG -> cob.lload(i.slot());
case DoubleType -> cob.dload(i.slot()); case DOUBLE -> cob.dload(i.slot());
case ReferenceType -> cob.aload(i.slot()); case REFERENCE -> cob.aload(i.slot());
default -> throw new AssertionError("Should not reach here"); default -> throw new AssertionError("Should not reach here");
} }
} }
case StoreInstruction i -> { case StoreInstruction i -> {
switch (i.typeKind()) { switch (i.typeKind()) {
case IntType -> cob.istore(i.slot()); case INT -> cob.istore(i.slot());
case FloatType -> cob.fstore(i.slot()); case FLOAT -> cob.fstore(i.slot());
case LongType -> cob.lstore(i.slot()); case LONG -> cob.lstore(i.slot());
case DoubleType -> cob.dstore(i.slot()); case DOUBLE -> cob.dstore(i.slot());
case ReferenceType -> cob.astore(i.slot()); case REFERENCE -> cob.astore(i.slot());
default -> throw new AssertionError("Should not reach here"); default -> throw new AssertionError("Should not reach here");
} }
} }
@ -515,12 +515,12 @@ class RebuildingTransformation {
} }
case ReturnInstruction i -> { case ReturnInstruction i -> {
switch (i.typeKind()) { switch (i.typeKind()) {
case IntType -> cob.ireturn(); case INT -> cob.ireturn();
case FloatType -> cob.freturn(); case FLOAT -> cob.freturn();
case LongType -> cob.lreturn(); case LONG -> cob.lreturn();
case DoubleType -> cob.dreturn(); case DOUBLE -> cob.dreturn();
case ReferenceType -> cob.areturn(); case REFERENCE -> cob.areturn();
case VoidType -> cob.return_(); case VOID -> cob.return_();
default -> throw new AssertionError("Should not reach here"); default -> throw new AssertionError("Should not reach here");
} }
} }

View File

@ -24,7 +24,6 @@ package org.openjdk.bench.jdk.classfile;
import java.lang.reflect.AccessFlag; import java.lang.reflect.AccessFlag;
import java.lang.classfile.ClassFile; import java.lang.classfile.ClassFile;
import java.lang.classfile.TypeKind;
import java.lang.classfile.attribute.SourceFileAttribute; import java.lang.classfile.attribute.SourceFileAttribute;
import jdk.internal.org.objectweb.asm.*; import jdk.internal.org.objectweb.asm.*;
import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.annotations.*;
@ -142,9 +141,9 @@ public class Write {
cb.withVersion(52, 0); cb.withVersion(52, 0);
cb.with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java")))) cb.with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java"))))
.withMethod(INIT_NAME, MTD_void, 0, mb -> mb .withMethod(INIT_NAME, MTD_void, 0, mb -> mb
.withCode(codeb -> codeb.loadLocal(TypeKind.ReferenceType, 0) .withCode(codeb -> codeb.loadLocal(REFERENCE, 0)
.invoke(INVOKESPECIAL, CD_Object, INIT_NAME, MTD_void, false) .invoke(INVOKESPECIAL, CD_Object, INIT_NAME, MTD_void, false)
.return_(VoidType) .return_(VOID)
) )
); );
for (int xi = 0; xi < 40; ++xi) { for (int xi = 0; xi < 40; ++xi) {
@ -190,7 +189,7 @@ public class Write {
cb.withVersion(52, 0); cb.withVersion(52, 0);
cb.with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java")))) cb.with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java"))))
.withMethod(INIT_NAME, MTD_void, 0, .withMethod(INIT_NAME, MTD_void, 0,
mb -> mb.withCode(codeb -> codeb.loadLocal(ReferenceType, 0) mb -> mb.withCode(codeb -> codeb.loadLocal(REFERENCE, 0)
.invokespecial(CD_Object, INIT_NAME, MTD_void, false) .invokespecial(CD_Object, INIT_NAME, MTD_void, false)
.return_() .return_()
) )