@Override public final void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) { AttributesImpl attrs = new AttributesImpl(); attrs.addAttribute("", "min", "min", "", Integer.toString(min)); attrs.addAttribute("", "max", "max", "", Integer.toString(max)); attrs.addAttribute("", "dflt", "dflt", "", getLabel(dflt)); String o = Printer.OPCODES[Opcodes.TABLESWITCH]; sa.addStart(o, attrs); for (int i = 0; i < labels.length; i++) { AttributesImpl att2 = new AttributesImpl(); att2.addAttribute("", "name", "name", "", getLabel(labels[i])); sa.addElement("label", att2); } sa.addEnd(o); }
/** * Runs the two-pass compiler to generate a Painless script. (Used by the debugger.) * @param iface Interface the compiled script should implement * @param source The source code for the script. * @param settings The CompilerSettings to be used during the compilation. * @return The bytes for compilation. */ static byte[] compile(Class<?> iface, String name, String source, CompilerSettings settings, Printer debugStream) { if (source.length() > MAXIMUM_SOURCE_LENGTH) { throw new IllegalArgumentException("Scripts may be no longer than " + MAXIMUM_SOURCE_LENGTH + " characters. The passed in script is " + source.length() + " characters. Consider using a" + " plugin if a script longer than this length is a requirement."); } ScriptInterface scriptInterface = new ScriptInterface(iface); SSource root = Walker.buildPainlessTree(scriptInterface, name, source, settings, debugStream); root.analyze(); root.write(); return root.getBytes(); }
public SSource(ScriptInterface scriptInterface, CompilerSettings settings, String name, String source, Printer debugStream, MainMethodReserved reserved, Location location, List<SFunction> functions, Globals globals, List<AStatement> statements) { super(location); this.scriptInterface = Objects.requireNonNull(scriptInterface); this.settings = Objects.requireNonNull(settings); this.name = Objects.requireNonNull(name); this.source = Objects.requireNonNull(source); this.debugStream = debugStream; this.reserved = Objects.requireNonNull(reserved); // process any synthetic functions generated by walker (because right now, thats still easy) functions.addAll(globals.getSyntheticMethods().values()); globals.getSyntheticMethods().clear(); this.functions = Collections.unmodifiableList(functions); this.statements = Collections.unmodifiableList(statements); this.globals = globals; }
/** * 格式化输出字节码 * @param bytecode */ public static void viewByteCode(byte[] bytecode) { ClassReader cr = new ClassReader(bytecode); ClassNode cn = new ClassNode(); cr.accept(cn, 0); final List<MethodNode> mns = cn.methods; Printer printer = new Textifier(); TraceMethodVisitor mp = new TraceMethodVisitor(printer); for (MethodNode mn : mns) { InsnList inList = mn.instructions; System.out.println(mn.name); for (int i = 0; i < inList.size(); i++) { inList.get(i).accept(mp); StringWriter sw = new StringWriter(); printer.print(new PrintWriter(sw)); printer.getText().clear(); System.out.print(sw.toString()); } } }
private static String insToChars(String name) { for (int i = 0; i < Printer.OPCODES.length; i++) { if (name.equalsIgnoreCase(Printer.OPCODES[i])) { return new String(new char[] { opcodeToChar(i) }); } } int[] group = groups.get(name.toLowerCase()); if (group != null) { StringBuilder bldr = new StringBuilder("("); for (int i = 0; i < group.length; i++) { bldr.append(opcodeToChar(group[i])); if (i != group.length - 1) bldr.append("|"); } bldr.append(")"); return bldr.toString(); } if (name.equalsIgnoreCase("AbstractInsnNode")) { return "."; } throw new IllegalArgumentException(name + " is not an instruction."); }
public static void printMethod(ObfMapping method, byte[] bytes, Printer printer, File toFile) { try { if (!toFile.getParentFile().exists()) toFile.getParentFile().mkdirs(); if (!toFile.exists()) toFile.createNewFile(); PrintWriter printWriter = new PrintWriter(toFile); ClassVisitor cv = new MethodASMifier(method, printer, printWriter); ClassReader cr = new ClassReader(bytes); cr.accept(cv, 0); printWriter.close(); } catch (Exception e) { e.printStackTrace(); } }
@Override public void visitLdcInsn(final Object cst) { buf.setLength(0); buf.append(tab2).append("LDC "); if (cst instanceof String) { Printer.appendString(buf, (String) cst); } else if(cst instanceof Float) { buf.append(cst).append("F"); } else if(cst instanceof Double) { buf.append(cst).append("D"); } else if(cst instanceof Long) { buf.append(cst).append("L"); } else if (cst instanceof Type) { buf.append(((Type) cst).getDescriptor()).append(".class"); } else { buf.append(cst); } buf.append('\n'); text.add(buf.toString()); }
@Override public void visitEnd() { super.visitEnd(); if (!found && errorNoMatch) { StringWriter output = new StringWriter(); PrintWriter writer = new PrintWriter(output); writer.append("Cannot find nodes"); if (methods.size() > 0) { writer.append(" for methods ").append(methods.toString()); } writer.println(); Printer printer = new Textifier(); TraceMethodVisitor visitor = new TraceMethodVisitor(printer); for (AbstractInsnNode node : nodes) { node.accept(visitor); } printer.print(writer); throw new IllegalStateException(output.toString()); } }
public static void viewByteCode(byte[] bytecode) { ClassReader cr = new ClassReader(bytecode); ClassNode cn = new ClassNode(); cr.accept(cn, 0); final List<MethodNode> mns = cn.methods; Printer printer = new Textifier(); TraceMethodVisitor mp = new TraceMethodVisitor(printer); for (MethodNode mn : mns) { InsnList inList = mn.instructions; System.out.println(mn.name); for (int i = 0; i < inList.size(); i++) { inList.get(i).accept(mp); StringWriter sw = new StringWriter(); printer.print(new PrintWriter(sw)); printer.getText().clear(); System.out.print(sw.toString()); } } }
private static void checkIntComparisonOpcode(Type comparisonType, int opcode) { switch (opcode) { case Opcodes.IFEQ: case Opcodes.IFNE: return; case Opcodes.IFGT: case Opcodes.IFGE: case Opcodes.IFLT: case Opcodes.IFLE: if (comparisonType.getSort() == Type.ARRAY || comparisonType.getSort() == Type.OBJECT) { throw new IllegalArgumentException( "Type: " + comparisonType + " cannot be compared via " + Printer.OPCODES[opcode]); } return; default: throw new IllegalArgumentException( "Unsupported opcode for comparison operation: " + opcode); } }
public static String getMethodInstructionList(final MethodNode methodNode) { Preconditions.checkNotNull(methodNode, "methodNode"); final Printer printer = new NonMaxTextifier(); final TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer); methodNode.accept(traceMethodVisitor); final StringWriter stringWriter = new StringWriter(); final PrintWriter printWriter = new PrintWriter(stringWriter); printer.print(printWriter); printWriter.flush(); final String[] lines = PATTERN.split(stringWriter.toString()); int lineNr = 0; for (int i = 0; i < lines.length; i++) { if (!lines[i].startsWith(" @")) { lines[i] = String.format("%2d %s", lineNr++, lines[i]); } } return "Method '" + methodNode.name + "':\n" + NEWLINE.join(lines) + '\n'; }
protected void print(final Object cst) { if (cst instanceof String) { StringBuffer buf = new StringBuffer(); Printer.appendString(buf, (String) cst); pw.print(buf.toString()); } else if (cst instanceof Float) { Float f = (Float) cst; if (f.isNaN() || f.isInfinite()) { pw.print("0.0"); // TODO Jasmin bug workaround } else { pw.print(f); } } else if (cst instanceof Double) { Double d = (Double) cst; if (d.isNaN() || d.isInfinite()) { pw.print("0.0"); // TODO Jasmin bug workaround } else { pw.print(d); } } else { pw.print(cst); } }
/** * Converts an instruction to character(s) used to build the regular * expression. * @param name The name of the instruction. * @return The character(s) which represents this instruction. * @throws IllegalArgumentException if the name was not found. */ private static String insToChars(String name) { for (int i = 0; i < Printer.OPCODES.length; i++) { if (name.equalsIgnoreCase(Printer.OPCODES[i])) { return new String(new char[] { opcodeToChar(i) }); } } int[] group = groups.get(name.toLowerCase()); if (group != null) { StringBuilder bldr = new StringBuilder("("); for (int i = 0; i < group.length; i++) { bldr.append(opcodeToChar(group[i])); if (i != group.length - 1) bldr.append("|"); } bldr.append(")"); return bldr.toString(); } if (name.equalsIgnoreCase("AbstractInsnNode")) { return "."; } throw new IllegalArgumentException(name + " is not an instruction."); }
@Override public final void visitTableSwitchInsn( final int min, final int max, final Label dflt, final Label... labels) { AttributesImpl attrs = new AttributesImpl(); attrs.addAttribute("", "min", "min", "", Integer.toString(min)); attrs.addAttribute("", "max", "max", "", Integer.toString(max)); attrs.addAttribute("", "dflt", "dflt", "", getLabel(dflt)); String o = Printer.OPCODES[Opcodes.TABLESWITCH]; sa.addStart(o, attrs); for (int i = 0; i < labels.length; i++) { AttributesImpl att2 = new AttributesImpl(); att2.addAttribute("", "name", "name", "", getLabel(labels[i])); sa.addElement("label", att2); } sa.addEnd(o); }
@Override public final void visitLookupSwitchInsn( final Label dflt, final int[] keys, final Label[] labels) { AttributesImpl att = new AttributesImpl(); att.addAttribute("", "dflt", "dflt", "", getLabel(dflt)); String o = Printer.OPCODES[Opcodes.LOOKUPSWITCH]; sa.addStart(o, att); for (int i = 0; i < labels.length; i++) { AttributesImpl att2 = new AttributesImpl(); att2.addAttribute("", "name", "name", "", getLabel(labels[i])); att2.addAttribute("", "key", "key", "", Integer.toString(keys[i])); sa.addElement("label", att2); } sa.addEnd(o); }
@Override public int getByteCodeInstructionCount(MethodNode method) { final InsnList instructions = method.instructions; @SuppressWarnings("unchecked") final ListIterator<AbstractInsnNode> iterator = instructions.iterator(); int count = 0; for ( int index = 0 ; iterator.hasNext() ; index++ ) { final AbstractInsnNode node = iterator.next(); if ( containsInstructionNum( index ) ) { final int opCode = node.getOpcode(); if ( opCode >= 0 && opCode < Printer.OPCODES.length ) { count++; } } } return count; }
/** * Disassemble a single {@link AbstractInsnNode} node. * * @param node the node to disassemble * @param method the method this node comes from * @param includeVirtual whether to 'disassemble' virtual (ASM-generated) nodes that * have no equivalent in .class files * @param printInsnIndices whether to output the instruction index in front of the mnemonic * @return disassembled instruction or <code>null</code> if the node does not map * to a bytecode (=is virtual) and the <code>includeVirtual</code> flag was <code>false</code> */ public static String disassemble(AbstractInsnNode node,MethodNode method,boolean includeVirtual,boolean printInsnIndices) { final int opCode = node.getOpcode(); final String mnemonic; if ( opCode < 0 || opCode >= Printer.OPCODES.length ) { if ( ! includeVirtual ) { return null; } mnemonic = "// "+node.getClass().getSimpleName(); } else { mnemonic = disassemble(node,method); } if ( printInsnIndices ) { final int indexOf = method.instructions.indexOf( node ); String index = Integer.toString( indexOf ); if ( index.length() < 4 ) { index = StringUtils.leftPad(index, 4 ); } return index+": "+mnemonic; } return mnemonic; }
@Override public final void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { AttributesImpl attrs = new AttributesImpl(); attrs.addAttribute("", "owner", "owner", "", owner); attrs.addAttribute("", "name", "name", "", name); attrs.addAttribute("", "desc", "desc", "", desc); sa.addElement(Printer.OPCODES[opcode], attrs); }
@Override public final void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) { AttributesImpl attrs = new AttributesImpl(); attrs.addAttribute("", "owner", "owner", "", owner); attrs.addAttribute("", "name", "name", "", name); attrs.addAttribute("", "desc", "desc", "", desc); attrs.addAttribute("", "itf", "itf", "", itf ? "true" : "false"); sa.addElement(Printer.OPCODES[opcode], attrs); }
@Override public final void visitIincInsn(final int var, final int increment) { AttributesImpl attrs = new AttributesImpl(); attrs.addAttribute("", "var", "var", "", Integer.toString(var)); attrs.addAttribute("", "inc", "inc", "", Integer.toString(increment)); sa.addElement(Printer.OPCODES[Opcodes.IINC], attrs); }
@Override public final void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { AttributesImpl att = new AttributesImpl(); att.addAttribute("", "dflt", "dflt", "", getLabel(dflt)); String o = Printer.OPCODES[Opcodes.LOOKUPSWITCH]; sa.addStart(o, att); for (int i = 0; i < labels.length; i++) { AttributesImpl att2 = new AttributesImpl(); att2.addAttribute("", "name", "name", "", getLabel(labels[i])); att2.addAttribute("", "key", "key", "", Integer.toString(keys[i])); sa.addElement("label", att2); } sa.addEnd(o); }
@Override public final void visitMultiANewArrayInsn(final String desc, final int dims) { AttributesImpl attrs = new AttributesImpl(); attrs.addAttribute("", "desc", "desc", "", desc); attrs.addAttribute("", "dims", "dims", "", Integer.toString(dims)); sa.addElement(Printer.OPCODES[Opcodes.MULTIANEWARRAY], attrs); }
private Walker(ScriptInterface scriptInterface, String sourceName, String sourceText, CompilerSettings settings, Printer debugStream) { this.scriptInterface = scriptInterface; this.debugStream = debugStream; this.settings = settings; this.sourceName = Location.computeSourceName(sourceName, sourceText); this.sourceText = sourceText; this.globals = new Globals(new BitSet(sourceText.length())); this.source = (SSource)visit(buildAntlrTree(sourceText)); }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (method.matches(name, desc)) { Printer localPrinter = asmifier.visitMethod(access, name, desc, signature, exceptions); return new TraceMethodVisitor(null, localPrinter); } return null; }
public static void printMethod(ObfMapping method, Printer printer, File toFile) { try { printMethod(method, Launch.classLoader.getClassBytes(method.javaClass()), printer, toFile); } catch (Exception e) { e.printStackTrace(); } }