View Javadoc
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  }