1 /*
2 * MIT License
3 * Copyright (c) 2006-2025 JMockit developers
4 * See LICENSE file for full license text.
5 */
6 package mockit.asm.jvmConstants;
7
8 /**
9 * Constant data about all <a href="https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html">JVM bytecode
10 * instructions</a>: {@link #SIZE}, {@link #TYPE}.
11 */
12 public final class JVMInstruction {
13 /**
14 * The stack size variation corresponding to each JVM instruction. Said variation equals the size of the values
15 * produced by an instruction, minus the size of the values consumed by the instruction.
16 */
17 public static final int[] SIZE;
18 static {
19 String s = "EFFFFFFFFGGFFFGGFFFEEFGFGFEEEEEEEEEEEEEEEEEEEEDEDEDDDDD"
20 + "CDCDEEEEEEEEEEEEEEEEEEEEBABABBBBDCFFFGGGEDCDCDCDCDCDCDCDCD"
21 + "CDCEEEEDDDDDDDCDCDCEFEFDDEEFFDEDEEEBDDBBDDDDDDCCCCCCCCEFED" + "DDCDCDEEEEEEEEEEFEEEEEEDDEEDDEE";
22 int n = s.length();
23 int[] sizes = new int[n];
24
25 for (int i = 0; i < n; i++) {
26 // noinspection CharUsedInArithmeticContext
27 sizes[i] = s.charAt(i) - 'E';
28 }
29
30 SIZE = sizes;
31 }
32
33 /**
34 * Constants that subdivide the 220 {@linkplain Opcodes instruction opcodes} in 18 types of instructions. Such types
35 * vary in the number and size of arguments the instruction takes (no argument, a signed byte, a signed short), on
36 * whether it takes a local variable index, a jump target label, etc. Some types contain a single instruction, such
37 * as LDC and IINC.
38 */
39 public interface InstructionType {
40 int NOARG = 0; // instructions without any argument
41 int SBYTE = 1; // instructions with a signed byte argument
42 int SHORT = 2; // instructions with a signed short argument
43 int VAR = 3; // instructions with a local variable index argument
44 int IMPLVAR = 4; // instructions with an implicit local variable index argument
45 int TYPE_INSN = 5; // instructions with a type descriptor argument
46 int FIELDORMETH = 6; // field and method invocations instructions
47 int ITFMETH = 7; // INVOKEINTERFACE/INVOKEDYNAMIC instruction
48 int INDYMETH = 8; // INVOKEDYNAMIC instruction
49 int LABEL = 9; // instructions with a 2 bytes bytecode offset label
50 int LABELW = 10; // instructions with a 4 bytes bytecode offset label
51 int LDC_INSN = 11; // the LDC instruction
52 int LDCW_INSN = 12; // the LDC_W and LDC2_W instructions
53 int IINC_INSN = 13; // the IINC instruction
54 int TABL_INSN = 14; // the TABLESWITCH instruction
55 int LOOK_INSN = 15; // the LOOKUPSWITCH instruction
56 int MANA_INSN = 16; // the MULTIANEWARRAY instruction
57 int WIDE_INSN = 17; // the WIDE instruction
58 }
59
60 /**
61 * The {@linkplain InstructionType instruction types} of all JVM opcodes, one value for each instruction opcode.
62 */
63 public static final byte[] TYPE;
64 static {
65 String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
66 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
67 + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
68 + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
69 int n = s.length();
70 byte[] types = new byte[n];
71
72 for (int i = 0; i < n; i++) {
73 // noinspection NumericCastThatLosesPrecision,CharUsedInArithmeticContext
74 types[i] = (byte) (s.charAt(i) - 'A');
75 }
76
77 TYPE = types;
78 }
79
80 private JVMInstruction() {
81 }
82 }