summaryrefslogtreecommitdiff
path: root/tools/external/asm/org/objectweb/asm/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/external/asm/org/objectweb/asm/util')
-rw-r--r--tools/external/asm/org/objectweb/asm/util/ASMifierAbstractVisitor.java226
-rw-r--r--tools/external/asm/org/objectweb/asm/util/ASMifierAnnotationVisitor.java127
-rw-r--r--tools/external/asm/org/objectweb/asm/util/ASMifierClassVisitor.java607
-rw-r--r--tools/external/asm/org/objectweb/asm/util/ASMifierFieldVisitor.java50
-rw-r--r--tools/external/asm/org/objectweb/asm/util/ASMifierMethodVisitor.java347
-rw-r--r--tools/external/asm/org/objectweb/asm/util/AbstractVisitor.java201
-rw-r--r--tools/external/asm/org/objectweb/asm/util/CheckAnnotationAdapter.java125
-rw-r--r--tools/external/asm/org/objectweb/asm/util/CheckClassAdapter.java416
-rw-r--r--tools/external/asm/org/objectweb/asm/util/CheckFieldAdapter.java75
-rw-r--r--tools/external/asm/org/objectweb/asm/util/CheckMethodAdapter.java942
-rw-r--r--tools/external/asm/org/objectweb/asm/util/TraceAbstractVisitor.java180
-rw-r--r--tools/external/asm/org/objectweb/asm/util/TraceAnnotationVisitor.java272
-rw-r--r--tools/external/asm/org/objectweb/asm/util/TraceClassVisitor.java534
-rw-r--r--tools/external/asm/org/objectweb/asm/util/TraceFieldVisitor.java78
-rw-r--r--tools/external/asm/org/objectweb/asm/util/TraceMethodVisitor.java486
-rw-r--r--tools/external/asm/org/objectweb/asm/util/TraceSignatureVisitor.java300
-rw-r--r--tools/external/asm/org/objectweb/asm/util/attrs/ASMStackMapAttribute.java223
-rw-r--r--tools/external/asm/org/objectweb/asm/util/attrs/ASMStackMapTableAttribute.java214
-rw-r--r--tools/external/asm/org/objectweb/asm/util/attrs/ASMifiable.java53
-rw-r--r--tools/external/asm/org/objectweb/asm/util/attrs/Traceable.java52
-rw-r--r--tools/external/asm/org/objectweb/asm/util/attrs/package.html36
-rw-r--r--tools/external/asm/org/objectweb/asm/util/package.html40
22 files changed, 5584 insertions, 0 deletions
diff --git a/tools/external/asm/org/objectweb/asm/util/ASMifierAbstractVisitor.java b/tools/external/asm/org/objectweb/asm/util/ASMifierAbstractVisitor.java
new file mode 100644
index 000000000..4ebc7fc09
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/ASMifierAbstractVisitor.java
@@ -0,0 +1,226 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.util.HashMap;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.util.attrs.ASMifiable;
+
+/**
+ * An abstract ASMifier visitor.
+ *
+ * @author Eric Bruneton
+ */
+public class ASMifierAbstractVisitor extends AbstractVisitor {
+
+ /**
+ * The name of the variable for this visitor in the produced code.
+ */
+ protected String name;
+
+ /**
+ * The label names. This map associates String values to Label keys. It is
+ * used only in ASMifierMethodVisitor.
+ */
+ HashMap labelNames;
+
+ /**
+ * Constructs a new {@link ASMifierAbstractVisitor}.
+ *
+ * @param name the name of the variable for this visitor in the produced
+ * code.
+ */
+ protected ASMifierAbstractVisitor(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Prints the ASM code that generates 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 AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ buf.setLength(0);
+ buf.append("{\n")
+ .append("av0 = ")
+ .append(name)
+ .append(".visitAnnotation(");
+ appendConstant(desc);
+ buf.append(", ").append(visible).append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ /**
+ * Prints the ASM code that generates the given attribute.
+ *
+ * @param attr an attribute.
+ */
+ public void visitAttribute(final Attribute attr) {
+ buf.setLength(0);
+ if (attr instanceof ASMifiable) {
+ buf.append("{\n");
+ buf.append("// ATTRIBUTE\n");
+ ((ASMifiable) attr).asmify(buf, "attr", labelNames);
+ buf.append(name).append(".visitAttribute(attr);\n");
+ buf.append("}\n");
+ } else {
+ buf.append("// WARNING! skipped a non standard attribute of type \"");
+ buf.append(attr.type).append("\"\n");
+ }
+ text.add(buf.toString());
+ }
+
+ /**
+ * Prints the ASM code to end the visit.
+ */
+ public void visitEnd() {
+ buf.setLength(0);
+ buf.append(name).append(".visitEnd();\n");
+ text.add(buf.toString());
+ }
+
+ /**
+ * Appends a string representation of the given constant to the given
+ * buffer.
+ *
+ * @param cst an {@link Integer}, {@link Float}, {@link Long},
+ * {@link Double} or {@link String} object. May be <tt>null</tt>.
+ */
+ void appendConstant(final Object cst) {
+ appendConstant(buf, cst);
+ }
+
+ /**
+ * Appends a string representation of the given constant to the given
+ * buffer.
+ *
+ * @param buf a string buffer.
+ * @param cst an {@link Integer}, {@link Float}, {@link Long},
+ * {@link Double} or {@link String} object. May be <tt>null</tt>.
+ */
+ static void appendConstant(final StringBuffer buf, final Object cst) {
+ if (cst == null) {
+ buf.append("null");
+ } else if (cst instanceof String) {
+ appendString(buf, (String) cst);
+ } else if (cst instanceof Type) {
+ buf.append("Type.getType(\"");
+ buf.append(((Type) cst).getDescriptor());
+ buf.append("\")");
+ } else if (cst instanceof Byte) {
+ buf.append("new Byte((byte)").append(cst).append(")");
+ } else if (cst instanceof Boolean) {
+ buf.append("new Boolean(").append(cst).append(")");
+ } else if (cst instanceof Short) {
+ buf.append("new Short((short)").append(cst).append(")");
+ } else if (cst instanceof Character) {
+ int c = ((Character) cst).charValue();
+ buf.append("new Character((char)").append(c).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("\")");
+ } 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("\")");
+ } else if (cst instanceof byte[]) {
+ byte[] v = (byte[]) cst;
+ buf.append("new byte[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof boolean[]) {
+ boolean[] v = (boolean[]) cst;
+ buf.append("new boolean[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof short[]) {
+ short[] v = (short[]) cst;
+ buf.append("new short[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append("(short)").append(v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof char[]) {
+ char[] v = (char[]) cst;
+ buf.append("new char[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",")
+ .append("(char)")
+ .append((int) v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof int[]) {
+ int[] v = (int[]) cst;
+ buf.append("new int[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof long[]) {
+ long[] v = (long[]) cst;
+ buf.append("new long[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]).append("L");
+ }
+ buf.append("}");
+ } else if (cst instanceof float[]) {
+ float[] v = (float[]) cst;
+ buf.append("new float[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]).append("f");
+ }
+ buf.append("}");
+ } else if (cst instanceof double[]) {
+ double[] v = (double[]) cst;
+ buf.append("new double[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]).append("d");
+ }
+ buf.append("}");
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/ASMifierAnnotationVisitor.java b/tools/external/asm/org/objectweb/asm/util/ASMifierAnnotationVisitor.java
new file mode 100644
index 000000000..bb48e2cdf
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/ASMifierAnnotationVisitor.java
@@ -0,0 +1,127 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+ * An {@link AnnotationVisitor} that prints the ASM code that generates the
+ * annotations it visits.
+ *
+ * @author Eric Bruneton
+ */
+public class ASMifierAnnotationVisitor extends AbstractVisitor implements
+ AnnotationVisitor
+{
+
+ /**
+ * Identifier of the annotation visitor variable in the produced code.
+ */
+ protected final int id;
+
+ /**
+ * Constructs a new {@link ASMifierAnnotationVisitor}.
+ *
+ * @param id identifier of the annotation visitor variable in the produced
+ * code.
+ */
+ public ASMifierAnnotationVisitor(final int id) {
+ this.id = id;
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the AnnotationVisitor interface
+ // ------------------------------------------------------------------------
+
+ public void visit(final String name, final Object value) {
+ buf.setLength(0);
+ buf.append("av").append(id).append(".visit(");
+ ASMifierAbstractVisitor.appendConstant(buf, name);
+ buf.append(", ");
+ ASMifierAbstractVisitor.appendConstant(buf, value);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitEnum(
+ final String name,
+ final String desc,
+ final String value)
+ {
+ buf.setLength(0);
+ buf.append("av").append(id).append(".visitEnum(");
+ ASMifierAbstractVisitor.appendConstant(buf, name);
+ buf.append(", ");
+ ASMifierAbstractVisitor.appendConstant(buf, desc);
+ buf.append(", ");
+ ASMifierAbstractVisitor.appendConstant(buf, value);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("AnnotationVisitor av").append(id + 1).append(" = av");
+ buf.append(id).append(".visitAnnotation(");
+ ASMifierAbstractVisitor.appendConstant(buf, name);
+ buf.append(", ");
+ ASMifierAbstractVisitor.appendConstant(buf, desc);
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(id + 1);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public AnnotationVisitor visitArray(final String name) {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("AnnotationVisitor av").append(id + 1).append(" = av");
+ buf.append(id).append(".visitArray(");
+ ASMifierAbstractVisitor.appendConstant(buf, name);
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(id + 1);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public void visitEnd() {
+ buf.setLength(0);
+ buf.append("av").append(id).append(".visitEnd();\n");
+ text.add(buf.toString());
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/ASMifierClassVisitor.java b/tools/external/asm/org/objectweb/asm/util/ASMifierClassVisitor.java
new file mode 100644
index 000000000..222325f0f
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/ASMifierClassVisitor.java
@@ -0,0 +1,607 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.io.FileInputStream;
+import java.io.PrintWriter;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A {@link ClassVisitor} 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 ASMifierClassVisitor} 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: <p> <blockquote>
+ *
+ * <pre>
+ * import org.objectweb.asm.*;
+ *
+ * public class HelloDump implements Opcodes {
+ *
+ * public static byte[] dump() throws Exception {
+ *
+ * ClassWriter cw = new ClassWriter(false);
+ * FieldVisitor fv;
+ * MethodVisitor mv;
+ * AnnotationVisitor av0;
+ *
+ * cw.visit(49,
+ * ACC_PUBLIC + ACC_SUPER,
+ * &quot;Hello&quot;,
+ * null,
+ * &quot;java/lang/Object&quot;,
+ * null);
+ *
+ * cw.visitSource(&quot;Hello.java&quot;, null);
+ *
+ * {
+ * mv = cw.visitMethod(ACC_PUBLIC, &quot;&lt;init&gt;&quot;, &quot;()V&quot;, null, null);
+ * mv.visitVarInsn(ALOAD, 0);
+ * mv.visitMethodInsn(INVOKESPECIAL,
+ * &quot;java/lang/Object&quot;,
+ * &quot;&lt;init&gt;&quot;,
+ * &quot;()V&quot;);
+ * mv.visitInsn(RETURN);
+ * mv.visitMaxs(1, 1);
+ * mv.visitEnd();
+ * }
+ * {
+ * mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
+ * &quot;main&quot;,
+ * &quot;([Ljava/lang/String;)V&quot;,
+ * null,
+ * null);
+ * mv.visitFieldInsn(GETSTATIC,
+ * &quot;java/lang/System&quot;,
+ * &quot;out&quot;,
+ * &quot;Ljava/io/PrintStream;&quot;);
+ * mv.visitLdcInsn(&quot;hello&quot;);
+ * mv.visitMethodInsn(INVOKEVIRTUAL,
+ * &quot;java/io/PrintStream&quot;,
+ * &quot;println&quot;,
+ * &quot;(Ljava/lang/String;)V&quot;);
+ * mv.visitInsn(RETURN);
+ * mv.visitMaxs(2, 1);
+ * mv.visitEnd();
+ * }
+ * cw.visitEnd();
+ *
+ * return cw.toByteArray();
+ * }
+ * }
+ *
+ * </pre>
+ *
+ * </blockquote> where <tt>Hello</tt> is defined by: <p> <blockquote>
+ *
+ * <pre>
+ * public class Hello {
+ *
+ * public static void main(String[] args) {
+ * System.out.println(&quot;hello&quot;);
+ * }
+ * }
+ * </pre>
+ *
+ * </blockquote>
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class ASMifierClassVisitor extends ASMifierAbstractVisitor implements
+ ClassVisitor
+{
+
+ /**
+ * Pseudo access flag used to distinguish class access flags.
+ */
+ private final static int ACCESS_CLASS = 262144;
+
+ /**
+ * Pseudo access flag used to distinguish field access flags.
+ */
+ private final static int ACCESS_FIELD = 524288;
+
+ /**
+ * Pseudo access flag used to distinguish inner class flags.
+ */
+ private static final int ACCESS_INNER = 1048576;
+
+ /**
+ * The print writer to be used to print the class.
+ */
+ protected final PrintWriter pw;
+
+ /**
+ * Prints the ASM source code to generate the given class to the standard
+ * output. <p> Usage: ASMifierClassVisitor [-debug] &lt;fully qualified
+ * class name or class file name&gt;
+ *
+ * @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;
+ boolean skipDebug = true;
+
+ boolean ok = true;
+ if (args.length < 1 || args.length > 2) {
+ ok = false;
+ }
+ if (ok && args[0].equals("-debug")) {
+ i = 1;
+ skipDebug = false;
+ if (args.length != 2) {
+ ok = false;
+ }
+ }
+ if (!ok) {
+ System.err.println("Prints the ASM code to generate the given class.");
+ System.err.println("Usage: ASMifierClassVisitor [-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 ASMifierClassVisitor(new PrintWriter(System.out)),
+ getDefaultAttributes(),
+ skipDebug);
+ }
+
+ /**
+ * Constructs a new {@link ASMifierClassVisitor} object.
+ *
+ * @param pw the print writer to be used to print the class.
+ */
+ public ASMifierClassVisitor(final PrintWriter pw) {
+ super("cw");
+ this.pw = pw;
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the ClassVisitor interface
+ // ------------------------------------------------------------------------
+
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces)
+ {
+ String simpleName;
+ int n = name.lastIndexOf('/');
+ if (n != -1) {
+ text.add("package asm." + name.substring(0, n).replace('/', '.')
+ + ";\n");
+ simpleName = name.substring(n + 1);
+ } else {
+ simpleName = name;
+ }
+ text.add("import java.util.*;\n");
+ text.add("import org.objectweb.asm.*;\n");
+ text.add("import org.objectweb.asm.attrs.*;\n");
+ text.add("public class " + simpleName + "Dump implements Opcodes {\n\n");
+ text.add("public static byte[] dump () throws Exception {\n\n");
+ text.add("ClassWriter cw = new ClassWriter(false);\n");
+ text.add("FieldVisitor fv;\n");
+ text.add("MethodVisitor mv;\n");
+ text.add("AnnotationVisitor av0;\n\n");
+
+ buf.setLength(0);
+ buf.append("cw.visit(");
+ switch (version) {
+ case Opcodes.V1_1:
+ buf.append("V1_1");
+ break;
+ case Opcodes.V1_2:
+ buf.append("V1_2");
+ break;
+ case Opcodes.V1_3:
+ buf.append("V1_3");
+ break;
+ case Opcodes.V1_4:
+ buf.append("V1_4");
+ break;
+ case Opcodes.V1_5:
+ buf.append("V1_5");
+ break;
+ case Opcodes.V1_6:
+ buf.append("V1_6");
+ break;
+ default:
+ buf.append(version);
+ break;
+ }
+ buf.append(", ");
+ appendAccess(access | ACCESS_CLASS);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(signature);
+ buf.append(", ");
+ appendConstant(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(interfaces[i]);
+ }
+ buf.append(" }");
+ } else {
+ buf.append("null");
+ }
+ buf.append(");\n\n");
+ text.add(buf.toString());
+ }
+
+ public void visitSource(final String file, final String debug) {
+ buf.setLength(0);
+ buf.append("cw.visitSource(");
+ appendConstant(file);
+ buf.append(", ");
+ appendConstant(debug);
+ buf.append(");\n\n");
+ text.add(buf.toString());
+ }
+
+ public void visitOuterClass(
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ buf.append("cw.visitOuterClass(");
+ appendConstant(owner);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(");\n\n");
+ text.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(name);
+ buf.append(", ");
+ appendConstant(outerName);
+ buf.append(", ");
+ appendConstant(innerName);
+ buf.append(", ");
+ appendAccess(access | ACCESS_INNER);
+ buf.append(");\n\n");
+ text.add(buf.toString());
+ }
+
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final Object value)
+ {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("fv = cw.visitField(");
+ appendAccess(access | ACCESS_FIELD);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(", ");
+ appendConstant(signature);
+ buf.append(", ");
+ appendConstant(value);
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierFieldVisitor aav = new ASMifierFieldVisitor();
+ text.add(aav.getText());
+ text.add("}\n");
+ return aav;
+ }
+
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final String[] exceptions)
+ {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("mv = cw.visitMethod(");
+ appendAccess(access);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(", ");
+ appendConstant(signature);
+ 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(exceptions[i]);
+ }
+ buf.append(" }");
+ } else {
+ buf.append("null");
+ }
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierMethodVisitor acv = new ASMifierMethodVisitor();
+ text.add(acv.getText());
+ text.add("}\n");
+ return acv;
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("av0 = cw.visitAnnotation(");
+ appendConstant(desc);
+ buf.append(", ");
+ buf.append(visible);
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public void visitEnd() {
+ text.add("cw.visitEnd();\n\n");
+ text.add("return cw.toByteArray();\n");
+ text.add("}\n");
+ text.add("}\n");
+ printList(pw, text);
+ pw.flush();
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Appends a string representation of the given access modifiers to {@link
+ * #buf buf}.
+ *
+ * @param access some access modifiers.
+ */
+ void appendAccess(final int access) {
+ boolean first = true;
+ if ((access & Opcodes.ACC_PUBLIC) != 0) {
+ buf.append("ACC_PUBLIC");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_PRIVATE) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_PRIVATE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_PROTECTED) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_PROTECTED");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_FINAL) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_FINAL");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_STATIC) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_STATIC");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ if ((access & ACCESS_CLASS) != 0) {
+ buf.append("ACC_SUPER");
+ } else {
+ buf.append("ACC_SYNCHRONIZED");
+ }
+ first = false;
+ }
+ if ((access & Opcodes.ACC_VOLATILE) != 0
+ && (access & ACCESS_FIELD) != 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_VOLATILE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0
+ && (access & ACCESS_FIELD) == 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_BRIDGE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0
+ && (access & ACCESS_FIELD) == 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_VARARGS");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_TRANSIENT) != 0
+ && (access & ACCESS_FIELD) != 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_TRANSIENT");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_NATIVE) != 0 && (access & ACCESS_CLASS) == 0
+ && (access & ACCESS_FIELD) == 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_NATIVE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_ENUM) != 0
+ && ((access & ACCESS_CLASS) != 0
+ || (access & ACCESS_FIELD) != 0 || (access & ACCESS_INNER) != 0))
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_ENUM");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_ANNOTATION) != 0
+ && ((access & ACCESS_CLASS) != 0))
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_ANNOTATION");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_ABSTRACT) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_ABSTRACT");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_INTERFACE) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_INTERFACE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_STRICT) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_STRICT");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_SYNTHETIC");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_DEPRECATED");
+ first = false;
+ }
+ if (first) {
+ buf.append("0");
+ }
+ }
+
+ /**
+ * Appends a string representation of the given constant to the given
+ * buffer.
+ *
+ * @param buf a string buffer.
+ * @param cst an {@link java.lang.Integer Integer}, {@link java.lang.Float
+ * Float}, {@link java.lang.Long Long},
+ * {@link java.lang.Double Double} or {@link String String} object.
+ * May be <tt>null</tt>.
+ */
+ static void appendConstant(final StringBuffer buf, final Object cst) {
+ if (cst == null) {
+ buf.append("null");
+ } else if (cst instanceof String) {
+ AbstractVisitor.appendString(buf, (String) cst);
+ } else if (cst instanceof Type) {
+ buf.append("Type.getType(\"")
+ .append(((Type) cst).getDescriptor())
+ .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("\")");
+ } 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/tools/external/asm/org/objectweb/asm/util/ASMifierFieldVisitor.java b/tools/external/asm/org/objectweb/asm/util/ASMifierFieldVisitor.java
new file mode 100644
index 000000000..9da152ca3
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/ASMifierFieldVisitor.java
@@ -0,0 +1,50 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.FieldVisitor;
+
+/**
+ * A {@link FieldVisitor} that prints the ASM code that generates the fields it
+ * visits.
+ *
+ * @author Eric Bruneton
+ */
+public class ASMifierFieldVisitor extends ASMifierAbstractVisitor implements
+ FieldVisitor
+{
+
+ /**
+ * Constructs a new {@link ASMifierFieldVisitor}.
+ */
+ public ASMifierFieldVisitor() {
+ super("fv");
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/ASMifierMethodVisitor.java b/tools/external/asm/org/objectweb/asm/util/ASMifierMethodVisitor.java
new file mode 100644
index 000000000..33404d975
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/ASMifierMethodVisitor.java
@@ -0,0 +1,347 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+
+import java.util.HashMap;
+
+/**
+ * A {@link MethodVisitor} that prints the ASM code that generates the methods
+ * it visits.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class ASMifierMethodVisitor extends ASMifierAbstractVisitor implements
+ MethodVisitor
+{
+
+ /**
+ * Constructs a new {@link ASMifierMethodVisitor} object.
+ */
+ public ASMifierMethodVisitor() {
+ super("mv");
+ this.labelNames = new HashMap();
+ }
+
+ public AnnotationVisitor visitAnnotationDefault() {
+ buf.setLength(0);
+ buf.append("{\n").append("av0 = mv.visitAnnotationDefault();\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter,
+ final String desc,
+ final boolean visible)
+ {
+ buf.setLength(0);
+ buf.append("{\n")
+ .append("av0 = mv.visitParameterAnnotation(")
+ .append(parameter)
+ .append(", ");
+ appendConstant(desc);
+ buf.append(", ").append(visible).append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public void visitCode() {
+ text.add("mv.visitCode();\n");
+ }
+
+ public void visitInsn(final int opcode) {
+ buf.setLength(0);
+ buf.append("mv.visitInsn(").append(OPCODES[opcode]).append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitIntInsn(final int opcode, final int operand) {
+ buf.setLength(0);
+ buf.append("mv.visitIntInsn(")
+ .append(OPCODES[opcode])
+ .append(", ")
+ .append(opcode == Opcodes.NEWARRAY
+ ? TYPES[operand]
+ : Integer.toString(operand))
+ .append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitVarInsn(final int opcode, final int var) {
+ buf.setLength(0);
+ buf.append("mv.visitVarInsn(")
+ .append(OPCODES[opcode])
+ .append(", ")
+ .append(var)
+ .append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitTypeInsn(final int opcode, final String desc) {
+ buf.setLength(0);
+ buf.append("mv.visitTypeInsn(").append(OPCODES[opcode]).append(", ");
+ appendConstant(desc);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitFieldInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ buf.append("mv.visitFieldInsn(").append(OPCODES[opcode]).append(", ");
+ appendConstant(owner);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ buf.append("mv.visitMethodInsn(").append(OPCODES[opcode]).append(", ");
+ appendConstant(owner);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitJumpInsn(final int opcode, final Label label) {
+ buf.setLength(0);
+ declareLabel(label);
+ buf.append("mv.visitJumpInsn(").append(OPCODES[opcode]).append(", ");
+ appendLabel(label);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitLabel(final Label label) {
+ buf.setLength(0);
+ declareLabel(label);
+ buf.append("mv.visitLabel(");
+ appendLabel(label);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitLdcInsn(final Object cst) {
+ buf.setLength(0);
+ buf.append("mv.visitLdcInsn(");
+ appendConstant(cst);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitIincInsn(final int var, final int increment) {
+ buf.setLength(0);
+ buf.append("mv.visitIincInsn(")
+ .append(var)
+ .append(", ")
+ .append(increment)
+ .append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitTableSwitchInsn(
+ final int min,
+ final int max,
+ final Label dflt,
+ final Label labels[])
+ {
+ buf.setLength(0);
+ for (int i = 0; i < labels.length; ++i) {
+ declareLabel(labels[i]);
+ }
+ declareLabel(dflt);
+
+ buf.append("mv.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");
+ text.add(buf.toString());
+ }
+
+ public void visitLookupSwitchInsn(
+ final Label dflt,
+ final int keys[],
+ final Label labels[])
+ {
+ buf.setLength(0);
+ for (int i = 0; i < labels.length; ++i) {
+ declareLabel(labels[i]);
+ }
+ declareLabel(dflt);
+
+ buf.append("mv.visitLookupSwitchInsn(");
+ 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");
+ text.add(buf.toString());
+ }
+
+ public void visitMultiANewArrayInsn(final String desc, final int dims) {
+ buf.setLength(0);
+ buf.append("mv.visitMultiANewArrayInsn(");
+ appendConstant(desc);
+ buf.append(", ").append(dims).append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitTryCatchBlock(
+ final Label start,
+ final Label end,
+ final Label handler,
+ final String type)
+ {
+ buf.setLength(0);
+ declareLabel(start);
+ declareLabel(end);
+ declareLabel(handler);
+ buf.append("mv.visitTryCatchBlock(");
+ appendLabel(start);
+ buf.append(", ");
+ appendLabel(end);
+ buf.append(", ");
+ appendLabel(handler);
+ buf.append(", ");
+ appendConstant(type);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ 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("mv.visitLocalVariable(");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(", ");
+ appendConstant(signature);
+ buf.append(", ");
+ appendLabel(start);
+ buf.append(", ");
+ appendLabel(end);
+ buf.append(", ").append(index).append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitLineNumber(final int line, final Label start) {
+ buf.setLength(0);
+ buf.append("mv.visitLineNumber(").append(line).append(", ");
+ appendLabel(start);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ buf.setLength(0);
+ buf.append("mv.visitMaxs(")
+ .append(maxStack)
+ .append(", ")
+ .append(maxLocals)
+ .append(");\n");
+ text.add(buf.toString());
+ }
+
+ /**
+ * Appends a declaration of the given label to {@link #buf buf}. This
+ * declaration is of the form "Label lXXX = new Label();". Does nothing if
+ * the given label has already been declared.
+ *
+ * @param l a label.
+ */
+ 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");
+ }
+ }
+
+ /**
+ * Appends the name of the given label to {@link #buf buf}. The given label
+ * <i>must</i> already have a name. One way to ensure this is to always
+ * call {@link #declareLabel declared} before calling this method.
+ *
+ * @param l a label.
+ */
+ private void appendLabel(final Label l) {
+ buf.append((String) labelNames.get(l));
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/AbstractVisitor.java b/tools/external/asm/org/objectweb/asm/util/AbstractVisitor.java
new file mode 100644
index 000000000..3e329f7fe
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/AbstractVisitor.java
@@ -0,0 +1,201 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.util.attrs.ASMStackMapAttribute;
+import org.objectweb.asm.util.attrs.ASMStackMapTableAttribute;
+
+/**
+ * An abstract visitor.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class AbstractVisitor {
+
+ /**
+ * The names of the Java Virtual Machine opcodes.
+ */
+ public final static String[] OPCODES;
+ /**
+ * Types for <code>operand</code> parameter of the
+ * {@link org.objectweb.asm.MethodVisitor#visitIntInsn} method when
+ * <code>opcode</code> is <code>NEWARRAY</code>.
+ */
+ public final static String[] TYPES;
+
+ static {
+ String s = "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,,,"
+ + "ILOAD,LLOAD,FLOAD,DLOAD,ALOAD,,,,,,,,,,,,,,,,,,,,,IALOAD,"
+ + "LALOAD,FALOAD,DALOAD,AALOAD,BALOAD,CALOAD,SALOAD,ISTORE,"
+ + "LSTORE,FSTORE,DSTORE,ASTORE,,,,,,,,,,,,,,,,,,,,,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,,NEW,NEWARRAY,ANEWARRAY,"
+ + "ARRAYLENGTH,ATHROW,CHECKCAST,INSTANCEOF,MONITORENTER,"
+ + "MONITOREXIT,,MULTIANEWARRAY,IFNULL,IFNONNULL,";
+ OPCODES = new String[200];
+ int i = 0;
+ int j = 0;
+ int l;
+ while ((l = s.indexOf(',', j)) > 0) {
+ OPCODES[i++] = j + 1 == l ? null : s.substring(j, l);
+ j = l + 1;
+ }
+
+ s = "T_BOOLEAN,T_CHAR,T_FLOAT,T_DOUBLE,T_BYTE,T_SHORT,T_INT,T_LONG,";
+ TYPES = new String[12];
+ j = 0;
+ i = 4;
+ while ((l = s.indexOf(',', j)) > 0) {
+ TYPES[i++] = s.substring(j, l);
+ j = l + 1;
+ }
+ }
+
+ /**
+ * The text to be printed. Since the code of methods is not necessarily
+ * visited in sequential order, one method after the other, but can be
+ * interlaced (some instructions from method one, then some instructions
+ * from method two, then some instructions from method one again...), it is
+ * not possible to print the visited instructions directly to a sequential
+ * stream. A class is therefore printed in a two steps process: a string
+ * tree is constructed during the visit, and printed to a sequential stream
+ * at the end of the visit. This string tree is stored in this field, as a
+ * string list that can contain other string lists, which can themselves
+ * contain other string lists, and so on.
+ */
+ public final List text;
+
+ /**
+ * A buffer that can be used to create strings.
+ */
+ protected final StringBuffer buf;
+
+ /**
+ * Constructs a new {@link AbstractVisitor}.
+ */
+ protected AbstractVisitor() {
+ this.text = new ArrayList();
+ this.buf = new StringBuffer();
+ }
+
+ /**
+ * Returns the text printed by this visitor.
+ *
+ * @return the text printed by this visitor.
+ */
+ public List getText() {
+ return text;
+ }
+
+ /**
+ * Appends a quoted string to a given buffer.
+ *
+ * @param buf the buffer where the string must be added.
+ * @param s the string to be added.
+ */
+ public static void appendString(final StringBuffer buf, final String s) {
+ buf.append("\"");
+ for (int i = 0; i < s.length(); ++i) {
+ char c = s.charAt(i);
+ if (c == '\n') {
+ buf.append("\\n");
+ } else if (c == '\r') {
+ buf.append("\\r");
+ } else if (c == '\\') {
+ buf.append("\\\\");
+ } else if (c == '"') {
+ buf.append("\\\"");
+ } else if (c < 0x20 || c > 0x7f) {
+ buf.append("\\u");
+ if (c < 0x10) {
+ buf.append("000");
+ } else if (c < 0x100) {
+ buf.append("00");
+ } else if (c < 0x1000) {
+ buf.append("0");
+ }
+ buf.append(Integer.toString(c, 16));
+ } else {
+ buf.append(c);
+ }
+ }
+ buf.append("\"");
+ }
+
+ /**
+ * Prints the given string tree.
+ *
+ * @param pw the writer to be used to print the tree.
+ * @param l a string tree, i.e., a string list that can contain other string
+ * lists, and so on recursively.
+ */
+ void printList(final PrintWriter pw, final List l) {
+ for (int i = 0; i < l.size(); ++i) {
+ Object o = l.get(i);
+ if (o instanceof List) {
+ printList(pw, (List) o);
+ } else {
+ pw.print(o.toString());
+ }
+ }
+ }
+
+ /**
+ * Returns the default {@link ASMifiable} prototypes.
+ *
+ * @return the default {@link ASMifiable} prototypes.
+ */
+ public static Attribute[] getDefaultAttributes() {
+ try {
+ return new Attribute[] {
+ new ASMStackMapAttribute(),
+ new ASMStackMapTableAttribute() };
+ } catch (Exception e) {
+ return new Attribute[0];
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/CheckAnnotationAdapter.java b/tools/external/asm/org/objectweb/asm/util/CheckAnnotationAdapter.java
new file mode 100644
index 000000000..d00933ca5
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/CheckAnnotationAdapter.java
@@ -0,0 +1,125 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+
+/**
+ * An {@link AnnotationVisitor} that checks that its methods are properly used.
+ *
+ * @author Eric Bruneton
+ */
+public class CheckAnnotationAdapter implements AnnotationVisitor {
+
+ private AnnotationVisitor av;
+
+ private boolean named;
+
+ private boolean end;
+
+ public CheckAnnotationAdapter(final AnnotationVisitor av) {
+ this(av, true);
+ }
+
+ CheckAnnotationAdapter(
+ final AnnotationVisitor av,
+ final boolean named)
+ {
+ this.av = av;
+ this.named = named;
+ }
+
+ public void visit(final String name, final Object value) {
+ checkEnd();
+ checkName(name);
+ if (!(value instanceof Byte || value instanceof Boolean
+ || value instanceof Character || value instanceof Short
+ || value instanceof Integer || value instanceof Long
+ || value instanceof Float || value instanceof Double
+ || value instanceof String || value instanceof Type
+ || value instanceof byte[] || value instanceof boolean[]
+ || value instanceof char[] || value instanceof short[]
+ || value instanceof int[] || value instanceof long[]
+ || value instanceof float[] || value instanceof double[]))
+ {
+ throw new IllegalArgumentException("Invalid annotation value");
+ }
+ av.visit(name, value);
+ }
+
+ public void visitEnum(
+ final String name,
+ final String desc,
+ final String value)
+ {
+ checkEnd();
+ checkName(name);
+ CheckMethodAdapter.checkDesc(desc, false);
+ if (value == null) {
+ throw new IllegalArgumentException("Invalid enum value");
+ }
+ av.visitEnum(name, desc, value);
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String name,
+ final String desc)
+ {
+ checkEnd();
+ checkName(name);
+ CheckMethodAdapter.checkDesc(desc, false);
+ return new CheckAnnotationAdapter(av.visitAnnotation(name, desc));
+ }
+
+ public AnnotationVisitor visitArray(final String name) {
+ checkEnd();
+ checkName(name);
+ return new CheckAnnotationAdapter(av.visitArray(name), false);
+ }
+
+ public void visitEnd() {
+ checkEnd();
+ end = true;
+ av.visitEnd();
+ }
+
+ private void checkEnd() {
+ if (end) {
+ throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+ }
+ }
+
+ private void checkName(final String name) {
+ if (named && name == null) {
+ throw new IllegalArgumentException("Annotation value name must not be null");
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/CheckClassAdapter.java b/tools/external/asm/org/objectweb/asm/util/CheckClassAdapter.java
new file mode 100644
index 000000000..640e8b083
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/CheckClassAdapter.java
@@ -0,0 +1,416 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.io.FileInputStream;
+import java.io.PrintWriter;
+import java.util.List;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+import org.objectweb.asm.tree.analysis.Analyzer;
+import org.objectweb.asm.tree.analysis.SimpleVerifier;
+import org.objectweb.asm.tree.analysis.Frame;
+
+/**
+ * A {@link ClassAdapter} that checks that its methods are properly used. More
+ * precisely this class adapter checks each method call individually, based
+ * <i>only</i> on its arguments, but does <i>not</i> check the <i>sequence</i>
+ * of method calls. For example, the invalid sequence
+ * <tt>visitField(ACC_PUBLIC, "i", "I", null)</tt> <tt>visitField(ACC_PUBLIC,
+ * "i", "D", null)</tt>
+ * will <i>not</i> be detected by this class adapter.
+ *
+ * @author Eric Bruneton
+ */
+public class CheckClassAdapter extends ClassAdapter {
+
+ /**
+ * <tt>true</tt> if the visit method has been called.
+ */
+ private boolean start;
+
+ /**
+ * <tt>true</tt> if the visitSource method has been called.
+ */
+ private boolean source;
+
+ /**
+ * <tt>true</tt> if the visitOuterClass method has been called.
+ */
+ private boolean outer;
+
+ /**
+ * <tt>true</tt> if the visitEnd method has been called.
+ */
+ private boolean end;
+
+ /**
+ * Checks a given class. <p> Usage: CheckClassAdapter &lt;fully qualified
+ * class name or class file name&gt;
+ *
+ * @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 {
+ if (args.length != 1) {
+ System.err.println("Verifies the given class.");
+ System.err.println("Usage: CheckClassAdapter "
+ + "<fully qualified class name or class file name>");
+ return;
+ }
+ ClassReader cr;
+ if (args[0].endsWith(".class")) {
+ cr = new ClassReader(new FileInputStream(args[0]));
+ } else {
+ cr = new ClassReader(args[0]);
+ }
+
+ verify(cr, false, new PrintWriter(System.err));
+ }
+
+ /**
+ * Checks a given class
+ *
+ * @param cr a <code>ClassReader</code> that contains bytecode for the analysis.
+ * @param dump true if bytecode should be printed out not only when errors are found.
+ * @param pw write where results going to be printed
+ */
+ public static void verify(ClassReader cr, boolean dump, PrintWriter pw) {
+ ClassNode cn = new ClassNode();
+ cr.accept(new CheckClassAdapter(cn), true);
+
+ List methods = cn.methods;
+ for (int i = 0; i < methods.size(); ++i) {
+ MethodNode method = (MethodNode) methods.get(i);
+ if (method.instructions.size() > 0) {
+ Analyzer a = new Analyzer(new SimpleVerifier(Type.getType("L"
+ + cn.name + ";"),
+ Type.getType("L" + cn.superName + ";"),
+ (cn.access & Opcodes.ACC_INTERFACE) != 0));
+ try {
+ a.analyze(cn.name, method);
+ if (!dump) {
+ continue;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Frame[] frames = a.getFrames();
+
+ TraceMethodVisitor mv = new TraceMethodVisitor();
+
+ pw.println(method.name + method.desc);
+ for (int j = 0; j < method.instructions.size(); ++j) {
+ ((AbstractInsnNode) method.instructions.get(j)).accept(mv);
+
+ StringBuffer s = new StringBuffer();
+ Frame f = frames[j];
+ if (f == null) {
+ s.append('?');
+ } else {
+ for (int k = 0; k < f.getLocals(); ++k) {
+ s.append(getShortName(f.getLocal(k).toString()))
+ .append(' ');
+ }
+ s.append(" : ");
+ for (int k = 0; k < f.getStackSize(); ++k) {
+ s.append(getShortName(f.getStack(k).toString()))
+ .append(' ');
+ }
+ }
+ while (s.length() < method.maxStack + method.maxLocals + 1)
+ {
+ s.append(' ');
+ }
+ pw.print(Integer.toString(j + 100000).substring(1));
+ pw.print(" " + s + " : " + mv.buf); // mv.text.get(j));
+ }
+ for (int j = 0; j < method.tryCatchBlocks.size(); ++j) {
+ ((TryCatchBlockNode) method.tryCatchBlocks.get(j)).accept(mv);
+ pw.print(" " + mv.buf);
+ }
+ pw.println();
+ }
+ }
+ }
+
+ private static String getShortName(String name) {
+ int n = name.lastIndexOf('/');
+ int k = name.length();
+ if(name.charAt(k-1)==';') k--;
+ return n==-1 ? name : name.substring(n+1, k);
+ }
+
+ /**
+ * Constructs a new {@link CheckClassAdapter}.
+ *
+ * @param cv the class visitor to which this adapter must delegate calls.
+ */
+ public CheckClassAdapter(final ClassVisitor cv) {
+ super(cv);
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the ClassVisitor interface
+ // ------------------------------------------------------------------------
+
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces)
+ {
+ if (start) {
+ throw new IllegalStateException("visit must be called only once");
+ } else {
+ start = true;
+ }
+ checkState();
+ checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL
+ + Opcodes.ACC_SUPER + Opcodes.ACC_INTERFACE
+ + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC
+ + Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM
+ + Opcodes.ACC_DEPRECATED);
+ CheckMethodAdapter.checkInternalName(name, "class name");
+ if ("java/lang/Object".equals(name)) {
+ if (superName != null) {
+ throw new IllegalArgumentException("The super class name of the Object class must be 'null'");
+ }
+ } else {
+ CheckMethodAdapter.checkInternalName(superName, "super class name");
+ }
+ if (signature != null) {
+ // TODO
+ }
+ if ((access & Opcodes.ACC_INTERFACE) != 0) {
+ if (!"java/lang/Object".equals(superName)) {
+ throw new IllegalArgumentException("The super class name of interfaces must be 'java/lang/Object'");
+ }
+ }
+ if (interfaces != null) {
+ for (int i = 0; i < interfaces.length; ++i) {
+ CheckMethodAdapter.checkInternalName(interfaces[i],
+ "interface name at index " + i);
+ }
+ }
+ cv.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ public void visitSource(final String file, final String debug) {
+ checkState();
+ if (source) {
+ throw new IllegalStateException("visitSource can be called only once.");
+ }
+ source = true;
+ cv.visitSource(file, debug);
+ }
+
+ public void visitOuterClass(
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ checkState();
+ if (outer) {
+ throw new IllegalStateException("visitSource can be called only once.");
+ }
+ outer = true;
+ if (owner == null) {
+ throw new IllegalArgumentException("Illegal outer class owner");
+ }
+ if (desc != null) {
+ CheckMethodAdapter.checkMethodDesc(desc);
+ }
+ cv.visitOuterClass(owner, name, desc);
+ }
+
+ public void visitInnerClass(
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ checkState();
+ CheckMethodAdapter.checkInternalName(name, "class name");
+ if (outerName != null) {
+ CheckMethodAdapter.checkInternalName(outerName, "outer class name");
+ }
+ if (innerName != null) {
+ CheckMethodAdapter.checkIdentifier(innerName, "inner class name");
+ }
+ checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE
+ + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC
+ + Opcodes.ACC_FINAL + Opcodes.ACC_INTERFACE
+ + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC
+ + Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM);
+ cv.visitInnerClass(name, outerName, innerName, access);
+ }
+
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final Object value)
+ {
+ checkState();
+ checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE
+ + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC
+ + Opcodes.ACC_FINAL + Opcodes.ACC_VOLATILE
+ + Opcodes.ACC_TRANSIENT + Opcodes.ACC_SYNTHETIC
+ + Opcodes.ACC_ENUM + Opcodes.ACC_DEPRECATED);
+ CheckMethodAdapter.checkIdentifier(name, "field name");
+ CheckMethodAdapter.checkDesc(desc, false);
+ if (signature != null) {
+ // TODO
+ }
+ if (value != null) {
+ CheckMethodAdapter.checkConstant(value);
+ }
+ FieldVisitor av = cv.visitField(access, name, desc, signature, value);
+ return new CheckFieldAdapter(av);
+ }
+
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final String[] exceptions)
+ {
+ checkState();
+ checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE
+ + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC
+ + Opcodes.ACC_FINAL + Opcodes.ACC_SYNCHRONIZED
+ + Opcodes.ACC_BRIDGE + Opcodes.ACC_VARARGS + Opcodes.ACC_NATIVE
+ + Opcodes.ACC_ABSTRACT + Opcodes.ACC_STRICT
+ + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_DEPRECATED);
+ CheckMethodAdapter.checkMethodIdentifier(name, "method name");
+ CheckMethodAdapter.checkMethodDesc(desc);
+ if (signature != null) {
+ // TODO
+ }
+ if (exceptions != null) {
+ for (int i = 0; i < exceptions.length; ++i) {
+ CheckMethodAdapter.checkInternalName(exceptions[i],
+ "exception name at index " + i);
+ }
+ }
+ return new CheckMethodAdapter(cv.visitMethod(access,
+ name,
+ desc,
+ signature,
+ exceptions));
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ checkState();
+ CheckMethodAdapter.checkDesc(desc, false);
+ return new CheckAnnotationAdapter(cv.visitAnnotation(desc, visible));
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ checkState();
+ if (attr == null) {
+ throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ }
+ cv.visitAttribute(attr);
+ }
+
+ public void visitEnd() {
+ checkState();
+ end = true;
+ cv.visitEnd();
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Checks that the visit method has been called and that visitEnd has not
+ * been called.
+ */
+ private void checkState() {
+ if (!start) {
+ throw new IllegalStateException("Cannot visit member before visit has been called.");
+ }
+ if (end) {
+ throw new IllegalStateException("Cannot visit member after visitEnd has been called.");
+ }
+ }
+
+ /**
+ * Checks that the given access flags do not contain invalid flags. This
+ * method also checks that mutually incompatible flags are not set
+ * simultaneously.
+ *
+ * @param access the access flags to be checked
+ * @param possibleAccess the valid access flags.
+ */
+ static void checkAccess(final int access, final int possibleAccess) {
+ if ((access & ~possibleAccess) != 0) {
+ throw new IllegalArgumentException("Invalid access flags: "
+ + access);
+ }
+ int pub = ((access & Opcodes.ACC_PUBLIC) != 0 ? 1 : 0);
+ int pri = ((access & Opcodes.ACC_PRIVATE) != 0 ? 1 : 0);
+ int pro = ((access & Opcodes.ACC_PROTECTED) != 0 ? 1 : 0);
+ if (pub + pri + pro > 1) {
+ throw new IllegalArgumentException("public private and protected are mutually exclusive: "
+ + access);
+ }
+ int fin = ((access & Opcodes.ACC_FINAL) != 0 ? 1 : 0);
+ int abs = ((access & Opcodes.ACC_ABSTRACT) != 0 ? 1 : 0);
+ if (fin + abs > 1) {
+ throw new IllegalArgumentException("final and abstract are mutually exclusive: "
+ + access);
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/CheckFieldAdapter.java b/tools/external/asm/org/objectweb/asm/util/CheckFieldAdapter.java
new file mode 100644
index 000000000..3e7c113b8
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/CheckFieldAdapter.java
@@ -0,0 +1,75 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.FieldVisitor;
+
+/**
+ * A {@link FieldVisitor} that checks that its methods are properly used.
+ */
+public class CheckFieldAdapter implements FieldVisitor {
+
+ private FieldVisitor fv;
+
+ private boolean end;
+
+ public CheckFieldAdapter(final FieldVisitor fv) {
+ this.fv = fv;
+ }
+
+ public AnnotationVisitor visitAnnotation(final String desc, boolean visible)
+ {
+ checkEnd();
+ CheckMethodAdapter.checkDesc(desc, false);
+ return new CheckAnnotationAdapter(fv.visitAnnotation(desc, visible));
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ checkEnd();
+ if (attr == null) {
+ throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ }
+ fv.visitAttribute(attr);
+ }
+
+ public void visitEnd() {
+ checkEnd();
+ end = true;
+ fv.visitEnd();
+ }
+
+ private void checkEnd() {
+ if (end) {
+ throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/CheckMethodAdapter.java b/tools/external/asm/org/objectweb/asm/util/CheckMethodAdapter.java
new file mode 100644
index 000000000..1cd77c676
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/CheckMethodAdapter.java
@@ -0,0 +1,942 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodAdapter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Type;
+
+import java.util.HashMap;
+
+/**
+ * A {@link MethodAdapter} that checks that its methods are properly used. More
+ * precisely this code adapter checks each instruction individually (i.e., each
+ * visit method checks some preconditions based <i>only</i> on its arguments -
+ * such as the fact that the given opcode is correct for a given visit method),
+ * but does <i>not</i> check the <i>sequence</i> of instructions. For example,
+ * in a method whose signature is <tt>void m ()</tt>, the invalid instruction
+ * IRETURN, or the invalid sequence IADD L2I will <i>not</i> be detected by
+ * this code adapter.
+ *
+ * @author Eric Bruneton
+ */
+public class CheckMethodAdapter extends MethodAdapter {
+
+ /**
+ * <tt>true</tt> if the visitCode method has been called.
+ */
+ private boolean startCode;
+
+ /**
+ * <tt>true</tt> if the visitMaxs method has been called.
+ */
+ private boolean endCode;
+
+ /**
+ * <tt>true</tt> if the visitEnd method has been called.
+ */
+ private boolean endMethod;
+
+ /**
+ * The already visited labels. This map associate Integer values to Label
+ * keys.
+ */
+ private HashMap labels;
+
+ /**
+ * Code of the visit method to be used for each opcode.
+ */
+ private final static int[] TYPE;
+
+ static {
+ String s = "BBBBBBBBBBBBBBBBCCIAADDDDDAAAAAAAAAAAAAAAAAAAABBBBBBBBDD"
+ + "DDDAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
+ + "BBBBBBBBBBBBBBBBBBBJBBBBBBBBBBBBBBBBBBBBHHHHHHHHHHHHHHHHD"
+ + "KLBBBBBBFFFFGGGGAECEBBEEBBAMHHAA";
+ TYPE = new int[s.length()];
+ for (int i = 0; i < TYPE.length; ++i) {
+ TYPE[i] = (s.charAt(i) - 'A' - 1);
+ }
+ }
+
+ // code to generate the above string
+ // public static void main (String[] args) {
+ // int[] TYPE = new int[] {
+ // 0, //NOP
+ // 0, //ACONST_NULL
+ // 0, //ICONST_M1
+ // 0, //ICONST_0
+ // 0, //ICONST_1
+ // 0, //ICONST_2
+ // 0, //ICONST_3
+ // 0, //ICONST_4
+ // 0, //ICONST_5
+ // 0, //LCONST_0
+ // 0, //LCONST_1
+ // 0, //FCONST_0
+ // 0, //FCONST_1
+ // 0, //FCONST_2
+ // 0, //DCONST_0
+ // 0, //DCONST_1
+ // 1, //BIPUSH
+ // 1, //SIPUSH
+ // 7, //LDC
+ // -1, //LDC_W
+ // -1, //LDC2_W
+ // 2, //ILOAD
+ // 2, //LLOAD
+ // 2, //FLOAD
+ // 2, //DLOAD
+ // 2, //ALOAD
+ // -1, //ILOAD_0
+ // -1, //ILOAD_1
+ // -1, //ILOAD_2
+ // -1, //ILOAD_3
+ // -1, //LLOAD_0
+ // -1, //LLOAD_1
+ // -1, //LLOAD_2
+ // -1, //LLOAD_3
+ // -1, //FLOAD_0
+ // -1, //FLOAD_1
+ // -1, //FLOAD_2
+ // -1, //FLOAD_3
+ // -1, //DLOAD_0
+ // -1, //DLOAD_1
+ // -1, //DLOAD_2
+ // -1, //DLOAD_3
+ // -1, //ALOAD_0
+ // -1, //ALOAD_1
+ // -1, //ALOAD_2
+ // -1, //ALOAD_3
+ // 0, //IALOAD
+ // 0, //LALOAD
+ // 0, //FALOAD
+ // 0, //DALOAD
+ // 0, //AALOAD
+ // 0, //BALOAD
+ // 0, //CALOAD
+ // 0, //SALOAD
+ // 2, //ISTORE
+ // 2, //LSTORE
+ // 2, //FSTORE
+ // 2, //DSTORE
+ // 2, //ASTORE
+ // -1, //ISTORE_0
+ // -1, //ISTORE_1
+ // -1, //ISTORE_2
+ // -1, //ISTORE_3
+ // -1, //LSTORE_0
+ // -1, //LSTORE_1
+ // -1, //LSTORE_2
+ // -1, //LSTORE_3
+ // -1, //FSTORE_0
+ // -1, //FSTORE_1
+ // -1, //FSTORE_2
+ // -1, //FSTORE_3
+ // -1, //DSTORE_0
+ // -1, //DSTORE_1
+ // -1, //DSTORE_2
+ // -1, //DSTORE_3
+ // -1, //ASTORE_0
+ // -1, //ASTORE_1
+ // -1, //ASTORE_2
+ // -1, //ASTORE_3
+ // 0, //IASTORE
+ // 0, //LASTORE
+ // 0, //FASTORE
+ // 0, //DASTORE
+ // 0, //AASTORE
+ // 0, //BASTORE
+ // 0, //CASTORE
+ // 0, //SASTORE
+ // 0, //POP
+ // 0, //POP2
+ // 0, //DUP
+ // 0, //DUP_X1
+ // 0, //DUP_X2
+ // 0, //DUP2
+ // 0, //DUP2_X1
+ // 0, //DUP2_X2
+ // 0, //SWAP
+ // 0, //IADD
+ // 0, //LADD
+ // 0, //FADD
+ // 0, //DADD
+ // 0, //ISUB
+ // 0, //LSUB
+ // 0, //FSUB
+ // 0, //DSUB
+ // 0, //IMUL
+ // 0, //LMUL
+ // 0, //FMUL
+ // 0, //DMUL
+ // 0, //IDIV
+ // 0, //LDIV
+ // 0, //FDIV
+ // 0, //DDIV
+ // 0, //IREM
+ // 0, //LREM
+ // 0, //FREM
+ // 0, //DREM
+ // 0, //INEG
+ // 0, //LNEG
+ // 0, //FNEG
+ // 0, //DNEG
+ // 0, //ISHL
+ // 0, //LSHL
+ // 0, //ISHR
+ // 0, //LSHR
+ // 0, //IUSHR
+ // 0, //LUSHR
+ // 0, //IAND
+ // 0, //LAND
+ // 0, //IOR
+ // 0, //LOR
+ // 0, //IXOR
+ // 0, //LXOR
+ // 8, //IINC
+ // 0, //I2L
+ // 0, //I2F
+ // 0, //I2D
+ // 0, //L2I
+ // 0, //L2F
+ // 0, //L2D
+ // 0, //F2I
+ // 0, //F2L
+ // 0, //F2D
+ // 0, //D2I
+ // 0, //D2L
+ // 0, //D2F
+ // 0, //I2B
+ // 0, //I2C
+ // 0, //I2S
+ // 0, //LCMP
+ // 0, //FCMPL
+ // 0, //FCMPG
+ // 0, //DCMPL
+ // 0, //DCMPG
+ // 6, //IFEQ
+ // 6, //IFNE
+ // 6, //IFLT
+ // 6, //IFGE
+ // 6, //IFGT
+ // 6, //IFLE
+ // 6, //IF_ICMPEQ
+ // 6, //IF_ICMPNE
+ // 6, //IF_ICMPLT
+ // 6, //IF_ICMPGE
+ // 6, //IF_ICMPGT
+ // 6, //IF_ICMPLE
+ // 6, //IF_ACMPEQ
+ // 6, //IF_ACMPNE
+ // 6, //GOTO
+ // 6, //JSR
+ // 2, //RET
+ // 9, //TABLESWITCH
+ // 10, //LOOKUPSWITCH
+ // 0, //IRETURN
+ // 0, //LRETURN
+ // 0, //FRETURN
+ // 0, //DRETURN
+ // 0, //ARETURN
+ // 0, //RETURN
+ // 4, //GETSTATIC
+ // 4, //PUTSTATIC
+ // 4, //GETFIELD
+ // 4, //PUTFIELD
+ // 5, //INVOKEVIRTUAL
+ // 5, //INVOKESPECIAL
+ // 5, //INVOKESTATIC
+ // 5, //INVOKEINTERFACE
+ // -1, //UNUSED
+ // 3, //NEW
+ // 1, //NEWARRAY
+ // 3, //ANEWARRAY
+ // 0, //ARRAYLENGTH
+ // 0, //ATHROW
+ // 3, //CHECKCAST
+ // 3, //INSTANCEOF
+ // 0, //MONITORENTER
+ // 0, //MONITOREXIT
+ // -1, //WIDE
+ // 11, //MULTIANEWARRAY
+ // 6, //IFNULL
+ // 6, //IFNONNULL
+ // -1, //GOTO_W
+ // -1 //JSR_W
+ // };
+ // for (int i = 0; i < TYPE.length; ++i) {
+ // System.out.print((char)(TYPE[i] + 1 + 'A'));
+ // }
+ // System.out.println();
+ // }
+
+ /**
+ * Constructs a new {@link CheckMethodAdapter} object.
+ *
+ * @param cv the code visitor to which this adapter must delegate calls.
+ */
+ public CheckMethodAdapter(final MethodVisitor cv) {
+ super(cv);
+ this.labels = new HashMap();
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ checkEndMethod();
+ checkDesc(desc, false);
+ return new CheckAnnotationAdapter(mv.visitAnnotation(desc, visible));
+ }
+
+ public AnnotationVisitor visitAnnotationDefault() {
+ checkEndMethod();
+ return new CheckAnnotationAdapter(mv.visitAnnotationDefault(), false);
+ }
+
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter,
+ final String desc,
+ final boolean visible)
+ {
+ checkEndMethod();
+ checkDesc(desc, false);
+ return new CheckAnnotationAdapter(mv.visitParameterAnnotation(parameter,
+ desc,
+ visible));
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ checkEndMethod();
+ if (attr == null) {
+ throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ }
+ mv.visitAttribute(attr);
+ }
+
+ public void visitCode() {
+ startCode = true;
+ mv.visitCode();
+ }
+
+ public void visitInsn(final int opcode) {
+ checkStartCode();
+ checkEndCode();
+ checkOpcode(opcode, 0);
+ mv.visitInsn(opcode);
+ }
+
+ public void visitIntInsn(final int opcode, final int operand) {
+ checkStartCode();
+ checkEndCode();
+ checkOpcode(opcode, 1);
+ switch (opcode) {
+ case Opcodes.BIPUSH:
+ checkSignedByte(operand, "Invalid operand");
+ break;
+ case Opcodes.SIPUSH:
+ checkSignedShort(operand, "Invalid operand");
+ break;
+ // case Constants.NEWARRAY:
+ default:
+ if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
+ throw new IllegalArgumentException("Invalid operand (must be an array type code T_...): "
+ + operand);
+ }
+ }
+ mv.visitIntInsn(opcode, operand);
+ }
+
+ public void visitVarInsn(final int opcode, final int var) {
+ checkStartCode();
+ checkEndCode();
+ checkOpcode(opcode, 2);
+ checkUnsignedShort(var, "Invalid variable index");
+ mv.visitVarInsn(opcode, var);
+ }
+
+ public void visitTypeInsn(final int opcode, final String desc) {
+ checkStartCode();
+ checkEndCode();
+ checkOpcode(opcode, 3);
+ if (desc != null && desc.length() > 0 && desc.charAt(0) == '[') {
+ checkDesc(desc, false);
+ } else {
+ checkInternalName(desc, "type");
+ }
+ if (opcode == Opcodes.NEW && desc.charAt(0) == '[') {
+ throw new IllegalArgumentException("NEW cannot be used to create arrays: "
+ + desc);
+ }
+ mv.visitTypeInsn(opcode, desc);
+ }
+
+ public void visitFieldInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ checkStartCode();
+ checkEndCode();
+ checkOpcode(opcode, 4);
+ checkInternalName(owner, "owner");
+ checkIdentifier(name, "name");
+ checkDesc(desc, false);
+ mv.visitFieldInsn(opcode, owner, name, desc);
+ }
+
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ checkStartCode();
+ checkEndCode();
+ checkOpcode(opcode, 5);
+ checkMethodIdentifier(name, "name");
+ if (!name.equals("clone")) {
+ // In JDK1.5, clone method can be called on array class descriptors
+ checkInternalName(owner, "owner");
+ }
+ checkMethodDesc(desc);
+ mv.visitMethodInsn(opcode, owner, name, desc);
+ }
+
+ public void visitJumpInsn(final int opcode, final Label label) {
+ checkStartCode();
+ checkEndCode();
+ checkOpcode(opcode, 6);
+ checkLabel(label, false, "label");
+ mv.visitJumpInsn(opcode, label);
+ }
+
+ public void visitLabel(final Label label) {
+ checkStartCode();
+ checkEndCode();
+ checkLabel(label, false, "label");
+ if (labels.get(label) != null) {
+ throw new IllegalArgumentException("Already visited label");
+ } else {
+ labels.put(label, new Integer(labels.size()));
+ }
+ mv.visitLabel(label);
+ }
+
+ public void visitLdcInsn(final Object cst) {
+ checkStartCode();
+ checkEndCode();
+ if (!(cst instanceof Type)) {
+ checkConstant(cst);
+ }
+ mv.visitLdcInsn(cst);
+ }
+
+ public void visitIincInsn(final int var, final int increment) {
+ checkStartCode();
+ checkEndCode();
+ checkUnsignedShort(var, "Invalid variable index");
+ checkSignedShort(increment, "Invalid increment");
+ mv.visitIincInsn(var, increment);
+ }
+
+ public void visitTableSwitchInsn(
+ final int min,
+ final int max,
+ final Label dflt,
+ final Label labels[])
+ {
+ checkStartCode();
+ checkEndCode();
+ if (max < min) {
+ throw new IllegalArgumentException("Max = " + max
+ + " must be greater than or equal to min = " + min);
+ }
+ checkLabel(dflt, false, "default label");
+ if (labels == null || labels.length != max - min + 1) {
+ throw new IllegalArgumentException("There must be max - min + 1 labels");
+ }
+ for (int i = 0; i < labels.length; ++i) {
+ checkLabel(labels[i], false, "label at index " + i);
+ }
+ mv.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+
+ public void visitLookupSwitchInsn(
+ final Label dflt,
+ final int keys[],
+ final Label labels[])
+ {
+ checkEndCode();
+ checkStartCode();
+ checkLabel(dflt, false, "default label");
+ if (keys == null || labels == null || keys.length != labels.length) {
+ throw new IllegalArgumentException("There must be the same number of keys and labels");
+ }
+ for (int i = 0; i < labels.length; ++i) {
+ checkLabel(labels[i], false, "label at index " + i);
+ }
+ mv.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+
+ public void visitMultiANewArrayInsn(final String desc, final int dims) {
+ checkStartCode();
+ checkEndCode();
+ checkDesc(desc, false);
+ if (desc.charAt(0) != '[') {
+ throw new IllegalArgumentException("Invalid descriptor (must be an array type descriptor): "
+ + desc);
+ }
+ if (dims < 1) {
+ throw new IllegalArgumentException("Invalid dimensions (must be greater than 0): "
+ + dims);
+ }
+ if (dims > desc.lastIndexOf('[') + 1) {
+ throw new IllegalArgumentException("Invalid dimensions (must not be greater than dims(desc)): "
+ + dims);
+ }
+ mv.visitMultiANewArrayInsn(desc, dims);
+ }
+
+ public void visitTryCatchBlock(
+ final Label start,
+ final Label end,
+ final Label handler,
+ final String type)
+ {
+ checkStartCode();
+ checkEndCode();
+ if (type != null) {
+ checkInternalName(type, "type");
+ }
+ mv.visitTryCatchBlock(start, end, handler, type);
+ }
+
+ public void visitLocalVariable(
+ final String name,
+ final String desc,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index)
+ {
+ checkStartCode();
+ checkEndCode();
+ checkIdentifier(name, "name");
+ checkDesc(desc, false);
+ checkLabel(start, true, "start label");
+ checkLabel(end, true, "end label");
+ checkUnsignedShort(index, "Invalid variable index");
+ int s = ((Integer) labels.get(start)).intValue();
+ int e = ((Integer) labels.get(end)).intValue();
+ if (e < s) {
+ throw new IllegalArgumentException("Invalid start and end labels (end must be greater than start)");
+ }
+ mv.visitLocalVariable(name, desc, signature, start, end, index);
+ }
+
+ public void visitLineNumber(final int line, final Label start) {
+ checkStartCode();
+ checkEndCode();
+ checkUnsignedShort(line, "Invalid line number");
+ checkLabel(start, true, "start label");
+ mv.visitLineNumber(line, start);
+ }
+
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ checkStartCode();
+ checkEndCode();
+ endCode = true;
+ checkUnsignedShort(maxStack, "Invalid max stack");
+ checkUnsignedShort(maxLocals, "Invalid max locals");
+ mv.visitMaxs(maxStack, maxLocals);
+ }
+
+ public void visitEnd() {
+ checkEndMethod();
+ endMethod = true;
+ mv.visitEnd();
+ }
+
+ // -------------------------------------------------------------------------
+
+ /**
+ * Checks that the visitCode method has been called.
+ */
+ void checkStartCode() {
+ if (!startCode) {
+ throw new IllegalStateException("Cannot visit instructions before visitCode has been called.");
+ }
+ }
+
+ /**
+ * Checks that the visitMaxs method has not been called.
+ */
+ void checkEndCode() {
+ if (endCode) {
+ throw new IllegalStateException("Cannot visit instructions after visitMaxs has been called.");
+ }
+ }
+
+ /**
+ * Checks that the visitEnd method has not been called.
+ */
+ void checkEndMethod() {
+ if (endMethod) {
+ throw new IllegalStateException("Cannot visit elements after visitEnd has been called.");
+ }
+ }
+
+ /**
+ * Checks that the type of the given opcode is equal to the given type.
+ *
+ * @param opcode the opcode to be checked.
+ * @param type the expected opcode type.
+ */
+ static void checkOpcode(final int opcode, final int type) {
+ if (opcode < 0 || opcode > 199 || TYPE[opcode] != type) {
+ throw new IllegalArgumentException("Invalid opcode: " + opcode);
+ }
+ }
+
+ /**
+ * Checks that the given value is a signed byte.
+ *
+ * @param value the value to be checked.
+ * @param msg an message to be used in case of error.
+ */
+ static void checkSignedByte(final int value, final String msg) {
+ if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
+ throw new IllegalArgumentException(msg
+ + " (must be a signed byte): " + value);
+ }
+ }
+
+ /**
+ * Checks that the given value is a signed short.
+ *
+ * @param value the value to be checked.
+ * @param msg an message to be used in case of error.
+ */
+ static void checkSignedShort(final int value, final String msg) {
+ if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
+ throw new IllegalArgumentException(msg
+ + " (must be a signed short): " + value);
+ }
+ }
+
+ /**
+ * Checks that the given value is an unsigned short.
+ *
+ * @param value the value to be checked.
+ * @param msg an message to be used in case of error.
+ */
+ static void checkUnsignedShort(final int value, final String msg) {
+ if (value < 0 || value > 65535) {
+ throw new IllegalArgumentException(msg
+ + " (must be an unsigned short): " + value);
+ }
+ }
+
+ /**
+ * Checks that the given value is an {@link Integer}, a{@link Float}, a
+ * {@link Long}, a {@link Double} or a {@link String}.
+ *
+ * @param cst the value to be checked.
+ */
+ static void checkConstant(final Object cst) {
+ if (!(cst instanceof Integer) && !(cst instanceof Float)
+ && !(cst instanceof Long) && !(cst instanceof Double)
+ && !(cst instanceof String))
+ {
+ throw new IllegalArgumentException("Invalid constant: " + cst);
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid Java identifier.
+ *
+ * @param name the string to be checked.
+ * @param msg a message to be used in case of error.
+ */
+ static void checkIdentifier(final String name, final String msg) {
+ checkIdentifier(name, 0, -1, msg);
+ }
+
+ /**
+ * Checks that the given substring is a valid Java identifier.
+ *
+ * @param name the string to be checked.
+ * @param start index of the first character of the identifier (inclusive).
+ * @param end index of the last character of the identifier (exclusive). -1
+ * is equivalent to <tt>name.length()</tt> if name is not
+ * <tt>null</tt>.
+ * @param msg a message to be used in case of error.
+ */
+ static void checkIdentifier(
+ final String name,
+ final int start,
+ final int end,
+ final String msg)
+ {
+ if (name == null || (end == -1 ? name.length() <= start : end <= start))
+ {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not be null or empty)");
+ }
+ if (!Character.isJavaIdentifierStart(name.charAt(start))) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must be a valid Java identifier): " + name);
+ }
+ int max = (end == -1 ? name.length() : end);
+ for (int i = start + 1; i < max; ++i) {
+ if (!Character.isJavaIdentifierPart(name.charAt(i))) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must be a valid Java identifier): " + name);
+ }
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid Java identifier or is equal to
+ * '&lt;init&gt;' or '&lt;clinit&gt;'.
+ *
+ * @param name the string to be checked.
+ * @param msg a message to be used in case of error.
+ */
+ static void checkMethodIdentifier(final String name, final String msg) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not be null or empty)");
+ }
+ if (name.equals("<init>") || name.equals("<clinit>")) {
+ return;
+ }
+ if (!Character.isJavaIdentifierStart(name.charAt(0))) {
+ throw new IllegalArgumentException("Invalid "
+ + msg
+ + " (must be a '<init>', '<clinit>' or a valid Java identifier): "
+ + name);
+ }
+ for (int i = 1; i < name.length(); ++i) {
+ if (!Character.isJavaIdentifierPart(name.charAt(i))) {
+ throw new IllegalArgumentException("Invalid "
+ + msg
+ + " (must be '<init>' or '<clinit>' or a valid Java identifier): "
+ + name);
+ }
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid internal class name.
+ *
+ * @param name the string to be checked.
+ * @param msg a message to be used in case of error.
+ */
+ static void checkInternalName(final String name, final String msg) {
+ checkInternalName(name, 0, -1, msg);
+ }
+
+ /**
+ * Checks that the given substring is a valid internal class name.
+ *
+ * @param name the string to be checked.
+ * @param start index of the first character of the identifier (inclusive).
+ * @param end index of the last character of the identifier (exclusive). -1
+ * is equivalent to <tt>name.length()</tt> if name is not
+ * <tt>null</tt>.
+ * @param msg a message to be used in case of error.
+ */
+ static void checkInternalName(
+ final String name,
+ final int start,
+ final int end,
+ final String msg)
+ {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not be null or empty)");
+ }
+ int max = (end == -1 ? name.length() : end);
+ try {
+ int begin = start;
+ int slash;
+ do {
+ slash = name.indexOf('/', begin + 1);
+ if (slash == -1 || slash > max) {
+ slash = max;
+ }
+ checkIdentifier(name, begin, slash, null);
+ begin = slash + 1;
+ } while (slash != max);
+ } catch (IllegalArgumentException _) {
+ throw new IllegalArgumentException("Invalid "
+ + msg
+ + " (must be a fully qualified class name in internal form): "
+ + name);
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid type descriptor.
+ *
+ * @param desc the string to be checked.
+ * @param canBeVoid <tt>true</tt> if <tt>V</tt> can be considered valid.
+ */
+ static void checkDesc(final String desc, final boolean canBeVoid) {
+ int end = checkDesc(desc, 0, canBeVoid);
+ if (end != desc.length()) {
+ throw new IllegalArgumentException("Invalid descriptor: " + desc);
+ }
+ }
+
+ /**
+ * Checks that a the given substring is a valid type descriptor.
+ *
+ * @param desc the string to be checked.
+ * @param start index of the first character of the identifier (inclusive).
+ * @param canBeVoid <tt>true</tt> if <tt>V</tt> can be considered valid.
+ * @return the index of the last character of the type decriptor, plus one.
+ */
+ static int checkDesc(
+ final String desc,
+ final int start,
+ final boolean canBeVoid)
+ {
+ if (desc == null || start >= desc.length()) {
+ throw new IllegalArgumentException("Invalid type descriptor (must not be null or empty)");
+ }
+ int index;
+ switch (desc.charAt(start)) {
+ case 'V':
+ if (canBeVoid) {
+ return start + 1;
+ } else {
+ throw new IllegalArgumentException("Invalid descriptor: "
+ + desc);
+ }
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ case 'F':
+ case 'J':
+ case 'D':
+ return start + 1;
+ case '[':
+ index = start + 1;
+ while (index < desc.length() && desc.charAt(index) == '[') {
+ ++index;
+ }
+ if (index < desc.length()) {
+ return checkDesc(desc, index, false);
+ } else {
+ throw new IllegalArgumentException("Invalid descriptor: "
+ + desc);
+ }
+ case 'L':
+ index = desc.indexOf(';', start);
+ if (index == -1 || index - start < 2) {
+ throw new IllegalArgumentException("Invalid descriptor: "
+ + desc);
+ }
+ try {
+ checkInternalName(desc, start + 1, index, null);
+ } catch (IllegalArgumentException _) {
+ throw new IllegalArgumentException("Invalid descriptor: "
+ + desc);
+ }
+ return index + 1;
+ default:
+ throw new IllegalArgumentException("Invalid descriptor: "
+ + desc);
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid method descriptor.
+ *
+ * @param desc the string to be checked.
+ */
+ static void checkMethodDesc(final String desc) {
+ if (desc == null || desc.length() == 0) {
+ throw new IllegalArgumentException("Invalid method descriptor (must not be null or empty)");
+ }
+ if (desc.charAt(0) != '(' || desc.length() < 3) {
+ throw new IllegalArgumentException("Invalid descriptor: " + desc);
+ }
+ int start = 1;
+ if (desc.charAt(start) != ')') {
+ do {
+ if (desc.charAt(start) == 'V') {
+ throw new IllegalArgumentException("Invalid descriptor: "
+ + desc);
+ }
+ start = checkDesc(desc, start, false);
+ } while (start < desc.length() && desc.charAt(start) != ')');
+ }
+ start = checkDesc(desc, start + 1, true);
+ if (start != desc.length()) {
+ throw new IllegalArgumentException("Invalid descriptor: " + desc);
+ }
+ }
+
+ /**
+ * Checks that the given label is not null. This method can also check that
+ * the label has been visited.
+ *
+ * @param label the label to be checked.
+ * @param checkVisited <tt>true</tt> to check that the label has been
+ * visited.
+ * @param msg a message to be used in case of error.
+ */
+ void checkLabel(
+ final Label label,
+ final boolean checkVisited,
+ final String msg)
+ {
+ if (label == null) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must not be null)");
+ }
+ if (checkVisited && labels.get(label) == null) {
+ throw new IllegalArgumentException("Invalid " + msg
+ + " (must be visited first)");
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/TraceAbstractVisitor.java b/tools/external/asm/org/objectweb/asm/util/TraceAbstractVisitor.java
new file mode 100644
index 000000000..4250c815c
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/TraceAbstractVisitor.java
@@ -0,0 +1,180 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.util.attrs.Traceable;
+
+/**
+ * An abstract trace visitor.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class TraceAbstractVisitor extends AbstractVisitor {
+
+ /**
+ * Constant used in {@link #appendDescriptor appendDescriptor} for internal
+ * type names in bytecode notation.
+ */
+ public final static int INTERNAL_NAME = 0;
+
+ /**
+ * Constant used in {@link #appendDescriptor appendDescriptor} for field
+ * descriptors, formatted in bytecode notation
+ */
+ public final static int FIELD_DESCRIPTOR = 1;
+
+ /**
+ * Constant used in {@link #appendDescriptor appendDescriptor} for field
+ * signatures, formatted in bytecode notation
+ */
+ public final static int FIELD_SIGNATURE = 2;
+
+ /**
+ * Constant used in {@link #appendDescriptor appendDescriptor} for method
+ * descriptors, formatted in bytecode notation
+ */
+ public final static int METHOD_DESCRIPTOR = 3;
+
+ /**
+ * Constant used in {@link #appendDescriptor appendDescriptor} for method
+ * signatures, formatted in bytecode notation
+ */
+ public final static int METHOD_SIGNATURE = 4;
+
+ /**
+ * Constant used in {@link #appendDescriptor appendDescriptor} for class
+ * signatures, formatted in bytecode notation
+ */
+ public final static 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 final static int TYPE_DECLARATION = 6;
+
+ /**
+ * Constant used in {@link #appendDescriptor appendDescriptor} for class
+ * signatures, formatted in default Java notation (non-bytecode)
+ */
+ public final static int CLASS_DECLARATION = 7;
+
+ /**
+ * Constant used in {@link #appendDescriptor appendDescriptor} for method
+ * parameter signatures, formatted in default Java notation (non-bytecode)
+ */
+ public final static int PARAMETERS_DECLARATION = 8;
+
+ /**
+ * Tab for class members.
+ */
+ protected String tab = " ";
+
+ /**
+ * 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 AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ buf.setLength(0);
+ buf.append(tab).append('@');
+ appendDescriptor(FIELD_DESCRIPTOR, desc);
+ buf.append('(');
+ text.add(buf.toString());
+ TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
+ text.add(tav.getText());
+ text.add(visible ? ")\n" : ") // invisible\n");
+ return tav;
+ }
+
+ /**
+ * 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 Traceable) {
+ ((Traceable) attr).trace(buf, null);
+ } else {
+ buf.append(" : ").append(attr.toString()).append("\n");
+ }
+
+ text.add(buf.toString());
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void visitEnd() {
+ // does nothing
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ protected TraceAnnotationVisitor createTraceAnnotationVisitor() {
+ return new TraceAnnotationVisitor();
+ }
+
+ /**
+ * 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);
+ }
+ }
+
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/TraceAnnotationVisitor.java b/tools/external/asm/org/objectweb/asm/util/TraceAnnotationVisitor.java
new file mode 100644
index 000000000..827225b1c
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/TraceAnnotationVisitor.java
@@ -0,0 +1,272 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+
+/**
+ * An {@link AnnotationVisitor} that prints a disassembled view of the
+ * annotations it visits.
+ *
+ * @author Eric Bruneton
+ */
+public class TraceAnnotationVisitor extends TraceAbstractVisitor implements
+ AnnotationVisitor
+{
+
+ /**
+ * The {@link AnnotationVisitor} to which this visitor delegates calls. May
+ * be <tt>null</tt>.
+ */
+ protected AnnotationVisitor av;
+
+ private int valueNumber = 0;
+
+ /**
+ * Constructs a new {@link TraceAnnotationVisitor}.
+ */
+ public TraceAnnotationVisitor() {
+ // ignore
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the AnnotationVisitor interface
+ // ------------------------------------------------------------------------
+
+ 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('}');
+ } else {
+ buf.append(value);
+ }
+
+ text.add(buf.toString());
+
+ if (av != null) {
+ av.visit(name, value);
+ }
+ }
+
+ private void visitInt(int value) {
+ buf.append(value);
+ }
+
+ private void visitLong(long value) {
+ buf.append(value).append('L');
+ }
+
+ private void visitFloat(float value) {
+ buf.append(value).append('F');
+ }
+
+ private void visitDouble(double value) {
+ buf.append(value).append('D');
+ }
+
+ private void visitChar(char value) {
+ buf.append("(char)").append((int) value);
+ }
+
+ private void visitShort(short value) {
+ buf.append("(short)").append(value);
+ }
+
+ private void visitByte(byte value) {
+ buf.append("(byte)").append(value);
+ }
+
+ private void visitBoolean(boolean value) {
+ buf.append(value);
+ }
+
+ private void visitString(String value) {
+ appendString(buf, value);
+ }
+
+ private void visitType(Type value) {
+ buf.append(value.getClassName()).append(".class");
+ }
+
+ 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());
+
+ if (av != null) {
+ av.visitEnum(name, desc, value);
+ }
+ }
+
+ public AnnotationVisitor 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());
+ TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
+ text.add(tav.getText());
+ text.add(")");
+ if (av != null) {
+ tav.av = av.visitAnnotation(name, desc);
+ }
+ return tav;
+ }
+
+ public AnnotationVisitor visitArray(final String name) {
+ buf.setLength(0);
+ appendComa(valueNumber++);
+ if (name != null) {
+ buf.append(name).append('=');
+ }
+ buf.append('{');
+ text.add(buf.toString());
+ TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
+ text.add(tav.getText());
+ text.add("}");
+ if (av != null) {
+ tav.av = av.visitArray(name);
+ }
+ return tav;
+ }
+
+ public void visitEnd() {
+ if (av != null) {
+ av.visitEnd();
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ protected TraceAnnotationVisitor createTraceAnnotationVisitor() {
+ return new TraceAnnotationVisitor();
+ }
+
+ private void appendComa(int i) {
+ if (i != 0) {
+ buf.append(", ");
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/TraceClassVisitor.java b/tools/external/asm/org/objectweb/asm/util/TraceClassVisitor.java
new file mode 100644
index 000000000..9a727e50f
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/TraceClassVisitor.java
@@ -0,0 +1,534 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.io.FileInputStream;
+import java.io.PrintWriter;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.signature.SignatureReader;
+
+/**
+ * A {@link ClassVisitor} 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: <p> <blockquote>
+ *
+ * <pre>
+ * // class version 49.0 (49)
+ * // access flags 33
+ * public class Hello {
+ *
+ * // compiled from: Hello.java
+ *
+ * // access flags 1
+ * public &lt;init&gt; ()V
+ * ALOAD 0
+ * INVOKESPECIAL java/lang/Object &lt;init&gt; ()V
+ * RETURN
+ * MAXSTACK = 1
+ * MAXLOCALS = 1
+ *
+ * // access flags 9
+ * public static main ([Ljava/lang/String;)V
+ * GETSTATIC java/lang/System out Ljava/io/PrintStream;
+ * LDC &quot;hello&quot;
+ * 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(&quot;hello&quot;);
+ * }
+ * }
+ * </pre>
+ *
+ * </blockquote>
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class TraceClassVisitor extends TraceAbstractVisitor implements
+ ClassVisitor
+{
+
+ /**
+ * The {@link ClassVisitor} to which this visitor delegates calls. May be
+ * <tt>null</tt>.
+ */
+ protected final ClassVisitor cv;
+
+ /**
+ * The print writer to be used to print the class.
+ */
+ protected final PrintWriter pw;
+
+ /**
+ * Prints a disassembled view of the given class to the standard output. <p>
+ * Usage: TraceClassVisitor [-debug] &lt;fully qualified class name or class
+ * file name &gt;
+ *
+ * @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;
+ boolean skipDebug = true;
+
+ boolean ok = true;
+ if (args.length < 1 || args.length > 2) {
+ ok = false;
+ }
+ if (ok && args[0].equals("-debug")) {
+ i = 1;
+ skipDebug = false;
+ if (args.length != 2) {
+ ok = false;
+ }
+ }
+ if (!ok) {
+ System.err.println("Prints a disassembled view of the given class.");
+ System.err.println("Usage: TraceClassVisitor [-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)),
+ getDefaultAttributes(),
+ skipDebug);
+ }
+
+ /**
+ * 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 = cv;
+ this.pw = pw;
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the ClassVisitor interface
+ // ------------------------------------------------------------------------
+
+ 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 ").append(access).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("enum ");
+ } else {
+ buf.append("class ");
+ }
+ appendDescriptor(INTERNAL_NAME, name);
+
+ if (superName != null && !superName.equals("java/lang/Object")) {
+ 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());
+
+ if (cv != null) {
+ cv.visit(version, access, name, signature, superName, interfaces);
+ }
+ }
+
+ 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());
+ }
+
+ if (cv != null) {
+ cv.visitSource(file, debug);
+ }
+ }
+
+ public void visitOuterClass(
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ buf.append(tab).append("OUTERCLASS ");
+ appendDescriptor(INTERNAL_NAME, owner);
+ // if enclosing name is null, so why should we show this info?
+ if (name != null) {
+ buf.append(' ').append(name).append(' ');
+ } else {
+ buf.append(' ');
+ }
+ appendDescriptor(METHOD_DESCRIPTOR, desc);
+ buf.append('\n');
+ text.add(buf.toString());
+
+ if (cv != null) {
+ cv.visitOuterClass(owner, name, desc);
+ }
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ text.add("\n");
+ AnnotationVisitor tav = super.visitAnnotation(desc, visible);
+ if (cv != null) {
+ ((TraceAnnotationVisitor) tav).av = cv.visitAnnotation(desc,
+ visible);
+ }
+ return tav;
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ text.add("\n");
+ super.visitAttribute(attr);
+
+ if (cv != null) {
+ cv.visitAttribute(attr);
+ }
+ }
+
+ public void visitInnerClass(
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ buf.setLength(0);
+ buf.append(tab).append("// access flags ").append(access
+ & ~Opcodes.ACC_SUPER).append('\n');
+ buf.append(tab);
+ appendAccess(access);
+ buf.append("INNERCLASS ");
+ if ((access & Opcodes.ACC_ENUM) != 0) {
+ buf.append("enum ");
+ }
+ appendDescriptor(INTERNAL_NAME, name);
+ buf.append(' ');
+ appendDescriptor(INTERNAL_NAME, outerName);
+ buf.append(' ');
+ appendDescriptor(INTERNAL_NAME, innerName);
+ buf.append('\n');
+ text.add(buf.toString());
+
+ if (cv != null) {
+ cv.visitInnerClass(name, outerName, innerName, access);
+ }
+ }
+
+ public FieldVisitor 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 ").append(access).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);
+ if ((access & Opcodes.ACC_ENUM) != 0) {
+ buf.append("enum ");
+ }
+
+ 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());
+
+ TraceFieldVisitor tav = createTraceFieldVisitor();
+ text.add(tav.getText());
+
+ if (cv != null) {
+ tav.fv = cv.visitField(access, name, desc, signature, value);
+ }
+
+ return tav;
+ }
+
+ public MethodVisitor 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 ").append(access).append('\n');
+ buf.append(tab);
+ appendDescriptor(METHOD_SIGNATURE, signature);
+
+ if (signature != null) {
+ 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');
+ }
+
+ 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());
+
+ TraceMethodVisitor tcv = createTraceMethodVisitor();
+ text.add(tcv.getText());
+
+ if (cv != null) {
+ tcv.mv = cv.visitMethod(access, name, desc, signature, exceptions);
+ }
+
+ return tcv;
+ }
+
+ public void visitEnd() {
+ text.add("}\n");
+
+ printList(pw, text);
+ pw.flush();
+
+ if (cv != null) {
+ cv.visitEnd();
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ protected TraceFieldVisitor createTraceFieldVisitor() {
+ return new TraceFieldVisitor();
+ }
+
+ protected TraceMethodVisitor createTraceMethodVisitor() {
+ return new TraceMethodVisitor();
+ }
+
+ /**
+ * 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 & Constants.ACC_NATIVE) != 0) {
+ // buf.append("native ");
+ // }
+ 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 ");
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/TraceFieldVisitor.java b/tools/external/asm/org/objectweb/asm/util/TraceFieldVisitor.java
new file mode 100644
index 000000000..7546a3c92
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/TraceFieldVisitor.java
@@ -0,0 +1,78 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.FieldVisitor;
+
+/**
+ * A {@link FieldVisitor} that prints a disassembled view of the fields it
+ * visits.
+ *
+ * @author Eric Bruneton
+ */
+public class TraceFieldVisitor extends TraceAbstractVisitor implements
+ FieldVisitor
+{
+
+ /**
+ * The {@link FieldVisitor} to which this visitor delegates calls. May be
+ * <tt>null</tt>.
+ */
+ protected FieldVisitor fv;
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ AnnotationVisitor av = super.visitAnnotation(desc, visible);
+ if (fv != null) {
+ ((TraceAnnotationVisitor) av).av = fv.visitAnnotation(desc, visible);
+ }
+ return av;
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ super.visitAttribute(attr);
+
+ if (fv != null) {
+ fv.visitAttribute(attr);
+ }
+ }
+
+ public void visitEnd() {
+ super.visitEnd();
+
+ if (fv != null) {
+ fv.visitEnd();
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/TraceMethodVisitor.java b/tools/external/asm/org/objectweb/asm/util/TraceMethodVisitor.java
new file mode 100644
index 000000000..899f52ea7
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/TraceMethodVisitor.java
@@ -0,0 +1,486 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.signature.SignatureReader;
+import org.objectweb.asm.util.attrs.Traceable;
+
+import java.util.HashMap;
+
+/**
+ * A {@link MethodVisitor} that prints a disassembled view of the methods it
+ * visits.
+ *
+ * @author Eric Bruneton
+ */
+public class TraceMethodVisitor extends TraceAbstractVisitor implements
+ MethodVisitor
+{
+
+ /**
+ * The {@link MethodVisitor} to which this visitor delegates calls. May be
+ * <tt>null</tt>.
+ */
+ protected MethodVisitor mv;
+
+ /**
+ * 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 final HashMap labelNames;
+
+ /**
+ * Constructs a new {@link TraceMethodVisitor}.
+ */
+ public TraceMethodVisitor() {
+ this(null);
+ }
+
+ /**
+ * Constructs a new {@link TraceMethodVisitor}.
+ *
+ * @param mv the {@link MethodVisitor} to which this visitor delegates
+ * calls. May be <tt>null</tt>.
+ */
+ public TraceMethodVisitor(final MethodVisitor mv) {
+ this.labelNames = new HashMap();
+ this.mv = mv;
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the MethodVisitor interface
+ // ------------------------------------------------------------------------
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ AnnotationVisitor av = super.visitAnnotation(desc, visible);
+ if (mv != null) {
+ ((TraceAnnotationVisitor) av).av = mv.visitAnnotation(desc, visible);
+ }
+ return av;
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ buf.setLength(0);
+ buf.append(tab).append("ATTRIBUTE ");
+ appendDescriptor(-1, attr.type);
+
+ if (attr instanceof Traceable) {
+ ((Traceable) attr).trace(buf, labelNames);
+ } else {
+ buf.append(" : ").append(attr.toString()).append("\n");
+ }
+
+ text.add(buf.toString());
+ if (mv != null) {
+ mv.visitAttribute(attr);
+ }
+ }
+
+ public AnnotationVisitor visitAnnotationDefault() {
+ text.add(tab2 + "default=");
+ TraceAnnotationVisitor tav = new TraceAnnotationVisitor();
+ text.add(tav.getText());
+ text.add("\n");
+ if (mv != null) {
+ tav.av = mv.visitAnnotationDefault();
+ }
+ return tav;
+ }
+
+ public AnnotationVisitor 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());
+ TraceAnnotationVisitor tav = new TraceAnnotationVisitor();
+ text.add(tav.getText());
+ text.add(visible ? ") // parameter " : ") // invisible, parameter ");
+ text.add(new Integer(parameter));
+ text.add("\n");
+ if (mv != null) {
+ tav.av = mv.visitParameterAnnotation(parameter, desc, visible);
+ }
+ return tav;
+ }
+
+ public void visitCode() {
+ if (mv != null) {
+ mv.visitCode();
+ }
+ }
+
+ public void visitInsn(final int opcode) {
+ buf.setLength(0);
+ buf.append(tab2).append(OPCODES[opcode]).append('\n');
+ text.add(buf.toString());
+
+ if (mv != null) {
+ mv.visitInsn(opcode);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitIntInsn(opcode, operand);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitVarInsn(opcode, var);
+ }
+ }
+
+ public void visitTypeInsn(final int opcode, final String desc) {
+ buf.setLength(0);
+ buf.append(tab2).append(OPCODES[opcode]).append(' ');
+ if (desc.startsWith("[")) {
+ appendDescriptor(FIELD_DESCRIPTOR, desc);
+ } else {
+ appendDescriptor(INTERNAL_NAME, desc);
+ }
+ buf.append('\n');
+ text.add(buf.toString());
+
+ if (mv != null) {
+ mv.visitTypeInsn(opcode, desc);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitFieldInsn(opcode, owner, name, desc);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitMethodInsn(opcode, owner, name, desc);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitJumpInsn(opcode, label);
+ }
+ }
+
+ public void visitLabel(final Label label) {
+ buf.setLength(0);
+ buf.append(ltab);
+ appendLabel(label);
+ buf.append('\n');
+ text.add(buf.toString());
+
+ if (mv != null) {
+ mv.visitLabel(label);
+ }
+ }
+
+ public void visitLdcInsn(final Object cst) {
+ buf.setLength(0);
+ buf.append(tab2).append("LDC ");
+ if (cst instanceof String) {
+ AbstractVisitor.appendString(buf, (String) cst);
+ } else if (cst instanceof Type) {
+ buf.append(((Type) cst).getDescriptor() + ".class");
+ } else {
+ buf.append(cst);
+ }
+ buf.append('\n');
+ text.add(buf.toString());
+
+ if (mv != null) {
+ mv.visitLdcInsn(cst);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitIincInsn(var, increment);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitMultiANewArrayInsn(desc, dims);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitTryCatchBlock(start, end, handler, type);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitLocalVariable(name, desc, signature, start, end, index);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitLineNumber(line, start);
+ }
+ }
+
+ 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());
+
+ if (mv != null) {
+ mv.visitMaxs(maxStack, maxLocals);
+ }
+ }
+
+ public void visitEnd() {
+ super.visitEnd();
+
+ if (mv != null) {
+ mv.visitEnd();
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * 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.
+ */
+ public 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/tools/external/asm/org/objectweb/asm/util/TraceSignatureVisitor.java b/tools/external/asm/org/objectweb/asm/util/TraceSignatureVisitor.java
new file mode 100644
index 000000000..c7145c0e8
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/TraceSignatureVisitor.java
@@ -0,0 +1,300 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.Opcodes;
+import 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 class TraceSignatureVisitor implements SignatureVisitor {
+
+ private 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(int access) {
+ isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
+ this.declaration = new StringBuffer();
+ }
+
+ private TraceSignatureVisitor(StringBuffer buf) {
+ this.declaration = buf;
+ }
+
+ public void visitFormalTypeParameter(String name) {
+ declaration.append(seenFormalParameter ? ", " : "<").append(name);
+ seenFormalParameter = true;
+ seenInterfaceBound = false;
+ }
+
+ public SignatureVisitor visitClassBound() {
+ separator = " extends ";
+ startType();
+ return this;
+ }
+
+ public SignatureVisitor visitInterfaceBound() {
+ separator = seenInterfaceBound ? ", " : " extends ";
+ seenInterfaceBound = true;
+ startType();
+ return this;
+ }
+
+ public SignatureVisitor visitSuperclass() {
+ endFormals();
+ separator = " extends ";
+ startType();
+ return this;
+ }
+
+ public SignatureVisitor visitInterface() {
+ separator = seenInterface ? ", " : (isInterface
+ ? " extends "
+ : " implements ");
+ seenInterface = true;
+ startType();
+ return this;
+ }
+
+ public SignatureVisitor visitParameterType() {
+ endFormals();
+ if (!seenParameter) {
+ seenParameter = true;
+ declaration.append('(');
+ } else {
+ declaration.append(", ");
+ }
+ startType();
+ return this;
+ }
+
+ public SignatureVisitor visitReturnType() {
+ endFormals();
+ if (!seenParameter) {
+ declaration.append('(');
+ } else {
+ seenParameter = false;
+ }
+ declaration.append(')');
+ returnType = new StringBuffer();
+ return new TraceSignatureVisitor(returnType);
+ }
+
+ public SignatureVisitor visitExceptionType() {
+ if (exceptions == null) {
+ exceptions = new StringBuffer();
+ } else {
+ exceptions.append(", ");
+ }
+ // startType();
+ return new TraceSignatureVisitor(exceptions);
+ }
+
+ public void visitBaseType(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();
+ }
+
+ public void visitTypeVariable(String name) {
+ declaration.append(name);
+ endType();
+ }
+
+ public SignatureVisitor visitArrayType() {
+ startType();
+ arrayStack |= 1;
+ return this;
+ }
+
+ public void visitClassType(String name) {
+ if (!"java/lang/Object".equals(name)) {
+ declaration.append(separator).append(name.replace('/', '.'));
+ } else {
+ // 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 == 1 || seenParameter;
+ if (needObjectClass) {
+ declaration.append(separator).append(name.replace('/', '.'));
+ }
+ }
+ separator = "";
+ argumentStack *= 2;
+ }
+
+ public void visitInnerClassType(String name) {
+ if (argumentStack % 2 == 1) {
+ declaration.append('>');
+ }
+ argumentStack /= 2;
+ declaration.append('.');
+ declaration.append(separator).append(name.replace('/', '.'));
+ separator = "";
+ argumentStack *= 2;
+ }
+
+ public void visitTypeArgument() {
+ if (argumentStack % 2 == 0) {
+ ++argumentStack;
+ declaration.append('<');
+ } else {
+ declaration.append(", ");
+ }
+ declaration.append('?');
+ }
+
+ public SignatureVisitor visitTypeArgument(char tag) {
+ if (argumentStack % 2 == 0) {
+ ++argumentStack;
+ declaration.append('<');
+ } else {
+ declaration.append(", ");
+ }
+
+ if (tag == SignatureVisitor.EXTENDS) {
+ declaration.append("? extends ");
+ } else if (tag == SignatureVisitor.SUPER) {
+ declaration.append("? super ");
+ }
+
+ startType();
+ return this;
+ }
+
+ public void visitEnd() {
+ if (argumentStack % 2 == 1) {
+ 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 == 1) {
+ while (arrayStack % 2 == 1) {
+ arrayStack /= 2;
+ declaration.append("[]");
+ }
+ } else {
+ arrayStack /= 2;
+ }
+ }
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/attrs/ASMStackMapAttribute.java b/tools/external/asm/org/objectweb/asm/util/attrs/ASMStackMapAttribute.java
new file mode 100644
index 000000000..88c7af899
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/attrs/ASMStackMapAttribute.java
@@ -0,0 +1,223 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util.attrs;
+
+import java.util.List;
+import java.util.Map;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.attrs.StackMapAttribute;
+import org.objectweb.asm.attrs.StackMapFrame;
+import org.objectweb.asm.attrs.StackMapType;
+
+/**
+ * An {@link ASMifiable} {@link StackMapAttribute} sub class.
+ *
+ * @author Eugene Kuleshov
+ */
+public class ASMStackMapAttribute extends StackMapAttribute implements
+ ASMifiable,
+ Traceable
+{
+ /**
+ * Length of the attribute used for comparison
+ */
+ private int len;
+
+ public ASMStackMapAttribute() {
+ super();
+ }
+
+ public ASMStackMapAttribute(List frames, int len) {
+ super(frames);
+ this.len = len;
+ }
+
+ protected Attribute read(
+ ClassReader cr,
+ int off,
+ int len,
+ char[] buf,
+ int codeOff,
+ Label[] labels)
+ {
+ StackMapAttribute attr = (StackMapAttribute) super.read(cr,
+ off,
+ len,
+ buf,
+ codeOff,
+ labels);
+
+ return new ASMStackMapAttribute(attr.getFrames(), len);
+ }
+
+ public void asmify(StringBuffer buf, String varName, Map labelNames) {
+ List frames = getFrames();
+ buf.append("{\n");
+ buf.append("StackMapAttribute ").append(varName).append("Attr");
+ buf.append(" = new StackMapAttribute();\n");
+ if (frames.size() > 0) {
+ for (int i = 0; i < frames.size(); i++) {
+ asmify((StackMapFrame) frames.get(i), buf, varName + "frame"
+ + i, labelNames);
+ }
+ }
+ buf.append(varName).append(".visitAttribute(").append(varName);
+ buf.append("Attr);\n}\n");
+ }
+
+ void asmify(
+ StackMapFrame f,
+ StringBuffer buf,
+ String varName,
+ Map labelNames)
+ {
+ declareLabel(buf, labelNames, f.label);
+ buf.append("{\n");
+
+ buf.append("StackMapFrame ")
+ .append(varName)
+ .append(" = new StackMapFrame();\n");
+
+ buf.append(varName)
+ .append(".label = ")
+ .append(labelNames.get(f.label))
+ .append(";\n");
+
+ asmifyTypeInfo(buf, varName, labelNames, f.locals, "locals");
+ asmifyTypeInfo(buf, varName, labelNames, f.stack, "stack");
+
+ buf.append("cvAttr.frames.add(").append(varName).append(");\n");
+ buf.append("}\n");
+ }
+
+ void asmifyTypeInfo(
+ StringBuffer buf,
+ String varName,
+ Map labelNames,
+ List infos,
+ String field)
+ {
+ if (infos.size() > 0) {
+ buf.append("{\n");
+ for (int i = 0; i < infos.size(); i++) {
+ StackMapType typeInfo = (StackMapType) infos.get(i);
+ String localName = varName + "Info" + i;
+ int type = typeInfo.getType();
+ buf.append("StackMapType ")
+ .append(localName)
+ .append(" = StackMapType.getTypeInfo( StackMapType.ITEM_")
+ .append(StackMapType.ITEM_NAMES[type])
+ .append(");\n");
+
+ switch (type) {
+ case StackMapType.ITEM_Object: //
+ buf.append(localName)
+ .append(".setObject(\"")
+ .append(typeInfo.getObject())
+ .append("\");\n");
+ break;
+
+ case StackMapType.ITEM_Uninitialized: //
+ declareLabel(buf, labelNames, typeInfo.getLabel());
+ buf.append(localName)
+ .append(".setLabel(")
+ .append(labelNames.get(typeInfo.getLabel()))
+ .append(");\n");
+ break;
+ }
+ buf.append(varName)
+ .append(".")
+ .append(field)
+ .append(".add(")
+ .append(localName)
+ .append(");\n");
+ }
+ buf.append("}\n");
+ }
+ }
+
+ static void declareLabel(StringBuffer buf, Map labelNames, 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");
+ }
+ }
+
+ public void trace(StringBuffer buf, Map labelNames) {
+ List frames = getFrames();
+ buf.append("[\n");
+ for (int i = 0; i < frames.size(); i++) {
+ StackMapFrame f = (StackMapFrame) frames.get(i);
+
+ buf.append(" Frame:");
+ appendLabel(buf, labelNames, f.label);
+
+ buf.append(" locals[");
+ traceTypeInfo(buf, labelNames, f.locals);
+ buf.append("]");
+ buf.append(" stack[");
+ traceTypeInfo(buf, labelNames, f.stack);
+ buf.append("]\n");
+ }
+ buf.append(" ] length:").append(len).append("\n");
+ }
+
+ private void traceTypeInfo(StringBuffer buf, Map labelNames, List infos) {
+ String sep = "";
+ for (int i = 0; i < infos.size(); i++) {
+ StackMapType t = (StackMapType) infos.get(i);
+
+ buf.append(sep).append(StackMapType.ITEM_NAMES[t.getType()]);
+ sep = ", ";
+ if (t.getType() == StackMapType.ITEM_Object) {
+ buf.append(":").append(t.getObject());
+ }
+ if (t.getType() == StackMapType.ITEM_Uninitialized) {
+ buf.append(":");
+ appendLabel(buf, labelNames, t.getLabel());
+ }
+ }
+ }
+
+ protected void appendLabel(StringBuffer buf, Map labelNames, 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/tools/external/asm/org/objectweb/asm/util/attrs/ASMStackMapTableAttribute.java b/tools/external/asm/org/objectweb/asm/util/attrs/ASMStackMapTableAttribute.java
new file mode 100644
index 000000000..b878357d6
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/attrs/ASMStackMapTableAttribute.java
@@ -0,0 +1,214 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util.attrs;
+
+import java.util.List;
+import java.util.Map;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.attrs.StackMapTableAttribute;
+import org.objectweb.asm.attrs.StackMapFrame;
+import org.objectweb.asm.attrs.StackMapType;
+
+/**
+ * An {@link ASMifiable} {@link StackMapTableAttribute} sub class.
+ *
+ * @author Eugene Kuleshov
+ */
+public class ASMStackMapTableAttribute extends StackMapTableAttribute implements
+ ASMifiable,
+ Traceable
+{
+ /**
+ * Length of the attribute used for comparison
+ */
+ private int len;
+
+ public ASMStackMapTableAttribute() {
+ super();
+ }
+
+ public ASMStackMapTableAttribute(List frames, int len) {
+ super(frames);
+ this.len = len;
+ }
+
+ protected Attribute read(
+ ClassReader cr,
+ int off,
+ int len,
+ char[] buf,
+ int codeOff,
+ Label[] labels)
+ {
+ StackMapTableAttribute attr = (StackMapTableAttribute) super.read(cr,
+ off,
+ len,
+ buf,
+ codeOff,
+ labels);
+
+ return new ASMStackMapTableAttribute(attr.getFrames(), len);
+ }
+
+ public void asmify(StringBuffer buf, String varName, Map labelNames) {
+ List frames = getFrames();
+ if (frames.size() == 0) {
+ buf.append("List frames = Collections.EMPTY_LIST;\n");
+ } else {
+ buf.append("List frames = new ArrayList();\n");
+ for (int i = 0; i < frames.size(); i++) {
+ buf.append("{\n");
+ StackMapFrame f = (StackMapFrame) frames.get(i);
+ declareLabel(buf, labelNames, f.label);
+
+ String frameVar = varName + "frame" + i;
+ asmifyTypeInfo(buf, frameVar, labelNames, f.locals, "locals");
+ asmifyTypeInfo(buf, frameVar, labelNames, f.stack, "stack");
+
+ buf.append("StackMapFrame ")
+ .append(frameVar)
+ .append(" = new StackMapFrame(")
+ .append(labelNames.get(f.label))
+ .append(", locals, stack);\n");
+ buf.append("frames.add(").append(frameVar).append(");\n");
+ buf.append("}\n");
+ }
+ }
+ buf.append("StackMapTableAttribute ").append(varName);
+ buf.append(" = new StackMapTableAttribute(frames);\n");
+ }
+
+ void asmifyTypeInfo(
+ StringBuffer buf,
+ String varName,
+ Map labelNames,
+ List infos,
+ String field)
+ {
+ if (infos.size() == 0) {
+ buf.append("List ")
+ .append(field)
+ .append(" = Collections.EMPTY_LIST;\n");
+ } else {
+ buf.append("List ").append(field).append(" = new ArrayList();\n");
+ buf.append("{\n");
+ for (int i = 0; i < infos.size(); i++) {
+ StackMapType typeInfo = (StackMapType) infos.get(i);
+ String localName = varName + "Info" + i;
+ int type = typeInfo.getType();
+ buf.append("StackMapType ")
+ .append(localName)
+ .append(" = StackMapType.getTypeInfo( StackMapType.ITEM_")
+ .append(StackMapType.ITEM_NAMES[type])
+ .append(");\n");
+
+ switch (type) {
+ case StackMapType.ITEM_Object: //
+ buf.append(localName)
+ .append(".setObject(\"")
+ .append(typeInfo.getObject())
+ .append("\");\n");
+ break;
+
+ case StackMapType.ITEM_Uninitialized: //
+ declareLabel(buf, labelNames, typeInfo.getLabel());
+ buf.append(localName)
+ .append(".setLabel(")
+ .append(labelNames.get(typeInfo.getLabel()))
+ .append(");\n");
+ break;
+ }
+ buf.append(field)
+ .append(".add(")
+ .append(localName)
+ .append(");\n");
+ }
+ buf.append("}\n");
+ }
+ }
+
+ static void declareLabel(StringBuffer buf, Map labelNames, 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");
+ }
+ }
+
+ public void trace(StringBuffer buf, Map labelNames) {
+ List frames = getFrames();
+ buf.append("[\n");
+ for (int i = 0; i < frames.size(); i++) {
+ StackMapFrame f = (StackMapFrame) frames.get(i);
+
+ buf.append(" Frame:");
+ appendLabel(buf, labelNames, f.label);
+
+ buf.append(" locals[");
+ traceTypeInfo(buf, labelNames, f.locals);
+ buf.append("]");
+ buf.append(" stack[");
+ traceTypeInfo(buf, labelNames, f.stack);
+ buf.append("]\n");
+ }
+ buf.append(" ] length:").append(len).append("\n");
+ }
+
+ private void traceTypeInfo(StringBuffer buf, Map labelNames, List infos) {
+ String sep = "";
+ for (int i = 0; i < infos.size(); i++) {
+ StackMapType t = (StackMapType) infos.get(i);
+
+ buf.append(sep).append(StackMapType.ITEM_NAMES[t.getType()]);
+ sep = ", ";
+ if (t.getType() == StackMapType.ITEM_Object) {
+ buf.append(":").append(t.getObject());
+ }
+ if (t.getType() == StackMapType.ITEM_Uninitialized) {
+ buf.append(":");
+ appendLabel(buf, labelNames, t.getLabel());
+ }
+ }
+ }
+
+ protected void appendLabel(StringBuffer buf, Map labelNames, 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/tools/external/asm/org/objectweb/asm/util/attrs/ASMifiable.java b/tools/external/asm/org/objectweb/asm/util/attrs/ASMifiable.java
new file mode 100644
index 000000000..149d7daee
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/attrs/ASMifiable.java
@@ -0,0 +1,53 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util.attrs;
+
+import java.util.Map;
+
+/**
+ * An attribute that can print the ASM code to create an equivalent attribute.
+ *
+ * Implementation should print the ASM code that generates attribute data
+ * structures for current attribute state.
+ *
+ * @author Eugene Kuleshov
+ */
+public interface ASMifiable {
+
+ /**
+ * Prints the ASM code to create an attribute equal to this attribute.
+ *
+ * @param buf A buffer used for printing Java code.
+ * @param varName name of the variable in a printed code used to store
+ * attribute instance.
+ * @param labelNames map of label instances to their names.
+ */
+ void asmify(StringBuffer buf, String varName, Map labelNames);
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/attrs/Traceable.java b/tools/external/asm/org/objectweb/asm/util/attrs/Traceable.java
new file mode 100644
index 000000000..c40d2a62c
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/attrs/Traceable.java
@@ -0,0 +1,52 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util.attrs;
+
+import java.util.Map;
+
+/**
+ * An attribute that can print eadable representation of the attribute.
+ *
+ * Implementation should construct readable output from an attribute data
+ * structures for current attribute state. Such representation could be used in
+ * unit test assertions.
+ *
+ * @author Eugene Kuleshov
+ */
+public interface Traceable {
+
+ /**
+ * Build a human readable representation of the attribute.
+ *
+ * @param buf A buffer used for printing Java code.
+ * @param labelNames map of label instances to their names.
+ */
+ void trace(StringBuffer buf, Map labelNames);
+}
diff --git a/tools/external/asm/org/objectweb/asm/util/attrs/package.html b/tools/external/asm/org/objectweb/asm/util/attrs/package.html
new file mode 100644
index 000000000..a21cb004a
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/attrs/package.html
@@ -0,0 +1,36 @@
+<html>
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<body>
+Provides attributes sub classes that can work with the ASMifier utility.
+
+@since ASM 1.4.3
+</body>
+</html>
diff --git a/tools/external/asm/org/objectweb/asm/util/package.html b/tools/external/asm/org/objectweb/asm/util/package.html
new file mode 100644
index 000000000..e967b8b10
--- /dev/null
+++ b/tools/external/asm/org/objectweb/asm/util/package.html
@@ -0,0 +1,40 @@
+<html>
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<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>