feat: added BytecodePrinter

This commit is contained in:
zaaarf 2023-02-09 00:04:34 +01:00
parent 483b111259
commit 016846f92e
No known key found for this signature in database
GPG key ID: 82240E075E31FA4C
2 changed files with 81 additions and 0 deletions

View file

@ -8,4 +8,6 @@ repositories {
dependencies { dependencies {
implementation 'org.ow2.asm:asm-commons:9.4' implementation 'org.ow2.asm:asm-commons:9.4'
implementation 'org.ow2.asm:asm-util:9.4'
implementation 'org.apache.logging.log4j:log4j-api:2.15.0'
} }

View file

@ -0,0 +1,79 @@
package ftbsc.lll.tools.debug;
import org.apache.logging.log4j.Logger;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceMethodVisitor;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* A collection of static methods for debugging by printing the ASM bytecode.
* These methods are only for debug, so most of the time they should stay unused.
*/
public class BytecodePrinter {
/**
* Used for converting visit events to text, acts pretty much like a buffer in our case.
*/
private static final Printer PRINTER = new Textifier();
/**
* MethodVisitor that visits the method and prints it to a given printer.
*/
private static final TraceMethodVisitor MP = new TraceMethodVisitor(PRINTER);
/**
* Prints the bytecode of a method using System.out.print().
* @param main the method to print
*/
public static void printAsmMethod(final MethodNode main) {
for (AbstractInsnNode i : main.instructions.toArray())
System.out.print(insnToString(i));
}
/**
* Logs the bytecode of a method using the ASM logger.
* @param main the method to print
* @param logger the Log4j logger to print it with
*/
public static void logAsmMethod(final MethodNode main, final Logger logger) {
for (AbstractInsnNode i : main.instructions.toArray())
logger.debug(insnToString(i));
}
/**
* Logs the bytecode of a method to a file.
* @param main the method to print
* @param path the file to log it to
*/
public static void logAsmMethod(final MethodNode main, String path) {
StringBuilder out = new StringBuilder();
for (AbstractInsnNode i : main.instructions.toArray())
out.append(insnToString(i));
try {
Files.write(Paths.get(path), out.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Converts an instruction node to a String.
* @param insn the node to convert
* @return the converted string
*/
public static String insnToString(AbstractInsnNode insn) {
insn.accept(MP);
StringWriter sw = new StringWriter();
PRINTER.print(new PrintWriter(sw));
PRINTER.getText().clear();
return sw.toString();
}
}