diff --git a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java index 75413011731..be0778d1984 100644 --- a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java @@ -262,7 +262,7 @@ public sealed interface CodeBuilder */ default CodeBuilder ifThen(Opcode opcode, Consumer thenHandler) { - if (opcode.kind() != Opcode.Kind.BRANCH || opcode.primaryTypeKind() == TypeKind.VOID) { + if (opcode.kind() != Opcode.Kind.BRANCH || BytecodeHelpers.isUnconditionalBranch(opcode)) { throw new IllegalArgumentException("Illegal branch opcode: " + opcode); } @@ -312,7 +312,7 @@ public sealed interface CodeBuilder default CodeBuilder ifThenElse(Opcode opcode, Consumer thenHandler, Consumer elseHandler) { - if (opcode.kind() != Opcode.Kind.BRANCH || opcode.primaryTypeKind() == TypeKind.VOID) { + if (opcode.kind() != Opcode.Kind.BRANCH || BytecodeHelpers.isUnconditionalBranch(opcode)) { throw new IllegalArgumentException("Illegal branch opcode: " + opcode); } diff --git a/src/java.base/share/classes/java/lang/classfile/Opcode.java b/src/java.base/share/classes/java/lang/classfile/Opcode.java index 9e4c35276cf..ab991d98345 100644 --- a/src/java.base/share/classes/java/lang/classfile/Opcode.java +++ b/src/java.base/share/classes/java/lang/classfile/Opcode.java @@ -24,8 +24,6 @@ */ package java.lang.classfile; -import java.lang.constant.ConstantDesc; -import java.lang.constant.ConstantDescs; import jdk.internal.javac.PreviewFeature; /** @@ -45,55 +43,55 @@ public enum Opcode { NOP(ClassFile.NOP, 1, Kind.NOP), /** Push null */ - ACONST_NULL(ClassFile.ACONST_NULL, 1, Kind.CONSTANT, TypeKind.REFERENCE, 0, ConstantDescs.NULL), + ACONST_NULL(ClassFile.ACONST_NULL, 1, Kind.CONSTANT), /** Push int constant -1 */ - ICONST_M1(ClassFile.ICONST_M1, 1, Kind.CONSTANT, TypeKind.INT, 0, -1), + ICONST_M1(ClassFile.ICONST_M1, 1, Kind.CONSTANT), /** Push int constant 0 */ - ICONST_0(ClassFile.ICONST_0, 1, Kind.CONSTANT, TypeKind.INT, 0, 0), + ICONST_0(ClassFile.ICONST_0, 1, Kind.CONSTANT), /** Push int constant 1 */ - ICONST_1(ClassFile.ICONST_1, 1, Kind.CONSTANT, TypeKind.INT, 0, 1), + ICONST_1(ClassFile.ICONST_1, 1, Kind.CONSTANT), /** Push int constant 2 */ - ICONST_2(ClassFile.ICONST_2, 1, Kind.CONSTANT, TypeKind.INT, 0, 2), + ICONST_2(ClassFile.ICONST_2, 1, Kind.CONSTANT), /** Push int constant 3 */ - ICONST_3(ClassFile.ICONST_3, 1, Kind.CONSTANT, TypeKind.INT, 0, 3), + ICONST_3(ClassFile.ICONST_3, 1, Kind.CONSTANT), /** Push int constant 4 */ - ICONST_4(ClassFile.ICONST_4, 1, Kind.CONSTANT, TypeKind.INT, 0, 4), + ICONST_4(ClassFile.ICONST_4, 1, Kind.CONSTANT), /** Push int constant 5 */ - ICONST_5(ClassFile.ICONST_5, 1, Kind.CONSTANT, TypeKind.INT, 0, 5), + ICONST_5(ClassFile.ICONST_5, 1, Kind.CONSTANT), /** Push long constant 0 */ - LCONST_0(ClassFile.LCONST_0, 1, Kind.CONSTANT, TypeKind.LONG, 0, 0L), + LCONST_0(ClassFile.LCONST_0, 1, Kind.CONSTANT), /** Push long constant 1 */ - LCONST_1(ClassFile.LCONST_1, 1, Kind.CONSTANT, TypeKind.LONG, 0, 1L), + LCONST_1(ClassFile.LCONST_1, 1, Kind.CONSTANT), /** Push float constant 0 */ - FCONST_0(ClassFile.FCONST_0, 1, Kind.CONSTANT, TypeKind.FLOAT, 0, 0.0f), + FCONST_0(ClassFile.FCONST_0, 1, Kind.CONSTANT), /** Push float constant 1 */ - FCONST_1(ClassFile.FCONST_1, 1, Kind.CONSTANT, TypeKind.FLOAT, 0, 1.0f), + FCONST_1(ClassFile.FCONST_1, 1, Kind.CONSTANT), /** Push float constant 2 */ - FCONST_2(ClassFile.FCONST_2, 1, Kind.CONSTANT, TypeKind.FLOAT, 0, 2.0f), + FCONST_2(ClassFile.FCONST_2, 1, Kind.CONSTANT), /** Push double constant 0 */ - DCONST_0(ClassFile.DCONST_0, 1, Kind.CONSTANT, TypeKind.DOUBLE, 0, 0.0d), + DCONST_0(ClassFile.DCONST_0, 1, Kind.CONSTANT), /** Push double constant 1 */ - DCONST_1(ClassFile.DCONST_1, 1, Kind.CONSTANT, TypeKind.DOUBLE, 0, 1.0d), + DCONST_1(ClassFile.DCONST_1, 1, Kind.CONSTANT), /** Push byte */ - BIPUSH(ClassFile.BIPUSH, 2, Kind.CONSTANT, TypeKind.BYTE), + BIPUSH(ClassFile.BIPUSH, 2, Kind.CONSTANT), /** Push short */ - SIPUSH(ClassFile.SIPUSH, 3, Kind.CONSTANT, TypeKind.SHORT), + SIPUSH(ClassFile.SIPUSH, 3, Kind.CONSTANT), /** Push item from run-time constant pool */ LDC(ClassFile.LDC, 2, Kind.CONSTANT), @@ -105,202 +103,202 @@ public enum Opcode { LDC2_W(ClassFile.LDC2_W, 3, Kind.CONSTANT), /** Load int from local variable */ - ILOAD(ClassFile.ILOAD, 2, Kind.LOAD, TypeKind.INT, -1), + ILOAD(ClassFile.ILOAD, 2, Kind.LOAD), /** Load long from local variable */ - LLOAD(ClassFile.LLOAD, 2, Kind.LOAD, TypeKind.LONG, -1), + LLOAD(ClassFile.LLOAD, 2, Kind.LOAD), /** Load float from local variable */ - FLOAD(ClassFile.FLOAD, 2, Kind.LOAD, TypeKind.FLOAT, -1), + FLOAD(ClassFile.FLOAD, 2, Kind.LOAD), /** Load double from local variable */ - DLOAD(ClassFile.DLOAD, 2, Kind.LOAD, TypeKind.DOUBLE, -1), + DLOAD(ClassFile.DLOAD, 2, Kind.LOAD), /** Load reference from local variable */ - ALOAD(ClassFile.ALOAD, 2, Kind.LOAD, TypeKind.REFERENCE, -1), + ALOAD(ClassFile.ALOAD, 2, Kind.LOAD), /** Load int from local variable 0 */ - ILOAD_0(ClassFile.ILOAD_0, 1, Kind.LOAD, TypeKind.INT, 0), + ILOAD_0(ClassFile.ILOAD_0, 1, Kind.LOAD), /** Load int from local variable 1 */ - ILOAD_1(ClassFile.ILOAD_1, 1, Kind.LOAD, TypeKind.INT, 1), + ILOAD_1(ClassFile.ILOAD_1, 1, Kind.LOAD), /** Load int from local variable 2 */ - ILOAD_2(ClassFile.ILOAD_2, 1, Kind.LOAD, TypeKind.INT, 2), + ILOAD_2(ClassFile.ILOAD_2, 1, Kind.LOAD), /** Load int from local variable3 */ - ILOAD_3(ClassFile.ILOAD_3, 1, Kind.LOAD, TypeKind.INT, 3), + ILOAD_3(ClassFile.ILOAD_3, 1, Kind.LOAD), /** Load long from local variable 0 */ - LLOAD_0(ClassFile.LLOAD_0, 1, Kind.LOAD, TypeKind.LONG, 0), + LLOAD_0(ClassFile.LLOAD_0, 1, Kind.LOAD), /** Load long from local variable 1 */ - LLOAD_1(ClassFile.LLOAD_1, 1, Kind.LOAD, TypeKind.LONG, 1), + LLOAD_1(ClassFile.LLOAD_1, 1, Kind.LOAD), /** Load long from local variable 2 */ - LLOAD_2(ClassFile.LLOAD_2, 1, Kind.LOAD, TypeKind.LONG, 2), + LLOAD_2(ClassFile.LLOAD_2, 1, Kind.LOAD), /** Load long from local variable 3 */ - LLOAD_3(ClassFile.LLOAD_3, 1, Kind.LOAD, TypeKind.LONG, 3), + LLOAD_3(ClassFile.LLOAD_3, 1, Kind.LOAD), /** Load float from local variable 0 */ - FLOAD_0(ClassFile.FLOAD_0, 1, Kind.LOAD, TypeKind.FLOAT, 0), + FLOAD_0(ClassFile.FLOAD_0, 1, Kind.LOAD), /** Load float from local variable 1 */ - FLOAD_1(ClassFile.FLOAD_1, 1, Kind.LOAD, TypeKind.FLOAT, 1), + FLOAD_1(ClassFile.FLOAD_1, 1, Kind.LOAD), /** Load float from local variable 2 */ - FLOAD_2(ClassFile.FLOAD_2, 1, Kind.LOAD, TypeKind.FLOAT, 2), + FLOAD_2(ClassFile.FLOAD_2, 1, Kind.LOAD), /** Load float from local variable 3 */ - FLOAD_3(ClassFile.FLOAD_3, 1, Kind.LOAD, TypeKind.FLOAT, 3), + FLOAD_3(ClassFile.FLOAD_3, 1, Kind.LOAD), /** Load double from local variable 0 */ - DLOAD_0(ClassFile.DLOAD_0, 1, Kind.LOAD, TypeKind.DOUBLE, 0), + DLOAD_0(ClassFile.DLOAD_0, 1, Kind.LOAD), /** Load double from local variable 1 */ - DLOAD_1(ClassFile.DLOAD_1, 1, Kind.LOAD, TypeKind.DOUBLE, 1), + DLOAD_1(ClassFile.DLOAD_1, 1, Kind.LOAD), /** Load double from local variable 2 */ - DLOAD_2(ClassFile.DLOAD_2, 1, Kind.LOAD, TypeKind.DOUBLE, 2), + DLOAD_2(ClassFile.DLOAD_2, 1, Kind.LOAD), /** Load double from local variable 3 */ - DLOAD_3(ClassFile.DLOAD_3, 1, Kind.LOAD, TypeKind.DOUBLE, 3), + DLOAD_3(ClassFile.DLOAD_3, 1, Kind.LOAD), /** Load reference from local variable 0 */ - ALOAD_0(ClassFile.ALOAD_0, 1, Kind.LOAD, TypeKind.REFERENCE, 0), + ALOAD_0(ClassFile.ALOAD_0, 1, Kind.LOAD), /** Load reference from local variable 1 */ - ALOAD_1(ClassFile.ALOAD_1, 1, Kind.LOAD, TypeKind.REFERENCE, 1), + ALOAD_1(ClassFile.ALOAD_1, 1, Kind.LOAD), /** Load reference from local variable 2 */ - ALOAD_2(ClassFile.ALOAD_2, 1, Kind.LOAD, TypeKind.REFERENCE, 2), + ALOAD_2(ClassFile.ALOAD_2, 1, Kind.LOAD), /** Load reference from local variable 3 */ - ALOAD_3(ClassFile.ALOAD_3, 1, Kind.LOAD, TypeKind.REFERENCE, 3), + ALOAD_3(ClassFile.ALOAD_3, 1, Kind.LOAD), /** Load int from array */ - IALOAD(ClassFile.IALOAD, 1, Kind.ARRAY_LOAD, TypeKind.INT), + IALOAD(ClassFile.IALOAD, 1, Kind.ARRAY_LOAD), /** Load long from array */ - LALOAD(ClassFile.LALOAD, 1, Kind.ARRAY_LOAD, TypeKind.LONG), + LALOAD(ClassFile.LALOAD, 1, Kind.ARRAY_LOAD), /** Load float from array */ - FALOAD(ClassFile.FALOAD, 1, Kind.ARRAY_LOAD, TypeKind.FLOAT), + FALOAD(ClassFile.FALOAD, 1, Kind.ARRAY_LOAD), /** Load double from array */ - DALOAD(ClassFile.DALOAD, 1, Kind.ARRAY_LOAD, TypeKind.DOUBLE), + DALOAD(ClassFile.DALOAD, 1, Kind.ARRAY_LOAD), /** Load reference from array */ - AALOAD(ClassFile.AALOAD, 1, Kind.ARRAY_LOAD, TypeKind.REFERENCE), + AALOAD(ClassFile.AALOAD, 1, Kind.ARRAY_LOAD), - /** Load byte or boolean from array */ - BALOAD(ClassFile.BALOAD, 1, Kind.ARRAY_LOAD, TypeKind.BYTE), + /** Load byte from array */ + BALOAD(ClassFile.BALOAD, 1, Kind.ARRAY_LOAD), /** Load char from array */ - CALOAD(ClassFile.CALOAD, 1, Kind.ARRAY_LOAD, TypeKind.CHAR), + CALOAD(ClassFile.CALOAD, 1, Kind.ARRAY_LOAD), /** Load short from array */ - SALOAD(ClassFile.SALOAD, 1, Kind.ARRAY_LOAD, TypeKind.SHORT), + SALOAD(ClassFile.SALOAD, 1, Kind.ARRAY_LOAD), /** Store int into local variable */ - ISTORE(ClassFile.ISTORE, 2, Kind.STORE, TypeKind.INT, -1), + ISTORE(ClassFile.ISTORE, 2, Kind.STORE), /** Store long into local variable */ - LSTORE(ClassFile.LSTORE, 2, Kind.STORE, TypeKind.LONG, -1), + LSTORE(ClassFile.LSTORE, 2, Kind.STORE), /** Store float into local variable */ - FSTORE(ClassFile.FSTORE, 2, Kind.STORE, TypeKind.FLOAT, -1), + FSTORE(ClassFile.FSTORE, 2, Kind.STORE), /** Store double into local variable */ - DSTORE(ClassFile.DSTORE, 2, Kind.STORE, TypeKind.DOUBLE, -1), + DSTORE(ClassFile.DSTORE, 2, Kind.STORE), /** Store reference into local variable */ - ASTORE(ClassFile.ASTORE, 2, Kind.STORE, TypeKind.REFERENCE, -1), + ASTORE(ClassFile.ASTORE, 2, Kind.STORE), /** Store int into local variable 0 */ - ISTORE_0(ClassFile.ISTORE_0, 1, Kind.STORE, TypeKind.INT, 0), + ISTORE_0(ClassFile.ISTORE_0, 1, Kind.STORE), /** Store int into local variable 1 */ - ISTORE_1(ClassFile.ISTORE_1, 1, Kind.STORE, TypeKind.INT, 1), + ISTORE_1(ClassFile.ISTORE_1, 1, Kind.STORE), /** Store int into local variable 2 */ - ISTORE_2(ClassFile.ISTORE_2, 1, Kind.STORE, TypeKind.INT, 2), + ISTORE_2(ClassFile.ISTORE_2, 1, Kind.STORE), /** Store int into local variable 3 */ - ISTORE_3(ClassFile.ISTORE_3, 1, Kind.STORE, TypeKind.INT, 3), + ISTORE_3(ClassFile.ISTORE_3, 1, Kind.STORE), /** Store long into local variable 0 */ - LSTORE_0(ClassFile.LSTORE_0, 1, Kind.STORE, TypeKind.LONG, 0), + LSTORE_0(ClassFile.LSTORE_0, 1, Kind.STORE), /** Store long into local variable 1 */ - LSTORE_1(ClassFile.LSTORE_1, 1, Kind.STORE, TypeKind.LONG, 1), + LSTORE_1(ClassFile.LSTORE_1, 1, Kind.STORE), /** Store long into local variable 2 */ - LSTORE_2(ClassFile.LSTORE_2, 1, Kind.STORE, TypeKind.LONG, 2), + LSTORE_2(ClassFile.LSTORE_2, 1, Kind.STORE), /** Store long into local variable 3 */ - LSTORE_3(ClassFile.LSTORE_3, 1, Kind.STORE, TypeKind.LONG, 3), + LSTORE_3(ClassFile.LSTORE_3, 1, Kind.STORE), /** Store float into local variable 0 */ - FSTORE_0(ClassFile.FSTORE_0, 1, Kind.STORE, TypeKind.FLOAT, 0), + FSTORE_0(ClassFile.FSTORE_0, 1, Kind.STORE), /** Store float into local variable 1 */ - FSTORE_1(ClassFile.FSTORE_1, 1, Kind.STORE, TypeKind.FLOAT, 1), + FSTORE_1(ClassFile.FSTORE_1, 1, Kind.STORE), /** Store float into local variable 2 */ - FSTORE_2(ClassFile.FSTORE_2, 1, Kind.STORE, TypeKind.FLOAT, 2), + FSTORE_2(ClassFile.FSTORE_2, 1, Kind.STORE), /** Store float into local variable 3 */ - FSTORE_3(ClassFile.FSTORE_3, 1, Kind.STORE, TypeKind.FLOAT, 3), + FSTORE_3(ClassFile.FSTORE_3, 1, Kind.STORE), /** Store double into local variable 0 */ - DSTORE_0(ClassFile.DSTORE_0, 1, Kind.STORE, TypeKind.DOUBLE, 0), + DSTORE_0(ClassFile.DSTORE_0, 1, Kind.STORE), /** Store double into local variable 1 */ - DSTORE_1(ClassFile.DSTORE_1, 1, Kind.STORE, TypeKind.DOUBLE, 1), + DSTORE_1(ClassFile.DSTORE_1, 1, Kind.STORE), /** Store double into local variable 2 */ - DSTORE_2(ClassFile.DSTORE_2, 1, Kind.STORE, TypeKind.DOUBLE, 2), + DSTORE_2(ClassFile.DSTORE_2, 1, Kind.STORE), /** Store double into local variable 3 */ - DSTORE_3(ClassFile.DSTORE_3, 1, Kind.STORE, TypeKind.DOUBLE, 3), + DSTORE_3(ClassFile.DSTORE_3, 1, Kind.STORE), /** Store reference into local variable 0 */ - ASTORE_0(ClassFile.ASTORE_0, 1, Kind.STORE, TypeKind.REFERENCE, 0), + ASTORE_0(ClassFile.ASTORE_0, 1, Kind.STORE), /** Store reference into local variable 1 */ - ASTORE_1(ClassFile.ASTORE_1, 1, Kind.STORE, TypeKind.REFERENCE, 1), + ASTORE_1(ClassFile.ASTORE_1, 1, Kind.STORE), /** Store reference into local variable 2 */ - ASTORE_2(ClassFile.ASTORE_2, 1, Kind.STORE, TypeKind.REFERENCE, 2), + ASTORE_2(ClassFile.ASTORE_2, 1, Kind.STORE), /** Store reference into local variable 3 */ - ASTORE_3(ClassFile.ASTORE_3, 1, Kind.STORE, TypeKind.REFERENCE, 3), + ASTORE_3(ClassFile.ASTORE_3, 1, Kind.STORE), /** Store into int array */ - IASTORE(ClassFile.IASTORE, 1, Kind.ARRAY_STORE, TypeKind.INT), + IASTORE(ClassFile.IASTORE, 1, Kind.ARRAY_STORE), /** Store into long array */ - LASTORE(ClassFile.LASTORE, 1, Kind.ARRAY_STORE, TypeKind.LONG), + LASTORE(ClassFile.LASTORE, 1, Kind.ARRAY_STORE), /** Store into float array */ - FASTORE(ClassFile.FASTORE, 1, Kind.ARRAY_STORE, TypeKind.FLOAT), + FASTORE(ClassFile.FASTORE, 1, Kind.ARRAY_STORE), /** Store into double array */ - DASTORE(ClassFile.DASTORE, 1, Kind.ARRAY_STORE, TypeKind.DOUBLE), + DASTORE(ClassFile.DASTORE, 1, Kind.ARRAY_STORE), /** Store into reference array */ - AASTORE(ClassFile.AASTORE, 1, Kind.ARRAY_STORE, TypeKind.REFERENCE), + AASTORE(ClassFile.AASTORE, 1, Kind.ARRAY_STORE), - /** Store into byte or boolean array */ - BASTORE(ClassFile.BASTORE, 1, Kind.ARRAY_STORE, TypeKind.BYTE), + /** Store into byte array */ + BASTORE(ClassFile.BASTORE, 1, Kind.ARRAY_STORE), /** Store into char array */ - CASTORE(ClassFile.CASTORE, 1, Kind.ARRAY_STORE, TypeKind.CHAR), + CASTORE(ClassFile.CASTORE, 1, Kind.ARRAY_STORE), /** Store into short array */ - SASTORE(ClassFile.SASTORE, 1, Kind.ARRAY_STORE, TypeKind.SHORT), + SASTORE(ClassFile.SASTORE, 1, Kind.ARRAY_STORE), /** Pop the top operand stack value */ POP(ClassFile.POP, 1, Kind.STACK), @@ -330,220 +328,220 @@ public enum Opcode { SWAP(ClassFile.SWAP, 1, Kind.STACK), /** Add int */ - IADD(ClassFile.IADD, 1, Kind.OPERATOR, TypeKind.INT), + IADD(ClassFile.IADD, 1, Kind.OPERATOR), /** Add long */ - LADD(ClassFile.LADD, 1, Kind.OPERATOR, TypeKind.LONG), + LADD(ClassFile.LADD, 1, Kind.OPERATOR), /** Add float */ - FADD(ClassFile.FADD, 1, Kind.OPERATOR, TypeKind.FLOAT), + FADD(ClassFile.FADD, 1, Kind.OPERATOR), /** Add double */ - DADD(ClassFile.DADD, 1, Kind.OPERATOR, TypeKind.DOUBLE), + DADD(ClassFile.DADD, 1, Kind.OPERATOR), /** Subtract int */ - ISUB(ClassFile.ISUB, 1, Kind.OPERATOR, TypeKind.INT), + ISUB(ClassFile.ISUB, 1, Kind.OPERATOR), /** Subtract long */ - LSUB(ClassFile.LSUB, 1, Kind.OPERATOR, TypeKind.LONG), + LSUB(ClassFile.LSUB, 1, Kind.OPERATOR), /** Subtract float */ - FSUB(ClassFile.FSUB, 1, Kind.OPERATOR, TypeKind.FLOAT), + FSUB(ClassFile.FSUB, 1, Kind.OPERATOR), /** Subtract double */ - DSUB(ClassFile.DSUB, 1, Kind.OPERATOR, TypeKind.DOUBLE), + DSUB(ClassFile.DSUB, 1, Kind.OPERATOR), /** Multiply int */ - IMUL(ClassFile.IMUL, 1, Kind.OPERATOR, TypeKind.INT), + IMUL(ClassFile.IMUL, 1, Kind.OPERATOR), /** Multiply long */ - LMUL(ClassFile.LMUL, 1, Kind.OPERATOR, TypeKind.LONG), + LMUL(ClassFile.LMUL, 1, Kind.OPERATOR), /** Multiply float */ - FMUL(ClassFile.FMUL, 1, Kind.OPERATOR, TypeKind.FLOAT), + FMUL(ClassFile.FMUL, 1, Kind.OPERATOR), /** Multiply double */ - DMUL(ClassFile.DMUL, 1, Kind.OPERATOR, TypeKind.DOUBLE), + DMUL(ClassFile.DMUL, 1, Kind.OPERATOR), /** Divide int */ - IDIV(ClassFile.IDIV, 1, Kind.OPERATOR, TypeKind.INT), + IDIV(ClassFile.IDIV, 1, Kind.OPERATOR), /** Divide long */ - LDIV(ClassFile.LDIV, 1, Kind.OPERATOR, TypeKind.LONG), + LDIV(ClassFile.LDIV, 1, Kind.OPERATOR), /** Divide float */ - FDIV(ClassFile.FDIV, 1, Kind.OPERATOR, TypeKind.FLOAT), + FDIV(ClassFile.FDIV, 1, Kind.OPERATOR), /** Divide double */ - DDIV(ClassFile.DDIV, 1, Kind.OPERATOR, TypeKind.DOUBLE), + DDIV(ClassFile.DDIV, 1, Kind.OPERATOR), /** Remainder int */ - IREM(ClassFile.IREM, 1, Kind.OPERATOR, TypeKind.INT), + IREM(ClassFile.IREM, 1, Kind.OPERATOR), /** Remainder long */ - LREM(ClassFile.LREM, 1, Kind.OPERATOR, TypeKind.LONG), + LREM(ClassFile.LREM, 1, Kind.OPERATOR), /** Remainder float */ - FREM(ClassFile.FREM, 1, Kind.OPERATOR, TypeKind.FLOAT), + FREM(ClassFile.FREM, 1, Kind.OPERATOR), /** Remainder double */ - DREM(ClassFile.DREM, 1, Kind.OPERATOR, TypeKind.DOUBLE), + DREM(ClassFile.DREM, 1, Kind.OPERATOR), /** Negate int */ - INEG(ClassFile.INEG, 1, Kind.OPERATOR, TypeKind.INT), + INEG(ClassFile.INEG, 1, Kind.OPERATOR), /** Negate long */ - LNEG(ClassFile.LNEG, 1, Kind.OPERATOR, TypeKind.LONG), + LNEG(ClassFile.LNEG, 1, Kind.OPERATOR), /** Negate float */ - FNEG(ClassFile.FNEG, 1, Kind.OPERATOR, TypeKind.FLOAT), + FNEG(ClassFile.FNEG, 1, Kind.OPERATOR), /** Negate double */ - DNEG(ClassFile.DNEG, 1, Kind.OPERATOR, TypeKind.DOUBLE), + DNEG(ClassFile.DNEG, 1, Kind.OPERATOR), /** Shift left int */ - ISHL(ClassFile.ISHL, 1, Kind.OPERATOR, TypeKind.INT), + ISHL(ClassFile.ISHL, 1, Kind.OPERATOR), /** Shift left long */ - LSHL(ClassFile.LSHL, 1, Kind.OPERATOR, TypeKind.LONG), + LSHL(ClassFile.LSHL, 1, Kind.OPERATOR), /** Shift right int */ - ISHR(ClassFile.ISHR, 1, Kind.OPERATOR, TypeKind.INT), + ISHR(ClassFile.ISHR, 1, Kind.OPERATOR), /** Shift right long */ - LSHR(ClassFile.LSHR, 1, Kind.OPERATOR, TypeKind.LONG), + LSHR(ClassFile.LSHR, 1, Kind.OPERATOR), /** Logical shift right int */ - IUSHR(ClassFile.IUSHR, 1, Kind.OPERATOR, TypeKind.INT), + IUSHR(ClassFile.IUSHR, 1, Kind.OPERATOR), /** Logical shift right long */ - LUSHR(ClassFile.LUSHR, 1, Kind.OPERATOR, TypeKind.LONG), + LUSHR(ClassFile.LUSHR, 1, Kind.OPERATOR), /** Boolean AND int */ - IAND(ClassFile.IAND, 1, Kind.OPERATOR, TypeKind.INT), + IAND(ClassFile.IAND, 1, Kind.OPERATOR), /** Boolean AND long */ - LAND(ClassFile.LAND, 1, Kind.OPERATOR, TypeKind.LONG), + LAND(ClassFile.LAND, 1, Kind.OPERATOR), /** Boolean OR int */ - IOR(ClassFile.IOR, 1, Kind.OPERATOR, TypeKind.INT), + IOR(ClassFile.IOR, 1, Kind.OPERATOR), /** Boolean OR long */ - LOR(ClassFile.LOR, 1, Kind.OPERATOR, TypeKind.LONG), + LOR(ClassFile.LOR, 1, Kind.OPERATOR), /** Boolean XOR int */ - IXOR(ClassFile.IXOR, 1, Kind.OPERATOR, TypeKind.INT), + IXOR(ClassFile.IXOR, 1, Kind.OPERATOR), /** Boolean XOR long */ - LXOR(ClassFile.LXOR, 1, Kind.OPERATOR, TypeKind.LONG), + LXOR(ClassFile.LXOR, 1, Kind.OPERATOR), /** Increment local variable by constant */ - IINC(ClassFile.IINC, 3, Kind.INCREMENT, TypeKind.INT, -1), + IINC(ClassFile.IINC, 3, Kind.INCREMENT), /** Convert int to long */ - I2L(ClassFile.I2L, 1, Kind.CONVERT, TypeKind.INT, TypeKind.LONG), + I2L(ClassFile.I2L, 1, Kind.CONVERT), /** Convert int to float */ - I2F(ClassFile.I2F, 1, Kind.CONVERT, TypeKind.INT, TypeKind.FLOAT), + I2F(ClassFile.I2F, 1, Kind.CONVERT), /** Convert int to double */ - I2D(ClassFile.I2D, 1, Kind.CONVERT, TypeKind.INT, TypeKind.DOUBLE), + I2D(ClassFile.I2D, 1, Kind.CONVERT), /** Convert long to int */ - L2I(ClassFile.L2I, 1, Kind.CONVERT, TypeKind.LONG, TypeKind.INT), + L2I(ClassFile.L2I, 1, Kind.CONVERT), /** Convert long to float */ - L2F(ClassFile.L2F, 1, Kind.CONVERT, TypeKind.LONG, TypeKind.FLOAT), + L2F(ClassFile.L2F, 1, Kind.CONVERT), /** Convert long to double */ - L2D(ClassFile.L2D, 1, Kind.CONVERT, TypeKind.LONG, TypeKind.DOUBLE), + L2D(ClassFile.L2D, 1, Kind.CONVERT), /** Convert float to int */ - F2I(ClassFile.F2I, 1, Kind.CONVERT, TypeKind.FLOAT, TypeKind.INT), + F2I(ClassFile.F2I, 1, Kind.CONVERT), /** Convert float to long */ - F2L(ClassFile.F2L, 1, Kind.CONVERT, TypeKind.FLOAT, TypeKind.LONG), + F2L(ClassFile.F2L, 1, Kind.CONVERT), /** Convert float to double */ - F2D(ClassFile.F2D, 1, Kind.CONVERT, TypeKind.FLOAT, TypeKind.DOUBLE), + F2D(ClassFile.F2D, 1, Kind.CONVERT), /** Convert double to int */ - D2I(ClassFile.D2I, 1, Kind.CONVERT, TypeKind.DOUBLE, TypeKind.INT), + D2I(ClassFile.D2I, 1, Kind.CONVERT), /** Convert double to long */ - D2L(ClassFile.D2L, 1, Kind.CONVERT, TypeKind.DOUBLE, TypeKind.LONG), + D2L(ClassFile.D2L, 1, Kind.CONVERT), /** Convert double to float */ - D2F(ClassFile.D2F, 1, Kind.CONVERT, TypeKind.DOUBLE, TypeKind.FLOAT), + D2F(ClassFile.D2F, 1, Kind.CONVERT), /** Convert int to byte */ - I2B(ClassFile.I2B, 1, Kind.CONVERT, TypeKind.INT, TypeKind.BYTE), + I2B(ClassFile.I2B, 1, Kind.CONVERT), /** Convert int to char */ - I2C(ClassFile.I2C, 1, Kind.CONVERT, TypeKind.INT, TypeKind.CHAR), + I2C(ClassFile.I2C, 1, Kind.CONVERT), /** Convert int to short */ - I2S(ClassFile.I2S, 1, Kind.CONVERT, TypeKind.INT, TypeKind.SHORT), + I2S(ClassFile.I2S, 1, Kind.CONVERT), /** Compare long */ - LCMP(ClassFile.LCMP, 1, Kind.OPERATOR, TypeKind.LONG), + LCMP(ClassFile.LCMP, 1, Kind.OPERATOR), /** Compare float */ - FCMPL(ClassFile.FCMPL, 1, Kind.OPERATOR, TypeKind.FLOAT), + FCMPL(ClassFile.FCMPL, 1, Kind.OPERATOR), /** Compare float */ - FCMPG(ClassFile.FCMPG, 1, Kind.OPERATOR, TypeKind.FLOAT), + FCMPG(ClassFile.FCMPG, 1, Kind.OPERATOR), /** Compare double */ - DCMPL(ClassFile.DCMPL, 1, Kind.OPERATOR, TypeKind.DOUBLE), + DCMPL(ClassFile.DCMPL, 1, Kind.OPERATOR), /** Compare double */ - DCMPG(ClassFile.DCMPG, 1, Kind.OPERATOR, TypeKind.DOUBLE), + DCMPG(ClassFile.DCMPG, 1, Kind.OPERATOR), /** Branch if int comparison with zero succeeds */ - IFEQ(ClassFile.IFEQ, 3, Kind.BRANCH, TypeKind.INT), + IFEQ(ClassFile.IFEQ, 3, Kind.BRANCH), /** Branch if int comparison with zero succeeds */ - IFNE(ClassFile.IFNE, 3, Kind.BRANCH, TypeKind.INT), + IFNE(ClassFile.IFNE, 3, Kind.BRANCH), /** Branch if int comparison with zero succeeds */ - IFLT(ClassFile.IFLT, 3, Kind.BRANCH, TypeKind.INT), + IFLT(ClassFile.IFLT, 3, Kind.BRANCH), /** Branch if int comparison with zero succeeds */ - IFGE(ClassFile.IFGE, 3, Kind.BRANCH, TypeKind.INT), + IFGE(ClassFile.IFGE, 3, Kind.BRANCH), /** Branch if int comparison with zero succeeds */ - IFGT(ClassFile.IFGT, 3, Kind.BRANCH, TypeKind.INT), + IFGT(ClassFile.IFGT, 3, Kind.BRANCH), /** Branch if int comparison with zero succeeds */ - IFLE(ClassFile.IFLE, 3, Kind.BRANCH, TypeKind.INT), + IFLE(ClassFile.IFLE, 3, Kind.BRANCH), /** Branch if int comparison succeeds */ - IF_ICMPEQ(ClassFile.IF_ICMPEQ, 3, Kind.BRANCH, TypeKind.INT), + IF_ICMPEQ(ClassFile.IF_ICMPEQ, 3, Kind.BRANCH), /** Branch if int comparison succeeds */ - IF_ICMPNE(ClassFile.IF_ICMPNE, 3, Kind.BRANCH, TypeKind.INT), + IF_ICMPNE(ClassFile.IF_ICMPNE, 3, Kind.BRANCH), /** Branch if int comparison succeeds */ - IF_ICMPLT(ClassFile.IF_ICMPLT, 3, Kind.BRANCH, TypeKind.INT), + IF_ICMPLT(ClassFile.IF_ICMPLT, 3, Kind.BRANCH), /** Branch if int comparison succeeds */ - IF_ICMPGE(ClassFile.IF_ICMPGE, 3, Kind.BRANCH, TypeKind.INT), + IF_ICMPGE(ClassFile.IF_ICMPGE, 3, Kind.BRANCH), /** Branch if int comparison succeeds */ - IF_ICMPGT(ClassFile.IF_ICMPGT, 3, Kind.BRANCH, TypeKind.INT), + IF_ICMPGT(ClassFile.IF_ICMPGT, 3, Kind.BRANCH), /** Branch if int comparison succeeds */ - IF_ICMPLE(ClassFile.IF_ICMPLE, 3, Kind.BRANCH, TypeKind.INT), + IF_ICMPLE(ClassFile.IF_ICMPLE, 3, Kind.BRANCH), /** Branch if reference comparison succeeds */ - IF_ACMPEQ(ClassFile.IF_ACMPEQ, 3, Kind.BRANCH, TypeKind.REFERENCE), + IF_ACMPEQ(ClassFile.IF_ACMPEQ, 3, Kind.BRANCH), /** Branch if reference comparison succeeds */ - IF_ACMPNE(ClassFile.IF_ACMPNE, 3, Kind.BRANCH, TypeKind.REFERENCE), + IF_ACMPNE(ClassFile.IF_ACMPNE, 3, Kind.BRANCH), /** Branch always */ - GOTO(ClassFile.GOTO, 3, Kind.BRANCH, TypeKind.VOID), + GOTO(ClassFile.GOTO, 3, Kind.BRANCH), /** * Jump subroutine is discontinued opcode @@ -564,22 +562,22 @@ public enum Opcode { LOOKUPSWITCH(ClassFile.LOOKUPSWITCH, -1, Kind.LOOKUP_SWITCH), /** Return int from method */ - IRETURN(ClassFile.IRETURN, 1, Kind.RETURN, TypeKind.INT), + IRETURN(ClassFile.IRETURN, 1, Kind.RETURN), /** Return long from method */ - LRETURN(ClassFile.LRETURN, 1, Kind.RETURN, TypeKind.LONG), + LRETURN(ClassFile.LRETURN, 1, Kind.RETURN), /** Return float from method */ - FRETURN(ClassFile.FRETURN, 1, Kind.RETURN, TypeKind.FLOAT), + FRETURN(ClassFile.FRETURN, 1, Kind.RETURN), /** Return double from method */ - DRETURN(ClassFile.DRETURN, 1, Kind.RETURN, TypeKind.DOUBLE), + DRETURN(ClassFile.DRETURN, 1, Kind.RETURN), /** Return reference from method */ - ARETURN(ClassFile.ARETURN, 1, Kind.RETURN, TypeKind.REFERENCE), + ARETURN(ClassFile.ARETURN, 1, Kind.RETURN), /** Return void from method */ - RETURN(ClassFile.RETURN, 1, Kind.RETURN, TypeKind.VOID), + RETURN(ClassFile.RETURN, 1, Kind.RETURN), /** Get static field from class */ GETSTATIC(ClassFile.GETSTATIC, 3, Kind.FIELD_ACCESS), @@ -621,7 +619,7 @@ public enum Opcode { ANEWARRAY(ClassFile.ANEWARRAY, 3, Kind.NEW_REF_ARRAY), /** Get length of array */ - ARRAYLENGTH(ClassFile.ARRAYLENGTH, 1, Kind.OPERATOR, TypeKind.INT), + ARRAYLENGTH(ClassFile.ARRAYLENGTH, 1, Kind.OPERATOR), /** Throw exception or error */ ATHROW(ClassFile.ATHROW, 1, Kind.THROW_EXCEPTION), @@ -642,13 +640,13 @@ public enum Opcode { MULTIANEWARRAY(ClassFile.MULTIANEWARRAY, 4, Kind.NEW_MULTI_ARRAY), /** Branch if reference is null */ - IFNULL(ClassFile.IFNULL, 3, Kind.BRANCH, TypeKind.REFERENCE), + IFNULL(ClassFile.IFNULL, 3, Kind.BRANCH), /** Branch if reference not null */ - IFNONNULL(ClassFile.IFNONNULL, 3, Kind.BRANCH, TypeKind.REFERENCE), + IFNONNULL(ClassFile.IFNONNULL, 3, Kind.BRANCH), /** Branch always (wide index) */ - GOTO_W(ClassFile.GOTO_W, 5, Kind.BRANCH, TypeKind.VOID), + GOTO_W(ClassFile.GOTO_W, 5, Kind.BRANCH), /** * Jump subroutine (wide index) is discontinued opcode @@ -657,34 +655,34 @@ public enum Opcode { JSR_W(ClassFile.JSR_W, 5, Kind.DISCONTINUED_JSR), /** Load int from local variable (wide index) */ - ILOAD_W((ClassFile.WIDE << 8) | ClassFile.ILOAD, 4, Kind.LOAD, TypeKind.INT, -1), + ILOAD_W((ClassFile.WIDE << 8) | ClassFile.ILOAD, 4, Kind.LOAD), /** Load long from local variable (wide index) */ - LLOAD_W((ClassFile.WIDE << 8) | ClassFile.LLOAD, 4, Kind.LOAD, TypeKind.LONG, -1), + LLOAD_W((ClassFile.WIDE << 8) | ClassFile.LLOAD, 4, Kind.LOAD), /** Load float from local variable (wide index) */ - FLOAD_W((ClassFile.WIDE << 8) | ClassFile.FLOAD, 4, Kind.LOAD, TypeKind.FLOAT, -1), + FLOAD_W((ClassFile.WIDE << 8) | ClassFile.FLOAD, 4, Kind.LOAD), /** Load double from local variable (wide index) */ - DLOAD_W((ClassFile.WIDE << 8) | ClassFile.DLOAD, 4, Kind.LOAD, TypeKind.DOUBLE, -1), + DLOAD_W((ClassFile.WIDE << 8) | ClassFile.DLOAD, 4, Kind.LOAD), /** Load reference from local variable (wide index) */ - ALOAD_W((ClassFile.WIDE << 8) | ClassFile.ALOAD, 4, Kind.LOAD, TypeKind.REFERENCE, -1), + ALOAD_W((ClassFile.WIDE << 8) | ClassFile.ALOAD, 4, Kind.LOAD), /** Store int into local variable (wide index) */ - ISTORE_W((ClassFile.WIDE << 8) | ClassFile.ISTORE, 4, Kind.STORE, TypeKind.INT, -1), + ISTORE_W((ClassFile.WIDE << 8) | ClassFile.ISTORE, 4, Kind.STORE), /** Store long into local variable (wide index) */ - LSTORE_W((ClassFile.WIDE << 8) | ClassFile.LSTORE, 4, Kind.STORE, TypeKind.LONG, -1), + LSTORE_W((ClassFile.WIDE << 8) | ClassFile.LSTORE, 4, Kind.STORE), /** Store float into local variable (wide index) */ - FSTORE_W((ClassFile.WIDE << 8) | ClassFile.FSTORE, 4, Kind.STORE, TypeKind.FLOAT, -1), + FSTORE_W((ClassFile.WIDE << 8) | ClassFile.FSTORE, 4, Kind.STORE), /** Store double into local variable (wide index) */ - DSTORE_W((ClassFile.WIDE << 8) | ClassFile.DSTORE, 4, Kind.STORE, TypeKind.DOUBLE, -1), + DSTORE_W((ClassFile.WIDE << 8) | ClassFile.DSTORE, 4, Kind.STORE), /** Store reference into local variable (wide index) */ - ASTORE_W((ClassFile.WIDE << 8) | ClassFile.ASTORE, 4, Kind.STORE, TypeKind.REFERENCE, -1), + ASTORE_W((ClassFile.WIDE << 8) | ClassFile.ASTORE, 4, Kind.STORE), /** * Return from subroutine (wide index) is discontinued opcode @@ -693,7 +691,7 @@ public enum Opcode { RET_W((ClassFile.WIDE << 8) | ClassFile.RET, 4, Kind.DISCONTINUED_RET), /** Increment local variable by constant (wide index) */ - IINC_W((ClassFile.WIDE << 8) | ClassFile.IINC, 6, Kind.INCREMENT, TypeKind.INT, -1); + IINC_W((ClassFile.WIDE << 8) | ClassFile.IINC, 6, Kind.INCREMENT); /** * Kinds of opcodes. @@ -1078,59 +1076,41 @@ public enum Opcode { private final int bytecode; private final int sizeIfFixed; private final Kind kind; - private final TypeKind primaryTypeKind; - private final TypeKind secondaryTypeKind; - private final int slot; - private final ConstantDesc constantValue; Opcode(int bytecode, int sizeIfFixed, Kind kind) { - this(bytecode, sizeIfFixed, kind, null, null, -1, null); - } - - Opcode(int bytecode, int sizeIfFixed, Kind kind, TypeKind typeKind) { - this(bytecode, sizeIfFixed, kind, typeKind, null, -1, null); - } - - Opcode(int bytecode, int sizeIfFixed, Kind kind, TypeKind typeKind, int slot) { - this(bytecode, sizeIfFixed, kind, typeKind, null, slot, null); - } - - Opcode(int bytecode, int sizeIfFixed, Kind kind, TypeKind typeKind, int slot, ConstantDesc constantValue) { - this(bytecode, sizeIfFixed, kind, typeKind, null, slot, constantValue); - } - - Opcode(int bytecode, int sizeIfFixed, Kind kind, TypeKind primaryTypeKind, TypeKind secondaryTypeKind) { - this(bytecode, sizeIfFixed, kind, primaryTypeKind, secondaryTypeKind, 0, null); - } - - Opcode(int bytecode, - int sizeIfFixed, - Kind kind, - TypeKind primaryTypeKind, - TypeKind secondaryTypeKind, - int slot, - ConstantDesc constantValue) { this.bytecode = bytecode; this.sizeIfFixed = sizeIfFixed; this.kind = kind; - this.primaryTypeKind = primaryTypeKind; - this.secondaryTypeKind = secondaryTypeKind; - this.slot = slot; - this.constantValue = constantValue; } /** - * {@return bytecode} + * {@return the opcode value} For {@linkplain #isWide() wide} pseudo-opcodes, returns the + * first 2 bytes of the instruction, which are the {@code wide} opcode and the functional + * local variable opcode, as a U2 value. */ public int bytecode() { return bytecode; } /** - * {@return true if the instruction has extended local variable index by additional bytes} + * {@return true if this is a pseudo-opcode modified by {@code wide}} + * + * @see #ILOAD_W + * @see #LLOAD_W + * @see #FLOAD_W + * @see #DLOAD_W + * @see #ALOAD_W + * @see #ISTORE_W + * @see #LSTORE_W + * @see #FSTORE_W + * @see #DSTORE_W + * @see #ASTORE_W + * @see #RET_W + * @see #IINC_W */ public boolean isWide() { return bytecode > 255; } /** - * {@return size of the instruction if fixed, or -1 otherwise} + * {@return size of the instruction in bytes if fixed, or -1 otherwise} This size includes + * the opcode itself. */ public int sizeIfFixed() { return sizeIfFixed; } @@ -1138,42 +1118,4 @@ public enum Opcode { * {@return instruction kind} */ public Kind kind() { return kind; } - - /** - * {@return primary type kind for instructions operating with at least one type, or null otherwise} - */ - public TypeKind primaryTypeKind() { - return primaryTypeKind; - } - - /** - * {@return secondary type kind for instructions operating with two types, or null otherwise} - */ - public TypeKind secondaryTypeKind() { - return secondaryTypeKind; - } - - /** - * {@return local variable slot for instructions operating with local variable, or -1 otherwise} - */ - public int slot() { - return slot; - } - - /** - * {@return constant value for constant instructions, or null otherwise} - */ - public ConstantDesc constantValue() { - return constantValue; - } - - /** - * {@return true if the instruction represents an unconditional branch} - */ - public boolean isUnconditionalBranch() { - return switch (this) { - case GOTO, ATHROW, GOTO_W, LOOKUPSWITCH, TABLESWITCH -> true; - default -> kind() == Kind.RETURN; - }; - } } diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java index 022c45fdeef..6f07805a1e8 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java @@ -75,7 +75,7 @@ public sealed interface ConstantInstruction extends Instruction { */ @Override default TypeKind typeKind() { - return opcode().primaryTypeKind(); + return BytecodeHelpers.intrinsicConstantType(opcode()); } } @@ -98,7 +98,7 @@ public sealed interface ConstantInstruction extends Instruction { */ @Override default TypeKind typeKind() { - return opcode().primaryTypeKind(); + return TypeKind.INT; } } @@ -137,7 +137,7 @@ public sealed interface ConstantInstruction extends Instruction { */ static IntrinsicConstantInstruction ofIntrinsic(Opcode op) { Util.checkKind(op, Opcode.Kind.CONSTANT); - if (op.constantValue() == null) + if (op.sizeIfFixed() != 1) throw new IllegalArgumentException(String.format("Wrong opcode specified; found %s, expected xCONST_val", op)); return new AbstractInstruction.UnboundIntrinsicConstantInstruction(op); } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java index 463668dcb00..10c9cf0a5e1 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java @@ -145,7 +145,7 @@ public abstract sealed class AbstractInstruction @Override public TypeKind typeKind() { - return op.primaryTypeKind(); + return BytecodeHelpers.loadType(op); } @Override @@ -173,7 +173,7 @@ public abstract sealed class AbstractInstruction @Override public TypeKind typeKind() { - return op.primaryTypeKind(); + return BytecodeHelpers.storeType(op); } @Override @@ -800,7 +800,7 @@ public abstract sealed class AbstractInstruction @Override public TypeKind typeKind() { - return op.primaryTypeKind(); + return BytecodeHelpers.loadType(op); } @Override @@ -831,7 +831,7 @@ public abstract sealed class AbstractInstruction @Override public TypeKind typeKind() { - return op.primaryTypeKind(); + return BytecodeHelpers.storeType(op); } @Override @@ -993,7 +993,7 @@ public abstract sealed class AbstractInstruction @Override public TypeKind typeKind() { - return op.primaryTypeKind(); + return BytecodeHelpers.returnType(op); } @Override @@ -1226,7 +1226,7 @@ public abstract sealed class AbstractInstruction @Override public TypeKind typeKind() { - return op.primaryTypeKind(); + return BytecodeHelpers.arrayLoadType(op); } } @@ -1239,7 +1239,7 @@ public abstract sealed class AbstractInstruction @Override public TypeKind typeKind() { - return op.primaryTypeKind(); + return BytecodeHelpers.arrayStoreType(op); } } @@ -1286,12 +1286,12 @@ public abstract sealed class AbstractInstruction @Override public TypeKind fromType() { - return op.primaryTypeKind(); + return BytecodeHelpers.convertFromType(op); } @Override public TypeKind toType() { - return op.secondaryTypeKind(); + return BytecodeHelpers.convertToType(op); } } @@ -1304,22 +1304,19 @@ public abstract sealed class AbstractInstruction @Override public TypeKind typeKind() { - return op.primaryTypeKind(); + return BytecodeHelpers.operatorOperandType(op); } } public static final class UnboundIntrinsicConstantInstruction extends UnboundInstruction implements ConstantInstruction.IntrinsicConstantInstruction { - final ConstantDesc constant; - public UnboundIntrinsicConstantInstruction(Opcode op) { super(op); - constant = op.constantValue(); } @Override public ConstantDesc constantValue() { - return constant; + return BytecodeHelpers.intrinsicConstantValue(op); } } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BlockCodeBuilderImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BlockCodeBuilderImpl.java index 66e974b4a51..b28bcc0b4b5 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BlockCodeBuilderImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BlockCodeBuilderImpl.java @@ -85,7 +85,7 @@ public final class BlockCodeBuilderImpl hasInstructions |= element instanceof Instruction; if (reachable) { - if (element instanceof Instruction i && i.opcode().isUnconditionalBranch()) + if (element instanceof Instruction i && BytecodeHelpers.isUnconditionalBranch(i.opcode())) reachable = false; } else if (element instanceof LabelTarget) { diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java index e52d198e1f4..75991531c31 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BytecodeHelpers.java @@ -46,6 +46,11 @@ import java.lang.classfile.constantpool.MemberRefEntry; import java.lang.classfile.constantpool.MethodHandleEntry; import java.lang.classfile.constantpool.NameAndTypeEntry; +import static java.lang.classfile.ClassFile.*; + +/** + * Note: This class switches on opcode.bytecode for code size + */ public class BytecodeHelpers { private BytecodeHelpers() { @@ -236,7 +241,7 @@ public class BytecodeHelpers { case IF_ACMPNE -> Opcode.IF_ACMPEQ; case IFNULL -> Opcode.IFNONNULL; case IFNONNULL -> Opcode.IFNULL; - default -> throw new IllegalArgumentException("Unknown branch instruction: " + op); + default -> throw Util.badOpcodeKindException(op, Opcode.Kind.BRANCH); }; } @@ -277,6 +282,29 @@ public class BytecodeHelpers { }; } + public static TypeKind convertFromType(Opcode opcode) { + return switch (opcode) { + case I2D, I2F, I2L, I2B, I2C, I2S -> TypeKind.INT; + case L2D, L2F, L2I -> TypeKind.LONG; + case F2D, F2I, F2L -> TypeKind.FLOAT; + case D2F, D2I, D2L -> TypeKind.DOUBLE; + default -> throw Util.badOpcodeKindException(opcode, Opcode.Kind.CONVERT); + }; + } + + public static TypeKind convertToType(Opcode opcode) { + return switch (opcode) { + case I2B -> TypeKind.BYTE; + case I2C -> TypeKind.CHAR; + case I2S -> TypeKind.SHORT; + case L2I, F2I, D2I -> TypeKind.INT; + case I2L, F2L, D2L -> TypeKind.LONG; + case I2F, L2F, D2F -> TypeKind.FLOAT; + case I2D, L2D, F2D -> TypeKind.DOUBLE; + default -> throw Util.badOpcodeKindException(opcode, Opcode.Kind.CONVERT); + }; + } + public static void validateSipush(int value) { if (value != (short) value) throw new IllegalArgumentException( @@ -358,4 +386,145 @@ public class BytecodeHelpers { } throw new UnsupportedOperationException("not yet: " + constantValue); } + + public static ConstantDesc intrinsicConstantValue(Opcode opcode) { + return switch (opcode) { + case ACONST_NULL -> ConstantDescs.NULL; + case ICONST_M1 -> -1; + case ICONST_0 -> 0; + case ICONST_1 -> 1; + case ICONST_2 -> 2; + case ICONST_3 -> 3; + case ICONST_4 -> 4; + case ICONST_5 -> 5; + case LCONST_0 -> 0L; + case LCONST_1 -> 1L; + case FCONST_0 -> 0F; + case FCONST_1 -> 1F; + case FCONST_2 -> 2F; + case DCONST_0 -> 0D; + case DCONST_1 -> 1D; + default -> throw Util.badOpcodeKindException(opcode, Opcode.Kind.CONSTANT); + }; + } + + public static TypeKind intrinsicConstantType(Opcode opcode) { + return switch (opcode) { + case ACONST_NULL -> TypeKind.REFERENCE; + case ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5 -> TypeKind.INT; + case LCONST_0, LCONST_1 -> TypeKind.LONG; + case FCONST_0, FCONST_1, FCONST_2 -> TypeKind.FLOAT; + case DCONST_0, DCONST_1 -> TypeKind.DOUBLE; + default -> throw Util.badOpcodeKindException(opcode, Opcode.Kind.CONSTANT); + }; + } + + public static boolean isUnconditionalBranch(Opcode opcode) { + return switch (opcode) { + case GOTO, ATHROW, GOTO_W, LOOKUPSWITCH, TABLESWITCH -> true; + default -> opcode.kind() == Opcode.Kind.RETURN; + }; + } + + // Must check Opcode.sizeIfFixed() == 1 before call! + public static int intrinsicLoadSlot(Opcode loadOpcode) { + return switch (loadOpcode) { + case ILOAD_0, LLOAD_0, FLOAD_0, DLOAD_0, ALOAD_0 -> 0; + case ILOAD_1, LLOAD_1, FLOAD_1, DLOAD_1, ALOAD_1 -> 1; + case ILOAD_2, LLOAD_2, FLOAD_2, DLOAD_2, ALOAD_2 -> 2; + case ILOAD_3, LLOAD_3, FLOAD_3, DLOAD_3, ALOAD_3 -> 3; + default -> throw Util.badOpcodeKindException(loadOpcode, Opcode.Kind.LOAD); + }; + } + + // Must check Opcode.sizeIfFixed() == 1 before call! + public static int intrinsicStoreSlot(Opcode storeOpcode) { + return switch (storeOpcode) { + case ISTORE_0, LSTORE_0, FSTORE_0, DSTORE_0, ASTORE_0 -> 0; + case ISTORE_1, LSTORE_1, FSTORE_1, DSTORE_1, ASTORE_1 -> 1; + case ISTORE_2, LSTORE_2, FSTORE_2, DSTORE_2, ASTORE_2 -> 2; + case ISTORE_3, LSTORE_3, FSTORE_3, DSTORE_3, ASTORE_3 -> 3; + default -> throw Util.badOpcodeKindException(storeOpcode, Opcode.Kind.STORE); + }; + } + + public static TypeKind loadType(Opcode loadOpcode) { + // Note: 0xFF handles wide pseudo-opcodes + return switch (loadOpcode.bytecode() & 0xFF) { + case ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3 -> TypeKind.INT; + case LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3 -> TypeKind.LONG; + case FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3 -> TypeKind.FLOAT; + case DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3 -> TypeKind.DOUBLE; + case ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3 -> TypeKind.REFERENCE; + default -> throw Util.badOpcodeKindException(loadOpcode, Opcode.Kind.LOAD); + }; + } + + public static TypeKind storeType(Opcode storeOpcode) { + // Note: 0xFF handles wide pseudo-opcodes + return switch (storeOpcode.bytecode() & 0xFF) { + case ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3 -> TypeKind.INT; + case LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3 -> TypeKind.LONG; + case FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3 -> TypeKind.FLOAT; + case DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3 -> TypeKind.DOUBLE; + case ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3 -> TypeKind.REFERENCE; + default -> throw Util.badOpcodeKindException(storeOpcode, Opcode.Kind.STORE); + }; + } + + public static TypeKind arrayLoadType(Opcode arrayLoadOpcode) { + return switch (arrayLoadOpcode) { + case IALOAD -> TypeKind.INT; + case LALOAD -> TypeKind.LONG; + case FALOAD -> TypeKind.FLOAT; + case DALOAD -> TypeKind.DOUBLE; + case AALOAD -> TypeKind.REFERENCE; + case BALOAD -> TypeKind.BYTE; + case CALOAD -> TypeKind.CHAR; + case SALOAD -> TypeKind.SHORT; + default -> throw Util.badOpcodeKindException(arrayLoadOpcode, Opcode.Kind.ARRAY_LOAD); + }; + } + + public static TypeKind arrayStoreType(Opcode arrayStoreOpcode) { + return switch (arrayStoreOpcode) { + case IASTORE -> TypeKind.INT; + case LASTORE -> TypeKind.LONG; + case FASTORE -> TypeKind.FLOAT; + case DASTORE -> TypeKind.DOUBLE; + case AASTORE -> TypeKind.REFERENCE; + case BASTORE -> TypeKind.BYTE; + case CASTORE -> TypeKind.CHAR; + case SASTORE -> TypeKind.SHORT; + default -> throw Util.badOpcodeKindException(arrayStoreOpcode, Opcode.Kind.ARRAY_STORE); + }; + } + + public static TypeKind returnType(Opcode returnOpcode) { + return switch (returnOpcode) { + case IRETURN -> TypeKind.INT; + case LRETURN -> TypeKind.LONG; + case FRETURN -> TypeKind.FLOAT; + case DRETURN -> TypeKind.DOUBLE; + case ARETURN -> TypeKind.REFERENCE; + case RETURN -> TypeKind.VOID; + default -> throw Util.badOpcodeKindException(returnOpcode, Opcode.Kind.RETURN); + }; + } + + public static TypeKind operatorOperandType(Opcode operationOpcode) { + return switch (operationOpcode) { + case IADD, ISUB, IMUL, IDIV, IREM, INEG, + ISHL, ISHR, IUSHR, IAND, IOR, IXOR, + ARRAYLENGTH -> TypeKind.INT; + case LADD, LSUB, LMUL, LDIV, LREM, LNEG, + LSHL, LSHR, LUSHR, LAND, LOR, LXOR, + LCMP -> TypeKind.LONG; + case FADD, FSUB, FMUL, FDIV, FREM, FNEG, + FCMPL, FCMPG -> TypeKind.FLOAT; + case DADD, DSUB, DMUL, DDIV, DREM, DNEG, + DCMPL, DCMPG -> TypeKind.DOUBLE; + default -> throw Util.badOpcodeKindException(operationOpcode, Opcode.Kind.OPERATOR); + }; + } } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/CodeImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/CodeImpl.java index 8be7e92f5b6..68c93249c1b 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/CodeImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/CodeImpl.java @@ -55,13 +55,13 @@ public final class CodeImpl case ARRAY_STORE -> ArrayStoreInstruction.of(o); case CONSTANT -> ConstantInstruction.ofIntrinsic(o); case CONVERT -> ConvertInstruction.of(o); - case LOAD -> LoadInstruction.of(o, o.slot()); + case LOAD -> LoadInstruction.of(o, BytecodeHelpers.intrinsicLoadSlot(o)); case MONITOR -> MonitorInstruction.of(o); case NOP -> NopInstruction.of(); case OPERATOR -> OperatorInstruction.of(o); case RETURN -> ReturnInstruction.of(o); case STACK -> StackInstruction.of(o); - case STORE -> StoreInstruction.of(o, o.slot()); + case STORE -> StoreInstruction.of(o, BytecodeHelpers.intrinsicStoreSlot(o)); case THROW_EXCEPTION -> ThrowInstruction.of(); default -> throw new AssertionError("invalid opcode: " + o); }; diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java index a064c40be30..2d9e27b8d74 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java @@ -185,8 +185,12 @@ public class Util { public static void checkKind(Opcode op, Opcode.Kind k) { if (op.kind() != k) - throw new IllegalArgumentException( - String.format("Wrong opcode kind specified; found %s(%s), expected %s", op, op.kind(), k)); + throw badOpcodeKindException(op, k); + } + + public static IllegalArgumentException badOpcodeKindException(Opcode op, Opcode.Kind k) { + return new IllegalArgumentException( + String.format("Wrong opcode kind specified; found %s(%s), expected %s", op, op.kind(), k)); } public static int flagsToBits(AccessFlag.Location location, Collection flags) {