added asm utils
diff --git a/archive/asmutil.mf b/archive/asmutil.mf
new file mode 100644
index 0000000..0a7de8f
--- /dev/null
+++ b/archive/asmutil.mf
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Implementation-Title: "ASM Utilities"
+Implementation-Version: "1.3"
+Implementation-Vendor: "France Telecom R&D"
diff --git a/archive/asmutil.xml b/archive/asmutil.xml
new file mode 100644
index 0000000..0a3d6af
--- /dev/null
+++ b/archive/asmutil.xml
@@ -0,0 +1,9 @@
+<project name="asm" default="dist">
+ <target name="dist">
+ <jar jarfile="${dist.lib}/asmutil.jar"
+ basedir="${build}"
+ manifest="${archive}/asmutil.mf">
+ <include name="org/objectweb/asm/util/*.class"/>
+ </jar>
+ </target>
+</project>
diff --git a/src/org/objectweb/asm/util/DumpClassVisitor.java b/src/org/objectweb/asm/util/DumpClassVisitor.java
new file mode 100644
index 0000000..52d502d
--- /dev/null
+++ b/src/org/objectweb/asm/util/DumpClassVisitor.java
@@ -0,0 +1,364 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (C) 2000 INRIA, France Telecom
+ * Copyright (C) 2002 France Telecom
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Contact: Eric.Bruneton@rd.francetelecom.com
+ *
+ * Author: Eric Bruneton
+ */
+
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.Constants;
+import org.objectweb.asm.ClassReader;
+
+import java.io.PrintWriter;
+
+/**
+ * A {@link PrintClassVisitor PrintClassVisitor} that prints the ASM code that
+ * generates the classes it visits. This class visitor can be used to quickly
+ * write ASM code to generate some given bytecode:
+ * <ul>
+ * <li>write the Java source code equivalent to the bytecode you want to
+ * generate;</li>
+ * <li>compile it with <tt>javac</tt>;</li>
+ * <li>make a {@link DumpClassVisitor DumpClassVisitor} visit this compiled
+ * class (see the {@link #main main} method);</li>
+ * <li>edit the generated source code, if necessary.</li>
+ * </ul>
+ * The source code printed when visiting the <tt>Hello</tt> class is the
+ * following:
+ * <pre>
+ * import org.objectweb.asm.*;
+ * import java.io.FileOutputStream;
+ *
+ * public class Dump implements Constants {
+ *
+ * public static void main (String[] args) throws Exception {
+ *
+ * ClassWriter cw = new ClassWriter(false);
+ * CodeVisitor cv;
+ *
+ * cw.visit(ACC_PUBLIC + ACC_SUPER, "Hello", "java/lang/Object", null, "Hello.java");
+ *
+ * {
+ * cv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null);
+ * cv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ * cv.visitLdcInsn("hello");
+ * cv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
+ * cv.visitInsn(RETURN);
+ * cv.visitMaxs(2, 1);
+ * }
+ * {
+ * cv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null);
+ * cv.visitVarInsn(ALOAD, 0);
+ * cv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+ * cv.visitInsn(RETURN);
+ * cv.visitMaxs(1, 1);
+ * }
+ * cw.visitEnd();
+ *
+ * FileOutputStream os = new FileOutputStream("Dumped.class");
+ * os.write(cw.toByteArray());
+ * os.close();
+ * }
+ * }
+ * </pre>
+ * where <tt>Hello</tt> is defined by:
+ * <pre>
+ * public class Hello {
+ *
+ * public static void main (String[] args) {
+ * System.out.println("hello");
+ * }
+ * }
+ * </pre>
+ */
+
+public class DumpClassVisitor extends PrintClassVisitor {
+
+ private StringBuffer buf;
+
+ /**
+ * Prints the ASM source code to generate the given class to the standard
+ * output.
+ * <p>
+ * Usage: DumpClassVisitor <fully qualified class name>
+ */
+
+ public static void main (final String[] args) throws Exception {
+ if (args.length == 0) {
+ System.err.println("Prints the ASM code to generate the given class.");
+ System.err.println("Usage: DumpClassVisitor <fully qualified class name>");
+ }
+ ClassReader cr = new ClassReader(args[0]);
+ cr.accept(new DumpClassVisitor(new PrintWriter(System.out)), true);
+ }
+
+ /**
+ * Constructs a new {@link DumpClassVisitor DumpClassVisitor} object.
+ *
+ * @param pw the print writer to be used to print the trace.
+ */
+
+ public DumpClassVisitor (final PrintWriter pw) {
+ super(pw);
+ buf = new StringBuffer();
+ }
+
+ public void visit (
+ final int access,
+ final String name,
+ final String superName,
+ final String[] interfaces,
+ final String sourceFile)
+ {
+ dump.add("import org.objectweb.asm.*;\n");
+ dump.add("import java.io.FileOutputStream;\n\n");
+ dump.add("public class Dump implements Constants {\n\n");
+ dump.add("public static void main (String[] args) throws Exception {\n\n");
+ dump.add("ClassWriter cw = new ClassWriter(false);\n");
+ dump.add("CodeVisitor cv;\n\n");
+
+ buf.setLength(0);
+ buf.append("cw.visit(");
+ appendAccess(access | 262144);
+ buf.append(", ");
+ appendConstant(buf, name);
+ buf.append(", ");
+ appendConstant(buf, superName);
+ buf.append(", ");
+ if (interfaces != null && interfaces.length > 0) {
+ buf.append("new String[] {");
+ for (int i = 0; i < interfaces.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(buf, interfaces[i]);
+ }
+ buf.append(" }");
+ } else {
+ buf.append("null");
+ }
+ buf.append(", ");
+ appendConstant(buf, sourceFile);
+ buf.append(");\n\n");
+ dump.add(buf.toString());
+ }
+
+ public void visitInnerClass (
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ buf.setLength(0);
+ buf.append("cw.visitInnerClass(");
+ appendConstant(buf, name);
+ buf.append(", ");
+ appendConstant(buf, outerName);
+ buf.append(", ");
+ appendConstant(buf, innerName);
+ buf.append(", ");
+ appendAccess(access);
+ buf.append(");\n\n");
+ dump.add(buf.toString());
+ }
+
+ public void visitField (
+ final int access,
+ final String name,
+ final String desc,
+ final Object value)
+ {
+ buf.setLength(0);
+ buf.append("cw.visitField(");
+ appendAccess(access);
+ buf.append(", ");
+ appendConstant(buf, name);
+ buf.append(", ");
+ appendConstant(buf, desc);
+ buf.append(", ");
+ appendConstant(buf, value);
+ buf.append(");\n\n");
+ dump.add(buf.toString());
+ }
+
+ public PrintCodeVisitor printMethod (
+ final int access,
+ final String name,
+ final String desc,
+ final String[] exceptions)
+ {
+ buf.setLength(0);
+ buf.append("{\n").append("cv = cw.visitMethod(");
+ appendAccess(access);
+ buf.append(", ");
+ appendConstant(buf, name);
+ buf.append(", ");
+ appendConstant(buf, desc);
+ buf.append(", ");
+ if (exceptions != null && exceptions.length > 0) {
+ buf.append("new String[] {");
+ for (int i = 0; i < exceptions.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(buf, exceptions[i]);
+ }
+ buf.append(" });");
+ } else {
+ buf.append("null);");
+ }
+ buf.append("\n");
+ dump.add(buf.toString());
+ return new DumpCodeVisitor();
+ }
+
+ public void visitEnd () {
+ dump.add("cw.visitEnd();\n\n");
+ dump.add("FileOutputStream os = new FileOutputStream(\"Dumped.class\");\n");
+ dump.add("os.write(cw.toByteArray());\n");
+ dump.add("os.close();\n");
+ dump.add("}\n");
+ dump.add("}\n");
+ super.visitEnd();
+ }
+
+ void appendAccess (final int access) {
+ boolean first = true;
+ if ((access & Constants.ACC_PUBLIC) != 0) {
+ buf.append("ACC_PUBLIC");
+ first = false;
+ }
+ if ((access & Constants.ACC_PRIVATE) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_PRIVATE");
+ first = false;
+ }
+ if ((access & Constants.ACC_PROTECTED) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_PROTECTED");
+ first = false;
+ }
+ if ((access & Constants.ACC_FINAL) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_FINAL");
+ first = false;
+ }
+ if ((access & Constants.ACC_STATIC) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_STATIC");
+ first = false;
+ }
+ if ((access & Constants.ACC_SYNCHRONIZED) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ if ((access & 262144) != 0) {
+ buf.append("ACC_SUPER");
+ } else {
+ buf.append("ACC_SYNCHRONIZED");
+ }
+ first = false;
+ }
+ if ((access & Constants.ACC_VOLATILE) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_VOLATILE");
+ first = false;
+ }
+ if ((access & Constants.ACC_TRANSIENT) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_TRANSIENT");
+ first = false;
+ }
+ if ((access & Constants.ACC_NATIVE) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_NATIVE");
+ first = false;
+ }
+ if ((access & Constants.ACC_ABSTRACT) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_ABSTRACT");
+ first = false;
+ }
+ if ((access & Constants.ACC_SYNTHETIC) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_SYNTHETIC");
+ first = false;
+ }
+ if ((access & Constants.ACC_DEPRECATED) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_DEPRECATED");
+ }
+ }
+
+ static void appendConstant (final StringBuffer buf, final Object cst) {
+ if (cst == null) {
+ buf.append("null");
+ } else if (cst instanceof String) {
+ String s = (String)cst;
+ buf.append("\"");
+ for (int i = 0; i < s.length(); ++i) {
+ char c = s.charAt(i);
+ if (c == '\n') {
+ buf.append("\\n");
+ } else if (c == '\\') {
+ buf.append("\\\\");
+ } else if (c == '"') {
+ buf.append("\\\"");
+ } else {
+ buf.append(c);
+ }
+ }
+ buf.append("\"");
+ } else if (cst instanceof Integer) {
+ buf.append("new Integer(")
+ .append(cst)
+ .append(")");
+ } else if (cst instanceof Float) {
+ buf.append("new Float(")
+ .append(cst)
+ .append("F)");
+ } else if (cst instanceof Long) {
+ buf.append("new Long(")
+ .append(cst)
+ .append("L)");
+ } else if (cst instanceof Double) {
+ buf.append("new Double(")
+ .append(cst)
+ .append(")");
+ }
+ }
+}
diff --git a/src/org/objectweb/asm/util/DumpCodeVisitor.java b/src/org/objectweb/asm/util/DumpCodeVisitor.java
new file mode 100644
index 0000000..758fcc4
--- /dev/null
+++ b/src/org/objectweb/asm/util/DumpCodeVisitor.java
@@ -0,0 +1,265 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (C) 2000 INRIA, France Telecom
+ * Copyright (C) 2002 France Telecom
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Contact: Eric.Bruneton@rd.francetelecom.com
+ *
+ * Author: Eric Bruneton
+ */
+
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.Label;
+
+import java.util.HashMap;
+
+/**
+ * A {@link PrintCodeVisitor PrintCodeVisitor} that prints the ASM code that
+ * generates the code it visits.
+ */
+
+public class DumpCodeVisitor extends PrintCodeVisitor {
+
+ private final HashMap labelNames;
+
+ /**
+ * Constructs a new {@link DumpCodeVisitor DumpCodeVisitor} object.
+ */
+
+ public DumpCodeVisitor () {
+ this.labelNames = new HashMap();
+ }
+
+ public void printInsn (final int opcode) {
+ buf.append("cv.visitInsn(").
+ append(OPCODES[opcode]).
+ append(");\n");
+ }
+
+ public void printIntInsn (final int opcode, final int operand) {
+ buf.append("cv.visitIntInsn(").
+ append(OPCODES[opcode]).
+ append(", ").
+ append(operand).
+ append(");\n");
+ }
+
+ public void printVarInsn (final int opcode, final int var) {
+ buf.append("cv.visitVarInsn(").
+ append(OPCODES[opcode]).
+ append(", ").
+ append(var).
+ append(");\n");
+ }
+
+ public void printTypeInsn (final int opcode, final String desc) {
+ buf.append("cv.visitTypeInsn(").
+ append(OPCODES[opcode]).
+ append(", ");
+ DumpClassVisitor.appendConstant(buf, desc);
+ buf.append(");\n");
+ }
+
+ public void printFieldInsn (
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.append("cv.visitFieldInsn(")
+ .append(OPCODES[opcode])
+ .append(", ");
+ DumpClassVisitor.appendConstant(buf, owner);
+ buf.append(", ");
+ DumpClassVisitor.appendConstant(buf, name);
+ buf.append(", ");
+ DumpClassVisitor.appendConstant(buf, desc);
+ buf.append(");\n");
+ }
+
+ public void printMethodInsn (
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.append("cv.visitMethodInsn(")
+ .append(OPCODES[opcode])
+ .append(", ");
+ DumpClassVisitor.appendConstant(buf, owner);
+ buf.append(", ");
+ DumpClassVisitor.appendConstant(buf, name);
+ buf.append(", ");
+ DumpClassVisitor.appendConstant(buf, desc);
+ buf.append(");\n");
+ }
+
+ public void printJumpInsn (final int opcode, final Label label) {
+ declareLabel(label);
+ buf.append("cv.visitJumpInsn(")
+ .append(OPCODES[opcode])
+ .append(", ");
+ appendLabel(label);
+ buf.append(");\n");
+ }
+
+ public void printLabel (final Label label) {
+ declareLabel(label);
+ buf.append("cv.visitLabel(");
+ appendLabel(label);
+ buf.append(");\n");
+ }
+
+ public void printLdcInsn (final Object cst) {
+ buf.append("cv.visitLdcInsn(");
+ DumpClassVisitor.appendConstant(buf, cst);
+ buf.append(");\n");
+ }
+
+ public void printIincInsn (final int var, final int increment) {
+ buf.append("cv.visitIincInsn(")
+ .append(var)
+ .append(", ")
+ .append(increment)
+ .append(");\n");
+ }
+
+ public void printTableSwitchInsn (
+ final int min,
+ final int max,
+ final Label dflt,
+ final Label labels[])
+ {
+ for (int i = 0; i < labels.length; ++i) {
+ declareLabel(labels[i]);
+ }
+ declareLabel(dflt);
+
+ buf.append("cv.visitTableSwitchInsn(")
+ .append(min)
+ .append(", ")
+ .append(max)
+ .append(", ");
+ appendLabel(dflt);
+ buf.append(", new Label[] {");
+ for (int i = 0; i < labels.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendLabel(labels[i]);
+ }
+ buf.append(" });\n");
+ }
+
+ public void printLookupSwitchInsn (
+ final Label dflt,
+ final int keys[],
+ final Label labels[])
+ {
+ for (int i = 0; i < labels.length; ++i) {
+ declareLabel(labels[i]);
+ }
+ declareLabel(dflt);
+
+ buf.append("cv.visitLookupSwitch(");
+ appendLabel(dflt);
+ buf.append(", new int[] {");
+ for (int i = 0; i < keys.length; ++i) {
+ buf.append(i == 0 ? " " : ", ").append(keys[i]);
+ }
+ buf.append(" }, new Label[] {");
+ for (int i = 0; i < labels.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendLabel(labels[i]);
+ }
+ buf.append(" });\n");
+ }
+
+ public void printMultiANewArrayInsn (final String desc, final int dims) {
+ buf.append("cv.visitMultiANewArrayInsn(");
+ DumpClassVisitor.appendConstant(buf, desc);
+ buf.append(", ")
+ .append(dims)
+ .append(");\n");
+ }
+
+ public void printTryCatchBlock (
+ final Label start,
+ final Label end,
+ final Label handler,
+ final String type)
+ {
+ buf.append("cv.visitTryCatchBlock(");
+ appendLabel(start);
+ buf.append(", ");
+ appendLabel(end);
+ buf.append(", ");
+ appendLabel(handler);
+ buf.append(", ");
+ DumpClassVisitor.appendConstant(buf, type);
+ buf.append(");\n");
+ }
+
+ public void printMaxs (final int maxStack, final int maxLocals) {
+ buf.append("cv.visitMaxs(")
+ .append(maxStack)
+ .append(", ")
+ .append(maxLocals)
+ .append(");\n")
+ .append("}\n");
+ }
+
+ public void printLocalVariable (
+ final String name,
+ final String desc,
+ final Label start,
+ final Label end,
+ final int index)
+ {
+ buf.append("cv.visitLocalVariable(");
+ DumpClassVisitor.appendConstant(buf, name);
+ buf.append(", ");
+ DumpClassVisitor.appendConstant(buf, desc);
+ buf.append(", ");
+ appendLabel(start);
+ buf.append(", ");
+ appendLabel(end);
+ buf.append(", ").append(index).append(");\n");
+ }
+
+ public void printLineNumber (final int line, final Label start) {
+ buf.append("cv.visitLineNumber(")
+ .append(line)
+ .append(", ");
+ appendLabel(start);
+ buf.append(");\n");
+ }
+
+ private void declareLabel (final Label l) {
+ String name = (String)labelNames.get(l);
+ if (name == null) {
+ name = "l" + labelNames.size();
+ labelNames.put(l, name);
+ buf.append("Label ")
+ .append(name)
+ .append(" = new Label();\n");
+ }
+ }
+
+ private void appendLabel (final Label l) {
+ buf.append((String)labelNames.get(l));
+ }
+}
diff --git a/src/org/objectweb/asm/util/PrintClassVisitor.java b/src/org/objectweb/asm/util/PrintClassVisitor.java
new file mode 100644
index 0000000..1777a60
--- /dev/null
+++ b/src/org/objectweb/asm/util/PrintClassVisitor.java
@@ -0,0 +1,87 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (C) 2000 INRIA, France Telecom
+ * Copyright (C) 2002 France Telecom
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Contact: Eric.Bruneton@rd.francetelecom.com
+ *
+ * Author: Eric Bruneton
+ */
+
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.CodeVisitor;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An abstract class visitor that prints the classes it visits.
+ */
+
+public abstract class PrintClassVisitor implements ClassVisitor {
+
+ protected final ArrayList dump;
+
+ protected final PrintWriter pw;
+
+ /**
+ * Constructs a new {@link PrintClassVisitor PrintClassVisitor} object.
+ *
+ * @param pw the print writer to be used to print the trace.
+ */
+
+ public PrintClassVisitor (final PrintWriter pw) {
+ this.dump = new ArrayList();
+ this.pw = pw;
+ }
+
+ public CodeVisitor visitMethod (
+ final int access,
+ final String name,
+ final String desc,
+ final String[] exceptions)
+ {
+ PrintCodeVisitor pcv = printMethod(access, name, desc, exceptions);
+ dump.add(pcv.getText());
+ return pcv;
+ }
+
+ public void visitEnd () {
+ printList(dump);
+ pw.flush();
+ }
+
+ private void printList (final List l) {
+ for (int i = 0; i < l.size(); ++i) {
+ Object o = l.get(i);
+ if (o instanceof List) {
+ printList((List)o);
+ } else {
+ pw.print(o.toString());
+ }
+ }
+ }
+
+ public abstract PrintCodeVisitor printMethod (
+ final int access,
+ final String name,
+ final String desc,
+ final String[] exceptions);
+}
diff --git a/src/org/objectweb/asm/util/PrintCodeVisitor.java b/src/org/objectweb/asm/util/PrintCodeVisitor.java
new file mode 100644
index 0000000..5c64d50
--- /dev/null
+++ b/src/org/objectweb/asm/util/PrintCodeVisitor.java
@@ -0,0 +1,451 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (C) 2000 INRIA, France Telecom
+ * Copyright (C) 2002 France Telecom
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Contact: Eric.Bruneton@rd.francetelecom.com
+ *
+ * Author: Eric Bruneton
+ */
+
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.CodeVisitor;
+import org.objectweb.asm.Label;
+
+import java.util.ArrayList;
+
+/**
+ * An abstract code visitor that prints the code it visits.
+ */
+
+public abstract class PrintCodeVisitor implements CodeVisitor {
+
+ protected final StringBuffer buf;
+
+ protected final ArrayList dump;
+
+ protected final static String[] OPCODES = {
+ "NOP",
+ "ACONST_NULL",
+ "ICONST_M1",
+ "ICONST_0",
+ "ICONST_1",
+ "ICONST_2",
+ "ICONST_3",
+ "ICONST_4",
+ "ICONST_5",
+ "LCONST_0",
+ "LCONST_1",
+ "FCONST_0",
+ "FCONST_1",
+ "FCONST_2",
+ "DCONST_0",
+ "DCONST_1",
+ "BIPUSH",
+ "SIPUSH",
+ "LDC",
+ null,
+ null,
+ "ILOAD",
+ "LLOAD",
+ "FLOAD",
+ "DLOAD",
+ "ALOAD",
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ "IALOAD",
+ "LALOAD",
+ "FALOAD",
+ "DALOAD",
+ "AALOAD",
+ "BALOAD",
+ "CALOAD",
+ "SALOAD",
+ "ISTORE",
+ "LSTORE",
+ "FSTORE",
+ "DSTORE",
+ "ASTORE",
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ "IASTORE",
+ "LASTORE",
+ "FASTORE",
+ "DASTORE",
+ "AASTORE",
+ "BASTORE",
+ "CASTORE",
+ "SASTORE",
+ "POP",
+ "POP2",
+ "DUP",
+ "DUP_X1",
+ "DUP_X2",
+ "DUP2",
+ "DUP2_X1",
+ "DUP2_X2",
+ "SWAP",
+ "IADD",
+ "LADD",
+ "FADD",
+ "DADD",
+ "ISUB",
+ "LSUB",
+ "FSUB",
+ "DSUB",
+ "IMUL",
+ "LMUL",
+ "FMUL",
+ "DMUL",
+ "IDIV",
+ "LDIV",
+ "FDIV",
+ "DDIV",
+ "IREM",
+ "LREM",
+ "FREM",
+ "DREM",
+ "INEG",
+ "LNEG",
+ "FNEG",
+ "DNEG",
+ "ISHL",
+ "LSHL",
+ "ISHR",
+ "LSHR",
+ "IUSHR",
+ "LUSHR",
+ "IAND",
+ "LAND",
+ "IOR",
+ "LOR",
+ "IXOR",
+ "LXOR",
+ "IINC",
+ "I2L",
+ "I2F",
+ "I2D",
+ "L2I",
+ "L2F",
+ "L2D",
+ "F2I",
+ "F2L",
+ "F2D",
+ "D2I",
+ "D2L",
+ "D2F",
+ "I2B",
+ "I2C",
+ "I2S",
+ "LCMP",
+ "FCMPL",
+ "FCMPG",
+ "DCMPL",
+ "DCMPG",
+ "IFEQ",
+ "IFNE",
+ "IFLT",
+ "IFGE",
+ "IFGT",
+ "IFLE",
+ "IF_ICMPEQ",
+ "IF_ICMPNE",
+ "IF_ICMPLT",
+ "IF_ICMPGE",
+ "IF_ICMPGT",
+ "IF_ICMPLE",
+ "IF_ACMPEQ",
+ "IF_ACMPNE",
+ "GOTO",
+ "JSR",
+ "RET",
+ "TABLESWITCH",
+ "LOOKUPSWITCH",
+ "IRETURN",
+ "LRETURN",
+ "FRETURN",
+ "DRETURN",
+ "ARETURN",
+ "RETURN",
+ "GETSTATIC",
+ "PUTSTATIC",
+ "GETFIELD",
+ "PUTFIELD",
+ "INVOKEVIRTUAL",
+ "INVOKESPECIAL",
+ "INVOKESTATIC",
+ "INVOKEINTERFACE",
+ null,
+ "NEW",
+ "NEWARRAY",
+ "ANEWARRAY",
+ "ARRAYLENGTH",
+ "ATHROW",
+ "CHECKCAST",
+ "INSTANCEOF",
+ "MONITORENTER",
+ "MONITOREXIT",
+ null,
+ "MULTIANEWARRAY",
+ "IFNULL",
+ "IFNONNULL",
+ null,
+ null
+ };
+
+ /**
+ * Constructs a new {@link PrintCodeVisitor PrintCodeVisitor} object.
+ */
+
+ public PrintCodeVisitor () {
+ this.buf = new StringBuffer();
+ this.dump = new ArrayList();
+ }
+
+ public void visitInsn (final int opcode) {
+ buf.setLength(0);
+ printInsn(opcode);
+ dump.add(buf.toString());
+ }
+
+ public void visitIntInsn (final int opcode, final int operand) {
+ buf.setLength(0);
+ printIntInsn(opcode, operand);
+ dump.add(buf.toString());
+ }
+
+ public void visitVarInsn (final int opcode, final int var) {
+ buf.setLength(0);
+ printVarInsn(opcode, var);
+ dump.add(buf.toString());
+ }
+
+ public void visitTypeInsn (final int opcode, final String desc) {
+ buf.setLength(0);
+ printTypeInsn(opcode, desc);
+ dump.add(buf.toString());
+ }
+
+ public void visitFieldInsn (
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ printFieldInsn(opcode, owner, name, desc);
+ dump.add(buf.toString());
+ }
+
+ public void visitMethodInsn (
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ printMethodInsn(opcode, owner, name, desc);
+ dump.add(buf.toString());
+ }
+
+ public void visitJumpInsn (final int opcode, final Label label) {
+ buf.setLength(0);
+ printJumpInsn(opcode, label);
+ dump.add(buf.toString());
+ }
+
+ public void visitLabel (final Label label) {
+ buf.setLength(0);
+ printLabel(label);
+ dump.add(buf.toString());
+ }
+
+ public void visitLdcInsn (final Object cst) {
+ buf.setLength(0);
+ printLdcInsn(cst);
+ dump.add(buf.toString());
+ }
+
+ public void visitIincInsn (final int var, final int increment) {
+ buf.setLength(0);
+ printIincInsn(var, increment);
+ dump.add(buf.toString());
+ }
+
+ public void visitTableSwitchInsn (
+ final int min,
+ final int max,
+ final Label dflt,
+ final Label labels[])
+ {
+ buf.setLength(0);
+ printTableSwitchInsn(min, max, dflt, labels);
+ dump.add(buf.toString());
+ }
+
+ public void visitLookupSwitchInsn (
+ final Label dflt,
+ final int keys[],
+ final Label labels[])
+ {
+ buf.setLength(0);
+ printLookupSwitchInsn(dflt, keys, labels);
+ dump.add(buf.toString());
+ }
+
+ public void visitMultiANewArrayInsn (final String desc, final int dims) {
+ buf.setLength(0);
+ printMultiANewArrayInsn(desc, dims);
+ dump.add(buf.toString());
+ }
+
+ public void visitTryCatchBlock (
+ final Label start,
+ final Label end,
+ final Label handler,
+ final String type)
+ {
+ buf.setLength(0);
+ printTryCatchBlock(start, end, handler, type);
+ dump.add(buf.toString());
+ }
+
+ public void visitMaxs (final int maxStack, final int maxLocals) {
+ buf.setLength(0);
+ printMaxs(maxStack, maxLocals);
+ dump.add(buf.toString());
+ }
+
+ public void visitLocalVariable (
+ final String name,
+ final String desc,
+ final Label start,
+ final Label end,
+ final int index)
+ {
+ buf.setLength(0);
+ printLocalVariable(name, desc, start, end, index);
+ dump.add(buf.toString());
+ }
+
+ public void visitLineNumber (final int line, final Label start) {
+ buf.setLength(0);
+ printLineNumber(line, start);
+ dump.add(buf.toString());
+ }
+
+ public ArrayList getText () {
+ return dump;
+ }
+
+ public abstract void printInsn (final int opcode);
+
+ public abstract void printIntInsn (final int opcode, final int operand);
+
+ public abstract void printVarInsn (final int opcode, final int var);
+
+ public abstract void printTypeInsn (final int opcode, final String desc);
+
+ public abstract void printFieldInsn (
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc);
+
+ public abstract void printMethodInsn (
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc);
+
+ public abstract void printJumpInsn (final int opcode, final Label label);
+
+ public abstract void printLabel (final Label label);
+
+ public abstract void printLdcInsn (final Object cst);
+
+ public abstract void printIincInsn (final int var, final int increment);
+
+ public abstract void printTableSwitchInsn (
+ final int min,
+ final int max,
+ final Label dflt,
+ final Label labels[]);
+
+ public abstract void printLookupSwitchInsn (
+ final Label dflt,
+ final int keys[],
+ final Label labels[]);
+
+ public abstract void printMultiANewArrayInsn (
+ final String desc,
+ final int dims);
+
+ public abstract void printTryCatchBlock (
+ final Label start,
+ final Label end,
+ final Label handler,
+ final String type);
+
+ public abstract void printMaxs (final int maxStack, final int maxLocals);
+
+ public abstract void printLocalVariable (
+ final String name,
+ final String desc,
+ final Label start,
+ final Label end,
+ final int index);
+
+ public abstract void printLineNumber (final int line, final Label start);
+}
diff --git a/src/org/objectweb/asm/util/TraceClassVisitor.java b/src/org/objectweb/asm/util/TraceClassVisitor.java
new file mode 100644
index 0000000..41bfbf0
--- /dev/null
+++ b/src/org/objectweb/asm/util/TraceClassVisitor.java
@@ -0,0 +1,276 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (C) 2000 INRIA, France Telecom
+ * Copyright (C) 2002 France Telecom
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Contact: Eric.Bruneton@rd.francetelecom.com
+ *
+ * Author: Eric Bruneton
+ */
+
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.CodeVisitor;
+import org.objectweb.asm.Constants;
+import org.objectweb.asm.ClassReader;
+
+import java.io.PrintWriter;
+
+/**
+ * A {@link PrintClassVisitor PrintClassVisitor} that prints a disassembled
+ * view of the classes it visits. This class visitor can be used alone (see the
+ * {@link #main main} method) to disassemble a class. It can also be used in
+ * the middle of class visitor chain to trace the class that is visited at a
+ * given point in this chain. This may be uselful for debugging purposes.
+ * <p>
+ * The trace printed when visiting the <tt>Hello</tt> class is the following:
+ * <pre>
+ * // compiled from Hello.java
+ * public class Hello {
+ *
+ * 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
+ *
+ * public <init> ()V
+ * ALOAD 0
+ * INVOKESPECIAL java/lang/Object <init> ()V
+ * RETURN
+ * MAXSTACK = 1
+ * MAXLOCALS = 1
+ *
+ * }
+ * </pre>
+ * where <tt>Hello</tt> is defined by:
+ * <pre>
+ * public class Hello {
+ *
+ * public static void main (String[] args) {
+ * System.out.println("hello");
+ * }
+ * }
+ * </pre>
+ */
+
+public class TraceClassVisitor extends PrintClassVisitor {
+
+ private final StringBuffer buf;
+
+ private final ClassVisitor cv;
+
+ /**
+ * Prints a disassembled view of the given class to the standard output.
+ * <p>
+ * Usage: TraceClassVisitor <fully qualified class name>
+ */
+
+ public static void main (final String[] args) throws Exception {
+ if (args.length == 0) {
+ System.err.println("Prints a disassembled view of the given class.");
+ System.err.println("Usage: TraceClassVisitor <fully qualified class name>");
+ }
+ ClassReader cr = new ClassReader(args[0]);
+ cr.accept(new TraceClassVisitor(null, new PrintWriter(System.out)), true);
+ }
+
+ /**
+ * Constructs a new {@link TraceClassVisitor TraceClassVisitor} object.
+ *
+ * @param cv the class visitor to which this adapter must delegate calls. May
+ * be <tt>null</tt>.
+ * @param pw the print writer to be used to print the trace.
+ */
+
+ public TraceClassVisitor (final ClassVisitor cv, final PrintWriter pw) {
+ super(pw);
+ this.buf = new StringBuffer();
+ this.cv = cv;
+ }
+
+ public void visit (
+ final int access,
+ final String name,
+ final String superName,
+ final String[] interfaces,
+ final String sourceFile)
+ {
+ buf.setLength(0);
+ if ((access & Constants.ACC_DEPRECATED) != 0) {
+ buf.append("// DEPRECATED\n");
+ }
+ if (sourceFile != null) {
+ buf.append("// compiled from ").append(sourceFile).append("\n");
+ }
+ appendAccess(access & ~Constants.ACC_SUPER);
+ if ((access & Constants.ACC_INTERFACE) != 0) {
+ buf.append("interface ");
+ } else {
+ buf.append("class ");
+ }
+ buf.append(name).append(" ");
+ if (!superName.equals("java/lang/Object")) {
+ buf.append("extends ").append(superName).append(" ");
+ }
+ if (interfaces != null && interfaces.length > 0) {
+ buf.append("implements ");
+ for (int i = 0; i < interfaces.length; ++i) {
+ buf.append(interfaces[i]).append(" ");
+ }
+ }
+ buf.append("{\n\n");
+ dump.add(buf.toString());
+
+ if (cv != null) {
+ cv.visit(access, name, superName, interfaces, sourceFile);
+ }
+ }
+
+ public void visitInnerClass (
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ buf.setLength(0);
+ buf.append(" INNERCLASS ")
+ .append(name)
+ .append(" ")
+ .append(outerName)
+ .append(" ")
+ .append(innerName)
+ .append(" ")
+ .append(access)
+ .append("\n");
+ dump.add(buf.toString());
+
+ if (cv != null) {
+ cv.visitInnerClass(name, outerName, innerName, access);
+ }
+ }
+
+ public void visitField (
+ final int access,
+ final String name,
+ final String desc,
+ final Object value)
+ {
+ buf.setLength(0);
+ if ((access & Constants.ACC_DEPRECATED) != 0) {
+ buf.append(" // DEPRECATED\n");
+ }
+ buf.append(" ");
+ appendAccess(access);
+ buf.append(desc)
+ .append(" ")
+ .append(name);
+ if (value != null) {
+ buf.append(" = ");
+ if (value instanceof String) {
+ buf.append("\"").append(value).append("\"");
+ } else {
+ buf.append(value);
+ }
+ }
+ buf.append("\n\n");
+ dump.add(buf.toString());
+
+ if (cv != null) {
+ cv.visitField(access, name, desc, value);
+ }
+ }
+
+ public PrintCodeVisitor printMethod (
+ final int access,
+ final String name,
+ final String desc,
+ final String[] exceptions)
+ {
+ buf.setLength(0);
+ if ((access & Constants.ACC_DEPRECATED) != 0) {
+ buf.append(" // DEPRECATED\n");
+ }
+ buf.append(" ");
+ appendAccess(access);
+ buf.append(name).
+ append(" ").
+ append(desc);
+ if (exceptions != null && exceptions.length > 0) {
+ buf.append(" throws ");
+ for (int i = 0; i < exceptions.length; ++i) {
+ buf.append(exceptions[i]).append(" ");
+ }
+ }
+ buf.append("\n");
+ dump.add(buf.toString());
+
+ CodeVisitor cv;
+ if (this.cv != null) {
+ cv = this.cv.visitMethod(access, name, desc, exceptions);
+ } else {
+ cv = null;
+ }
+ return new TraceCodeVisitor(cv);
+ }
+
+ public void visitEnd () {
+ dump.add("}\n");
+
+ if (cv != null) {
+ cv.visitEnd();
+ }
+
+ super.visitEnd();
+ }
+
+ private void appendAccess (final int access) {
+ if ((access & Constants.ACC_PUBLIC) != 0) {
+ buf.append("public ");
+ }
+ if ((access & Constants.ACC_PRIVATE) != 0) {
+ buf.append("private ");
+ }
+ if ((access & Constants.ACC_PROTECTED) != 0) {
+ buf.append("protected ");
+ }
+ if ((access & Constants.ACC_FINAL) != 0) {
+ buf.append("final ");
+ }
+ if ((access & Constants.ACC_STATIC) != 0) {
+ buf.append("static ");
+ }
+ if ((access & Constants.ACC_SYNCHRONIZED) != 0) {
+ buf.append("synchronized ");
+ }
+ if ((access & Constants.ACC_VOLATILE) != 0) {
+ buf.append("volatile ");
+ }
+ if ((access & Constants.ACC_TRANSIENT) != 0) {
+ buf.append("transient ");
+ }
+ if ((access & Constants.ACC_NATIVE) != 0) {
+ buf.append("native ");
+ }
+ if ((access & Constants.ACC_ABSTRACT) != 0) {
+ buf.append("abstract ");
+ }
+ }
+}
diff --git a/src/org/objectweb/asm/util/TraceCodeVisitor.java b/src/org/objectweb/asm/util/TraceCodeVisitor.java
new file mode 100644
index 0000000..223e06d
--- /dev/null
+++ b/src/org/objectweb/asm/util/TraceCodeVisitor.java
@@ -0,0 +1,324 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (C) 2000 INRIA, France Telecom
+ * Copyright (C) 2002 France Telecom
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Contact: Eric.Bruneton@rd.francetelecom.com
+ *
+ * Author: Eric Bruneton
+ */
+
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.CodeVisitor;
+import org.objectweb.asm.Label;
+
+import java.util.HashMap;
+
+/**
+ * A {@link PrintCodeVisitor PrintCodeVisitor} that prints a disassembled view
+ * of the code it visits.
+ */
+
+public class TraceCodeVisitor extends PrintCodeVisitor {
+
+ private final CodeVisitor cv;
+
+ private final HashMap labelNames;
+
+ /**
+ * Constructs a new {@link TraceCodeVisitor TraceCodeVisitor} object.
+ *
+ * @param cv the code visitor to which this adapter must delegate calls. May
+ * be <tt>null</tt>.
+ */
+
+ public TraceCodeVisitor (final CodeVisitor cv) {
+ this.cv = cv;
+ this.labelNames = new HashMap();
+ }
+
+ public void printInsn (final int opcode) {
+ buf.append(" ")
+ .append(OPCODES[opcode])
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitInsn(opcode);
+ }
+ }
+
+ public void printIntInsn (final int opcode, final int operand) {
+ buf.append(" ")
+ .append(OPCODES[opcode])
+ .append(" ").append(operand)
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitIntInsn(opcode, operand);
+ }
+ }
+
+ public void printVarInsn (final int opcode, final int var) {
+ buf.append(" ")
+ .append(OPCODES[opcode])
+ .append(" ")
+ .append(var)
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitVarInsn(opcode, var);
+ }
+ }
+
+ public void printTypeInsn (final int opcode, final String desc) {
+ buf.append(" ")
+ .append(OPCODES[opcode])
+ .append(" ")
+ .append(desc)
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitTypeInsn(opcode, desc);
+ }
+ }
+
+ public void printFieldInsn (
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.append(" ")
+ .append(OPCODES[opcode])
+ .append(" ")
+ .append(owner)
+ .append(" ")
+ .append(name)
+ .append(" ")
+ .append(desc)
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitFieldInsn(opcode, owner, name, desc);
+ }
+ }
+
+ public void printMethodInsn (
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.append(" ")
+ .append(OPCODES[opcode])
+ .append(" ")
+ .append(owner)
+ .append(" ")
+ .append(name)
+ .append(" ")
+ .append(desc)
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitMethodInsn(opcode, owner, name, desc);
+ }
+ }
+
+ public void printJumpInsn (final int opcode, final Label label) {
+ buf.append(" ")
+ .append(OPCODES[opcode]).
+ append(" ");
+ appendLabel(label);
+ buf.append("\n");
+
+ if (cv != null) {
+ cv.visitJumpInsn(opcode, label);
+ }
+ }
+
+ public void printLabel (final Label label) {
+ buf.append(" ");
+ appendLabel(label);
+ buf.append(":\n");
+
+ if (cv != null) {
+ cv.visitLabel(label);
+ }
+ }
+
+ public void printLdcInsn (final Object cst) {
+ buf.append(" LDC ");
+ if (cst instanceof String) {
+ buf.append("\"").append(cst).append("\"");
+ } else {
+ buf.append(cst);
+ }
+ buf.append("\n");
+
+ if (cv != null) {
+ cv.visitLdcInsn(cst);
+ }
+ }
+
+ public void printIincInsn (final int var, final int increment) {
+ buf.append(" IINC ")
+ .append(var)
+ .append(" ")
+ .append(increment)
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitIincInsn(var, increment);
+ }
+ }
+
+ public void printTableSwitchInsn (
+ final int min,
+ final int max,
+ final Label dflt,
+ final Label labels[])
+ {
+ buf.append(" TABLESWITCH\n");
+ for (int i = 0; i < labels.length; ++i) {
+ buf.append(" ")
+ .append(min + i)
+ .append(": ");
+ appendLabel(labels[i]);
+ buf.append("\n");
+ }
+ buf.append(" default: ");
+ appendLabel(dflt);
+ buf.append("\n");
+
+ if (cv != null) {
+ cv.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+ }
+
+ public void printLookupSwitchInsn (
+ final Label dflt,
+ final int keys[],
+ final Label labels[])
+ {
+ buf.append(" LOOKUPSWITCH\n");
+ for (int i = 0; i < labels.length; ++i) {
+ buf.append(" ")
+ .append(keys[i])
+ .append(": ");
+ appendLabel(labels[i]);
+ buf.append("\n");
+ }
+ buf.append(" default: ");
+ appendLabel(dflt);
+ buf.append("\n");
+
+ if (cv != null) {
+ cv.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+ }
+
+ public void printMultiANewArrayInsn (final String desc, final int dims) {
+ buf.append(" MULTIANEWARRAY ")
+ .append(desc)
+ .append(" ")
+ .append(dims)
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitMultiANewArrayInsn(desc, dims);
+ }
+ }
+
+ public void printTryCatchBlock (
+ final Label start,
+ final Label end,
+ final Label handler,
+ final String type)
+ {
+ buf.append(" TRYCATCHBLOCK ");
+ appendLabel(start);
+ buf.append(" ");
+ appendLabel(end);
+ buf.append(" ");
+ appendLabel(handler);
+ buf.append(" ")
+ .append(type)
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitTryCatchBlock(start, end, handler, type);
+ }
+ }
+
+ public void printMaxs (final int maxStack, final int maxLocals) {
+ buf.append(" MAXSTACK = ")
+ .append(maxStack)
+ .append("\n MAXLOCALS = ")
+ .append(maxLocals)
+ .append("\n\n");
+
+ if (cv != null) {
+ cv.visitMaxs(maxStack, maxLocals);
+ }
+ }
+
+ public void printLocalVariable (
+ final String name,
+ final String desc,
+ final Label start,
+ final Label end,
+ final int index)
+ {
+ buf.append(" LOCALVARIABLE ")
+ .append(name)
+ .append(" ")
+ .append(desc)
+ .append(" ");
+ appendLabel(start);
+ buf.append(" ");
+ appendLabel(end);
+ buf.append(" ")
+ .append(index)
+ .append("\n");
+
+ if (cv != null) {
+ cv.visitLocalVariable(name, desc, start, end, index);
+ }
+ }
+
+ public void printLineNumber (final int line, final Label start) {
+ buf.append(" LINENUMBER ")
+ .append(line)
+ .append(" ");
+ appendLabel(start);
+ buf.append("\n");
+
+ if (cv != null) {
+ cv.visitLineNumber(line, start);
+ }
+ }
+
+ private void appendLabel (final Label l) {
+ String name = (String)labelNames.get(l);
+ if (name == null) {
+ name = "L" + labelNames.size();
+ labelNames.put(l, name);
+ }
+ buf.append(name);
+ }
+}
diff --git a/src/org/objectweb/asm/util/package.html b/src/org/objectweb/asm/util/package.html
new file mode 100644
index 0000000..93268ce
--- /dev/null
+++ b/src/org/objectweb/asm/util/package.html
@@ -0,0 +1,28 @@
+<html>
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (C) 2000 INRIA, France Telecom
+ * Copyright (C) 2002 France Telecom
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Contact: Eric.Bruneton@rd.francetelecom.com
+ *
+ * Author: Eric Bruneton
+-->
+<body>
+Provides some useful ASM class visitors.
+</body>
+</html>