http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/Textifier.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/Textifier.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/Textifier.java new file mode 100644 index 0000000..7dc1fb1 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/Textifier.java @@ -0,0 +1,1200 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 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 org.apache.tajo.org.objectweb.asm.util; + +import java.io.FileInputStream; +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tajo.org.objectweb.asm.Attribute; +import org.apache.tajo.org.objectweb.asm.ClassReader; +import org.apache.tajo.org.objectweb.asm.Label; +import org.apache.tajo.org.objectweb.asm.Type; +import org.apache.tajo.org.objectweb.asm.signature.SignatureReader; +import org.apache.tajo.org.objectweb.asm.Handle; +import org.apache.tajo.org.objectweb.asm.Opcodes; + +/** + * A {@link Printer} that prints a disassembled view of the classes it visits. + * + * @author Eric Bruneton + */ +public class Textifier extends Printer { + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for internal + * type names in bytecode notation. + */ + public static final int INTERNAL_NAME = 0; + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for field + * descriptors, formatted in bytecode notation + */ + public static final int FIELD_DESCRIPTOR = 1; + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for field + * signatures, formatted in bytecode notation + */ + public static final int FIELD_SIGNATURE = 2; + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for method + * descriptors, formatted in bytecode notation + */ + public static final int METHOD_DESCRIPTOR = 3; + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for method + * signatures, formatted in bytecode notation + */ + public static final int METHOD_SIGNATURE = 4; + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for class + * signatures, formatted in bytecode notation + */ + public static final int CLASS_SIGNATURE = 5; + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for field or + * method return value signatures, formatted in default Java notation + * (non-bytecode) + */ + public static final int TYPE_DECLARATION = 6; + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for class + * signatures, formatted in default Java notation (non-bytecode) + */ + public static final int CLASS_DECLARATION = 7; + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for method + * parameter signatures, formatted in default Java notation (non-bytecode) + */ + public static final int PARAMETERS_DECLARATION = 8; + + /** + * Constant used in {@link #appendDescriptor appendDescriptor} for handle + * descriptors, formatted in bytecode notation + */ + public static final int HANDLE_DESCRIPTOR = 9; + + /** + * Tab for class members. + */ + protected String tab = " "; + + /** + * Tab for bytecode instructions. + */ + protected String tab2 = " "; + + /** + * Tab for table and lookup switch instructions. + */ + protected String tab3 = " "; + + /** + * Tab for labels. + */ + protected String ltab = " "; + + /** + * The label names. This map associate String values to Label keys. + */ + protected Map<Label, String> labelNames; + + private int valueNumber = 0; + + /** + * Constructs a new {@link Textifier}. <i>Subclasses must not use this + * constructor</i>. Instead, they must use the {@link #Textifier(int)} + * version. + */ + public Textifier() { + this(Opcodes.ASM4); + } + + /** + * Constructs a new {@link Textifier}. + * + * @param api + * the ASM API version implemented by this visitor. Must be one + * of {@link Opcodes#ASM4}. + */ + protected Textifier(final int api) { + super(api); + } + + /** + * Prints a disassembled view of the given class to the standard output. + * <p> + * Usage: Textifier [-debug] <binary class name or class file name > + * + * @param args + * the command line arguments. + * + * @throws Exception + * if the class cannot be found, or if an IO exception occurs. + */ + public static void main(final String[] args) throws Exception { + int i = 0; + int flags = ClassReader.SKIP_DEBUG; + + boolean ok = true; + if (args.length < 1 || args.length > 2) { + ok = false; + } + if (ok && "-debug".equals(args[0])) { + i = 1; + flags = 0; + if (args.length != 2) { + ok = false; + } + } + if (!ok) { + System.err + .println("Prints a disassembled view of the given class."); + System.err.println("Usage: Textifier [-debug] " + + "<fully qualified class name or class file name>"); + return; + } + ClassReader cr; + if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1 + || args[i].indexOf('/') > -1) { + cr = new ClassReader(new FileInputStream(args[i])); + } else { + cr = new ClassReader(args[i]); + } + cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), flags); + } + + // ------------------------------------------------------------------------ + // Classes + // ------------------------------------------------------------------------ + + @Override + public void visit(final int version, final int access, final String name, + final String signature, final String superName, + final String[] interfaces) { + int major = version & 0xFFFF; + int minor = version >>> 16; + buf.setLength(0); + buf.append("// class version ").append(major).append('.').append(minor) + .append(" (").append(version).append(")\n"); + if ((access & Opcodes.ACC_DEPRECATED) != 0) { + buf.append("// DEPRECATED\n"); + } + buf.append("// access flags 0x") + .append(Integer.toHexString(access).toUpperCase()).append('\n'); + + appendDescriptor(CLASS_SIGNATURE, signature); + if (signature != null) { + TraceSignatureVisitor sv = new TraceSignatureVisitor(access); + SignatureReader r = new SignatureReader(signature); + r.accept(sv); + buf.append("// declaration: ").append(name) + .append(sv.getDeclaration()).append('\n'); + } + + appendAccess(access & ~Opcodes.ACC_SUPER); + if ((access & Opcodes.ACC_ANNOTATION) != 0) { + buf.append("@interface "); + } else if ((access & Opcodes.ACC_INTERFACE) != 0) { + buf.append("interface "); + } else if ((access & Opcodes.ACC_ENUM) == 0) { + buf.append("class "); + } + appendDescriptor(INTERNAL_NAME, name); + + if (superName != null && !"java/lang/Object".equals(superName)) { + buf.append(" extends "); + appendDescriptor(INTERNAL_NAME, superName); + buf.append(' '); + } + if (interfaces != null && interfaces.length > 0) { + buf.append(" implements "); + for (int i = 0; i < interfaces.length; ++i) { + appendDescriptor(INTERNAL_NAME, interfaces[i]); + buf.append(' '); + } + } + buf.append(" {\n\n"); + + text.add(buf.toString()); + } + + @Override + public void visitSource(final String file, final String debug) { + buf.setLength(0); + if (file != null) { + buf.append(tab).append("// compiled from: ").append(file) + .append('\n'); + } + if (debug != null) { + buf.append(tab).append("// debug info: ").append(debug) + .append('\n'); + } + if (buf.length() > 0) { + text.add(buf.toString()); + } + } + + @Override + public void visitOuterClass(final String owner, final String name, + final String desc) { + buf.setLength(0); + buf.append(tab).append("OUTERCLASS "); + appendDescriptor(INTERNAL_NAME, owner); + buf.append(' '); + if (name != null) { + buf.append(name).append(' '); + } + appendDescriptor(METHOD_DESCRIPTOR, desc); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public Textifier visitClassAnnotation(final String desc, + final boolean visible) { + text.add("\n"); + return visitAnnotation(desc, visible); + } + + @Override + public void visitClassAttribute(final Attribute attr) { + text.add("\n"); + visitAttribute(attr); + } + + @Override + public void visitInnerClass(final String name, final String outerName, + final String innerName, final int access) { + buf.setLength(0); + buf.append(tab).append("// access flags 0x"); + buf.append( + Integer.toHexString(access & ~Opcodes.ACC_SUPER).toUpperCase()) + .append('\n'); + buf.append(tab); + appendAccess(access); + buf.append("INNERCLASS "); + appendDescriptor(INTERNAL_NAME, name); + buf.append(' '); + appendDescriptor(INTERNAL_NAME, outerName); + buf.append(' '); + appendDescriptor(INTERNAL_NAME, innerName); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public Textifier visitField(final int access, final String name, + final String desc, final String signature, final Object value) { + buf.setLength(0); + buf.append('\n'); + if ((access & Opcodes.ACC_DEPRECATED) != 0) { + buf.append(tab).append("// DEPRECATED\n"); + } + buf.append(tab).append("// access flags 0x") + .append(Integer.toHexString(access).toUpperCase()).append('\n'); + if (signature != null) { + buf.append(tab); + appendDescriptor(FIELD_SIGNATURE, signature); + + TraceSignatureVisitor sv = new TraceSignatureVisitor(0); + SignatureReader r = new SignatureReader(signature); + r.acceptType(sv); + buf.append(tab).append("// declaration: ") + .append(sv.getDeclaration()).append('\n'); + } + + buf.append(tab); + appendAccess(access); + + appendDescriptor(FIELD_DESCRIPTOR, desc); + buf.append(' ').append(name); + if (value != null) { + buf.append(" = "); + if (value instanceof String) { + buf.append('\"').append(value).append('\"'); + } else { + buf.append(value); + } + } + + buf.append('\n'); + text.add(buf.toString()); + + Textifier t = createTextifier(); + text.add(t.getText()); + return t; + } + + @Override + public Textifier visitMethod(final int access, final String name, + final String desc, final String signature, final String[] exceptions) { + buf.setLength(0); + buf.append('\n'); + if ((access & Opcodes.ACC_DEPRECATED) != 0) { + buf.append(tab).append("// DEPRECATED\n"); + } + buf.append(tab).append("// access flags 0x") + .append(Integer.toHexString(access).toUpperCase()).append('\n'); + + if (signature != null) { + buf.append(tab); + appendDescriptor(METHOD_SIGNATURE, signature); + + TraceSignatureVisitor v = new TraceSignatureVisitor(0); + SignatureReader r = new SignatureReader(signature); + r.accept(v); + String genericDecl = v.getDeclaration(); + String genericReturn = v.getReturnType(); + String genericExceptions = v.getExceptions(); + + buf.append(tab).append("// declaration: ").append(genericReturn) + .append(' ').append(name).append(genericDecl); + if (genericExceptions != null) { + buf.append(" throws ").append(genericExceptions); + } + buf.append('\n'); + } + + buf.append(tab); + appendAccess(access); + if ((access & Opcodes.ACC_NATIVE) != 0) { + buf.append("native "); + } + if ((access & Opcodes.ACC_VARARGS) != 0) { + buf.append("varargs "); + } + if ((access & Opcodes.ACC_BRIDGE) != 0) { + buf.append("bridge "); + } + + buf.append(name); + appendDescriptor(METHOD_DESCRIPTOR, desc); + if (exceptions != null && exceptions.length > 0) { + buf.append(" throws "); + for (int i = 0; i < exceptions.length; ++i) { + appendDescriptor(INTERNAL_NAME, exceptions[i]); + buf.append(' '); + } + } + + buf.append('\n'); + text.add(buf.toString()); + + Textifier t = createTextifier(); + text.add(t.getText()); + return t; + } + + @Override + public void visitClassEnd() { + text.add("}\n"); + } + + // ------------------------------------------------------------------------ + // Annotations + // ------------------------------------------------------------------------ + + @Override + public void visit(final String name, final Object value) { + buf.setLength(0); + appendComa(valueNumber++); + + if (name != null) { + buf.append(name).append('='); + } + + if (value instanceof String) { + visitString((String) value); + } else if (value instanceof Type) { + visitType((Type) value); + } else if (value instanceof Byte) { + visitByte(((Byte) value).byteValue()); + } else if (value instanceof Boolean) { + visitBoolean(((Boolean) value).booleanValue()); + } else if (value instanceof Short) { + visitShort(((Short) value).shortValue()); + } else if (value instanceof Character) { + visitChar(((Character) value).charValue()); + } else if (value instanceof Integer) { + visitInt(((Integer) value).intValue()); + } else if (value instanceof Float) { + visitFloat(((Float) value).floatValue()); + } else if (value instanceof Long) { + visitLong(((Long) value).longValue()); + } else if (value instanceof Double) { + visitDouble(((Double) value).doubleValue()); + } else if (value.getClass().isArray()) { + buf.append('{'); + if (value instanceof byte[]) { + byte[] v = (byte[]) value; + for (int i = 0; i < v.length; i++) { + appendComa(i); + visitByte(v[i]); + } + } else if (value instanceof boolean[]) { + boolean[] v = (boolean[]) value; + for (int i = 0; i < v.length; i++) { + appendComa(i); + visitBoolean(v[i]); + } + } else if (value instanceof short[]) { + short[] v = (short[]) value; + for (int i = 0; i < v.length; i++) { + appendComa(i); + visitShort(v[i]); + } + } else if (value instanceof char[]) { + char[] v = (char[]) value; + for (int i = 0; i < v.length; i++) { + appendComa(i); + visitChar(v[i]); + } + } else if (value instanceof int[]) { + int[] v = (int[]) value; + for (int i = 0; i < v.length; i++) { + appendComa(i); + visitInt(v[i]); + } + } else if (value instanceof long[]) { + long[] v = (long[]) value; + for (int i = 0; i < v.length; i++) { + appendComa(i); + visitLong(v[i]); + } + } else if (value instanceof float[]) { + float[] v = (float[]) value; + for (int i = 0; i < v.length; i++) { + appendComa(i); + visitFloat(v[i]); + } + } else if (value instanceof double[]) { + double[] v = (double[]) value; + for (int i = 0; i < v.length; i++) { + appendComa(i); + visitDouble(v[i]); + } + } + buf.append('}'); + } + + text.add(buf.toString()); + } + + private void visitInt(final int value) { + buf.append(value); + } + + private void visitLong(final long value) { + buf.append(value).append('L'); + } + + private void visitFloat(final float value) { + buf.append(value).append('F'); + } + + private void visitDouble(final double value) { + buf.append(value).append('D'); + } + + private void visitChar(final char value) { + buf.append("(char)").append((int) value); + } + + private void visitShort(final short value) { + buf.append("(short)").append(value); + } + + private void visitByte(final byte value) { + buf.append("(byte)").append(value); + } + + private void visitBoolean(final boolean value) { + buf.append(value); + } + + private void visitString(final String value) { + appendString(buf, value); + } + + private void visitType(final Type value) { + buf.append(value.getClassName()).append(".class"); + } + + @Override + public void visitEnum(final String name, final String desc, + final String value) { + buf.setLength(0); + appendComa(valueNumber++); + if (name != null) { + buf.append(name).append('='); + } + appendDescriptor(FIELD_DESCRIPTOR, desc); + buf.append('.').append(value); + text.add(buf.toString()); + } + + @Override + public Textifier visitAnnotation(final String name, final String desc) { + buf.setLength(0); + appendComa(valueNumber++); + if (name != null) { + buf.append(name).append('='); + } + buf.append('@'); + appendDescriptor(FIELD_DESCRIPTOR, desc); + buf.append('('); + text.add(buf.toString()); + Textifier t = createTextifier(); + text.add(t.getText()); + text.add(")"); + return t; + } + + @Override + public Textifier visitArray(final String name) { + buf.setLength(0); + appendComa(valueNumber++); + if (name != null) { + buf.append(name).append('='); + } + buf.append('{'); + text.add(buf.toString()); + Textifier t = createTextifier(); + text.add(t.getText()); + text.add("}"); + return t; + } + + @Override + public void visitAnnotationEnd() { + } + + // ------------------------------------------------------------------------ + // Fields + // ------------------------------------------------------------------------ + + @Override + public Textifier visitFieldAnnotation(final String desc, + final boolean visible) { + return visitAnnotation(desc, visible); + } + + @Override + public void visitFieldAttribute(final Attribute attr) { + visitAttribute(attr); + } + + @Override + public void visitFieldEnd() { + } + + // ------------------------------------------------------------------------ + // Methods + // ------------------------------------------------------------------------ + + @Override + public Textifier visitAnnotationDefault() { + text.add(tab2 + "default="); + Textifier t = createTextifier(); + text.add(t.getText()); + text.add("\n"); + return t; + } + + @Override + public Textifier visitMethodAnnotation(final String desc, + final boolean visible) { + return visitAnnotation(desc, visible); + } + + @Override + public Textifier visitParameterAnnotation(final int parameter, + final String desc, final boolean visible) { + buf.setLength(0); + buf.append(tab2).append('@'); + appendDescriptor(FIELD_DESCRIPTOR, desc); + buf.append('('); + text.add(buf.toString()); + Textifier t = createTextifier(); + text.add(t.getText()); + text.add(visible ? ") // parameter " : ") // invisible, parameter "); + text.add(new Integer(parameter)); + text.add("\n"); + return t; + } + + @Override + public void visitMethodAttribute(final Attribute attr) { + buf.setLength(0); + buf.append(tab).append("ATTRIBUTE "); + appendDescriptor(-1, attr.type); + + if (attr instanceof Textifiable) { + ((Textifiable) attr).textify(buf, labelNames); + } else { + buf.append(" : unknown\n"); + } + + text.add(buf.toString()); + } + + @Override + public void visitCode() { + } + + @Override + public void visitFrame(final int type, final int nLocal, + final Object[] local, final int nStack, final Object[] stack) { + buf.setLength(0); + buf.append(ltab); + buf.append("FRAME "); + switch (type) { + case Opcodes.F_NEW: + case Opcodes.F_FULL: + buf.append("FULL ["); + appendFrameTypes(nLocal, local); + buf.append("] ["); + appendFrameTypes(nStack, stack); + buf.append(']'); + break; + case Opcodes.F_APPEND: + buf.append("APPEND ["); + appendFrameTypes(nLocal, local); + buf.append(']'); + break; + case Opcodes.F_CHOP: + buf.append("CHOP ").append(nLocal); + break; + case Opcodes.F_SAME: + buf.append("SAME"); + break; + case Opcodes.F_SAME1: + buf.append("SAME1 "); + appendFrameTypes(1, stack); + break; + } + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitInsn(final int opcode) { + buf.setLength(0); + buf.append(tab2).append(OPCODES[opcode]).append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitIntInsn(final int opcode, final int operand) { + buf.setLength(0); + buf.append(tab2) + .append(OPCODES[opcode]) + .append(' ') + .append(opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer + .toString(operand)).append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitVarInsn(final int opcode, final int var) { + buf.setLength(0); + buf.append(tab2).append(OPCODES[opcode]).append(' ').append(var) + .append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitTypeInsn(final int opcode, final String type) { + buf.setLength(0); + buf.append(tab2).append(OPCODES[opcode]).append(' '); + appendDescriptor(INTERNAL_NAME, type); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitFieldInsn(final int opcode, final String owner, + final String name, final String desc) { + buf.setLength(0); + buf.append(tab2).append(OPCODES[opcode]).append(' '); + appendDescriptor(INTERNAL_NAME, owner); + buf.append('.').append(name).append(" : "); + appendDescriptor(FIELD_DESCRIPTOR, desc); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc) { + buf.setLength(0); + buf.append(tab2).append(OPCODES[opcode]).append(' '); + appendDescriptor(INTERNAL_NAME, owner); + buf.append('.').append(name).append(' '); + appendDescriptor(METHOD_DESCRIPTOR, desc); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, + Object... bsmArgs) { + buf.setLength(0); + buf.append(tab2).append("INVOKEDYNAMIC").append(' '); + buf.append(name); + appendDescriptor(METHOD_DESCRIPTOR, desc); + buf.append(" ["); + appendHandle(bsm); + buf.append(tab3).append("// arguments:"); + if (bsmArgs.length == 0) { + buf.append(" none"); + } else { + buf.append('\n').append(tab3); + for (int i = 0; i < bsmArgs.length; i++) { + Object cst = bsmArgs[i]; + if (cst instanceof String) { + Printer.appendString(buf, (String) cst); + } else if (cst instanceof Type) { + buf.append(((Type) cst).getDescriptor()).append(".class"); + } else if (cst instanceof Handle) { + appendHandle((Handle) cst); + } else { + buf.append(cst); + } + buf.append(", "); + } + buf.setLength(buf.length() - 2); + } + buf.append('\n'); + buf.append(tab2).append("]\n"); + text.add(buf.toString()); + } + + @Override + public void visitJumpInsn(final int opcode, final Label label) { + buf.setLength(0); + buf.append(tab2).append(OPCODES[opcode]).append(' '); + appendLabel(label); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitLabel(final Label label) { + buf.setLength(0); + buf.append(ltab); + appendLabel(label); + buf.append('\n'); + text.add(buf.toString()); + } + + @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 Type) { + buf.append(((Type) cst).getDescriptor()).append(".class"); + } else { + buf.append(cst); + } + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitIincInsn(final int var, final int increment) { + buf.setLength(0); + buf.append(tab2).append("IINC ").append(var).append(' ') + .append(increment).append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitTableSwitchInsn(final int min, final int max, + final Label dflt, final Label... labels) { + buf.setLength(0); + buf.append(tab2).append("TABLESWITCH\n"); + for (int i = 0; i < labels.length; ++i) { + buf.append(tab3).append(min + i).append(": "); + appendLabel(labels[i]); + buf.append('\n'); + } + buf.append(tab3).append("default: "); + appendLabel(dflt); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitLookupSwitchInsn(final Label dflt, final int[] keys, + final Label[] labels) { + buf.setLength(0); + buf.append(tab2).append("LOOKUPSWITCH\n"); + for (int i = 0; i < labels.length; ++i) { + buf.append(tab3).append(keys[i]).append(": "); + appendLabel(labels[i]); + buf.append('\n'); + } + buf.append(tab3).append("default: "); + appendLabel(dflt); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitMultiANewArrayInsn(final String desc, final int dims) { + buf.setLength(0); + buf.append(tab2).append("MULTIANEWARRAY "); + appendDescriptor(FIELD_DESCRIPTOR, desc); + buf.append(' ').append(dims).append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitTryCatchBlock(final Label start, final Label end, + final Label handler, final String type) { + buf.setLength(0); + buf.append(tab2).append("TRYCATCHBLOCK "); + appendLabel(start); + buf.append(' '); + appendLabel(end); + buf.append(' '); + appendLabel(handler); + buf.append(' '); + appendDescriptor(INTERNAL_NAME, type); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitLocalVariable(final String name, final String desc, + final String signature, final Label start, final Label end, + final int index) { + buf.setLength(0); + buf.append(tab2).append("LOCALVARIABLE ").append(name).append(' '); + appendDescriptor(FIELD_DESCRIPTOR, desc); + buf.append(' '); + appendLabel(start); + buf.append(' '); + appendLabel(end); + buf.append(' ').append(index).append('\n'); + + if (signature != null) { + buf.append(tab2); + appendDescriptor(FIELD_SIGNATURE, signature); + + TraceSignatureVisitor sv = new TraceSignatureVisitor(0); + SignatureReader r = new SignatureReader(signature); + r.acceptType(sv); + buf.append(tab2).append("// declaration: ") + .append(sv.getDeclaration()).append('\n'); + } + text.add(buf.toString()); + } + + @Override + public void visitLineNumber(final int line, final Label start) { + buf.setLength(0); + buf.append(tab2).append("LINENUMBER ").append(line).append(' '); + appendLabel(start); + buf.append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitMaxs(final int maxStack, final int maxLocals) { + buf.setLength(0); + buf.append(tab2).append("MAXSTACK = ").append(maxStack).append('\n'); + text.add(buf.toString()); + + buf.setLength(0); + buf.append(tab2).append("MAXLOCALS = ").append(maxLocals).append('\n'); + text.add(buf.toString()); + } + + @Override + public void visitMethodEnd() { + } + + // ------------------------------------------------------------------------ + // Common methods + // ------------------------------------------------------------------------ + + /** + * Prints a disassembled view of the given annotation. + * + * @param desc + * the class descriptor of the annotation class. + * @param visible + * <tt>true</tt> if the annotation is visible at runtime. + * @return a visitor to visit the annotation values. + */ + public Textifier visitAnnotation(final String desc, final boolean visible) { + buf.setLength(0); + buf.append(tab).append('@'); + appendDescriptor(FIELD_DESCRIPTOR, desc); + buf.append('('); + text.add(buf.toString()); + Textifier t = createTextifier(); + text.add(t.getText()); + text.add(visible ? ")\n" : ") // invisible\n"); + return t; + } + + /** + * Prints a disassembled view of the given attribute. + * + * @param attr + * an attribute. + */ + public void visitAttribute(final Attribute attr) { + buf.setLength(0); + buf.append(tab).append("ATTRIBUTE "); + appendDescriptor(-1, attr.type); + + if (attr instanceof Textifiable) { + ((Textifiable) attr).textify(buf, null); + } else { + buf.append(" : unknown\n"); + } + + text.add(buf.toString()); + } + + // ------------------------------------------------------------------------ + // Utility methods + // ------------------------------------------------------------------------ + + /** + * Creates a new TraceVisitor instance. + * + * @return a new TraceVisitor. + */ + protected Textifier createTextifier() { + return new Textifier(); + } + + /** + * Appends an internal name, a type descriptor or a type signature to + * {@link #buf buf}. + * + * @param type + * indicates if desc is an internal name, a field descriptor, a + * method descriptor, a class signature, ... + * @param desc + * an internal name, type descriptor, or type signature. May be + * <tt>null</tt>. + */ + protected void appendDescriptor(final int type, final String desc) { + if (type == CLASS_SIGNATURE || type == FIELD_SIGNATURE + || type == METHOD_SIGNATURE) { + if (desc != null) { + buf.append("// signature ").append(desc).append('\n'); + } + } else { + buf.append(desc); + } + } + + /** + * Appends the name of the given label to {@link #buf buf}. Creates a new + * label name if the given label does not yet have one. + * + * @param l + * a label. + */ + protected void appendLabel(final Label l) { + if (labelNames == null) { + labelNames = new HashMap<Label, String>(); + } + String name = labelNames.get(l); + if (name == null) { + name = "L" + labelNames.size(); + labelNames.put(l, name); + } + buf.append(name); + } + + /** + * Appends the information about the given handle to {@link #buf buf}. + * + * @param h + * a handle, non null. + */ + protected void appendHandle(final Handle h) { + buf.append('\n').append(tab3); + int tag = h.getTag(); + buf.append("// handle kind 0x").append(Integer.toHexString(tag)) + .append(" : "); + switch (tag) { + case Opcodes.H_GETFIELD: + buf.append("GETFIELD"); + break; + case Opcodes.H_GETSTATIC: + buf.append("GETSTATIC"); + break; + case Opcodes.H_PUTFIELD: + buf.append("PUTFIELD"); + break; + case Opcodes.H_PUTSTATIC: + buf.append("PUTSTATIC"); + break; + case Opcodes.H_INVOKEINTERFACE: + buf.append("INVOKEINTERFACE"); + break; + case Opcodes.H_INVOKESPECIAL: + buf.append("INVOKESPECIAL"); + break; + case Opcodes.H_INVOKESTATIC: + buf.append("INVOKESTATIC"); + break; + case Opcodes.H_INVOKEVIRTUAL: + buf.append("INVOKEVIRTUAL"); + break; + case Opcodes.H_NEWINVOKESPECIAL: + buf.append("NEWINVOKESPECIAL"); + break; + } + buf.append('\n'); + buf.append(tab3); + appendDescriptor(INTERNAL_NAME, h.getOwner()); + buf.append('.'); + buf.append(h.getName()); + buf.append('('); + appendDescriptor(HANDLE_DESCRIPTOR, h.getDesc()); + buf.append(')').append('\n'); + } + + /** + * Appends a string representation of the given access modifiers to + * {@link #buf buf}. + * + * @param access + * some access modifiers. + */ + private void appendAccess(final int access) { + if ((access & Opcodes.ACC_PUBLIC) != 0) { + buf.append("public "); + } + if ((access & Opcodes.ACC_PRIVATE) != 0) { + buf.append("private "); + } + if ((access & Opcodes.ACC_PROTECTED) != 0) { + buf.append("protected "); + } + if ((access & Opcodes.ACC_FINAL) != 0) { + buf.append("final "); + } + if ((access & Opcodes.ACC_STATIC) != 0) { + buf.append("static "); + } + if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) { + buf.append("synchronized "); + } + if ((access & Opcodes.ACC_VOLATILE) != 0) { + buf.append("volatile "); + } + if ((access & Opcodes.ACC_TRANSIENT) != 0) { + buf.append("transient "); + } + if ((access & Opcodes.ACC_ABSTRACT) != 0) { + buf.append("abstract "); + } + if ((access & Opcodes.ACC_STRICT) != 0) { + buf.append("strictfp "); + } + if ((access & Opcodes.ACC_SYNTHETIC) != 0) { + buf.append("synthetic "); + } + if ((access & Opcodes.ACC_ENUM) != 0) { + buf.append("enum "); + } + } + + private void appendComa(final int i) { + if (i != 0) { + buf.append(", "); + } + } + + private void appendFrameTypes(final int n, final Object[] o) { + for (int i = 0; i < n; ++i) { + if (i > 0) { + buf.append(' '); + } + if (o[i] instanceof String) { + String desc = (String) o[i]; + if (desc.startsWith("[")) { + appendDescriptor(FIELD_DESCRIPTOR, desc); + } else { + appendDescriptor(INTERNAL_NAME, desc); + } + } else if (o[i] instanceof Integer) { + switch (((Integer) o[i]).intValue()) { + case 0: + appendDescriptor(FIELD_DESCRIPTOR, "T"); + break; + case 1: + appendDescriptor(FIELD_DESCRIPTOR, "I"); + break; + case 2: + appendDescriptor(FIELD_DESCRIPTOR, "F"); + break; + case 3: + appendDescriptor(FIELD_DESCRIPTOR, "D"); + break; + case 4: + appendDescriptor(FIELD_DESCRIPTOR, "J"); + break; + case 5: + appendDescriptor(FIELD_DESCRIPTOR, "N"); + break; + case 6: + appendDescriptor(FIELD_DESCRIPTOR, "U"); + break; + } + } else { + appendLabel((Label) o[i]); + } + } + } +}
http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceAnnotationVisitor.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceAnnotationVisitor.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceAnnotationVisitor.java new file mode 100644 index 0000000..42ca34e --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceAnnotationVisitor.java @@ -0,0 +1,89 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 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 org.apache.tajo.org.objectweb.asm.util; + +import org.apache.tajo.org.objectweb.asm.AnnotationVisitor; +import org.apache.tajo.org.objectweb.asm.Opcodes; + +/** + * An {@link org.apache.tajo.org.objectweb.asm.AnnotationVisitor} that prints the annotations it visits with a + * {@link Printer}. + * + * @author Eric Bruneton + */ +public final class TraceAnnotationVisitor extends AnnotationVisitor { + + private final Printer p; + + public TraceAnnotationVisitor(final Printer p) { + this(null, p); + } + + public TraceAnnotationVisitor(final AnnotationVisitor av, final Printer p) { + super(Opcodes.ASM4, av); + this.p = p; + } + + @Override + public void visit(final String name, final Object value) { + p.visit(name, value); + super.visit(name, value); + } + + @Override + public void visitEnum(final String name, final String desc, + final String value) { + p.visitEnum(name, desc, value); + super.visitEnum(name, desc, value); + } + + @Override + public AnnotationVisitor visitAnnotation(final String name, + final String desc) { + Printer p = this.p.visitAnnotation(name, desc); + AnnotationVisitor av = this.av == null ? null : this.av + .visitAnnotation(name, desc); + return new TraceAnnotationVisitor(av, p); + } + + @Override + public AnnotationVisitor visitArray(final String name) { + Printer p = this.p.visitArray(name); + AnnotationVisitor av = this.av == null ? null : this.av + .visitArray(name); + return new TraceAnnotationVisitor(av, p); + } + + @Override + public void visitEnd() { + p.visitAnnotationEnd(); + super.visitEnd(); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceClassVisitor.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceClassVisitor.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceClassVisitor.java new file mode 100644 index 0000000..478d899 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceClassVisitor.java @@ -0,0 +1,209 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 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 org.apache.tajo.org.objectweb.asm.util; + +import java.io.PrintWriter; + +import org.apache.tajo.org.objectweb.asm.AnnotationVisitor; +import org.apache.tajo.org.objectweb.asm.Attribute; +import org.apache.tajo.org.objectweb.asm.ClassVisitor; +import org.apache.tajo.org.objectweb.asm.FieldVisitor; +import org.apache.tajo.org.objectweb.asm.MethodVisitor; +import org.apache.tajo.org.objectweb.asm.Opcodes; + +/** + * A {@link org.apache.tajo.org.objectweb.asm.ClassVisitor} that prints the classes it visits with a + * {@link Printer}. This class visitor can be used in the middle of a class + * visitor chain to trace the class that is visited at a given point in this + * chain. This may be useful for debugging purposes. + * <p> + * The trace printed when visiting the <tt>Hello</tt> class is the following: + * <p> + * <blockquote> + * + * <pre> + * // class version 49.0 (49) // access flags 0x21 public class Hello { + * + * // compiled from: Hello.java + * + * // access flags 0x1 public <init> ()V ALOAD 0 INVOKESPECIAL + * java/lang/Object <init> ()V RETURN MAXSTACK = 1 MAXLOCALS = 1 + * + * // access flags 0x9 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 + * MAXSTACK = 2 MAXLOCALS = 1 } + * </pre> + * + * </blockquote> where <tt>Hello</tt> is defined by: + * <p> + * <blockquote> + * + * <pre> + * public class Hello { + * + * public static void main(String[] args) { + * System.out.println("hello"); + * } + * } + * </pre> + * + * </blockquote> + * + * @author Eric Bruneton + * @author Eugene Kuleshov + */ +public final class TraceClassVisitor extends ClassVisitor { + + /** + * The print writer to be used to print the class. May be null. + */ + private final PrintWriter pw; + + /** + * The object that actually converts visit events into text. + */ + public final Printer p; + + /** + * Constructs a new {@link TraceClassVisitor}. + * + * @param pw + * the print writer to be used to print the class. + */ + public TraceClassVisitor(final PrintWriter pw) { + this(null, pw); + } + + /** + * Constructs a new {@link TraceClassVisitor}. + * + * @param cv + * the {@link ClassVisitor} to which this visitor delegates + * calls. May be <tt>null</tt>. + * @param pw + * the print writer to be used to print the class. + */ + public TraceClassVisitor(final ClassVisitor cv, final PrintWriter pw) { + this(cv, new Textifier(), pw); + } + + /** + * Constructs a new {@link TraceClassVisitor}. + * + * @param cv + * the {@link ClassVisitor} to which this visitor delegates + * calls. May be <tt>null</tt>. + * @param p + * the object that actually converts visit events into text. + * @param pw + * the print writer to be used to print the class. May be null if + * you simply want to use the result via + * {@link Printer#getText()}, instead of printing it. + */ + public TraceClassVisitor(final ClassVisitor cv, final Printer p, + final PrintWriter pw) { + super(Opcodes.ASM4, cv); + this.pw = pw; + this.p = p; + } + + @Override + public void visit(final int version, final int access, final String name, + final String signature, final String superName, + final String[] interfaces) { + p.visit(version, access, name, signature, superName, interfaces); + super.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public void visitSource(final String file, final String debug) { + p.visitSource(file, debug); + super.visitSource(file, debug); + } + + @Override + public void visitOuterClass(final String owner, final String name, + final String desc) { + p.visitOuterClass(owner, name, desc); + super.visitOuterClass(owner, name, desc); + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, + final boolean visible) { + Printer p = this.p.visitClassAnnotation(desc, visible); + AnnotationVisitor av = cv == null ? null : cv.visitAnnotation(desc, + visible); + return new TraceAnnotationVisitor(av, p); + } + + @Override + public void visitAttribute(final Attribute attr) { + p.visitClassAttribute(attr); + super.visitAttribute(attr); + } + + @Override + public void visitInnerClass(final String name, final String outerName, + final String innerName, final int access) { + p.visitInnerClass(name, outerName, innerName, access); + super.visitInnerClass(name, outerName, innerName, access); + } + + @Override + public FieldVisitor visitField(final int access, final String name, + final String desc, final String signature, final Object value) { + Printer p = this.p.visitField(access, name, desc, signature, value); + FieldVisitor fv = cv == null ? null : cv.visitField(access, name, desc, + signature, value); + return new TraceFieldVisitor(fv, p); + } + + @Override + public MethodVisitor visitMethod(final int access, final String name, + final String desc, final String signature, final String[] exceptions) { + Printer p = this.p.visitMethod(access, name, desc, signature, + exceptions); + MethodVisitor mv = cv == null ? null : cv.visitMethod(access, name, + desc, signature, exceptions); + return new TraceMethodVisitor(mv, p); + } + + @Override + public void visitEnd() { + p.visitClassEnd(); + if (pw != null) { + p.print(pw); + pw.flush(); + } + super.visitEnd(); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceFieldVisitor.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceFieldVisitor.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceFieldVisitor.java new file mode 100644 index 0000000..e24510e --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceFieldVisitor.java @@ -0,0 +1,76 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 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 org.apache.tajo.org.objectweb.asm.util; + +import org.apache.tajo.org.objectweb.asm.AnnotationVisitor; +import org.apache.tajo.org.objectweb.asm.Attribute; +import org.apache.tajo.org.objectweb.asm.FieldVisitor; +import org.apache.tajo.org.objectweb.asm.Opcodes; + +/** + * A {@link org.apache.tajo.org.objectweb.asm.FieldVisitor} that prints the fields it visits with a + * {@link Printer}. + * + * @author Eric Bruneton + */ +public final class TraceFieldVisitor extends FieldVisitor { + + public final Printer p; + + public TraceFieldVisitor(final Printer p) { + this(null, p); + } + + public TraceFieldVisitor(final FieldVisitor fv, final Printer p) { + super(Opcodes.ASM4, fv); + this.p = p; + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, + final boolean visible) { + Printer p = this.p.visitFieldAnnotation(desc, visible); + AnnotationVisitor av = fv == null ? null : fv.visitAnnotation(desc, + visible); + return new TraceAnnotationVisitor(av, p); + } + + @Override + public void visitAttribute(final Attribute attr) { + p.visitFieldAttribute(attr); + super.visitAttribute(attr); + } + + @Override + public void visitEnd() { + p.visitFieldEnd(); + super.visitEnd(); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceMethodVisitor.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceMethodVisitor.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceMethodVisitor.java new file mode 100644 index 0000000..1a4cf96 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceMethodVisitor.java @@ -0,0 +1,223 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 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 org.apache.tajo.org.objectweb.asm.util; + +import org.apache.tajo.org.objectweb.asm.AnnotationVisitor; +import org.apache.tajo.org.objectweb.asm.Attribute; +import org.apache.tajo.org.objectweb.asm.Handle; +import org.apache.tajo.org.objectweb.asm.Label; +import org.apache.tajo.org.objectweb.asm.MethodVisitor; +import org.apache.tajo.org.objectweb.asm.Opcodes; + +/** + * A {@link org.apache.tajo.org.objectweb.asm.MethodVisitor} that prints the methods it visits with a + * {@link Printer}. + * + * @author Eric Bruneton + */ +public final class TraceMethodVisitor extends MethodVisitor { + + public final Printer p; + + public TraceMethodVisitor(final Printer p) { + this(null, p); + } + + public TraceMethodVisitor(final MethodVisitor mv, final Printer p) { + super(Opcodes.ASM4, mv); + this.p = p; + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, + final boolean visible) { + Printer p = this.p.visitMethodAnnotation(desc, visible); + AnnotationVisitor av = mv == null ? null : mv.visitAnnotation(desc, + visible); + return new TraceAnnotationVisitor(av, p); + } + + @Override + public void visitAttribute(final Attribute attr) { + p.visitMethodAttribute(attr); + super.visitAttribute(attr); + } + + @Override + public AnnotationVisitor visitAnnotationDefault() { + Printer p = this.p.visitAnnotationDefault(); + AnnotationVisitor av = mv == null ? null : mv.visitAnnotationDefault(); + return new TraceAnnotationVisitor(av, p); + } + + @Override + public AnnotationVisitor visitParameterAnnotation(final int parameter, + final String desc, final boolean visible) { + Printer p = this.p.visitParameterAnnotation(parameter, desc, visible); + AnnotationVisitor av = mv == null ? null : mv.visitParameterAnnotation( + parameter, desc, visible); + return new TraceAnnotationVisitor(av, p); + } + + @Override + public void visitCode() { + p.visitCode(); + super.visitCode(); + } + + @Override + public void visitFrame(final int type, final int nLocal, + final Object[] local, final int nStack, final Object[] stack) { + p.visitFrame(type, nLocal, local, nStack, stack); + super.visitFrame(type, nLocal, local, nStack, stack); + } + + @Override + public void visitInsn(final int opcode) { + p.visitInsn(opcode); + super.visitInsn(opcode); + } + + @Override + public void visitIntInsn(final int opcode, final int operand) { + p.visitIntInsn(opcode, operand); + super.visitIntInsn(opcode, operand); + } + + @Override + public void visitVarInsn(final int opcode, final int var) { + p.visitVarInsn(opcode, var); + super.visitVarInsn(opcode, var); + } + + @Override + public void visitTypeInsn(final int opcode, final String type) { + p.visitTypeInsn(opcode, type); + super.visitTypeInsn(opcode, type); + } + + @Override + public void visitFieldInsn(final int opcode, final String owner, + final String name, final String desc) { + p.visitFieldInsn(opcode, owner, name, desc); + super.visitFieldInsn(opcode, owner, name, desc); + } + + @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc) { + p.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc); + } + + @Override + public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, + Object... bsmArgs) { + p.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); + super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); + } + + @Override + public void visitJumpInsn(final int opcode, final Label label) { + p.visitJumpInsn(opcode, label); + super.visitJumpInsn(opcode, label); + } + + @Override + public void visitLabel(final Label label) { + p.visitLabel(label); + super.visitLabel(label); + } + + @Override + public void visitLdcInsn(final Object cst) { + p.visitLdcInsn(cst); + super.visitLdcInsn(cst); + } + + @Override + public void visitIincInsn(final int var, final int increment) { + p.visitIincInsn(var, increment); + super.visitIincInsn(var, increment); + } + + @Override + public void visitTableSwitchInsn(final int min, final int max, + final Label dflt, final Label... labels) { + p.visitTableSwitchInsn(min, max, dflt, labels); + super.visitTableSwitchInsn(min, max, dflt, labels); + } + + @Override + public void visitLookupSwitchInsn(final Label dflt, final int[] keys, + final Label[] labels) { + p.visitLookupSwitchInsn(dflt, keys, labels); + super.visitLookupSwitchInsn(dflt, keys, labels); + } + + @Override + public void visitMultiANewArrayInsn(final String desc, final int dims) { + p.visitMultiANewArrayInsn(desc, dims); + super.visitMultiANewArrayInsn(desc, dims); + } + + @Override + public void visitTryCatchBlock(final Label start, final Label end, + final Label handler, final String type) { + p.visitTryCatchBlock(start, end, handler, type); + super.visitTryCatchBlock(start, end, handler, type); + } + + @Override + public void visitLocalVariable(final String name, final String desc, + final String signature, final Label start, final Label end, + final int index) { + p.visitLocalVariable(name, desc, signature, start, end, index); + super.visitLocalVariable(name, desc, signature, start, end, index); + } + + @Override + public void visitLineNumber(final int line, final Label start) { + p.visitLineNumber(line, start); + super.visitLineNumber(line, start); + } + + @Override + public void visitMaxs(final int maxStack, final int maxLocals) { + p.visitMaxs(maxStack, maxLocals); + super.visitMaxs(maxStack, maxLocals); + } + + @Override + public void visitEnd() { + p.visitMethodEnd(); + super.visitEnd(); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceSignatureVisitor.java ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceSignatureVisitor.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceSignatureVisitor.java new file mode 100644 index 0000000..ee712be --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/TraceSignatureVisitor.java @@ -0,0 +1,317 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 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 org.apache.tajo.org.objectweb.asm.util; + +import org.apache.tajo.org.objectweb.asm.Opcodes; +import org.apache.tajo.org.objectweb.asm.signature.SignatureVisitor; + +/** + * A {@link SignatureVisitor} that prints a disassembled view of the signature + * it visits. + * + * @author Eugene Kuleshov + * @author Eric Bruneton + */ +public final class TraceSignatureVisitor extends SignatureVisitor { + + private final StringBuffer declaration; + + private boolean isInterface; + + private boolean seenFormalParameter; + + private boolean seenInterfaceBound; + + private boolean seenParameter; + + private boolean seenInterface; + + private StringBuffer returnType; + + private StringBuffer exceptions; + + /** + * Stack used to keep track of class types that have arguments. Each element + * of this stack is a boolean encoded in one bit. The top of the stack is + * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping = + * /2. + */ + private int argumentStack; + + /** + * Stack used to keep track of array class types. Each element of this stack + * is a boolean encoded in one bit. The top of the stack is the lowest order + * bit. Pushing false = *2, pushing true = *2+1, popping = /2. + */ + private int arrayStack; + + private String separator = ""; + + public TraceSignatureVisitor(final int access) { + super(Opcodes.ASM4); + isInterface = (access & Opcodes.ACC_INTERFACE) != 0; + this.declaration = new StringBuffer(); + } + + private TraceSignatureVisitor(final StringBuffer buf) { + super(Opcodes.ASM4); + this.declaration = buf; + } + + @Override + public void visitFormalTypeParameter(final String name) { + declaration.append(seenFormalParameter ? ", " : "<").append(name); + seenFormalParameter = true; + seenInterfaceBound = false; + } + + @Override + public SignatureVisitor visitClassBound() { + separator = " extends "; + startType(); + return this; + } + + @Override + public SignatureVisitor visitInterfaceBound() { + separator = seenInterfaceBound ? ", " : " extends "; + seenInterfaceBound = true; + startType(); + return this; + } + + @Override + public SignatureVisitor visitSuperclass() { + endFormals(); + separator = " extends "; + startType(); + return this; + } + + @Override + public SignatureVisitor visitInterface() { + separator = seenInterface ? ", " : isInterface ? " extends " + : " implements "; + seenInterface = true; + startType(); + return this; + } + + @Override + public SignatureVisitor visitParameterType() { + endFormals(); + if (seenParameter) { + declaration.append(", "); + } else { + seenParameter = true; + declaration.append('('); + } + startType(); + return this; + } + + @Override + public SignatureVisitor visitReturnType() { + endFormals(); + if (seenParameter) { + seenParameter = false; + } else { + declaration.append('('); + } + declaration.append(')'); + returnType = new StringBuffer(); + return new TraceSignatureVisitor(returnType); + } + + @Override + public SignatureVisitor visitExceptionType() { + if (exceptions == null) { + exceptions = new StringBuffer(); + } else { + exceptions.append(", "); + } + // startType(); + return new TraceSignatureVisitor(exceptions); + } + + @Override + public void visitBaseType(final char descriptor) { + switch (descriptor) { + case 'V': + declaration.append("void"); + break; + case 'B': + declaration.append("byte"); + break; + case 'J': + declaration.append("long"); + break; + case 'Z': + declaration.append("boolean"); + break; + case 'I': + declaration.append("int"); + break; + case 'S': + declaration.append("short"); + break; + case 'C': + declaration.append("char"); + break; + case 'F': + declaration.append("float"); + break; + // case 'D': + default: + declaration.append("double"); + break; + } + endType(); + } + + @Override + public void visitTypeVariable(final String name) { + declaration.append(name); + endType(); + } + + @Override + public SignatureVisitor visitArrayType() { + startType(); + arrayStack |= 1; + return this; + } + + @Override + public void visitClassType(final String name) { + if ("java/lang/Object".equals(name)) { + // Map<java.lang.Object,java.util.List> + // or + // abstract public V get(Object key); (seen in Dictionary.class) + // should have Object + // but java.lang.String extends java.lang.Object is unnecessary + boolean needObjectClass = argumentStack % 2 != 0 || seenParameter; + if (needObjectClass) { + declaration.append(separator).append(name.replace('/', '.')); + } + } else { + declaration.append(separator).append(name.replace('/', '.')); + } + separator = ""; + argumentStack *= 2; + } + + @Override + public void visitInnerClassType(final String name) { + if (argumentStack % 2 != 0) { + declaration.append('>'); + } + argumentStack /= 2; + declaration.append('.'); + declaration.append(separator).append(name.replace('/', '.')); + separator = ""; + argumentStack *= 2; + } + + @Override + public void visitTypeArgument() { + if (argumentStack % 2 == 0) { + ++argumentStack; + declaration.append('<'); + } else { + declaration.append(", "); + } + declaration.append('?'); + } + + @Override + public SignatureVisitor visitTypeArgument(final char tag) { + if (argumentStack % 2 == 0) { + ++argumentStack; + declaration.append('<'); + } else { + declaration.append(", "); + } + + if (tag == EXTENDS) { + declaration.append("? extends "); + } else if (tag == SUPER) { + declaration.append("? super "); + } + + startType(); + return this; + } + + @Override + public void visitEnd() { + if (argumentStack % 2 != 0) { + declaration.append('>'); + } + argumentStack /= 2; + endType(); + } + + public String getDeclaration() { + return declaration.toString(); + } + + public String getReturnType() { + return returnType == null ? null : returnType.toString(); + } + + public String getExceptions() { + return exceptions == null ? null : exceptions.toString(); + } + + // ----------------------------------------------- + + private void endFormals() { + if (seenFormalParameter) { + declaration.append('>'); + seenFormalParameter = false; + } + } + + private void startType() { + arrayStack *= 2; + } + + private void endType() { + if (arrayStack % 2 == 0) { + arrayStack /= 2; + } else { + while (arrayStack % 2 != 0) { + arrayStack /= 2; + declaration.append("[]"); + } + } + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/package.html ---------------------------------------------------------------------- diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/package.html b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/package.html new file mode 100644 index 0000000..adf2013 --- /dev/null +++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/util/package.html @@ -0,0 +1,58 @@ +<!--~ + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<html> +<!-- + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 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. +--> +<body> +Provides ASM visitors that can be useful for programming and +debugging purposes. These class visitors are normally not used by applications +at runtime. This is why they are bundled in an optional <tt>asm-util.jar</tt> +library that is separated from (but requires) the <tt>asm.jar</tt> library, +which contains the core ASM framework. + +@since ASM 1.3.2 +</body> +</html>
