All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.d2j.jasmin.JasminDumper Maven / Gradle / Ivy

The newest version!
/***
 * ASM: a very small and fast Java bytecode manipulation framework
 * Copyright (c) 2000-2005 INRIA, France Telecom
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.googlecode.d2j.jasmin;

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.*;
import org.objectweb.asm.util.Printer;

import java.io.PrintWriter;
import java.util.*;

/**
 * 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 ()V
 * aload 0
 * invokespecial java/lang/Object/()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 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(access_clz(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(access_clz(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 = false; if (fn.visibleAnnotations != null && fn.visibleAnnotations.size() > 0) { annotations = true; } if (fn.invisibleAnnotations != null && fn.invisibleAnnotations.size() > 0) { annotations = true; } boolean deprecated = (fn.access & Opcodes.ACC_DEPRECATED) != 0; pw.print("\n.field"); pw.print(access_fld(fn.access)); pw.print(' '); printIdAfterAccess(pw,fn.name); pw.print(' '); pw.print(fn.desc); if (fn.value instanceof String) { StringBuffer buf = new StringBuffer(); Printer.appendString(buf, (String) fn.value); pw.print(" = "); pw.print(buf.toString()); } 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(access_mtd(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(ASM4) { @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) { print(opcode); pw.print(' '); pw.print(owner); pw.print('/'); pw.print(name); pw.print(desc); if (opcode == Opcodes.INVOKEINTERFACE) { pw.print(' '); pw.print((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1); } pw.println(); } @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 access_clz(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 access_fld(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 access_mtd(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) { 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(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.get(l); if (name == null) { name = "L" + labelNames.size(); labelNames.put(l, name); } 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(new Integer(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(new Float(element)); pw.print(' '); } pw.println(); } else if (value instanceof double[]) { pw.print("[D = "); double[] v = (double[]) value; for (double element : v) { print(new Double(element)); pw.print(' '); } pw.println(); } else if (value instanceof List) { List l = (List) value; if (l.size() > 0) { 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).booleanValue() ? 1 : 0); } else if (value instanceof Character) { pw.print("C = "); pw.println(new Integer(((Character) value).charValue())); } 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).booleanValue() ? 1 : 0); } else if (value instanceof Character) { pw.print(new Integer(((Character) value).charValue())); } 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 (type == Opcodes.TOP) { pw.print("Top"); } else if (type == Opcodes.INTEGER) { pw.print("Integer"); } else if (type == Opcodes.FLOAT) { pw.print("Float"); } else if (type == Opcodes.LONG) { pw.print("Long"); } else if (type == Opcodes.DOUBLE) { pw.print("Double"); } else if (type == Opcodes.NULL) { pw.print("Null"); } else if (type == Opcodes.UNINITIALIZED_THIS) { pw.print("UninitializedThis"); } else if (type instanceof Label) { pw.print("Uninitialized "); print((Label) type); } else { pw.print("Object "); pw.print(type); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy