Files
ByteEdit/src/me/ByteEdit/main/Assembler.java
T

1479 lines
42 KiB
Java

package me.ByteEdit.main;
import java.awt.Color;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.text.BadLocationException;
import org.apache.commons.lang3.StringEscapeUtils;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.LineNumberNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.LookupSwitchInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
public class Assembler {
public static ClassNode assemble(String input) {
Main.textArea.removeAllLineHighlights();
CustomBufferedReader read = null;
try {
ClassNode clazz = new ClassNode();
read = new CustomBufferedReader(new StringReader(input));
String s;
while (!(s = read.readLine()).startsWith("// #Class v:")) {
if (clazz.visibleAnnotations == null) {
clazz.visibleAnnotations = new ArrayList<>();
}
clazz.visibleAnnotations.add(parseAnnotation(s));
}
clazz.version = Integer.parseInt(s.substring(12));
while ((s = read.readLine()).startsWith("// ")) {
if (s.startsWith("// #Signature: ")) {
clazz.signature = s.substring(15).equals("null") ? null : s.substring(15);
} else if (s.startsWith("// #OuterClass: ")) {
clazz.outerClass = s.substring(16).equals("null") ? null : s.substring(16);
} else if (s.equals("// #InnerClasses:")) {
clazz.innerClasses = new ArrayList<>();
} else {
String split[] = s.split(" ");
clazz.innerClasses.add(new InnerClassNode(split[1], split[2].equals("null") ? null : split[2],
split[3].equals("null") ? null : split[3], Integer.parseInt(split[4].substring(2), 16)));
}
}
{
s = s.substring(0, s.length() - 2);
if (s.contains(" implements ")) {
String interfaces = s.substring(s.indexOf(" implements ") + 12);
clazz.interfaces = new ArrayList<>();
for (String interf : interfaces.split(", ")) {
clazz.interfaces.add(interf);
}
s = s.substring(0, s.indexOf(" implements "));
}
clazz.superName = s.substring(s.indexOf(" extends ") + 9);
s = s.substring(0, s.indexOf(" extends "));
String[] split = s.split(" ");
clazz.name = split[split.length - 1];
clazz.access = ClassUtil.ACC_SUPER;
switch (split[split.length - 2]) {
case "class":
break;
case "enum":
clazz.access ^= ClassUtil.ACC_ENUM;
break;
case "interface":
clazz.access = 0;
clazz.access ^= ClassUtil.ACC_ABSTRACT;
clazz.access ^= ClassUtil.ACC_INTERFACE;
break;
case "@interface":
clazz.access = 0;
clazz.access ^= ClassUtil.ACC_ABSTRACT;
clazz.access ^= ClassUtil.ACC_ANNOTATION;
clazz.access ^= ClassUtil.ACC_INTERFACE;
break;
}
if (split.length > 2) {
String cons = consolidateStrings(split, 0, split.length - 2);
if (cons.contains("public")) {
clazz.access ^= ClassUtil.ACC_PUBLIC;
}
if (cons.contains("final")) {
clazz.access ^= ClassUtil.ACC_FINAL;
}
if (cons.contains("synthetic")) {
clazz.access ^= ClassUtil.ACC_SYNTHETIC;
}
if (cons.contains("abstract")) {
clazz.access ^= ClassUtil.ACC_ABSTRACT;
}
}
}
s = read.readLine();
clazz.sourceFile = s.substring(16).equals("null") ? null : s.substring(16);
while (!(s = read.readLine()).equals("// #Fields")) {
}
clazz.fields = new ArrayList<>();
clazz.methods = new ArrayList<>();
String signature = null;
ArrayList<String> annotationsForNext = new ArrayList<>();
while (!(s = read.readLine()).equals("// #Methods")) {
s = s.trim();
if (s.isEmpty())
continue;
if (s.startsWith("@")) {
annotationsForNext.add(s);
} else {
if (s.startsWith("// #Signature: ")) {
signature = s.substring(15);
} else {
String[] split = s.split(" ");
boolean hasValue = false;
if (s.contains(" = ")) {
hasValue = true;
}
Object value = hasValue ? split[split.length - 1] : null;
if (hasValue) {
split = s.substring(0, s.indexOf(" = ")).split(" ");
}
String name = split[split.length - 1];
String desc = split[split.length - 2];
value = getValue((String) value, desc);
int access = 0;
if (split.length > 2) {
String cons = consolidateStrings(split, 0, split.length - 2);
if (cons.startsWith("0x")) {
access = Integer.parseInt(cons.substring(2), 16);
} else {
if (cons.contains("public")) {
access ^= ClassUtil.ACC_PUBLIC;
}
if (cons.contains("private")) {
access ^= ClassUtil.ACC_PRIVATE;
}
if (cons.contains("protected")) {
access ^= ClassUtil.ACC_PROTECTED;
}
if (cons.contains("static")) {
access ^= ClassUtil.ACC_STATIC;
}
if (cons.contains("final")) {
access ^= ClassUtil.ACC_FINAL;
}
if (cons.contains("synchronized")) {
access ^= ClassUtil.ACC_SYNCHRONIZED;
}
if (cons.contains("bridge")) {
access ^= ClassUtil.ACC_BRIDGE;
}
if (cons.contains("varargs")) {
access ^= ClassUtil.ACC_VARARGS;
}
if (cons.contains("native")) {
access ^= ClassUtil.ACC_NATIVE;
}
if (cons.contains("interface")) {
access ^= ClassUtil.ACC_INTERFACE;
}
if (cons.contains("abstract")) {
access ^= ClassUtil.ACC_ABSTRACT;
}
if (cons.contains("strictfp")) {
access ^= ClassUtil.ACC_STRICTFP;
}
if (cons.contains("synthetic")) {
access ^= ClassUtil.ACC_SYNTHETIC;
}
if (cons.contains("annotation")) {
access ^= ClassUtil.ACC_ANNOTATION;
}
if (cons.contains("enum")) {
access ^= ClassUtil.ACC_ENUM;
}
if (cons.contains("mandated")) {
access ^= ClassUtil.ACC_MANDATED;
}
}
}
FieldNode node = new FieldNode(access, name, desc, signature, value);
if (!annotationsForNext.isEmpty()) {
if (node.visibleAnnotations == null) {
node.visibleAnnotations = new ArrayList<>();
}
for (String anno : annotationsForNext) {
node.visibleAnnotations.add(parseAnnotation(anno));
}
annotationsForNext.clear();
}
clazz.fields.add(node);
signature = null;
}
}
}
HashMap<Label, Integer> methodLabelMap = new HashMap<Label, Integer>();
annotationsForNext.clear();
MethodNode node = null;
String temp = "";
ArrayList<String> localVarsToParse = new ArrayList<>();
ArrayList<String> tryCatchBlocksToParse = new ArrayList<>();
int stage = 0;
while ((s = read.readLine()) != null) {
if (s.trim().isEmpty() || s.equals("}"))
continue;
s = s.substring(1);
if (s.startsWith("@")) {
annotationsForNext.add(s.trim());
} else {
if (s.startsWith("// #Max: ")) {
node = new MethodNode();
node.exceptions = new ArrayList<>();
node.tryCatchBlocks = new ArrayList<>();
node.localVariables = new ArrayList<>();
node.instructions = new InsnList();
s = s.substring(11);
node.maxLocals = Integer.parseInt(s.split(" ")[0]);
node.maxStack = Integer.parseInt(s.split(" ")[1].substring(2));
localVarsToParse.clear();
tryCatchBlocksToParse.clear();
stage = 0;
} else if (s.startsWith("// #Signature: ")) {
node.signature = s.substring(15);
} else if (s.equals("// #TryCatch:")) {
stage = 1;
} else if (s.equals("// #LocalVars:")) {
stage = 2;
} else if (s.startsWith("// ")) {
s = s.substring(3);
if (stage == 1) {
tryCatchBlocksToParse.add(s);
} else if (stage == 2) {
localVarsToParse.add(s);
}
} else if (s.equals("}")) {
if (!annotationsForNext.isEmpty()) {
if (node.visibleAnnotations == null) {
node.visibleAnnotations = new ArrayList<>();
}
for (String anno : annotationsForNext) {
node.visibleAnnotations.add(parseAnnotation(anno));
}
annotationsForNext.clear();
}
for (String st : localVarsToParse) {
String[] sp = st.split(":");
int start = Integer.parseInt(sp[3].substring(0, sp[3].length() - 2));
int end = Integer.parseInt(sp[4].substring(0, sp[4].length() - 4));
String signat = sp[5].equals("null") ? null : sp[5];
LabelNode _start = null;
LabelNode _end = null;
for (Entry<Label, Integer> entry : methodLabelMap.entrySet()) {
if (entry.getValue() == start) {
_start = new LabelNode(entry.getKey());
}
if (entry.getValue() == end) {
_end = new LabelNode(entry.getKey());
}
}
node.localVariables.add(new LocalVariableNode(sp[0], sp[1].substring(1, sp[1].length() - 2),
signat, _start, _end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
}
for (String st : tryCatchBlocksToParse) {
String[] sp = st.split(" ");
int start = Integer.parseInt(sp[1].substring(2));
int end = Integer.parseInt(sp[2].substring(2));
int handler = Integer.parseInt(sp[3].substring(2));
LabelNode _start = null;
LabelNode _end = null;
LabelNode _handler = null;
for (Entry<Label, Integer> entry : methodLabelMap.entrySet()) {
if (entry.getValue() == start) {
_start = new LabelNode(entry.getKey());
}
if (entry.getValue() == end) {
_end = new LabelNode(entry.getKey());
}
if (entry.getValue() == handler) {
_handler = new LabelNode(entry.getKey());
}
}
node.tryCatchBlocks.add(
new TryCatchBlockNode(_start, _end, _handler, sp[0].equals("null") ? null : sp[0]));
}
clazz.methods.add(node);
// signature = null;
} else if (!s.startsWith("\t")) {
s = s.substring(0, s.length() - 2);
if (s.contains(" throws ")) {
String exceptions = s.substring(s.indexOf(" throws ") + 8);
for (String excp : exceptions.split(", ")) {
node.exceptions.add(excp);
}
s = s.substring(0, s.indexOf(" throws "));
}
String[] split = s.split(" ");
node.desc = split[split.length - 1];
node.name = split[split.length - 2];
int access = 0;
if (split.length > 2) {
String cons = consolidateStrings(split, 0, split.length - 2);
if (cons.startsWith("0x")) {
access = Integer.parseInt(cons.substring(2), 16);
} else {
if (cons.contains("public")) {
access ^= ClassUtil.ACC_PUBLIC;
}
if (cons.contains("private")) {
access ^= ClassUtil.ACC_PRIVATE;
}
if (cons.contains("protected")) {
access ^= ClassUtil.ACC_PROTECTED;
}
if (cons.contains("static")) {
access ^= ClassUtil.ACC_STATIC;
}
if (cons.contains("final")) {
access ^= ClassUtil.ACC_FINAL;
}
if (cons.contains("synchronized")) {
access ^= ClassUtil.ACC_SYNCHRONIZED;
}
if (cons.contains("bridge")) {
access ^= ClassUtil.ACC_BRIDGE;
}
if (cons.contains("varargs")) {
access ^= ClassUtil.ACC_VARARGS;
}
if (cons.contains("native")) {
access ^= ClassUtil.ACC_NATIVE;
}
if (cons.contains("interface")) {
access ^= ClassUtil.ACC_INTERFACE;
}
if (cons.contains("abstract")) {
access ^= ClassUtil.ACC_ABSTRACT;
}
if (cons.contains("strictfp")) {
access ^= ClassUtil.ACC_STRICTFP;
}
if (cons.contains("synthetic")) {
access ^= ClassUtil.ACC_SYNTHETIC;
}
if (cons.contains("annotation")) {
access ^= ClassUtil.ACC_ANNOTATION;
}
if (cons.contains("enum")) {
access ^= ClassUtil.ACC_ENUM;
}
if (cons.contains("mandated")) {
access ^= ClassUtil.ACC_MANDATED;
}
}
}
node.access = access;
methodLabelMap.clear();
} else {
s = s.substring(1);
if (!temp.isEmpty()) {
if (s.equals("]")) {
temp += s;
node.instructions.add(getNode(temp, methodLabelMap));
temp = "";
} else {
temp += s + "\n";
}
} else {
if (s.endsWith("[")) {
temp += s + "\n";
} else {
node.instructions.add(getNode(s, methodLabelMap));
}
}
}
}
}
return clazz;
} catch (Throwable e) {
System.err.println("Error at line: " + read.currentLine);
try {
Main.textArea.addLineHighlight(read.currentLine, Color.RED.darker());
} catch (BadLocationException e1) {
System.err.println("Can't show line!");
}
e.printStackTrace();
return null;
} finally {
try {
read.close();
} catch (Exception e) {
}
}
}
public static AnnotationNode parseAnnotation(String s) {
s = s.substring(1);
String[] split = s.split(" ");
AnnotationNode node = new AnnotationNode(split[0]);
if (split.length > 1) {
if (node.values == null) {
node.values = new ArrayList<>();
}
s = consolidateStrings(split, 1);
s = s.substring(1, s.length() - 1);
split = s.split("\\], ");
for (int i = 0; i < split.length; i++) {
String[] split2 = split[i].split(" = \\[");
node.values.add(split2[0]);
String value = split2[1];
if (value.endsWith("]"))
value = value.substring(0, value.length() - 1);
if (value.startsWith("{ ")) {
String split3[] = value.substring(2, value.length() - 2).split(", ");
List<Object> list = new ArrayList<>();
for (String rofl : split3) {
if (!rofl.startsWith("(")) {
int index = rofl.indexOf(";");
list.add(new String[] { rofl.substring(0, index) + ";",
rofl.substring(index).substring(2) });
} else { // anderer typ mit casten
list.add(ClassUtil.getCastedValue(rofl.split(" ")[1], rofl.split("\\) ")[0].substring(1)));
}
}
} else {
if (!value.startsWith("(")) {
int index = value.indexOf(";");
node.values.add(
new String[] { value.substring(0, index) + ";", value.substring(index).substring(2) });
} else { // anderer typ mit casten
node.values.add(
ClassUtil.getCastedValue(value.split(" ")[1], value.split("\\) ")[0].substring(1)));
}
}
}
}
return node;
}
public static String consolidateStrings(String[] args, int start) {
if (args.length == 0) {
return null;
}
String ret = args[start];
if (args.length > start + 1) {
for (int i = start + 1; i < args.length; i++) {
ret = ret + " " + args[i];
}
}
return ret;
}
public static String consolidateStrings(String[] args, int start, int end) {
if (end == 0) {
return null;
}
String ret = args[start];
if (end > start + 1) {
for (int i = start + 1; i < end; i++) {
ret = ret + " " + args[i];
}
}
return ret;
}
public static Object getValue(String s, String to) {
if (s == null) {
return null;
}
switch (to) {
case "B":
return Byte.parseByte(s);
case "Z":
return Boolean.parseBoolean(s);
case "I":
return Integer.parseInt(s);
case "J":
return Long.parseLong(s.substring(0, s.length() - 1));
case "C":
return (char) Integer.parseInt(s);
case "D":
return Double.parseDouble(s);
case "F":
return Float.parseFloat(s.substring(0, s.length() - 1));
case "S":
return Short.parseShort(s);
case "Ljava/lang/String;":
return StringEscapeUtils.unescapeJava(s.substring(1, s.length() - 1)).replace("\\n", "\n").replace("\\r",
"\r");
default: {
return null;
}
}
}
public static AbstractInsnNode getNode(String s, HashMap<Label, Integer> labels) throws Exception {
if (s.startsWith("// label ")) {
int labelNr = Integer.parseInt(s.substring(9));
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new LabelNode(entry.getKey());
}
}
Label l = new Label();
labels.put(l, labelNr);
return new LabelNode(l);
} else if (s.startsWith("// line ")) {
s = s.substring(8);
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new LineNumberNode(Integer.parseInt(s.split(" ")[0]), new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new LineNumberNode(Integer.parseInt(s.split(" ")[0]), new LabelNode(l));
} else if (s.startsWith("// frame ")) {
String str1 = s.substring(9);
String str = str1.substring(2);
Object[] local;
Object[] stack;
ArrayList<Object> arr = new ArrayList<>();
if (str.startsWith("l:null")) {
local = new Object[0];
} else {
String l = str.substring(3, str.indexOf("s:") - 2);
if (l.isEmpty()) {
local = new Object[0];
} else {
for (String asd : l.split(", ")) {
if (!asd.startsWith("(")) {
arr.add(asd);
} else { // anderer typ mit casten
if (asd.startsWith("(label) ")) {
int labelNr = Integer.parseInt(asd.split(" ")[1]);
boolean found = false;
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
arr.add(new LabelNode(entry.getKey()));
found = true;
}
}
if (!found) {
Label lb = new Label();
labels.put(lb, labelNr);
arr.add(new LabelNode(lb));
}
} else {
arr.add(ClassUtil.getCastedValue(asd.split(" ")[1], asd.split("\\) ")[0].substring(1)));
}
}
}
local = new Object[arr.size()];
int c = 0;
for (Object o : arr) {
local[c] = o;
c++;
}
}
}
arr.clear();
if (str.endsWith("s:null")) {
stack = new Object[0];
} else {
String st = str.substring(str.indexOf("s:") + 3, str.length() - 1);
if (st.isEmpty()) {
stack = new Object[0];
} else {
for (String asd : st.split(", ")) {
if (!asd.startsWith("(")) {
arr.add(asd);
} else { // anderer typ mit casten
if (asd.startsWith("(label) ")) {
int labelNr = Integer.parseInt(asd.split(" ")[1]);
boolean found = false;
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
arr.add(new LabelNode(entry.getKey()));
found = true;
}
}
if (!found) {
Label l = new Label();
labels.put(l, labelNr);
arr.add(new LabelNode(l));
}
} else {
arr.add(ClassUtil.getCastedValue(asd.split(" ")[1], asd.split("\\) ")[0].substring(1)));
}
}
}
stack = new Object[arr.size()];
int c = 0;
for (Object o : arr) {
stack[c] = o;
c++;
}
}
}
return new FrameNode(Integer.parseInt(str1.split(" ")[0]), local != null ? local.length : 0, local,
stack != null ? stack.length : 0, stack);
} else {
String[] split = s.split(" ");
String command = split[0];
switch (command) {
case "nop":
return new InsnNode(0);
case "aconst_null":
return new InsnNode(1);
case "iconst_m1":
return new InsnNode(2);
case "iconst_0":
return new InsnNode(3);
case "iconst_1":
return new InsnNode(4);
case "iconst_2":
return new InsnNode(5);
case "iconst_3":
return new InsnNode(6);
case "iconst_4":
return new InsnNode(7);
case "iconst_5":
return new InsnNode(8);
case "lconst_0":
return new InsnNode(9);
case "lconst_1":
return new InsnNode(10);
case "fconst_0":
return new InsnNode(11);
case "fconst_1":
return new InsnNode(12);
case "fconst_2":
return new InsnNode(13);
case "dconst_0":
return new InsnNode(14);
case "dconst_1":
return new InsnNode(15);
case "bipush": {
return new IntInsnNode(16, Integer.parseInt(split[1]));
}
case "sipush": {
return new IntInsnNode(17, Integer.parseInt(split[1]));
}
case "ldc": {
String str = consolidateStrings(split, 1);
Object val;
try {
if (str.startsWith("Type: ")) {
str = str.substring(8, str.length() - 2);
String[] split2 = str.split("\n\t");
Constructor<Type> constr = Type.class.getDeclaredConstructor(int.class, char[].class, int.class,
int.class);
constr.setAccessible(true);
String type = split2[0].substring(7);
val = constr.newInstance(new Object[] { ClassUtil.getIDFromClassNameForType(type),
split2[3].substring(6, split2[3].length() - 1).toCharArray(),
Integer.parseInt(split2[1].substring(5)), Integer.parseInt(split2[2].substring(5)) });
} else if (str.startsWith("\"") && str.endsWith("\"")) {
val = StringEscapeUtils.unescapeJava(str.substring(1, str.length() - 1)).replace("\\n", "\n")
.replace("\\r", "\r");
} else if (str.endsWith("l")) {
val = Long.parseLong(str.substring(0, str.length() - 1));
} else if (str.endsWith("f")) {
val = Float.parseFloat(str.substring(0, str.length() - 1));
} else if (str.contains(".")) {
val = Double.parseDouble(str);
} else {
val = Integer.parseInt(str);
}
} catch (Exception e) {
val = null;
throw e;
}
return new LdcInsnNode(val);
}
case "iload": {
return new VarInsnNode(21, Integer.parseInt(split[1]));
}
case "lload": {
return new VarInsnNode(22, Integer.parseInt(split[1]));
}
case "fload": {
return new VarInsnNode(23, Integer.parseInt(split[1]));
}
case "dload": {
return new VarInsnNode(24, Integer.parseInt(split[1]));
}
case "aload": {
return new VarInsnNode(25, Integer.parseInt(split[1]));
}
case "iaload": {
return new InsnNode(46);
}
case "laload": {
return new InsnNode(47);
}
case "faload": {
return new InsnNode(48);
}
case "daload": {
return new InsnNode(49);
}
case "aaload": {
return new InsnNode(50);
}
case "baload": {
return new InsnNode(51);
}
case "caload": {
return new InsnNode(52);
}
case "saload": {
return new InsnNode(53);
}
case "istore": {
return new VarInsnNode(54, Integer.parseInt(split[1]));
}
case "lstore": {
return new VarInsnNode(55, Integer.parseInt(split[1]));
}
case "fstore": {
return new VarInsnNode(56, Integer.parseInt(split[1]));
}
case "dstore": {
return new VarInsnNode(57, Integer.parseInt(split[1]));
}
case "astore": {
return new VarInsnNode(58, Integer.parseInt(split[1]));
}
case "iastore": {
return new InsnNode(79);
}
case "lastore": {
return new InsnNode(80);
}
case "fastore": {
return new InsnNode(81);
}
case "dastore": {
return new InsnNode(82);
}
case "aastore": {
return new InsnNode(83);
}
case "bastore": {
return new InsnNode(84);
}
case "castore": {
return new InsnNode(85);
}
case "sastore": {
return new InsnNode(86);
}
case "pop": {
return new InsnNode(87);
}
case "pop2": {
return new InsnNode(88);
}
case "dup": {
return new InsnNode(89);
}
case "dup_x1": {
return new InsnNode(90);
}
case "dup_x2": {
return new InsnNode(91);
}
case "dup2": {
return new InsnNode(92);
}
case "dup2_x1": {
return new InsnNode(93);
}
case "dup2_x2": {
return new InsnNode(94);
}
case "swap": {
return new InsnNode(95);
}
case "iadd": {
return new InsnNode(96);
}
case "ladd": {
return new InsnNode(97);
}
case "fadd": {
return new InsnNode(98);
}
case "dadd": {
return new InsnNode(99);
}
case "isub": {
return new InsnNode(100);
}
case "lsub": {
return new InsnNode(101);
}
case "fsub": {
return new InsnNode(102);
}
case "dsub": {
return new InsnNode(103);
}
case "imul": {
return new InsnNode(104);
}
case "lmul": {
return new InsnNode(105);
}
case "fmul": {
return new InsnNode(106);
}
case "dmul": {
return new InsnNode(107);
}
case "idiv": {
return new InsnNode(108);
}
case "ldiv": {
return new InsnNode(109);
}
case "fdiv": {
return new InsnNode(110);
}
case "ddiv": {
return new InsnNode(111);
}
case "irem": {
return new InsnNode(112);
}
case "lrem": {
return new InsnNode(113);
}
case "frem": {
return new InsnNode(114);
}
case "drem": {
return new InsnNode(115);
}
case "ineg": {
return new InsnNode(116);
}
case "lneg": {
return new InsnNode(117);
}
case "fneg": {
return new InsnNode(118);
}
case "dneg": {
return new InsnNode(119);
}
case "ishl": {
return new InsnNode(120);
}
case "lshl": {
return new InsnNode(121);
}
case "ishr": {
return new InsnNode(122);
}
case "lshr": {
return new InsnNode(123);
}
case "iushr": {
return new InsnNode(124);
}
case "lushr": {
return new InsnNode(125);
}
case "iand": {
return new InsnNode(126);
}
case "land": {
return new InsnNode(127);
}
case "ior": {
return new InsnNode(128);
}
case "lor": {
return new InsnNode(129);
}
case "ixor": {
return new InsnNode(130);
}
case "lxor": {
return new InsnNode(131);
}
case "iinc": {
return new IincInsnNode(Integer.parseInt(split[1]), Integer.parseInt(split[3]));
}
case "i2l": {
return new InsnNode(133);
}
case "i2f": {
return new InsnNode(134);
}
case "i2d": {
return new InsnNode(135);
}
case "l2i": {
return new InsnNode(136);
}
case "l2f": {
return new InsnNode(137);
}
case "l2d": {
return new InsnNode(138);
}
case "f2i": {
return new InsnNode(139);
}
case "f2l": {
return new InsnNode(140);
}
case "f2d": {
return new InsnNode(141);
}
case "d2i": {
return new InsnNode(142);
}
case "d2l": {
return new InsnNode(143);
}
case "d2f": {
return new InsnNode(144);
}
case "i2b": {
return new InsnNode(145);
}
case "i2c": {
return new InsnNode(146);
}
case "i2s": {
return new InsnNode(147);
}
case "lcmp": {
return new InsnNode(148);
}
case "fcmpl": {
return new InsnNode(149);
}
case "fcmpg": {
return new InsnNode(150);
}
case "dcmpl": {
return new InsnNode(151);
}
case "dcmpg": {
return new InsnNode(152);
}
case "ifeq": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(153, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(153, new LabelNode(l));
}
case "ifne": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(154, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(154, new LabelNode(l));
}
case "iflt": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(155, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(155, new LabelNode(l));
}
case "ifge": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(156, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(156, new LabelNode(l));
}
case "ifgt": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(157, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(157, new LabelNode(l));
}
case "ifle": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(158, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(158, new LabelNode(l));
}
case "if_icmpeq": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(159, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(159, new LabelNode(l));
}
case "if_icmpne": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(160, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(160, new LabelNode(l));
}
case "if_icmplt": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(161, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(161, new LabelNode(l));
}
case "if_icmpge": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(162, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(162, new LabelNode(l));
}
case "if_icmpgt": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(163, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(163, new LabelNode(l));
}
case "if_icmple": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(164, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(164, new LabelNode(l));
}
case "if_acmpeq": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(165, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(165, new LabelNode(l));
}
case "if_acmpne": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(166, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(166, new LabelNode(l));
}
case "goto": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(167, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(167, new LabelNode(l));
}
case "jsr": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(168, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(168, new LabelNode(l));
}
case "ret": {
return new VarInsnNode(169, Integer.parseInt(s.split(" ")[1]));
}
case "tableswitch": {
String str = s.substring(14, s.length() - 2).replace("\t", "");
String split2[] = str.split("\n");
LinkedHashMap<Integer, LabelNode> labelMap = new LinkedHashMap<>();
for (int i = 4; i < split2.length - 1; i++) {
if (split2[i].equals("null")) {
labelMap.put(-1 - labelMap.size(), null);
} else {
labelMap.put(Integer.parseInt(split2[i]), null);
}
}
LabelNode dflt = null;
if (!split2[2].substring(9).equals("null")) {
int dfltLabelNr = Integer.parseInt(split2[2].substring(9));
for (Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == dfltLabelNr) {
dflt = new LabelNode(entry.getKey());
}
if (labelMap.containsKey(entry.getValue())) {
labelMap.replace(entry.getValue(), new LabelNode(entry.getKey()));
}
}
if (dflt == null) {
Label l = new Label();
labels.put(l, dfltLabelNr);
dflt = new LabelNode(l);
}
} else {
dflt = new LabelNode(new Label());
}
LabelNode[] arr = new LabelNode[labelMap.size()];
int counter = 0;
for (Entry<Integer, LabelNode> entry : labelMap.entrySet()) {
LabelNode ln;
if (entry.getValue() == null) {
Label l = new Label();
labels.put(l, entry.getKey());
ln = new LabelNode(l);
} else {
ln = entry.getValue();
}
arr[counter] = ln;
counter++;
}
return new TableSwitchInsnNode(Integer.parseInt(split2[0].substring(5)),
Integer.parseInt(split2[1].substring(5)), dflt, arr);
}
case "lookupswitch": {
String str = s.substring(15, s.length() - 2).replace("\t", "");
String split2[] = str.split("\n");
ArrayList<Integer> keys = new ArrayList<>();
LinkedHashMap<Integer, LabelNode> labelMap = new LinkedHashMap<>();
int stage = 0;
for (int i = 2; i < split2.length; i++) {
String spl = split2[i];
if (spl.equals("]")) {
stage = 1;
} else if (spl.equals("labels: [")) {
stage = 2;
} else if (stage == 0) {
keys.add(Integer.parseInt(spl));
} else if (stage == 2) {
if (spl.equals("null")) {
labelMap.put(-1 - labelMap.size(), null);
} else {
labelMap.put(Integer.parseInt(spl), null);
}
}
}
LabelNode dflt = null;
int labelNr = Integer.parseInt(split2[0].substring(9));
for (Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
dflt = new LabelNode(entry.getKey());
}
if (labelMap.containsKey(entry.getValue())) {
labelMap.replace(entry.getValue(), new LabelNode(entry.getKey()));
}
}
if (dflt == null) {
Label l = new Label();
labels.put(l, labelNr);
dflt = new LabelNode(l);
}
LabelNode[] arr = new LabelNode[labelMap.size()];
int counter = 0;
for (Entry<Integer, LabelNode> entry : labelMap.entrySet()) {
LabelNode ln;
if (entry.getValue() == null) {
Label l = new Label();
labels.put(l, entry.getKey());
ln = new LabelNode(l);
} else {
ln = entry.getValue();
}
arr[counter] = ln;
counter++;
}
int[] _keys = new int[keys.size()];
counter = 0;
for (int i : keys) {
_keys[counter] = i;
counter++;
}
return new LookupSwitchInsnNode(dflt, _keys, arr);
}
case "ireturn": {
return new InsnNode(172);
}
case "lreturn": {
return new InsnNode(173);
}
case "freturn": {
return new InsnNode(174);
}
case "dreturn": {
return new InsnNode(175);
}
case "areturn": {
return new InsnNode(176);
}
case "return": {
return new InsnNode(177);
}
case "getstatic": {
String target = split[2];
int index = target.lastIndexOf("/");
return new FieldInsnNode(178, target.substring(0, index), target.substring(index + 1), split[1]);
}
case "putstatic": {
String target = split[2];
int index = target.lastIndexOf("/");
return new FieldInsnNode(179, target.substring(0, index), target.substring(index + 1), split[1]);
}
case "getfield": {
String target = split[2];
int index = target.lastIndexOf("/");
return new FieldInsnNode(180, target.substring(0, index), target.substring(index + 1), split[1]);
}
case "putfield": {
String target = split[2];
int index = target.lastIndexOf("/");
return new FieldInsnNode(181, target.substring(0, index), target.substring(index + 1), split[1]);
}
case "invokevirtual": {
String target = split[2];
int index = target.lastIndexOf("/");
return new MethodInsnNode(182, target.substring(0, index), target.substring(index + 1), split[1],
false);
}
case "invokespecial": {
String target = split[2];
int index = target.lastIndexOf("/");
return new MethodInsnNode(183, target.substring(0, index), target.substring(index + 1), split[1],
false);
}
case "invokestatic": {
String target = split[2];
int index = target.lastIndexOf("/");
return new MethodInsnNode(184, target.substring(0, index), target.substring(index + 1), split[1],
false);
}
case "invokeinterface": {
String target = split[2];
int index = target.lastIndexOf("/");
return new MethodInsnNode(185, target.substring(0, index), target.substring(index + 1), split[1], true);
}
case "invokedynamic": {
String str = s.substring(16, s.length() - 2).replace("", "");
String sp[] = str.split("\n\t");
ArrayList<Object> args = new ArrayList<>();
ArrayList<String> vals = new ArrayList<>();
int stage = 0;
for (int i = 10; i < sp.length - 1; i++) {
String st = sp[i].substring(1);
if (st.equals("]")) {
if (stage == 1) {
try {
Constructor<Type> constr = Type.class.getDeclaredConstructor(int.class, char[].class,
int.class, int.class);
constr.setAccessible(true);
args.add(constr.newInstance(new Object[] { Integer.parseInt(vals.get(0).substring(6)),
vals.get(3).substring(6, vals.get(3).length() - 1).toCharArray(),
Integer.parseInt(vals.get(1).substring(5)),
Integer.parseInt(vals.get(2).substring(5)) }));
} catch (Exception e) {
throw e;
}
} else if (stage == 2) {
args.add(new Handle(Integer.parseInt(vals.get(4).substring(5)), vals.get(1).substring(7),
vals.get(0).substring(6), vals.get(2).substring(6),
Boolean.parseBoolean(vals.get(3).substring(13))));
vals.clear();
}
stage = 0;
} else if (st.equals("Type: [")) {
stage = 1;
} else if (stage == 1) {
st = st.substring(1);
vals.add(st);
} else if (st.equals("Handle: [")) {
vals.clear();
stage = 2;
} else if (stage == 2) {
st = st.substring(1);
vals.add(st);
}
}
Object[] _args = new Object[args.size()];
stage = 0;
for (Object o : args) {
_args[stage] = o;
stage++;
}
return new InvokeDynamicInsnNode(sp[0].substring(7), sp[1].substring(6),
new Handle(Integer.parseInt(sp[7].substring(6)), sp[4].substring(8), sp[3].substring(7),
sp[5].substring(7), Boolean.parseBoolean(sp[6].substring(14))),
_args);
}
case "new": {
return new TypeInsnNode(187, split[1]);
}
case "newarray": {
return new IntInsnNode(188, ClassUtil.getArrayIDByType(split[1]));
}
case "anewarray": {
return new TypeInsnNode(189, split[1]);
}
case "arraylength": {
return new InsnNode(190);
}
case "athrow": {
return new InsnNode(191);
}
case "checkcast": {
return new TypeInsnNode(192, split[1]);
}
case "instanceof": {
return new TypeInsnNode(193, split[1]);
}
case "monitorenter": {
return new InsnNode(194);
}
case "monitorexit": {
return new InsnNode(195);
}
case "multianewarray": {
return new MultiANewArrayInsnNode(split[1], Integer.parseInt(split[2]));
}
case "ifnull": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(198, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(198, new LabelNode(l));
}
case "ifnonnull": {
int labelNr = Integer.parseInt(s.split(" ")[1]);
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
if (entry.getValue() == labelNr) {
return new JumpInsnNode(199, new LabelNode(entry.getKey()));
}
}
Label l = new Label();
labels.put(l, labelNr);
return new JumpInsnNode(199, new LabelNode(l));
}
default:
throw new IllegalArgumentException("Illegal Instruction: " + s);
}
}
}
}