OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / tools / external / asm / org / objectweb / asm / util / ASMifierMethodVisitor.java
1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  *    contributors may be used to endorse or promote products derived from
16  *    this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 package org.objectweb.asm.util;
31
32 import org.objectweb.asm.AnnotationVisitor;
33 import org.objectweb.asm.MethodVisitor;
34 import org.objectweb.asm.Label;
35 import org.objectweb.asm.Opcodes;
36
37 import java.util.HashMap;
38
39 /**
40  * A {@link MethodVisitor} that prints the ASM code that generates the methods
41  * it visits.
42  * 
43  * @author Eric Bruneton
44  * @author Eugene Kuleshov
45  */
46 public class ASMifierMethodVisitor extends ASMifierAbstractVisitor implements
47         MethodVisitor
48 {
49
50     /**
51      * Constructs a new {@link ASMifierMethodVisitor} object.
52      */
53     public ASMifierMethodVisitor() {
54         super("mv");
55         this.labelNames = new HashMap();
56     }
57
58     public AnnotationVisitor visitAnnotationDefault() {
59         buf.setLength(0);
60         buf.append("{\n").append("av0 = mv.visitAnnotationDefault();\n");
61         text.add(buf.toString());
62         ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
63         text.add(av.getText());
64         text.add("}\n");
65         return av;
66     }
67
68     public AnnotationVisitor visitParameterAnnotation(
69         final int parameter,
70         final String desc,
71         final boolean visible)
72     {
73         buf.setLength(0);
74         buf.append("{\n")
75                 .append("av0 = mv.visitParameterAnnotation(")
76                 .append(parameter)
77                 .append(", ");
78         appendConstant(desc);
79         buf.append(", ").append(visible).append(");\n");
80         text.add(buf.toString());
81         ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
82         text.add(av.getText());
83         text.add("}\n");
84         return av;
85     }
86
87     public void visitCode() {
88         text.add("mv.visitCode();\n");
89     }
90
91     public void visitInsn(final int opcode) {
92         buf.setLength(0);
93         buf.append("mv.visitInsn(").append(OPCODES[opcode]).append(");\n");
94         text.add(buf.toString());
95     }
96
97     public void visitIntInsn(final int opcode, final int operand) {
98         buf.setLength(0);
99         buf.append("mv.visitIntInsn(")
100                 .append(OPCODES[opcode])
101                 .append(", ")
102                 .append(opcode == Opcodes.NEWARRAY
103                         ? TYPES[operand]
104                         : Integer.toString(operand))
105                 .append(");\n");
106         text.add(buf.toString());
107     }
108
109     public void visitVarInsn(final int opcode, final int var) {
110         buf.setLength(0);
111         buf.append("mv.visitVarInsn(")
112                 .append(OPCODES[opcode])
113                 .append(", ")
114                 .append(var)
115                 .append(");\n");
116         text.add(buf.toString());
117     }
118
119     public void visitTypeInsn(final int opcode, final String desc) {
120         buf.setLength(0);
121         buf.append("mv.visitTypeInsn(").append(OPCODES[opcode]).append(", ");
122         appendConstant(desc);
123         buf.append(");\n");
124         text.add(buf.toString());
125     }
126
127     public void visitFieldInsn(
128         final int opcode,
129         final String owner,
130         final String name,
131         final String desc)
132     {
133         buf.setLength(0);
134         buf.append("mv.visitFieldInsn(").append(OPCODES[opcode]).append(", ");
135         appendConstant(owner);
136         buf.append(", ");
137         appendConstant(name);
138         buf.append(", ");
139         appendConstant(desc);
140         buf.append(");\n");
141         text.add(buf.toString());
142     }
143
144     public void visitMethodInsn(
145         final int opcode,
146         final String owner,
147         final String name,
148         final String desc)
149     {
150         buf.setLength(0);
151         buf.append("mv.visitMethodInsn(").append(OPCODES[opcode]).append(", ");
152         appendConstant(owner);
153         buf.append(", ");
154         appendConstant(name);
155         buf.append(", ");
156         appendConstant(desc);
157         buf.append(");\n");
158         text.add(buf.toString());
159     }
160
161     public void visitJumpInsn(final int opcode, final Label label) {
162         buf.setLength(0);
163         declareLabel(label);
164         buf.append("mv.visitJumpInsn(").append(OPCODES[opcode]).append(", ");
165         appendLabel(label);
166         buf.append(");\n");
167         text.add(buf.toString());
168     }
169
170     public void visitLabel(final Label label) {
171         buf.setLength(0);
172         declareLabel(label);
173         buf.append("mv.visitLabel(");
174         appendLabel(label);
175         buf.append(");\n");
176         text.add(buf.toString());
177     }
178
179     public void visitLdcInsn(final Object cst) {
180         buf.setLength(0);
181         buf.append("mv.visitLdcInsn(");
182         appendConstant(cst);
183         buf.append(");\n");
184         text.add(buf.toString());
185     }
186
187     public void visitIincInsn(final int var, final int increment) {
188         buf.setLength(0);
189         buf.append("mv.visitIincInsn(")
190                 .append(var)
191                 .append(", ")
192                 .append(increment)
193                 .append(");\n");
194         text.add(buf.toString());
195     }
196
197     public void visitTableSwitchInsn(
198         final int min,
199         final int max,
200         final Label dflt,
201         final Label labels[])
202     {
203         buf.setLength(0);
204         for (int i = 0; i < labels.length; ++i) {
205             declareLabel(labels[i]);
206         }
207         declareLabel(dflt);
208
209         buf.append("mv.visitTableSwitchInsn(")
210                 .append(min)
211                 .append(", ")
212                 .append(max)
213                 .append(", ");
214         appendLabel(dflt);
215         buf.append(", new Label[] {");
216         for (int i = 0; i < labels.length; ++i) {
217             buf.append(i == 0 ? " " : ", ");
218             appendLabel(labels[i]);
219         }
220         buf.append(" });\n");
221         text.add(buf.toString());
222     }
223
224     public void visitLookupSwitchInsn(
225         final Label dflt,
226         final int keys[],
227         final Label labels[])
228     {
229         buf.setLength(0);
230         for (int i = 0; i < labels.length; ++i) {
231             declareLabel(labels[i]);
232         }
233         declareLabel(dflt);
234
235         buf.append("mv.visitLookupSwitchInsn(");
236         appendLabel(dflt);
237         buf.append(", new int[] {");
238         for (int i = 0; i < keys.length; ++i) {
239             buf.append(i == 0 ? " " : ", ").append(keys[i]);
240         }
241         buf.append(" }, new Label[] {");
242         for (int i = 0; i < labels.length; ++i) {
243             buf.append(i == 0 ? " " : ", ");
244             appendLabel(labels[i]);
245         }
246         buf.append(" });\n");
247         text.add(buf.toString());
248     }
249
250     public void visitMultiANewArrayInsn(final String desc, final int dims) {
251         buf.setLength(0);
252         buf.append("mv.visitMultiANewArrayInsn(");
253         appendConstant(desc);
254         buf.append(", ").append(dims).append(");\n");
255         text.add(buf.toString());
256     }
257
258     public void visitTryCatchBlock(
259         final Label start,
260         final Label end,
261         final Label handler,
262         final String type)
263     {
264         buf.setLength(0);
265         declareLabel(start);
266         declareLabel(end);
267         declareLabel(handler);
268         buf.append("mv.visitTryCatchBlock(");
269         appendLabel(start);
270         buf.append(", ");
271         appendLabel(end);
272         buf.append(", ");
273         appendLabel(handler);
274         buf.append(", ");
275         appendConstant(type);
276         buf.append(");\n");
277         text.add(buf.toString());
278     }
279
280     public void visitLocalVariable(
281         final String name,
282         final String desc,
283         final String signature,
284         final Label start,
285         final Label end,
286         final int index)
287     {
288         buf.setLength(0);
289         buf.append("mv.visitLocalVariable(");
290         appendConstant(name);
291         buf.append(", ");
292         appendConstant(desc);
293         buf.append(", ");
294         appendConstant(signature);
295         buf.append(", ");
296         appendLabel(start);
297         buf.append(", ");
298         appendLabel(end);
299         buf.append(", ").append(index).append(");\n");
300         text.add(buf.toString());
301     }
302
303     public void visitLineNumber(final int line, final Label start) {
304         buf.setLength(0);
305         buf.append("mv.visitLineNumber(").append(line).append(", ");
306         appendLabel(start);
307         buf.append(");\n");
308         text.add(buf.toString());
309     }
310
311     public void visitMaxs(final int maxStack, final int maxLocals) {
312         buf.setLength(0);
313         buf.append("mv.visitMaxs(")
314                 .append(maxStack)
315                 .append(", ")
316                 .append(maxLocals)
317                 .append(");\n");
318         text.add(buf.toString());
319     }
320
321     /**
322      * Appends a declaration of the given label to {@link #buf buf}. This
323      * declaration is of the form "Label lXXX = new Label();". Does nothing if
324      * the given label has already been declared.
325      * 
326      * @param l a label.
327      */
328     private void declareLabel(final Label l) {
329         String name = (String) labelNames.get(l);
330         if (name == null) {
331             name = "l" + labelNames.size();
332             labelNames.put(l, name);
333             buf.append("Label ").append(name).append(" = new Label();\n");
334         }
335     }
336
337     /**
338      * Appends the name of the given label to {@link #buf buf}. The given label
339      * <i>must</i> already have a name. One way to ensure this is to always
340      * call {@link #declareLabel declared} before calling this method.
341      * 
342      * @param l a label.
343      */
344     private void appendLabel(final Label l) {
345         buf.append((String) labelNames.get(l));
346     }
347 }