diff options
Diffstat (limited to 'tools/external/asm/org/objectweb/asm/util/ASMifierMethodVisitor.java')
-rw-r--r-- | tools/external/asm/org/objectweb/asm/util/ASMifierMethodVisitor.java | 347 |
1 files changed, 347 insertions, 0 deletions
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)); + } +} |