package net.ptnkjke.jbeditor.logic.asm; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.*; import java.util.*; /** * Created by dalopatin on 17.11.2014. */ public class JAsmByteParser { private Map<Integer, LabelNode> labelNodeMap = new HashMap<Integer, LabelNode>(); private List<TryCatchBlockNode> tryCatchBlockNodeList = new ArrayList<TryCatchBlockNode>(); private InsnList insnList = new InsnList(); public void parse(String code) { String[] lines = code.split("\n"); String[] wLines = new String[lines.length]; for (int i = 0; i < lines.length; i++) { String line = lines[i]; String tLine = line; // Remove first and last Spaces + comments if (line.indexOf("//") != -1) { tLine = line.substring(0, line.indexOf("//")); } tLine = tLine.replaceAll("\\s+$", "").replaceAll("^\\s+", ""); wLines[i] = tLine; } } private void parseLine(String[] lines, int numLine) { String[] _s = lines[numLine].split(" "); String instructionName = _s[0].toUpperCase(); String[] args = Arrays.copyOfRange(_s, 1, _s.length); AbstractInsnNode insnNode = null; LabelNode labelNode = null; // JumpInstruction switch (instructionName) { case "IFEQ": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IFEQ, labelNode); break; case "IFNE": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IFNE, labelNode); break; case "IFLT": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IFLT, labelNode); break; case "IFGE": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IFGE, labelNode); break; case "IFGT": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IFGT, labelNode); break; case "IFLE": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IFLE, labelNode); break; case "IF_ICMPEQ": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IF_ICMPEQ, labelNode); break; case "IF_ICMPNE": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IF_ICMPNE, labelNode); break; case "IF_ICMPLT": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IF_ICMPLT, labelNode); break; case "IF_ICMPGE": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IF_ICMPGE, labelNode); break; case "IF_ICMPGT": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IF_ICMPGT, labelNode); break; case "IF_ICMPLE": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IF_ICMPLE, labelNode); break; case "IF_ACMPEQ": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IF_ACMPEQ, labelNode); break; case "IF_ACMPNE": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IF_ACMPNE, labelNode); break; case "GOTO": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.GOTO, labelNode); break; case "JSR": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.JSR, labelNode); break; case "IFNULL": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IFNULL, labelNode); break; case "IFNONNULL": labelNode = parseLable(args[0]); insnNode = new JumpInsnNode(Opcodes.IFNONNULL, labelNode); break; } if(insnNode != null){ insnList.add(insnNode); return; } // LineNumber if(instructionName.equals("LINENUMBER")){ labelNode = parseLable(args[1]); int lineNumber = Integer.parseInt(args[0]); insnList.add(new LineNumberNode(lineNumber, labelNode)); return; } // Insn switch (instructionName) { case "NOP": insnNode = new InsnNode(Opcodes.NOP); break; case "ACONST_NULL": insnNode = new InsnNode(Opcodes.ACONST_NULL); break; case "ICONST_M1": insnNode = new InsnNode(Opcodes.ICONST_M1); break; case "ICONST_0": insnNode = new InsnNode(Opcodes.ICONST_0); break; case "ICONST_1": insnNode = new InsnNode(Opcodes.ICONST_1); break; case "ICONST_2": insnNode = new InsnNode(Opcodes.ICONST_2); break; case "ICONST_3": insnNode = new InsnNode(Opcodes.ICONST_3); break; case "ICONST_4": insnNode = new InsnNode(Opcodes.ICONST_4); break; case "ICONST_5": insnNode = new InsnNode(Opcodes.ICONST_5); break; case "LCONST_0": insnNode = new InsnNode(Opcodes.LCONST_0); break; case "LCONST_1": insnNode = new InsnNode(Opcodes.LCONST_1); break; case "FCONST_0": insnNode = new InsnNode(Opcodes.FCONST_0); break; case "FCONST_1": insnNode = new InsnNode(Opcodes.FCONST_1); break; case "FCONST_2": insnNode = new InsnNode(Opcodes.FCONST_2); break; case "DCONST_0": insnNode = new InsnNode(Opcodes.DCONST_0); break; case "DCONST_1": insnNode = new InsnNode(Opcodes.DCONST_1); break; case "IALOAD": insnNode = new InsnNode(Opcodes.IALOAD); break; case "LALOAD": insnNode = new InsnNode(Opcodes.LALOAD); break; case "FALOAD": insnNode = new InsnNode(Opcodes.FALOAD); break; case "DALOAD": insnNode = new InsnNode(Opcodes.DALOAD); break; case "AALOAD": insnNode = new InsnNode(Opcodes.AALOAD); break; case "BALOAD": insnNode = new InsnNode(Opcodes.BALOAD); break; case "CALOAD": insnNode = new InsnNode(Opcodes.CALOAD); break; case "SALOAD": insnNode = new InsnNode(Opcodes.SALOAD); break; case "IASTORE": insnNode = new InsnNode(Opcodes.IASTORE); break; case "LASTORE": insnNode = new InsnNode(Opcodes.LASTORE); break; case "FASTORE": insnNode = new InsnNode(Opcodes.FASTORE); break; case "DASTORE": insnNode = new InsnNode(Opcodes.DASTORE); break; case "AASTORE": insnNode = new InsnNode(Opcodes.AASTORE); break; case "BASTORE": insnNode = new InsnNode(Opcodes.BASTORE); break; case "CASTORE": insnNode = new InsnNode(Opcodes.CASTORE); break; case "SASTORE": insnNode = new InsnNode(Opcodes.SASTORE); break; case "POP": insnNode = new InsnNode(Opcodes.POP); break; case "POP2": insnNode = new InsnNode(Opcodes.POP2); break; case "DUP": insnNode = new InsnNode(Opcodes.DUP); break; case "DUP_X1": insnNode = new InsnNode(Opcodes.DUP_X1); break; case "DUP_X2": insnNode = new InsnNode(Opcodes.DUP_X2); break; case "DUP2": insnNode = new InsnNode(Opcodes.DUP2); break; case "DUP2_X1": insnNode = new InsnNode(Opcodes.DUP2_X1); break; case "DUP2_X2": insnNode = new InsnNode(Opcodes.DUP2_X2); break; case "SWAP": insnNode = new InsnNode(Opcodes.SWAP); break; case "IADD": insnNode = new InsnNode(Opcodes.IADD); break; case "LADD": insnNode = new InsnNode(Opcodes.LADD); break; case "FADD": insnNode = new InsnNode(Opcodes.FADD); break; case "DADD": insnNode = new InsnNode(Opcodes.DADD); break; case "ISUB": insnNode = new InsnNode(Opcodes.ISUB); break; case "LSUB": insnNode = new InsnNode(Opcodes.LSUB); break; case "FSUB": insnNode = new InsnNode(Opcodes.FSUB); break; case "DSUB": insnNode = new InsnNode(Opcodes.DSUB); break; case "IMUL": insnNode = new InsnNode(Opcodes.IMUL); break; case "LMUL": insnNode = new InsnNode(Opcodes.LMUL); break; case "FMUL": insnNode = new InsnNode(Opcodes.FMUL); break; case "DMUL": insnNode = new InsnNode(Opcodes.DMUL); break; case "IDIV": insnNode = new InsnNode(Opcodes.IDIV); break; case "LDIV": insnNode = new InsnNode(Opcodes.LDIV); break; case "FDIV": insnNode = new InsnNode(Opcodes.FDIV); break; case "DDIV": insnNode = new InsnNode(Opcodes.DDIV); break; case "IREM": insnNode = new InsnNode(Opcodes.IREM); break; case "LREM": insnNode = new InsnNode(Opcodes.LREM); break; case "FREM": insnNode = new InsnNode(Opcodes.FREM); break; case "DREM": insnNode = new InsnNode(Opcodes.DREM); break; case "INEG": insnNode = new InsnNode(Opcodes.INEG); break; case "LNEG": insnNode = new InsnNode(Opcodes.LNEG); break; case "FNEG": insnNode = new InsnNode(Opcodes.FNEG); break; case "DNEG": insnNode = new InsnNode(Opcodes.DNEG); break; case "ISHL": insnNode = new InsnNode(Opcodes.ISHL); break; case "LSHL": insnNode = new InsnNode(Opcodes.LSHL); break; case "ISHR": insnNode = new InsnNode(Opcodes.ISHR); break; case "LSHR": insnNode = new InsnNode(Opcodes.LSHR); break; case "IUSHR": insnNode = new InsnNode(Opcodes.IUSHR); break; case "LUSHR": insnNode = new InsnNode(Opcodes.LUSHR); break; case "IAND": insnNode = new InsnNode(Opcodes.IAND); break; case "LAND": insnNode = new InsnNode(Opcodes.LAND); break; case "IOR": insnNode = new InsnNode(Opcodes.IOR); break; case "LOR": insnNode = new InsnNode(Opcodes.LOR); break; case "IXOR": insnNode = new InsnNode(Opcodes.IXOR); break; case "LXOR": insnNode = new InsnNode(Opcodes.LXOR); break; case "I2L": insnNode = new InsnNode(Opcodes.I2L); break; case "I2F": insnNode = new InsnNode(Opcodes.I2F); break; case "I2D": insnNode = new InsnNode(Opcodes.I2D); break; case "L2I": insnNode = new InsnNode(Opcodes.L2I); break; case "L2F": insnNode = new InsnNode(Opcodes.L2F); break; case "L2D": insnNode = new InsnNode(Opcodes.L2D); break; case "F2I": insnNode = new InsnNode(Opcodes.F2I); break; case "F2L": insnNode = new InsnNode(Opcodes.F2L); break; case "F2D": insnNode = new InsnNode(Opcodes.F2D); break; case "D2I": insnNode = new InsnNode(Opcodes.D2I); break; case "D2L": insnNode = new InsnNode(Opcodes.D2L); break; case "D2F": insnNode = new InsnNode(Opcodes.D2F); break; case "I2B": insnNode = new InsnNode(Opcodes.I2B); break; case "I2C": insnNode = new InsnNode(Opcodes.I2C); break; case "I2S": insnNode = new InsnNode(Opcodes.I2S); break; case "LCMP": insnNode = new InsnNode(Opcodes.LCMP); break; case "FCMPL": insnNode = new InsnNode(Opcodes.FCMPL); break; case "FCMPG": insnNode = new InsnNode(Opcodes.FCMPG); break; case "DCMPL": insnNode = new InsnNode(Opcodes.DCMPL); break; case "DCMPG": insnNode = new InsnNode(Opcodes.DCMPG); break; case "IRETURN": insnNode = new InsnNode(Opcodes.IRETURN); break; case "LRETURN": insnNode = new InsnNode(Opcodes.LRETURN); break; case "FRETURN": insnNode = new InsnNode(Opcodes.FRETURN); break; case "DRETURN": insnNode = new InsnNode(Opcodes.DRETURN); break; case "ARETURN": insnNode = new InsnNode(Opcodes.ARETURN); break; case "RETURN": insnNode = new InsnNode(Opcodes.RETURN); break; case "ARRAYLENGTH": insnNode = new InsnNode(Opcodes.ARRAYLENGTH); break; case "ATHROW": insnNode = new InsnNode(Opcodes.ATHROW); break; case "MONITORENTER": insnNode = new InsnNode(Opcodes.MONITORENTER); break; case "MONITOREXIT": insnNode = new InsnNode(Opcodes.MONITOREXIT); break; } if(insnNode != null){ insnList.add(insnNode); return; } // IincInsnNode if(instructionName.equals("")){ //TODO ME PLEASE <3!! return; } // TryCatchBlock if(instructionName.equals("TRYCATCHBLOCK")){ LabelNode start = parseLable(args[0]); LabelNode end = parseLable(args[1]); LabelNode handler= parseLable(args[2]); String type =args[3]; tryCatchBlockNodeList.add(new TryCatchBlockNode(start, end, handler, type)); return; } // LOOKUPSWITCH //TODO ME PLEASE <3!! // TABLESWITCH //TODO ME PLEASE <3!! try { throw new Exception(lines[numLine]); } catch (Exception e) { e.printStackTrace(); } } private LabelNode parseLable(String arg){ Integer number = Integer.parseInt(arg.substring(1)); LabelNode node = labelNodeMap.get(number); if(node == null){ node = new LabelNode(); node.resetLabel(); labelNodeMap.put(number, node); insnList.add(node); } return node; } }