Advertisement
SforzandoCF

cod

Sep 16th, 2024 (edited)
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 52.75 KB | None | 0 0
  1. public class CodeAttribute extends Attribute {
  2.     private final InputStream inst;
  3.     private final List<ExceptionHandler> exceptions;
  4.     private final List<Attribute> attributes;
  5.     private final int maxLocalCount;
  6.    
  7.     public CodeAttribute (Attribute attr) throws DecompilationException {
  8.         CodeAttribute atc = readFrom(new ByteArrayInputStream(attr.getRawData()));
  9.         this.instructions = atc.instructions;
  10.         this.exceptions = atc.exceptions;
  11.         this.attributes = atc.attributes;
  12.         this.maxStackSize = atc.maxStackSize;
  13.         this.maxLocalCount = atc.maxLocalCount;
  14.     }
  15.    
  16.     private CodeAttribute (InputStream reader, List<ExceptionHandler> exc, List<Attribute> att, int mss, int mlc) {
  17.         this.inst = reader;
  18.         this.exceptions = exc;
  19.         this.attributes = att;
  20.         this.maxStackSize = mss;
  21.         this.maxLocalCount = mlc;
  22.     }
  23.    
  24.     public static CodeAttribute readFrom (InputStream reader, List<Constant> constants) throws DecompilationException {
  25.         try {
  26.             if (constants.get((reader.read() << 8) | reader.read()).toString() != "Code") throw new DecompilationException("Reader does not define a valid code attribute");
  27.             reader.skip(6);
  28.             int mss = (reader.read() << 8) | reader.read();
  29.             int mlc = (reader.read() << 8) | reader.read();
  30.             int codeLength = ((reader.read() << 24) | (reader.read() << 16)) | ((reader.read() << 8) | reader.read());
  31.             ByteArrayInputStream reader2 = new ByteArrayInputStream(reader.readNBytes(codeLength));
  32.             int etl = (reader.read() << 8) | reader.read();
  33.             List<ExceptionHandler> exc = List.<ExceptionHandler>of();
  34.             for (int i = 0; i <= etl; i++)
  35.                 exc.add(ExceptionHandler.readFrom(reader, constants));
  36.             int atl = (reader.read() << 8) | reader.read();
  37.             List<Attribute> attributes = List.<Attribute>of();
  38.             for (int i = 0; i <= atl; i++)
  39.                 attributes.add(Attribute.readFrom(reader));
  40.             return new CodeAttribute(reader2, exc, atl, mss, mlc);
  41.         } catch (IOException ioe) {
  42.             throw new DecompilationException(ioe);
  43.         }
  44.     }
  45.    
  46.     public String toString (int indentFactor, List<Constant> c) {
  47.         String s = "";
  48.         int i = 0;
  49.         while (this.inst.available() > 0) {
  50.             Instruction j = Instructions.get(this.inst.read());
  51.             i += j.getLength(c);
  52.             s = s.concat("$$StringFormProgramCounterNotifier" + i + ";\n" + j.toString(c, this.inst));
  53.         }
  54.         return format(s, indentFactor, this);
  55.     }
  56.    
  57.     public static void format (String s, int i, CodeAttribute c) {
  58.         // Add indents in the proper places at the proper length
  59.         String indent = "";
  60.         for (int j = 0; j <= i; j++)
  61.             indent = indent.concat(" ");
  62.         s = s.replaceAll(";\n", ";\n" + indent);
  63.         // Add the whole program counter thing
  64.         while (s.contains("VirtualMachine.programCounter")) {
  65.             String endsAtPC = s.substring(0, s.indexOf("VirtualMachine.programCounter") - 1);
  66.             String weirdLittleGuy = endsAtPC.substring(endsAtPC.lastIndexOf("$$StringFormProgramCounterNotifier") + 34);
  67.             s.replaceFirst("VirtualMachine.programCounter", endsAtPC.substring(endsAtPC.lastIndexOf("$$StringFormProgramCounterNotifier") + 34, weirdLittleGuy.indexOf(";\n") + endsAtPC.lastIndexOf("$$StringFormProgramCounterNotifier") + 34));
  68.         }
  69.         // Replace every instance of VMLocalVariables.get(i) and set(i, v) with a variable
  70.         Object[] whatevertheheck = new Object[c.maxLocalCount];
  71.         Arrays.fill(whatevertheheck, null);
  72.         List<String> localVariables = List.<String>of(whatevertheheck);
  73.         while (s.contains("VMLocalVariables")) {
  74.             String funky = s.substring(s.indexOf("VMLocalVariables") + 17);
  75.             if (funky.startsWith("set")) {
  76.                 String concat = "";
  77.                 if (localVariables.get(Integer.parseInt(funky.substring(4, funky.indexOf(", ") - 1))) == null)
  78.                     concat = getType(funky.substring(funky.indexOf(", ") + 2, funky.indexOf(");\n") - 1)) + " var" + Integer.parseInt(funky.substring(4, funky.indexOf(", ") - 1)) + " = " + funky.substring(funky.indexOf(", ") + 2, funky.indexOf(");\n") - 1) + ";";
  79.                 else
  80.                     concat = "var" + Integer.parseInt(funky.substring(4, funky.indexOf(", ") - 1)) + " = " + funky.substring(funky.indexOf(", ") + 2, funky.indexOf(");\n") - 1) + ";";
  81.                 localVariables.set(Integer.parseInt(funky.substring(4, funky.indexOf(", ") - 1))), funky.substring(funky.indexOf(", ") + 2, funky.indexOf(");\n") - 1));
  82.                 String first = s.substring(0, s.indexOf("VMLocalVariables") - 1);
  83.                 String last = s.substring(funky.indexOf(");\n") + s.indexOf("VMLocalVariables") + 19);
  84.                 s = first + concat + last;
  85.             } else {
  86.                 String concat = "";
  87.                 concat = "VMStack.push(var" + Integer.parseInt(funky.substring(4, funky.indexOf(", ") - 1)) + ");";
  88.                 String first = s.substring(0, s.indexOf("VMLocalVariables") - 1);
  89.                 String last = s.substring(funky.indexOf(");\n") + s.indexOf("VMLocalVariables") + 19);
  90.                 s = first + concat + last;
  91.             }
  92.         }
  93.         // Replace every instance of VMStack.cast(class) with a push-pop that casts the object to class
  94.         String cast = ";\n" + indent + "VMStack.cast(";
  95.         while (s.contains(cast)) {
  96.             int internalIndex = s.indexOf(cast) + cast.length();
  97.             int internalEnd = s.substring(internalIndex).indexOf(";") + internalIndex;
  98.             String cast2 = s.substring(internalIndex, internalEnd - 1);
  99.             String regex = "VMStack.cast(" + cast2 + ");";
  100.             String rep = "VMStack.push((" + cast2.substring(0, cast2.length() - 7) + ") VMStack.pop());";
  101.             s = s.replaceFirst(regex, rep);
  102.         }
  103.         // Add every instance of VMStack.push(thing) to a stack, and remove all those instances
  104.         Stack<String> pushCalls = Stack.<String>of();
  105.         String push = ";\n" + indent + "VMStack.push(";
  106.         while (s.contains(push)) {
  107.             int internalIndex = s.indexOf(push) + push.length();
  108.             int internalEnd = s.substring(internalIndex).indexOf(";") + internalIndex;
  109.             pushCalls.push(s.substring(internalIndex, internalEnd - 1));
  110.             s = s.substring(0, internalIndex - 1).concat(s.substring(internalEnd));
  111.         }
  112.         // Fix a bug with nested VMStack.pop() calls inside VMStack.push()
  113.         List<String> reversed = pushCalls;
  114.         Stack<String> fixed = new Stack<String>();
  115.         for (int i = 0; i <= reversed.size(); i++) {
  116.             while (reversed.get(i).contains("VMStack.pop()"))
  117.                 reversed.set(i, reversed.get(i).replaceFirst("VMStack.pop()", fixed.pop()));
  118.             fixed.push(reversed.get(i));
  119.         }
  120.         // Replace every instance of VMStack.pop() with the thing in the last instance of VMStack.push(thing)
  121.         while (s.contains("VMStack.pop()"))
  122.             s = s.replaceFirst("VMStack.pop()", fixed.pop());
  123.         // Replace every instance of VirtualMachine.jumpTo(number) with the code at number
  124.         while (s.contains("VirtualMachine.jumpTo(")) {
  125.             String endsAtJump = s.substring(0, s.indexOf("VirtualMachine.jumpTo(") - 1);
  126.             String weirdLittleGuy = s.substring(s.indexOf("$$StringFormProgramCounterNotifier" + s.substring(s.indexOf("VirtualMachine.jumpTo(") + 22)));
  127.             int doTheThing = weirdLittleGuy.indexOf("$$StringFormProgramCounterNotifier" + (getGotoEnd(weirdLittleGuy) + 1));
  128.             s.replaceFirst("VirtualMachine.jumpTo(" + s.substring(s.indexOf("VirtualMachine.jumpTo(") + 22) + ")\n", weirdLittleGuy.substring(0, doTheThing - 1));
  129.             s = s.substring(0, s.indexOf(weirdLittleGuy)) + weirdLittleGuy.substring(doTheThing);
  130.         }
  131.         // Add try/catch statements
  132.         Map<AbstractMap.SimpleEntry<Integer, Integer>, List<ExceptionHandler>> handlers = Map.<AbstractMap.SimpleEntry<Integer, Integer>, List<ExceptionHandler>>of();
  133.         for (ExceptionHandler e : c.exceptions) {
  134.             AbstractMap.SimpleEntry<Integer, Integer> entry = new AbstractMap.SimpleEntry<Integer, Integer>(Integer.valueOf(e.getStart()), Integer.valueOf(e.getEnd()));
  135.             if (handlers.containsKey(entry))
  136.                 handlers.get(entry).add(e);
  137.             else
  138.                 handlers.put(entry, e);
  139.         }
  140.         for (AbstractMap.SimpleEntry<Integer, Integer> e : List.copyOf(handlers.keySet()).sorted((o1, o2) -> {
  141.             o1.getKey().intValue() == o2.getKey().intValue() ? o1.getValue().compareTo(o2.getValue()) : o1.getKey().compareTo(o2.getKey());
  142.         }))
  143.             s = toString(s, i, handlers.get(e));
  144.         // Remove the markers
  145.         String postSplit = "";
  146.         for (String s2 : s.split(";\n$$StringFormProgramCounterNotifier"))
  147.             postSplit = postSplit.concat(s2.substring(chopNonDigits(s2).length()));
  148.         String postSplit2 = "";
  149.         for (String s2 : postSplit.split(";\n$$StringFormSoftStopNotifier"))
  150.             postSplit2 = postSplit2.concat(s2);
  151.         String postSplit3 = "";
  152.         for (String s2 : postSplit2.split(";\n$$StringFormHardStopNotifier"))
  153.             postSplit3 = postSplit3.concat(s2);
  154.         return postSplit3;
  155.     }
  156.    
  157.     public static int getGotoEnd (String s) {
  158.         return chopNonDigits(s.substring(s.substring(0, Math.max(s.lastIndexOf("$$StringFormSoftStopNotifier"), s.lastIndexOf("$$StringFormHardStopNotifier"))).lastIndexOf("$$StringFormProgramCounterNotifier") + 34));
  159.     }
  160.    
  161.     public static String chopNonDigits (String s) {
  162.         char[] s2 = new char[s.length()];
  163.         for (int i = 0; i <= s.length(); i++) {
  164.             try {
  165.                 Integer.parseInt(Character.toString(s.toCharArray()[i])));
  166.                 s2[i] = s.toCharArray()[i];
  167.             } catch (NumberFormatException nfe) {
  168.                 break;
  169.             }
  170.         }
  171.         return new String(s2);
  172.     }
  173.    
  174.     public static String toString (String s, int i, List<ExceptionHandler> handlers) {
  175.         ExceptionHandler finallyCatch = null;
  176.         String catchString = "";
  177.         for (ExceptionHandler e : handlers) {
  178.             if (e.getCatchType().isFinally()) {
  179.                 finallyCatch = e;
  180.                 continue;
  181.             }
  182.             if (!s.substring(getCode(s, t.getStart())).startsWith("try {\n")) {
  183.                 String s1 = s.substring(0, getCode(s, t.getStart()) - 1);
  184.                 String s2 = s.substring(getCode(s, t.getStart()));
  185.                 s2 = "try {\n".concat(s2);
  186.                 s = s1.concat(s2);
  187.             }
  188.             String smth = catchType.getReference().toString();
  189.             catchString = catchString.concat("} catch (" + smth.substring(smth.indexOf("/") + 1) + " " + toExceptionName(smth) + ") {\n");
  190.             String preCode = "";
  191.             s.substring(getCode(s, t.getHandler())).lines().forEach(y -> preCode = preCode.concat("    " + y));
  192.             catchString = catchString.concat(preCode);
  193.         }
  194.         if (finallyCatch == null) {
  195.             catchString = catchString.concat("}\n");
  196.         } else {
  197.             String smth = catchType.getReference().toString();
  198.             catchString = catchString.concat("} finally {\n");
  199.             String preCode = "";
  200.             s.substring(getCode(s, finallyCatch.getHandler())).lines().forEach(y -> preCode = preCode.concat("    " + y));
  201.             catchString = catchString.concat(preCode + "}\n");
  202.         }
  203.         String s1 = s.substring(0, getCode(s, handlers.getFirst().getEnd()) - 1);
  204.         String s2 = s.substring(getCode(s, handlers.getFirst().getEnd()));
  205.         s2 = catchString.concat(s2);
  206.         s = s1.concat(s2);
  207.         return s;
  208.     }
  209.    
  210.     public static String toExceptionName (String clazz) {
  211.         clazz = clazz.substring(clazz.lastIndexOf("/") + 1);
  212.         StringBuilder b = new StringBuilder
  213.         for (char c : clazz.toCharArray())
  214.             if (Character.isUpperCase(c))
  215.                 b.append(Character.toLowerCase(c));
  216.         return b.toString();
  217.     }
  218. }
  219.  
  220. public class ExceptionHandler {
  221.     private final int startPC;
  222.     private final int endPC;
  223.     private final int handlerPC;
  224.    
  225.     private final CatchType catchType;
  226.    
  227.     private ExceptionHandler (int s, int e, int h, CatchType c) {
  228.         this.startPC = s;
  229.         this.endPC = e;
  230.         this.handlerPC = h;
  231.         this.catchType = c;
  232.     }
  233.    
  234.     public static ExceptionHandler readFrom (InputStream reader, List<Constant> constants) {
  235.         int startPC = (reader.read() << 8) | reader.read();
  236.         int endPC = (reader.read() << 8) | reader.read();
  237.         int handlerPC = (reader.read() << 8) | reader.read();
  238.         CatchType catchType = CatchType.of((reader.read() << 8) | reader.read(), constants);
  239.         return new ExceptionHandler(startPC, endPC, handlerPC, catchType);
  240.     }
  241.    
  242.     public int getStart () {
  243.         return this.startPC;
  244.     }
  245.    
  246.     public int getEnd () {
  247.         return this.endPC;
  248.     }
  249.    
  250.     public int getHandler () {
  251.         return this.handlerPC;
  252.     }
  253.    
  254.     public int getCatchType () {
  255.         return this.catchType;
  256.     }
  257.    
  258.     public static class CatchType {
  259.         private final boolean isFinally;
  260.        
  261.         private final ClassReference clazz;
  262.        
  263.         private CatchType (boolean f, ClassReference c) {
  264.             this.isFinally = f;
  265.             this.clazz = c;
  266.         }
  267.        
  268.         public static CatchType of (int i, List<Constant> constants) {
  269.             if (i == 0)
  270.                 return new CatchType (true, null);
  271.             else
  272.                 return new CatchType (false, (ClassReference)constants.get(i).get(constants));
  273.         }
  274.        
  275.         public boolean isFinally () {
  276.             return this.isFinally;
  277.         }
  278.        
  279.         public ClassReference getReference () {
  280.             return this.clazz;
  281.         }
  282.     }
  283. }
  284.  
  285. @FunctionalInterface
  286. public interface Instruction {
  287.     String toString (List<Constant> constants, InputStream stream) throws IOException;
  288.    
  289.     default int getLength (List<Constant> c) {
  290.         byte[] bb = new byte[256];
  291.         for (int i = 0; i <= 255; i++)
  292.             bb[i] = (byte)i;
  293.         ByteArrayInputStream s = new ByteArrayInputStream(bb);
  294.         this.toString(c, bb);
  295.         int read = s.read();
  296.         return read == -1 ? 256 : read;
  297.     }
  298. }
  299.  
  300. public class Instructions {
  301.     public static final int NOP = 0x00;
  302.     public static final int ACONST_NULL = 0x01;
  303.     public static final int ICONST_M1 = 0x02;
  304.     public static final int ICONST_0 = 0x03;
  305.     public static final int ICONST_1 = 0x04;
  306.     public static final int ICONST_2 = 0x05;
  307.     public static final int ICONST_3 = 0x06;
  308.     public static final int ICONST_4 = 0x07;
  309.     public static final int ICONST_5 = 0x08;
  310.     public static final int LCONST_0 = 0x09;
  311.     public static final int LCONST_1 = 0x0A;
  312.     public static final int FCONST_0 = 0x0B;
  313.     public static final int FCONST_1 = 0x0C;
  314.     public static final int DCONST_2 = 0x0D;
  315.     public static final int DCONST_0 = 0x0E;
  316.     public static final int DCONST_1 = 0x0F;
  317.     public static final int BIPUSH = 0x10;
  318.     public static final int SIPUSH = 0x11;
  319.     public static final int LDC = 0x12;
  320.     public static final int LDC_W = 0x13;
  321.     public static final int LDC2_W = 0x14;
  322.     public static final int ILOAD = 0x15;
  323.     public static final int LLOAD = 0x16;
  324.     public static final int FLOAD = 0x17;
  325.     public static final int DLOAD = 0x18;
  326.     public static final int ALOAD = 0x19;
  327.     public static final int ILOAD_0 = 0x1A;
  328.     public static final int ILOAD_1 = 0x1B;
  329.     public static final int ILOAD_2 = 0x1C;
  330.     public static final int ILOAD_3 = 0x1D;
  331.     public static final int LLOAD_0 = 0x1E;
  332.     public static final int LLOAD_1 = 0x1F;
  333.     public static final int LLOAD_2 = 0x20;
  334.     public static final int LLOAD_3 = 0x21;
  335.     public static final int FLOAD_0 = 0x22;
  336.     public static final int FLOAD_1 = 0x23;
  337.     public static final int FLOAD_2 = 0x24;
  338.     public static final int FLOAD_3 = 0x25;
  339.     public static final int DLOAD_0 = 0x26;
  340.     public static final int DLOAD_1 = 0x27;
  341.     public static final int DLOAD_2 = 0x28;
  342.     public static final int DLOAD_3 = 0x29;
  343.     public static final int ALOAD_0 = 0x2A;
  344.     public static final int ALOAD_1 = 0x2B;
  345.     public static final int ALOAD_2 = 0x2C;
  346.     public static final int ALOAD_3 = 0x2D;
  347.     public static final int IALOAD = 0x2E;
  348.     public static final int LALOAD = 0x2F;
  349.     public static final int FALOAD = 0x30;
  350.     public static final int DALOAD = 0x31;
  351.     public static final int AALOAD = 0x32;
  352.     public static final int BALOAD = 0x33;
  353.     public static final int CALOAD = 0x34;
  354.     public static final int SALOAD = 0x35;
  355.     public static final int ISTORE = 0x36;
  356.     public static final int LSTORE = 0x37;
  357.     public static final int FSTORE = 0x38;
  358.     public static final int DSTORE = 0x39;
  359.     public static final int ASTORE = 0x3A;
  360.     public static final int ISTORE_0 = 0x3B;
  361.     public static final int ISTORE_1 = 0x3C;
  362.     public static final int ISTORE_2 = 0x3D;
  363.     public static final int ISTORE_3 = 0x3E;
  364.     public static final int LSTORE_0 = 0x3F;
  365.     public static final int LSTORE_1 = 0x40;
  366.     public static final int LSTORE_2 = 0x41;
  367.     public static final int LSTORE_3 = 0x42;
  368.     public static final int FSTORE_0 = 0x43;
  369.     public static final int FSTORE_1 = 0x44;
  370.     public static final int FSTORE_2 = 0x45;
  371.     public static final int FSTORE_3 = 0x46;
  372.     public static final int DSTORE_0 = 0x47;
  373.     public static final int DSTORE_1 = 0x48;
  374.     public static final int DSTORE_2 = 0x49;
  375.     public static final int DSTORE_3 = 0x4A;
  376.     public static final int ASTORE_0 = 0x4B;
  377.     public static final int ASTORE_1 = 0x4C;
  378.     public static final int ASTORE_2 = 0x4D;
  379.     public static final int ASTORE_3 = 0x4E;
  380.     public static final int IASTORE = 0x4F;
  381.     public static final int LASTORE = 0x50;
  382.     public static final int FASTORE = 0x51;
  383.     public static final int DASTORE = 0x52;
  384.     public static final int AASTORE = 0x53;
  385.     public static final int BASTORE = 0x54;
  386.     public static final int CASTORE = 0x55;
  387.     public static final int SASTORE = 0x56;
  388.     public static final int POP = 0x57;
  389.     public static final int POP2 = 0x58;
  390.     public static final int DUP = 0x59;
  391.     public static final int DUP_X1 = 0x5A;
  392.     public static final int DUP_X2 = 0x5B;
  393.     public static final int DUP2 = 0x5C;
  394.     public static final int DUP2_X1 = 0x5D;
  395.     public static final int DUP2_X2 = 0x5E;
  396.     public static final int SWAP = 0x5F;
  397.     public static final int IADD = 0x60;
  398.     public static final int LADD = 0x61;
  399.     public static final int FADD = 0x62;
  400.     public static final int DADD = 0x63;
  401.     public static final int ISUB = 0x64;
  402.     public static final int LSUB = 0x65;
  403.     public static final int FSUB = 0x66;
  404.     public static final int DSUB = 0x67;
  405.     public static final int IMUL = 0x68;
  406.     public static final int LMUL = 0x69;
  407.     public static final int FMUL = 0x6A;
  408.     public static final int DMUL = 0x6B;
  409.     public static final int IDIV = 0x6C;
  410.     public static final int LDIV = 0x6D;
  411.     public static final int FDIV = 0x6E;
  412.     public static final int DDIV = 0x6F;
  413.     public static final int IREM = 0x70;
  414.     public static final int LREM = 0x71;
  415.     public static final int FREM = 0x72;
  416.     public static final int DREM = 0x73;
  417.     public static final int INEG = 0x74;
  418.     public static final int LNEG = 0x75;
  419.     public static final int FNEG = 0x76;
  420.     public static final int DNEG = 0x77;
  421.     public static final int ISHL = 0x78;
  422.     public static final int LSHL = 0x79;
  423.     public static final int ISHR = 0x7A;
  424.     public static final int LSHR = 0x7B;
  425.     public static final int IUSHR = 0x7C;
  426.     public static final int LUSHR = 0x7D;
  427.     public static final int IAND = 0x7E;
  428.     public static final int LAND = 0x7F;
  429.     public static final int IOR = 0x80;
  430.     public static final int LOR = 0x81;
  431.     public static final int IXOR = 0x82;
  432.     public static final int LXOR = 0x83;
  433.     public static final int IINC = 0x84;
  434.     public static final int I2L = 0x85;
  435.     public static final int I2F = 0x86;
  436.     public static final int I2L = 0x87;
  437.     public static final int L2I = 0x88;
  438.     public static final int L2F = 0x89;
  439.     public static final int L2D = 0x8A;
  440.     public static final int F2I = 0x8B;
  441.     public static final int F2L = 0x8C;
  442.     public static final int F2D = 0x8D;
  443.     public static final int D2I = 0x8E;
  444.     public static final int D2L = 0x8F;
  445.     public static final int D2F = 0x90;
  446.     public static final int I2B = 0x91;
  447.     public static final int I2C = 0x92;
  448.     public static final int I2S = 0x93;
  449.     public static final int LCMP = 0x94;
  450.     public static final int FCMPL = 0x95;
  451.     public static final int FCMPG = 0x96;
  452.     public static final int DCMPL = 0x97;
  453.     public static final int DCMPG = 0x98;
  454.     public static final int IFEQ = 0x99;
  455.     public static final int IFNE = 0x9A;
  456.     public static final int IFLT = 0x9B;
  457.     public static final int IFGE = 0x9C;
  458.     public static final int IFGT = 0x9D;
  459.     public static final int IFLE = 0x9E;
  460.     public static final int IF_ICMPEQ = 0x9F;
  461.     public static final int IF_ICMPNE = 0xA0;
  462.     public static final int IF_ICMPLT = 0xA1;
  463.     public static final int IF_ICMPGE = 0xA2;
  464.     public static final int IF_ICMPGT = 0xA3;
  465.     public static final int IF_ICMPLE = 0xA4;
  466.     public static final int IF_ACMPEQ = 0xA5;
  467.     public static final int IF_ACMPNE = 0xA6;
  468.     public static final int GOTO = 0xA7;
  469.     public static final int JSR = 0xA8;
  470.     public static final int RET = 0xA9;
  471.     public static final int TABLESWITCH = 0xAA;
  472.     public static final int LOOKUPSWITCH = 0xAB;
  473.     public static final int IRETURN = 0xAC;
  474.     public static final int LRETURN = 0xAD;
  475.     public static final int FRETURN = 0xAE;
  476.     public static final int DRETURN = 0xAF;
  477.     public static final int ARETURN = 0xB0;
  478.     public static final int RETURN = 0xB1;
  479.     public static final int GETSTATIC = 0xB2;
  480.     public static final int PUTSTATIC = 0xB3;
  481.     public static final int GETFIELD = 0xB4;
  482.     public static final int PUTFIELD = 0xB5;
  483.     public static final int INVOKEVIRTUAL = 0xB6;
  484.     public static final int INVOKESPECIAL = 0xB7;
  485.     public static final int INVOKESTATIC = 0xB8;
  486.     public static final int INVOKEINTERFACE = 0xB9;
  487.     public static final int INVOKEDYNAMIC = 0xBA;
  488.     public static final int NEW = 0xBB;
  489.     public static final int NEWARRAY = 0xBC;
  490.     public static final int ANEWARRAY = 0xBD;
  491.     public static final int ARRAYLENGTH = 0xBE;
  492.     public static final int ATHROW = 0xBF;
  493.     public static final int CHECKCAST = 0xC0;
  494.     public static final int INSTANCEOF = 0xC1;
  495.     public static final int MONITORENTER = 0xC2;
  496.     public static final int MONITOREXIT = 0xC3;
  497.     public static final int WIDE = 0xC4;
  498.     public static final int MULTIANEWARRAY = 0xC5;
  499.     public static final int IFNULL = 0xC6;
  500.     public static final int IFNONNULL = 0xC7;
  501.     public static final int GOTO_W = 0xC8;
  502.     public static final int JSR_W = 0xC9;
  503.     public static final int BREAKPOINT = 0xCA;
  504.     public static final int IMPDEP1 = 0xFE;
  505.     public static final int IMPDEP2 = 0xFF;
  506.    
  507.     public static Instruction get (int opcode) {
  508.         switch (opcode) {
  509.             case NOP:
  510.                 return (c, r) -> "";
  511.             case ACONST_NULL:
  512.                 return (c, r) -> "VMStack.push(null);\n";
  513.             case ICONST_M1:
  514.                 return (c, r) -> "VMStack.push(-1);\n";
  515.             case ICONST_0:
  516.                 return (c, r) -> "VMStack.push(0);\n";
  517.             case ICONST_1:
  518.                 return (c, r) -> "VMStack.push(1);\n";
  519.             case ICONST_2:
  520.                 return (c, r) -> "VMStack.push(2);\n";
  521.             case ICONST_3:
  522.                 return (c, r) -> "VMStack.push(3);\n";
  523.             case ICONST_4:
  524.                 return (c, r) -> "VMStack.push(4);\n";
  525.             case ICONST_5:
  526.                 return (c, r) -> "VMStack.push(5);\n";
  527.             case LCONST_0:
  528.                 return (c, r) -> "VMStack.push(0L);\n";
  529.             case LCONST_1:
  530.                 return (c, r) -> "VMStack.push(1L);\n";
  531.             case FCONST_0:
  532.                 return (c, r) -> "VMStack.push(0F);\n";
  533.             case FCONST_1:
  534.                 return (c, r) -> "VMStack.push(1F);\n";
  535.             case FCONST_2:
  536.                 return (c, r) -> "VMStack.push(2F);\n";
  537.             case DCONST_0:
  538.                 return (c, r) -> "VMStack.push(0D);\n";
  539.             case DCONST_1:
  540.                 return (c, r) -> "VMStack.push(1D);\n";
  541.             case BIPUSH:
  542.                 return (c, r) -> "VMStack.push((byte) " + r.read() + ");\n";
  543.             case SIPUSH:
  544.                 return (c, r) -> "VMStack.push((short) " + (r.read() << 8) | r.read() + ");\n";
  545.             case LDC:
  546.                 return (c, r) -> "VMStack.push(" + constants.get(r.read()).toString() + ");\n";
  547.             case LDC_W:
  548.                 return (c, r) -> "VMStack.push(" + constants.get((r.read() << 8) | r.read()).toString() + ");\n";
  549.             case LDC2_W:
  550.                 return (c, r) -> "VMStack.push(" + constants.get((r.read() << 8) | r.read()).toString() + ");\n";
  551.             case ILOAD:
  552.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(" + r.read() + "));\n";
  553.             case LLOAD:
  554.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(" + r.read() + "));\n";
  555.             case FLOAD:
  556.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(" + r.read() + "));\n";
  557.             case DLOAD:
  558.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(" + r.read() + "));\n";
  559.             case ALOAD:
  560.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(" + r.read() + "));\n";
  561.             case ILOAD_0:
  562.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(0));\n";
  563.             case ILOAD_1:
  564.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(1));\n";
  565.             case ILOAD_2:
  566.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(2));\n";
  567.             case ILOAD_3:
  568.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(3));\n";
  569.             case LLOAD_0:
  570.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(0));\n";
  571.             case LLOAD_1:
  572.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(1));\n";
  573.             case LLOAD_2:
  574.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(2));\n";
  575.             case LLOAD_3:
  576.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(3));\n";
  577.             case FLOAD_0:
  578.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(0));\n";
  579.             case FLOAD_1:
  580.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(1));\n";
  581.             case FLOAD_2:
  582.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(2));\n";
  583.             case FLOAD_3:
  584.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(3));\n";
  585.             case DLOAD_0:
  586.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(0));\n";
  587.             case DLOAD_1:
  588.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(1));\n";
  589.             case DLOAD_2:
  590.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(2));\n";
  591.             case DLOAD_3:
  592.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(3));\n";
  593.             case ALOAD_0:
  594.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(0));\n";
  595.             case ALOAD_1:
  596.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(1));\n";
  597.             case ALOAD_2:
  598.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(2));\n";
  599.             case ALOAD_3:
  600.                 return (c, r) -> "VMStack.push(VMLocalVariables.get(3));\n";
  601.             case IALOAD:
  602.                 return (c, r) -> "VMStack.push(VMStack.pop()[VMStack.pop()]);\n";
  603.             case LALOAD:
  604.                 return (c, r) -> "VMStack.push(VMStack.pop()[VMStack.pop()]);\n";
  605.             case FALOAD:
  606.                 return (c, r) -> "VMStack.push(VMStack.pop()[VMStack.pop()]);\n";
  607.             case DALOAD:
  608.                 return (c, r) -> "VMStack.push(VMStack.pop()[VMStack.pop()]);\n";
  609.             case AALOAD:
  610.                 return (c, r) -> "VMStack.push(VMStack.pop()[VMStack.pop()]);\n";
  611.             case BALOAD:
  612.                 return (c, r) -> "VMStack.push(VMStack.pop()[VMStack.pop()]);\n";
  613.             case CALOAD:
  614.                 return (c, r) -> "VMStack.push(VMStack.pop()[VMStack.pop()]);\n";
  615.             case SALOAD:
  616.                 return (c, r) -> "VMStack.push(VMStack.pop()[VMStack.pop()]);\n";
  617.             case ISTORE:
  618.                 return (c, r) -> "VMLocalVariables.set(" + r.read() + ", VMStack.pop());\n";
  619.             case LSTORE:
  620.                 return (c, r) -> "VMLocalVariables.set(" + r.read() + ", VMStack.pop());\n";
  621.             case FSTORE:
  622.                 return (c, r) -> "VMLocalVariables.set(" + r.read() + ", VMStack.pop());\n";
  623.             case DSTORE:
  624.                 return (c, r) -> "VMLocalVariables.set(" + r.read() + ", VMStack.pop());\n";
  625.             case ASTORE:
  626.                 return (c, r) -> "VMLocalVariables.set(" + r.read() + ", VMStack.pop());\n";
  627.             case ISTORE_0:
  628.                 return (c, r) -> "VMLocalVariables.set(0, VMStack.pop());\n";
  629.             case ISTORE_1:
  630.                 return (c, r) -> "VMLocalVariables.set(1, VMStack.pop());\n";
  631.             case ISTORE_2:
  632.                 return (c, r) -> "VMLocalVariables.set(2, VMStack.pop());\n";
  633.             case ISTORE_3:
  634.                 return (c, r) -> "VMLocalVariables.set(3, VMStack.pop());\n";
  635.             case LSTORE_0:
  636.                 return (c, r) -> "VMLocalVariables.set(0, VMStack.pop());\n";
  637.             case LSTORE_1:
  638.                 return (c, r) -> "VMLocalVariables.set(1, VMStack.pop());\n";
  639.             case LSTORE_2:
  640.                 return (c, r) -> "VMLocalVariables.set(2, VMStack.pop());\n";
  641.             case LSTORE_3:
  642.                 return (c, r) -> "VMLocalVariables.set(3, VMStack.pop());\n";
  643.             case FSTORE_0:
  644.                 return (c, r) -> "VMLocalVariables.set(0, VMStack.pop());\n";
  645.             case FSTORE_1:
  646.                 return (c, r) -> "VMLocalVariables.set(1, VMStack.pop());\n";
  647.             case FSTORE_2:
  648.                 return (c, r) -> "VMLocalVariables.set(2, VMStack.pop());\n";
  649.             case FSTORE_3:
  650.                 return (c, r) -> "VMLocalVariables.set(3, VMStack.pop());\n";
  651.             case DSTORE_0:
  652.                 return (c, r) -> "VMLocalVariables.set(0, VMStack.pop());\n";
  653.             case DSTORE_1:
  654.                 return (c, r) -> "VMLocalVariables.set(1, VMStack.pop());\n";
  655.             case DSTORE_2:
  656.                 return (c, r) -> "VMLocalVariables.set(2, VMStack.pop());\n";
  657.             case DSTORE_3:
  658.                 return (c, r) -> "VMLocalVariables.set(3, VMStack.pop());\n";
  659.             case ASTORE_0:
  660.                 return (c, r) -> "VMLocalVariables.set(0, VMStack.pop());\n";
  661.             case ASTORE_1:
  662.                 return (c, r) -> "VMLocalVariables.set(1, VMStack.pop());\n";
  663.             case ASTORE_2:
  664.                 return (c, r) -> "VMLocalVariables.set(2, VMStack.pop());\n";
  665.             case ASTORE_3:
  666.                 return (c, r) -> "VMLocalVariables.set(3, VMStack.pop());\n";
  667.             case IASTORE:
  668.                 return (c, r) -> "VMStack.pop()[VMStack.pop()] = VMStack.pop();\n";
  669.             case LASTORE:
  670.                 return (c, r) -> "VMStack.pop()[VMStack.pop()] = VMStack.pop();\n";
  671.             case FASTORE:
  672.                 return (c, r) -> "VMStack.pop()[VMStack.pop()] = VMStack.pop();\n";
  673.             case DASTORE:
  674.                 return (c, r) -> "VMStack.pop()[VMStack.pop()] = VMStack.pop();\n";
  675.             case AASTORE:
  676.                 return (c, r) -> "VMStack.pop()[VMStack.pop()] = VMStack.pop();\n";
  677.             case BASTORE:
  678.                 return (c, r) -> "VMStack.pop()[VMStack.pop()] = VMStack.pop();\n";
  679.             case CASTORE:
  680.                 return (c, r) -> "VMStack.pop()[VMStack.pop()] = VMStack.pop();\n";
  681.             case SASTORE:
  682.                 return (c, r) -> "VMStack.pop()[VMStack.pop()] = VMStack.pop();\n";
  683.             case POP:
  684.                 return (c, r) -> "VMStack.pop();\n";
  685.             case POP2:
  686.                 return (c, r) -> "VMStack.pop();\nVMStack.pop();\n";
  687.             case DUP:
  688.                 return (c, r) -> "VMStack.Value val = VMStack.pop();\nVMStack.push(val);\nVMStack.push(val);\n";
  689.             case DUP_X1:
  690.                 return (c, r) -> "VMStack.Value top = VMStack.pop();\nVMStack.Value next = VMStack.pop();\nVMStack.push(top);\nVMStack.push(next);\nVMStack.push(top);\n";
  691.             case DUP_X2:
  692.                 return (c, r) -> "VMStack.Value top = VMStack.pop();\nVMStack.Value next = VMStack.pop();\nVMStack.Value next2 = VMStack.pop();\nVMStack.push(top);\nVMStack.push(next2);\nVMStack.push(next);\nVMStack.push(top);\n";
  693.             case DUP2:
  694.                 return (c, r) -> "VMStack.Value top = VMStack.pop();\nVMStack.Value next = VMStack.pop();\nVMStack.push(next);\nVMStack.push(top);\nVMStack.push(next);\nVMStack.push(top);\n";
  695.             case DUP2_X1:
  696.                 return (c, r) -> "VMStack.Value top = VMStack.pop();\nVMStack.Value next = VMStack.pop();\nVMStack.Value next2 = VMStack.pop();\nVMStack.push(next);\nVMStack.push(top);\nVMStack.push(next2);\nVMStack.push(next);\nVMStack.push(top);\n";
  697.             case DUP2_X2:
  698.                 return (c, r) -> "VMStack.Value top = VMStack.pop();\nVMStack.Value next = VMStack.pop();\nVMStack.Value next2 = VMStack.pop();\nVMStack.Value next3 = VMStack.pop();\nVMStack.push(next);\nVMStack.push(top);\nVMStack.push(next3);\nVMStack.push(next2);\nVMStack.push(next);\nVMStack.push(top);\n";
  699.             case SWAP:
  700.                 return (c, r) -> "VMStack.Value top = VMStack.pop();\nVMStack.Value next = VMStack.pop();\nVMStack.push(top);\nVMStack.push(next);\n";
  701.             case IADD:
  702.                 return (c, r) -> "VMStack.push(VMStack.pop() + VMStack.pop());\n";
  703.             case LADD:
  704.                 return (c, r) -> "VMStack.push(VMStack.pop() + VMStack.pop());\n";
  705.             case FADD:
  706.                 return (c, r) -> "VMStack.push(VMStack.pop() + VMStack.pop());\n";
  707.             case DADD:
  708.                 return (c, r) -> "VMStack.push(VMStack.pop() + VMStack.pop());\n";
  709.             case ISUB:
  710.                 return (c, r) -> "VMStack.push(VMStack.pop() - VMStack.pop());\n";
  711.             case LSUB:
  712.                 return (c, r) -> "VMStack.push(VMStack.pop() - VMStack.pop());\n";
  713.             case FSUB:
  714.                 return (c, r) -> "VMStack.push(VMStack.pop() - VMStack.pop());\n";
  715.             case DSUB:
  716.                 return (c, r) -> "VMStack.push(VMStack.pop() - VMStack.pop());\n";
  717.             case IMUL:
  718.                 return (c, r) -> "VMStack.push(VMStack.pop() * VMStack.pop());\n";
  719.             case LMUL:
  720.                 return (c, r) -> "VMStack.push(VMStack.pop() * VMStack.pop());\n";
  721.             case FMUL:
  722.                 return (c, r) -> "VMStack.push(VMStack.pop() * VMStack.pop());\n";
  723.             case DMUL:
  724.                 return (c, r) -> "VMStack.push(VMStack.pop() * VMStack.pop());\n";
  725.             case IDIV:
  726.                 return (c, r) -> "VMStack.push(VMStack.pop() / VMStack.pop());\n";
  727.             case LDIV:
  728.                 return (c, r) -> "VMStack.push(VMStack.pop() / VMStack.pop());\n";
  729.             case FDIV:
  730.                 return (c, r) -> "VMStack.push(VMStack.pop() / VMStack.pop());\n";
  731.             case DDIV:
  732.                 return (c, r) -> "VMStack.push(VMStack.pop() / VMStack.pop());\n";
  733.             case IREM:
  734.                 return (c, r) -> "VMStack.push(VMStack.pop() % VMStack.pop());\n";
  735.             case LREM:
  736.                 return (c, r) -> "VMStack.push(VMStack.pop() % VMStack.pop());\n";
  737.             case FREM:
  738.                 return (c, r) -> "VMStack.push(VMStack.pop() % VMStack.pop());\n";
  739.             case DREM:
  740.                 return (c, r) -> "VMStack.push(VMStack.pop() % VMStack.pop());\n";
  741.             case INEG:
  742.                 return (c, r) -> "VMStack.push(-VMStack.pop());\n";
  743.             case LNEG:
  744.                 return (c, r) -> "VMStack.push(-VMStack.pop());\n";
  745.             case FNEG:
  746.                 return (c, r) -> "VMStack.push(-VMStack.pop());\n";
  747.             case DNEG:
  748.                 return (c, r) -> "VMStack.push(-VMStack.pop());\n";
  749.             case ISHL:
  750.                 return (c, r) -> "VMStack.push(VMStack.pop() << VMStack.pop());\n";
  751.             case LSHL:
  752.                 return (c, r) -> "VMStack.push(VMStack.pop() << VMStack.pop());\n";
  753.             case ISHR:
  754.                 return (c, r) -> "VMStack.push(VMStack.pop() >> VMStack.pop());\n";
  755.             case LSHR:
  756.                 return (c, r) -> "VMStack.push(VMStack.pop() >> VMStack.pop());\n";
  757.             case IUSHR:
  758.                 return (c, r) -> "VMStack.push(VMStack.pop() >>> VMStack.pop());\n";
  759.             case LUSHR:
  760.                 return (c, r) -> "VMStack.push(VMStack.pop() >>> VMStack.pop());\n";
  761.             case IAND:
  762.                 return (c, r) -> "VMStack.push(VMStack.pop() & VMStack.pop());\n";
  763.             case LAND:
  764.                 return (c, r) -> "VMStack.push(VMStack.pop() & VMStack.pop());\n";
  765.             case IOR:
  766.                 return (c, r) -> "VMStack.push(VMStack.pop() | VMStack.pop());\n";
  767.             case LOR:
  768.                 return (c, r) -> "VMStack.push(VMStack.pop() | VMStack.pop());\n";
  769.             case IXOR:
  770.                 return (c, r) -> "VMStack.push(VMStack.pop() ^ VMStack.pop());\n";
  771.             case LXOR:
  772.                 return (c, r) -> "VMStack.push(VMStack.pop() ^ VMStack.pop());\n";
  773.             case IINC:
  774.                 return (c, r) -> "VMLocalVariables.set(" + r.read() + ", VMLocalVariables.get(" + r.read() + ") + 1);\n";
  775.             case I2L:
  776.                 return (c, r) -> "VMStack.cast(long.class);\n";
  777.             case I2F:
  778.                 return (c, r) -> "VMStack.cast(float.class);\n";
  779.             case I2D:
  780.                 return (c, r) -> "VMStack.cast(double.class);\n";
  781.             case L2I:
  782.                 return (c, r) -> "VMStack.cast(long.class);\n";
  783.             case L2F:
  784.                 return (c, r) -> "VMStack.cast(float.class);\n";
  785.             case L2D:
  786.                 return (c, r) -> "VMStack.cast(double.class);\n";
  787.             case F2I:
  788.                 return (c, r) -> "VMStack.cast(long.class);\n";
  789.             case F2L:
  790.                 return (c, r) -> "VMStack.cast(float.class);\n";
  791.             case F2D:
  792.                 return (c, r) -> "VMStack.cast(double.class);\n";
  793.             case D2I:
  794.                 return (c, r) -> "VMStack.cast(long.class);\n";
  795.             case D2L:
  796.                 return (c, r) -> "VMStack.cast(float.class);\n";
  797.             case D2F:
  798.                 return (c, r) -> "VMStack.cast(double.class);\n";
  799.             case I2B:
  800.                 return (c, r) -> "VMStack.cast(byte.class);\n";
  801.             case I2C:
  802.                 return (c, r) -> "VMStack.cast(char.class);\n";
  803.             case I2S:
  804.                 return (c, r) -> "VMStack.cast(short.class);\n";
  805.             case LCMP:
  806.                 return (c, r) -> "VMStack.push(Long.compare(VMStack.pop(), VMStack.pop()));\n";
  807.             case FCMPL:
  808.                 return (c, r) -> "float f1 = VMStack.pop();\nfloat f2 = VMStack.pop();\nVMStack.push(Float.compare(f1 == Float.NAN ? -1F : f1, f2 == Float.NAN ? -1F : f2));\n";
  809.             case FCMPG:
  810.                 return (c, r) -> "float f1 = VMStack.pop();\nfloat f2 = VMStack.pop();\nVMStack.push(Float.compare(f1 == Float.NAN ? 1F : f1, f2 == Float.NAN ? 1F : f2));\n";
  811.             case DCMPL:
  812.                 return (c, r) -> "double d1 = VMStack.pop();\ndouble d2 = VMStack.pop();\nVMStack.push(Double.compare(d1 == Double.NAN ? -1D : d1, d2 == Double.NAN ? -1D : d2));\n";
  813.             case DCMPG:
  814.                 return (c, r) -> "double d1 = VMStack.pop();\ndouble d2 = VMStack.pop();\nVMStack.push(Double.compare(d1 == Double.NAN ? 1D : d1, d2 == Double.NAN ? 1D : d2));\n";
  815.             case IFEQ:
  816.                 return (c, r) -> "if (VMStack.pop() == 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  817.             case IFNE:
  818.                 return (c, r) -> "if (VMStack.pop() != 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  819.             case IFLT:
  820.                 return (c, r) -> "if (VMStack.pop() < 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  821.             case IFGE:
  822.                 return (c, r) -> "if (VMStack.pop() >= 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  823.             case IFGT:
  824.                 return (c, r) -> "if (VMStack.pop() > 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  825.             case IFLE:
  826.                 return (c, r) -> "if (VMStack.pop() <= 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  827.             case IF_ICMPEQ:
  828.                 return (c, r) -> "if (VMStack.pop() == 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  829.             case IF_ICMPNE:
  830.                 return (c, r) -> return "if (VMStack.pop() != 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  831.             case IF_ICMPLT:
  832.                 return (c, r) -> "if (VMStack.pop() < 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  833.             case IF_ICMPGE:
  834.                 return (c, r) -> "if (VMStack.pop() >= 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  835.             case IF_ICMPGT:
  836.                 return (c, r) -> "if (VMStack.pop() > 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  837.             case IF_ICMPLE:
  838.                 return (c, r) -> "if (VMStack.pop() <= 0) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  839.             case IF_ACMPEQ:
  840.                 return (c, r) -> "if (VMStack.pop() == VMStack.pop()) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  841.             case IF_ACMPNE:
  842.                 return (c, r) -> "if (VMStack.pop() != VMStack.pop()) {\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n}\n";
  843.             case GOTO:
  844.                 return (c, r) -> return "VirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n";
  845.             case JSR:
  846.                 return (c, r) -> "VMStack.push(VirtualMachine.programCounter);\nVirtualMachine.jumpTo(" + (r.read() << 8) | r.read() + ");\n$$StringFormSoftStopNotifier;\n";
  847.             case RTS:
  848.                 return (c, r) -> "VirtualMachine.jumpTo(VMLocalVariables.get(" + r.read() + "));\n$$StringFormSoftStopNotifier;\n";
  849.             case TABLESWITCH:
  850.                 return (c, r) -> {
  851.                     byte[] data = new byte[12];
  852.                     int read;
  853.                     while ((read = r.read()) == 0) {}
  854.                     data[0] = (byte)read;
  855.                     for (int i = 0; i <= 10; i++)
  856.                         data[i + 1] = (byte)r.read();
  857.                     int defaultValue = ((data[0] << 24) | (data[1] << 16)) | ((data[2] << 8) | data[3]);
  858.                     int lowLength = ((data[4] << 24) | (data[5] << 16)) | ((data[6] << 8) | data[7]);
  859.                     int highLength = ((data[8] << 24) | (data[9] << 16)) | ((data[10] << 8) | data[11]);
  860.                     int jumpLength = highLength - lowLength + 1;
  861.                     int[] jumpTable = new int[jumpLength];
  862.                     for (int i = 0; i <= jumpLength; i++)
  863.                         jumpTable[i] = ((r.read() << 24) | (r.read() << 16)) | ((r.read() << 8) | r.read());
  864.                     return "int[] jumpTable = " + Arrays.toString(jumpTable).replaceAll("[", "{").replaceAll("]", "}") + ";\nVirtualMachine.jumpTo(jumpTable[VMStack.pop()]);\n$$StringFormSoftStopNotifier;\n";
  865.                 }
  866.             case LOOKUPSWITCH:
  867.                 return (c, r) -> {
  868.                     byte[] data = new byte[12];
  869.                     int read;
  870.                     while ((read = r.read()) == 0) {}
  871.                     data[0] = (byte)read;
  872.                     for (int i = 0; i <= 10; i++)
  873.                         data[i + 1] = (byte)r.read();
  874.                     int pairLength = ((data[4] << 24) | (data[5] << 16)) | ((data[6] << 8) | data[7]);
  875.                     int[] keys = new int[pairLength];
  876.                     Arrays.fill(keys, 0);
  877.                     int[] values = new int[pairLength];
  878.                     for (int i = 0; i <= pairLength; i++) {
  879.                         keys[((r.read() << 24) | (r.read() << 16)) | ((r.read() << 8) | r.read())] = i;
  880.                         values[i] = ((r.read() << 24) | (r.read() << 16)) | ((r.read() << 8) | r.read());
  881.                     }
  882.                     return "int[] keys = " + Arrays.toString(keys).replaceAll("[", "{").replaceAll("]", "}") + ";\nint[] values = " + Arrays.toString(values).replaceAll("[", "{").replaceAll("]", "}") + ";\nVirtualMachine.jumpTo(values[keys[VMStack.pop()]]);\n$$StringFormSoftStopNotifier;\n";
  883.                 }
  884.             case IRETURN:
  885.                 return (c, r) -> "return VMStack.pop();\n$$StringFormHardStopNotifier;\n";
  886.             case LRETURN:
  887.                 return (c, r) -> "return VMStack.pop();\n$$StringFormHardStopNotifier;\n";
  888.             case FRETURN:
  889.                 return (c, r) -> "return VMStack.pop();\n$$StringFormHardStopNotifier;\n";
  890.             case DRETURN:
  891.                 return (c, r) -> "return VMStack.pop();\n$$StringFormHardStopNotifier;\n";
  892.             case ARETURN:
  893.                 return (c, r) -> "return VMStack.pop();\n$$StringFormHardStopNotifier;\n";
  894.             case RETURN:
  895.                 return (c, r) -> "return;\n$$StringFormHardStopNotifier;\n";
  896.             case GETSTATIC:
  897.                 return (c, r) -> {
  898.                     FieldReference ref = ((FieldReference)c.get((r.read() << 8) | r.read()).get(c));
  899.                     return "VMStack.push(" + ref.getClass().toString() + "." + ref.getNameAndType().getName() + ");\n";
  900.                 }
  901.             case PUTSTATIC:
  902.                 return (c, r) -> {
  903.                     FieldReference ref = ((FieldReference)constants.get((r.read() << 8) | r.read()).get(c));
  904.                     return ref.getClass().toString() + "." + ref.getNameAndType().getName() + " = VMStack.pop();\n";
  905.                 }
  906.             case GETFIELD:
  907.                 return (c, r) -> {
  908.                     FieldReference ref = ((FieldReference)c.get((r.read() << 8) | r.read()).get(c));
  909.                     return "VMStack.push(VMStack.pop()." + ref.getNameAndType().getName() + ");\n";
  910.                 }
  911.             case PUTFIELD:
  912.                 return (c, r) -> {
  913.                     FieldReference ref = ((FieldReference)c.get((r.read() << 8) | r.read()).get(c));
  914.                     return "VMStack.pop()." + ref.getNameAndType().getName() + " = VMStack.pop();\n";
  915.                 }
  916.             case INVOKEVIRTUAL:
  917.                 return (c, r) -> {
  918.                     MethodReference ref = ((MethodReference)c.get((r.read() << 8) | r.read()).get(c));
  919.                     return "VMStack.push(VMStack.pop()." + ref.getNameAndType().getName() + "());\n";
  920.                 }
  921.             case INVOKESPECIAL:
  922.                 return (c, r) -> {
  923.                     MethodReference ref = ((MethodReference)c.get((r.read() << 8) | r.read()).get(c));
  924.                     return "VMStack.push(new " + ref.getClass().toString() + "());\n";
  925.                 }
  926.             case INVOKESTATIC:
  927.                 return (c, r) -> {
  928.                     MethodReference ref = ((MethodReference)c.get((r.read() << 8) | r.read()).get(c));
  929.                     return "VMStack.push(" + ref.getClass().toString() + "." + ref.getNameAndType().getName() + "());\n";
  930.                 }
  931.             case INVOKEINTERFACE:
  932.                 return (c, r) -> {
  933.                     AbstractMethodReference ref = ((AbstractMethodReference)c.get((r.read() << 8) | r.read()));
  934.                     return "VMStack.push(VMStack.pop()." + ref.getNameAndType().getName() + "());\n";
  935.                 }
  936.             case INVOKEDYNAMIC:
  937.                 return (c, r) -> {
  938.                     MethodReference ref = ((MethodReference)constants.get((r.read() << 8) | r.read()));
  939.                     return "VMStack.push(VMStack.pop()." + ref.getNameAndType().getName() + "());\n";
  940.                 }
  941.             case NEW:
  942.                 return (c, r) -> {
  943.                     r.skip(2);
  944.                     return "";
  945.                 }
  946.             case NEWARRAY:
  947.                 return (c, r) -> {
  948.                     String type;
  949.                     switch (r.read()) {
  950.                         case 4:
  951.                             type = "boolean";
  952.                             break;
  953.                         case 5:
  954.                             type = "char";
  955.                             break;
  956.                         case 6:
  957.                             type = "float";
  958.                             break;
  959.                         case 7:
  960.                             type = "double";
  961.                             break;
  962.                         case 8:
  963.                             type = "byte";
  964.                             break;
  965.                         case 9:
  966.                             type = "short";
  967.                             break;
  968.                         case 10:
  969.                             type = "int";
  970.                             break;
  971.                         case 11:
  972.                             type = "long";
  973.                             break;
  974.                     }
  975.                     return "VMStack.push(new " + type + "[VMStack.pop()]);\n";
  976.                 }
  977.             case ANEWARRAY:
  978.                 return (c, r) -> {
  979.                     return "VMStack.push(new " + ((ClassReference)constants.get((r.read() << 8) | r.read())).toString() + "[VMStack.pop()]);\n";
  980.                 }
  981.             case ARRAYLENGTH:
  982.                 return (c, r) -> "VMStack.push(VMStack.pop().length);\n";
  983.             case ATHROW:
  984.                 return (c, r) -> "throw VMStack.pop();\n$$StringFormHardStopNotifier;\n";
  985.             case CHECKCAST:
  986.                 return (c, r) -> "VMStack.cast(" + ((ClassReference)constants.get((r.read() << 8) | r.read())).toString() + ".class);\n";
  987.             case INSTANCEOF:
  988.                 return (c, r) -> "VMStack.push(VMStack.pop() instanceof " + ((ClassReference)constants.get((r.read() << 8) | r.read())).toString() + ");\n";
  989.             case MONITORENTER:
  990.                 return (c, r) -> "";
  991.             case MONITOREXIT:
  992.                 return (c, r) -> "";
  993.             case WIDE:
  994.                 return (c, r) -> return get(r.read()).toString(i, c, a, r);
  995.             case MULTIANEWARRAY:
  996.                 return (c, r) -> {
  997.                     String s = "VMStack.push(new " + ((ClassReference)constants.get((r.read() << 8) | r.read())).toString();
  998.                     for (int i = 0; i <= r.read(); i++)
  999.                         s = s.concat("[VMStack.pop()]");
  1000.                     return s.concat(");\n");
  1001.                 }
  1002.             case IFNULL:
  1003.                 return (c, r) -> "if (VMStack.pop() == null) {\nVirtualMachine.jumpTo(" + ((r.read() << 24) | (r.read() << 16)) | (r.read() << 8) | r.read())) + ");\n$$StringFormSoftStopNotifier;\n}\n";
  1004.             case IFNONNULL:
  1005.                 return (c, r) -> "if (VMStack.pop() != null) {\nVirtualMachine.jumpTo(" + ((r.read() << 24) | (r.read() << 16)) | ((r.read() << 8) | r.read())) + ";\n$$StringFormSoftStopNotifier;\n}\n";
  1006.             case GOTO_W:
  1007.                 return (c, r) -> "VirtualMachine.jumpTo(" + ((r.read() << 24) | (r.read() << 16)) | (r.read() << 8) | r.read())) + ";\n$$StringFormSoftStopNotifier;\n";
  1008.             case JSR_W:
  1009.                 return (c, r) -> {
  1010.                     r.skip(4);
  1011.                     return "";
  1012.                 }
  1013.             case BREAKPOINT:
  1014.                 return (c, r) -> "";
  1015.             case IMPDEP1:
  1016.                 return (c, r) -> "";
  1017.             case IMPDEP2:
  1018.                 return (c, r) -> "";
  1019.             default:
  1020.                 return (c, r) -> "";
  1021.         }
  1022.     }
  1023. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement