Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.googlecode.d2j.jasmin.JasminDumper Maven / Gradle / Ivy
package com.googlecode.d2j.jasmin;
import com.googlecode.dex2jar.tools.Constants;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
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.FieldNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.util.Printer;
/**
* get from asm example
*
* Disassembled view of the classes in Jasmin assembler format.
*
* The trace printed when visiting the Hello
class is the following:
*
*
*
*
* .bytecode 45.3
* .class public Hello
* .super java/lang/Object
*
* .method public <init>()V
* aload 0
* invokespecial java/lang/Object/<init>()V
* return
* .limit locals 1
* .limit stack 1
* .end method
*
* .method public static main([Ljava/lang/String;)V
* getstatic java/lang/System/out Ljava/io/PrintStream;
* ldc "hello"
* invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
* return
* .limit locals 2
* .limit stack 2
* .end method
*
*
* where Hello
is defined by:
*
*
*
*
* public class Hello {
*
* public static void main(String[] args) {
* System.out.println("hello");
* }
* }
*
*
*
*
* @author Eric Bruneton
*/
public class JasminDumper implements Opcodes {
private static final Set ACCESS_KWS = new HashSet<>(Arrays
.asList("abstract", "private", "protected", "public", "enum", "final", "interface", "static", "strictfp",
"native", "super"));
public JasminDumper(PrintWriter pw) {
this.pw = pw;
}
/**
* The print writer to be used to print the class.
*/
protected PrintWriter pw;
/**
* The label names. This map associate String values to Label keys.
*/
protected final Map labelNames = new HashMap<>();
static void printIdAfterAccess(PrintWriter out, String id) {
if (ACCESS_KWS.contains(id)) {
out.print("\"");
out.print(id);
out.print("\"");
} else {
out.print(id);
}
}
public void dump(ClassNode cn) {
labelNames.clear();
pw.print(".bytecode ");
pw.print(cn.version & 0xFFFF);
pw.print('.');
pw.println(cn.version >>> 16);
println(".source ", cn.sourceFile);
pw.print(".class");
pw.print(accessClz(cn.access));
pw.print(' ');
printIdAfterAccess(pw, cn.name);
pw.println();
if (cn.superName != null) {
pw.print(".super ");
printIdAfterAccess(pw, cn.superName);
pw.println();
}
for (String itf : cn.interfaces) {
pw.print(".implements ");
printIdAfterAccess(pw, itf);
pw.println();
}
if (cn.signature != null) {
println(".signature ", '"' + cn.signature + '"');
}
if (cn.outerClass != null) {
pw.print(".enclosing method ");
pw.print(cn.outerClass);
if (cn.outerMethod != null) {
pw.print('/');
pw.print(cn.outerMethod);
pw.println(cn.outerMethodDesc);
} else {
pw.println();
}
}
if ((cn.access & Opcodes.ACC_DEPRECATED) != 0) {
pw.println(".deprecated");
}
if (cn.visibleAnnotations != null) {
for (AnnotationNode an : cn.visibleAnnotations) {
printAnnotation(an, 1, -1);
}
}
if (cn.invisibleAnnotations != null) {
for (AnnotationNode an : cn.invisibleAnnotations) {
printAnnotation(an, 2, -1);
}
}
println(".debug ", cn.sourceDebug == null ? null : '"' + cn.sourceDebug + '"');
for (InnerClassNode in : cn.innerClasses) {
pw.print(".inner class");
pw.print(accessClz(in.access & (~Opcodes.ACC_SUPER)));
if (in.innerName != null) {
pw.print(' ');
printIdAfterAccess(pw, in.innerName);
}
if (in.name != null) {
pw.print(" inner ");
pw.print(in.name);
}
if (in.outerName != null) {
pw.print(" outer ");
pw.print(in.outerName);
}
pw.println();
}
for (FieldNode fn : cn.fields) {
boolean annotations = fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty();
boolean deprecated = (fn.access & Opcodes.ACC_DEPRECATED) != 0;
pw.print("\n.field");
pw.print(accessFld(fn.access));
pw.print(' ');
printIdAfterAccess(pw, fn.name);
pw.print(' ');
pw.print(fn.desc);
if (fn.value instanceof String) {
StringBuilder buf = new StringBuilder();
Printer.appendString(buf, (String) fn.value);
pw.print(" = ");
pw.print(buf);
} else if (fn.value != null) {
pw.print(" = ");
print(fn.value);
}
pw.println();
if (fn.signature != null) {
pw.print(".signature \"");
pw.print(fn.signature);
pw.println("\"");
}
if (deprecated) {
pw.println(".deprecated");
}
if (fn.visibleAnnotations != null) {
for (AnnotationNode an : fn.visibleAnnotations) {
printAnnotation(an, 1, -1);
}
}
if (fn.invisibleAnnotations != null) {
for (AnnotationNode an : fn.invisibleAnnotations) {
printAnnotation(an, 2, -1);
}
}
if (fn.signature != null || deprecated || annotations) {
pw.println(".end field");
}
}
for (MethodNode mn : cn.methods) {
pw.print("\n.method");
pw.print(accessMtd(mn.access));
pw.print(' ');
printIdAfterAccess(pw, mn.name);
pw.println(mn.desc);
if (mn.signature != null) {
pw.print(".signature \"");
pw.print(mn.signature);
pw.println("\"");
}
if (mn.annotationDefault != null) {
pw.println(".annotation default");
printAnnotationValue(mn.annotationDefault);
pw.println(".end annotation");
}
if (mn.visibleAnnotations != null) {
for (AnnotationNode an : mn.visibleAnnotations) {
printAnnotation(an, 1, -1);
}
}
if (mn.invisibleAnnotations != null) {
for (AnnotationNode an : mn.invisibleAnnotations) {
printAnnotation(an, 2, -1);
}
}
if (mn.visibleParameterAnnotations != null) {
for (int j = 0; j < mn.visibleParameterAnnotations.length; ++j) {
List pas = mn.visibleParameterAnnotations[j];
if (pas != null) {
for (AnnotationNode an : pas) {
printAnnotation(an, 1, j + 1);
}
}
}
}
if (mn.invisibleParameterAnnotations != null) {
for (int j = 0; j < mn.invisibleParameterAnnotations.length; ++j) {
List pas = mn.invisibleParameterAnnotations[j];
if (pas != null) {
for (AnnotationNode an : pas) {
printAnnotation(an, 2, j + 1);
}
}
}
}
for (String ex : mn.exceptions) {
println(".throws ", ex);
}
if ((mn.access & Opcodes.ACC_DEPRECATED) != 0) {
pw.println(".deprecated");
}
if (mn.instructions != null && mn.instructions.size() > 0) {
labelNames.clear();
if (mn.tryCatchBlocks != null) {
for (TryCatchBlockNode tcb : mn.tryCatchBlocks) {
pw.print(".catch ");
pw.print(tcb.type == null ? "all" : "all".equals(tcb.type) ? "\\u0097ll" : tcb.type);
pw.print(" from ");
print(tcb.start);
pw.print(" to ");
print(tcb.end);
pw.print(" using ");
print(tcb.handler);
pw.println();
}
}
for (int j = 0; j < mn.instructions.size(); ++j) {
AbstractInsnNode in = mn.instructions.get(j);
if (in.getType() != AbstractInsnNode.LINE && in.getType() != AbstractInsnNode.FRAME) {
if (in.getType() == AbstractInsnNode.LABEL) {
pw.print(" ");
} else {
pw.print(" ");
}
}
in.accept(new MethodVisitor(Constants.ASM_VERSION) {
@Override
public void visitInsn(int opcode) {
print(opcode);
pw.println();
}
@Override
public void visitIntInsn(int opcode, int operand) {
print(opcode);
if (opcode == Opcodes.NEWARRAY) {
switch (operand) {
case Opcodes.T_BOOLEAN:
pw.println(" boolean");
break;
case Opcodes.T_CHAR:
pw.println(" char");
break;
case Opcodes.T_FLOAT:
pw.println(" float");
break;
case Opcodes.T_DOUBLE:
pw.println(" double");
break;
case Opcodes.T_BYTE:
pw.println(" byte");
break;
case Opcodes.T_SHORT:
pw.println(" short");
break;
case Opcodes.T_INT:
pw.println(" int");
break;
case Opcodes.T_LONG:
default:
pw.println(" long");
break;
}
} else {
pw.print(' ');
pw.println(operand);
}
}
@Override
public void visitVarInsn(int opcode, int var) {
print(opcode);
pw.print(' ');
pw.println(var);
}
@Override
public void visitTypeInsn(int opcode, String type) {
print(opcode);
pw.print(' ');
pw.println(type);
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
print(opcode);
pw.print(' ');
pw.print(owner);
pw.print('/');
pw.print(name);
pw.print(' ');
pw.println(desc);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc,
boolean isInterface) {
print(opcode);
pw.print(' ');
pw.print(owner);
pw.print('/');
pw.print(name);
pw.print(desc);
if (isInterface) {
pw.print(' ');
pw.print((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1);
}
pw.println();
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
visitMethodInsn(opcode, owner, name, desc, opcode == INVOKEINTERFACE);
}
@Override
public void visitJumpInsn(int opcode, Label label) {
print(opcode);
pw.print(' ');
print(label);
pw.println();
}
@Override
public void visitLabel(Label label) {
print(label);
pw.println(':');
}
@Override
public void visitLdcInsn(Object cst) {
if (cst instanceof Integer || cst instanceof Float) {
pw.print("ldc_w ");
print(cst);
} else if (cst instanceof Long || cst instanceof Double) {
pw.print("ldc2_w ");
print(cst);
} else {
pw.print("ldc ");
if (cst instanceof Type) {
pw.print(((Type) cst).getInternalName());
} else {
print(cst);
}
}
pw.println();
}
@Override
public void visitIincInsn(int var, int increment) {
pw.print("iinc ");
pw.print(var);
pw.print(' ');
pw.println(increment);
}
@Override
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
pw.print("tableswitch ");
pw.println(min);
for (Label label : labels) {
pw.print(" ");
print(label);
pw.println();
}
pw.print(" default : ");
print(dflt);
pw.println();
}
@Override
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
pw.println("lookupswitch");
for (int i = 0; i < keys.length; ++i) {
pw.print(" ");
pw.print(keys[i]);
pw.print(" : ");
print(labels[i]);
pw.println();
}
pw.print(" default : ");
print(dflt);
pw.println();
}
@Override
public void visitMultiANewArrayInsn(String desc, int dims) {
pw.print("multianewarray ");
pw.print(desc);
pw.print(' ');
pw.println(dims);
}
@Override
public void visitLineNumber(int line, Label start) {
pw.print(".line ");
pw.println(line);
}
});
}
if (mn.localVariables != null) {
for (LocalVariableNode lv : mn.localVariables) {
pw.print(" .var ");
pw.print(lv.index);
pw.print(" is '");
pw.print(lv.name);
pw.print("' ");
pw.print(lv.desc);
if (lv.signature != null) {
pw.print(" signature \"");
pw.print(lv.signature);
pw.print("\"");
}
pw.print(" from ");
print(lv.start);
pw.print(" to ");
print(lv.end);
pw.println();
}
}
println(" .limit locals ", Integer.toString(mn.maxLocals));
println(" .limit stack ", Integer.toString(mn.maxStack));
}
pw.println(".end method");
}
}
protected void println(final String directive, final String arg) {
if (arg != null) {
pw.print(directive);
pw.println(arg);
}
}
protected String accessClz(final int access) {
StringBuilder b = new StringBuilder();
if ((access & Opcodes.ACC_PUBLIC) != 0) {
b.append(" public");
}
if ((access & Opcodes.ACC_PRIVATE) != 0) {
b.append(" private");
}
if ((access & Opcodes.ACC_PROTECTED) != 0) {
b.append(" protected");
}
if ((access & Opcodes.ACC_FINAL) != 0) {
b.append(" final");
}
if ((access & Opcodes.ACC_SUPER) != 0) {
b.append(" super");
}
if ((access & Opcodes.ACC_ABSTRACT) != 0) {
b.append(" abstract");
}
if ((access & Opcodes.ACC_INTERFACE) != 0) {
b.append(" interface");
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
b.append(" synthetic");
}
if ((access & Opcodes.ACC_ANNOTATION) != 0) {
b.append(" annotation");
}
if ((access & Opcodes.ACC_ENUM) != 0) {
b.append(" enum");
}
return b.toString();
}
protected String accessFld(final int access) {
StringBuilder b = new StringBuilder();
if ((access & Opcodes.ACC_PUBLIC) != 0) {
b.append(" public");
}
if ((access & Opcodes.ACC_PRIVATE) != 0) {
b.append(" private");
}
if ((access & Opcodes.ACC_PROTECTED) != 0) {
b.append(" protected");
}
if ((access & Opcodes.ACC_STATIC) != 0) {
b.append(" static");
}
if ((access & Opcodes.ACC_FINAL) != 0) {
b.append(" final");
}
if ((access & Opcodes.ACC_VOLATILE) != 0) {
b.append(" volatile");
}
if ((access & Opcodes.ACC_TRANSIENT) != 0) {
b.append(" transient");
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
b.append(" synthetic");
}
if ((access & Opcodes.ACC_ENUM) != 0) {
b.append(" enum");
}
return b.toString();
}
protected String accessMtd(final int access) {
StringBuilder b = new StringBuilder();
if ((access & Opcodes.ACC_PUBLIC) != 0) {
b.append(" public");
}
if ((access & Opcodes.ACC_PRIVATE) != 0) {
b.append(" private");
}
if ((access & Opcodes.ACC_PROTECTED) != 0) {
b.append(" protected");
}
if ((access & Opcodes.ACC_STATIC) != 0) {
b.append(" static");
}
if ((access & Opcodes.ACC_FINAL) != 0) {
b.append(" final");
}
if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
b.append(" synchronized");
}
if ((access & Opcodes.ACC_BRIDGE) != 0) {
b.append(" bridge");
}
if ((access & Opcodes.ACC_VARARGS) != 0) {
b.append(" varargs");
}
if ((access & Opcodes.ACC_NATIVE) != 0) {
b.append(" native");
}
if ((access & Opcodes.ACC_ABSTRACT) != 0) {
b.append(" abstract");
}
if ((access & Opcodes.ACC_STRICT) != 0) {
b.append(" strict");
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
b.append(" synthetic");
}
return b.toString();
}
protected void print(final int opcode) {
pw.print(Printer.OPCODES[opcode].toLowerCase());
}
protected void print(final Object cst) {
if (cst instanceof String) {
StringBuilder buf = new StringBuilder();
Printer.appendString(buf, (String) cst);
pw.print(buf);
} else if (cst instanceof Float) {
Float f = (Float) cst;
if (!f.isNaN() && !f.isInfinite()) {
pw.print(cst + "F");
} else if (f.isNaN()) {
pw.print("floatnan");
} else {
double v = f;
if ((v == Float.POSITIVE_INFINITY)) {
pw.print("+floatinfinity");
} else {
pw.print("-floatinfinity");
}
}
} else if (cst instanceof Double) {
Double d = (Double) cst;
if (!d.isNaN() && !d.isInfinite()) {
pw.print(cst + "D");
} else if (d.isNaN()) {
pw.print("doublenan");
} else {
double v = d;
if ((v == Double.POSITIVE_INFINITY)) {
pw.print("+doubleinfinity");
} else {
pw.print("-doubleinfinity");
}
}
} else if (cst instanceof Long) {
pw.print(cst + "L");
} else {
pw.print(cst);
}
}
protected void print(final Label l) {
String name = labelNames.computeIfAbsent(l, k -> "L" + labelNames.size());
pw.print(name);
}
protected void print(final LabelNode l) {
print(l.getLabel());
}
protected void printAnnotation(final AnnotationNode n, final int visible, final int param) {
pw.print(".annotation ");
if (visible > 0) {
if (param == -1) {
pw.print(visible == 1 ? "visible " : "invisible ");
} else {
pw.print(visible == 1 ? "visibleparam " : "invisibleparam ");
pw.print(param);
pw.print(' ');
}
pw.print(n.desc);
}
pw.println();
if (n.values != null) {
for (int i = 0; i < n.values.size(); i += 2) {
pw.print(n.values.get(i));
pw.print(' ');
printAnnotationValue(n.values.get(i + 1));
}
}
pw.println(".end annotation");
}
protected void printAnnotationValue(final Object value) {
if (value instanceof String[]) {
pw.print("e ");
pw.print(((String[]) value)[0]);
pw.print(" = ");
pw.print(((String[]) value)[1]);
pw.println();
} else if (value instanceof AnnotationNode) {
pw.print("@ ");
pw.print(((AnnotationNode) value).desc);
pw.print(" = ");
printAnnotation((AnnotationNode) value, 0, -1);
} else if (value instanceof byte[]) {
pw.print("[B = ");
byte[] v = (byte[]) value;
for (byte element : v) {
pw.print(element);
pw.print(' ');
}
pw.println();
} else if (value instanceof boolean[]) {
pw.print("[Z = ");
boolean[] v = (boolean[]) value;
for (boolean element : v) {
pw.print(element ? '1' : '0');
pw.print(' ');
}
pw.println();
} else if (value instanceof short[]) {
pw.print("[S = ");
short[] v = (short[]) value;
for (short element : v) {
pw.print(element);
pw.print(' ');
}
pw.println();
} else if (value instanceof char[]) {
pw.print("[C = ");
char[] v = (char[]) value;
for (char element : v) {
pw.print(Integer.valueOf(element));
pw.print(' ');
}
pw.println();
} else if (value instanceof int[]) {
pw.print("[I = ");
int[] v = (int[]) value;
for (int element : v) {
pw.print(element);
pw.print(' ');
}
pw.println();
} else if (value instanceof long[]) {
pw.print("[J = ");
long[] v = (long[]) value;
for (long element : v) {
pw.print(element);
pw.print(' ');
}
pw.println();
} else if (value instanceof float[]) {
pw.print("[F = ");
float[] v = (float[]) value;
for (float element : v) {
print(element);
pw.print(' ');
}
pw.println();
} else if (value instanceof double[]) {
pw.print("[D = ");
double[] v = (double[]) value;
for (double element : v) {
print(element);
pw.print(' ');
}
pw.println();
} else if (value instanceof List) {
List> l = (List>) value;
if (!l.isEmpty()) {
Object o = l.get(0);
if (o instanceof String[]) {
pw.print("[e ");
pw.print(((String[]) o)[0]);
pw.print(" = ");
} else if (o instanceof AnnotationNode) {
pw.print("[& ");
pw.print(((AnnotationNode) o).desc);
pw.print(" = ");
pw.print("[@ = ");
} else if (o instanceof String) {
pw.print("[s = ");
} else if (o instanceof Byte) {
pw.print("[B = ");
} else if (o instanceof Boolean) {
pw.print("[Z = ");
} else if (o instanceof Character) {
pw.print("[C = ");
} else if (o instanceof Short) {
pw.print("[S = ");
} else if (o instanceof Type) {
pw.print("[c = ");
} else if (o instanceof Integer) {
pw.print("[I = ");
} else if (o instanceof Float) {
pw.print("[F = ");
} else if (o instanceof Long) {
pw.print("[J = ");
} else if (o instanceof Double) {
pw.print("[D = ");
}
for (Object aL : l) {
printAnnotationArrayValue(aL);
pw.print(' ');
}
} else {
pw.print("; empty array annotation value");
}
pw.println();
} else if (value instanceof String) {
pw.print("s = ");
print(value);
pw.println();
} else if (value instanceof Byte) {
pw.print("B = ");
pw.println(((Byte) value).intValue());
} else if (value instanceof Boolean) {
pw.print("Z = ");
pw.println((Boolean) value ? 1 : 0);
} else if (value instanceof Character) {
pw.print("C = ");
pw.println(Integer.valueOf((Character) value));
} else if (value instanceof Short) {
pw.print("S = ");
pw.println(((Short) value).intValue());
} else if (value instanceof Type) {
pw.print("c = ");
pw.println(((Type) value).getDescriptor());
} else if (value instanceof Integer) {
pw.print("I = ");
print(value);
pw.println();
} else if (value instanceof Float) {
pw.print("F = ");
print(value);
pw.println();
} else if (value instanceof Long) {
pw.print("J = ");
print(value);
pw.println();
} else if (value instanceof Double) {
pw.print("D = ");
print(value);
pw.println();
} else {
throw new RuntimeException();
}
}
protected void printAnnotationArrayValue(final Object value) {
if (value instanceof String[]) {
print(((String[]) value)[1]);
} else if (value instanceof AnnotationNode) {
printAnnotation((AnnotationNode) value, 0, -1);
} else if (value instanceof String) {
print(value);
} else if (value instanceof Byte) {
pw.print(((Byte) value).intValue());
} else if (value instanceof Boolean) {
pw.print((Boolean) value ? 1 : 0);
} else if (value instanceof Character) {
pw.print(Integer.valueOf((Character) value));
} else if (value instanceof Short) {
pw.print(((Short) value).intValue());
} else if (value instanceof Type) {
pw.print(((Type) value).getDescriptor());
} else {
print(value);
}
}
protected void printFrameType(final Object type) {
if (Opcodes.TOP.equals(type)) {
pw.print("Top");
} else if (Opcodes.INTEGER.equals(type)) {
pw.print("Integer");
} else if (Opcodes.FLOAT.equals(type)) {
pw.print("Float");
} else if (Opcodes.LONG.equals(type)) {
pw.print("Long");
} else if (Opcodes.DOUBLE.equals(type)) {
pw.print("Double");
} else if (Opcodes.NULL.equals(type)) {
pw.print("Null");
} else if (Opcodes.UNINITIALIZED_THIS.equals(type)) {
pw.print("UninitializedThis");
} else if (type instanceof Label) {
pw.print("Uninitialized ");
print((Label) type);
} else {
pw.print("Object ");
pw.print(type);
}
}
}