KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > generation > enhancer > CodeDuplicator


1 /**
2  * Copyright (C) 2001-2004 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.speedo.generation.enhancer;
19
20 import org.objectweb.asm.CodeVisitor;
21 import org.objectweb.asm.Label;
22 import org.objectweb.asm.Attribute;
23 import org.objectweb.util.monolog.api.Logger;
24
25 import java.util.Map JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.List JavaDoc;
28
29 /**
30  * Creates several copies of a method.
31  */

32 public class CodeDuplicator extends LoggedClass implements CodeVisitor {
33
34     /**
35      * The code visitor used to generate the copies.
36      */

37     private CodeVisitor[] cvs;
38
39     /**
40      * A map associating original labels to new labels, for each copy. Indeed
41      * labels can be used only inside a single method. It is therefore necessary
42      * to create copies of the original labels for each duplicated method.
43      */

44     private Map JavaDoc[] labels;
45
46     public CodeDuplicator(Logger logger) {
47         super(logger);
48     }
49
50     /**
51      * Constructs a {@link CodeDuplicator}.
52      *
53      * @param cvs a list of code visitors, to be used to generate the copies.
54      */

55     public CodeDuplicator(List JavaDoc cvs) {
56         this.cvs = (CodeVisitor[]) cvs.toArray(new CodeVisitor[cvs.size()]);
57         this.labels = new Map JavaDoc[this.cvs.length];
58     }
59
60     /**
61      * Constructs a {@link CodeDuplicator}.
62      *
63      * @param cvs an array of code visitors, to be used to generate the copies.
64      */

65     public CodeDuplicator(CodeVisitor[] cvs) {
66         this.cvs = cvs;
67         this.labels = new Map JavaDoc[cvs.length];
68     }
69
70     // IMPLEMENTATION OF THE CodeVisitor INTERFACE //
71
// --------------------------------------------//
72

73     public void visitInsn(final int opcode) {
74         for (int i = 0; i < cvs.length; ++i) {
75             cvs[i].visitInsn(opcode);
76         }
77     }
78
79     public void visitIntInsn(final int opcode, final int operand) {
80         for (int i = 0; i < cvs.length; ++i) {
81             cvs[i].visitIntInsn(opcode, operand);
82         }
83     }
84
85     public void visitVarInsn(final int opcode, final int var) {
86         for (int i = 0; i < cvs.length; ++i) {
87             cvs[i].visitVarInsn(opcode, var);
88         }
89     }
90
91     public void visitTypeInsn(final int opcode, final String JavaDoc desc) {
92         for (int i = 0; i < cvs.length; ++i) {
93             cvs[i].visitTypeInsn(opcode, desc);
94         }
95     }
96
97     public void visitFieldInsn(final int opcode,
98                                final String JavaDoc owner,
99                                final String JavaDoc name,
100                                final String JavaDoc desc) {
101         for (int i = 0; i < cvs.length; ++i) {
102             cvs[i].visitFieldInsn(opcode, owner, name, desc);
103         }
104     }
105
106     public void visitMethodInsn(final int opcode,
107                                 final String JavaDoc owner,
108                                 final String JavaDoc name,
109                                 final String JavaDoc desc) {
110         for (int i = 0; i < cvs.length; ++i) {
111             cvs[i].visitMethodInsn(opcode, owner, name, desc);
112         }
113     }
114
115     public void visitJumpInsn(final int opcode, final Label label) {
116         for (int i = 0; i < cvs.length; ++i) {
117             cvs[i].visitJumpInsn(opcode, getLabel(label, i));
118         }
119     }
120
121     public void visitLabel(final Label label) {
122         for (int i = 0; i < cvs.length; ++i) {
123             cvs[i].visitLabel(getLabel(label, i));
124         }
125     }
126
127     public void visitLdcInsn(final Object JavaDoc cst) {
128         for (int i = 0; i < cvs.length; ++i) {
129             cvs[i].visitLdcInsn(cst);
130         }
131     }
132
133     public void visitIincInsn(final int var, final int increment) {
134         for (int i = 0; i < cvs.length; ++i) {
135             cvs[i].visitIincInsn(var, increment);
136         }
137     }
138
139     public void visitTableSwitchInsn(final int min,
140                                      final int max,
141                                      final Label dflt,
142                                      final Label labels[]) {
143         for (int i = 0; i < cvs.length; ++i) {
144             cvs[i].visitTableSwitchInsn(min,
145                     max, getLabel(dflt, i), getLabels(labels, i));
146         }
147     }
148
149     public void visitLookupSwitchInsn(final Label dflt,
150                                       final int keys[],
151                                       final Label labels[]) {
152         for (int i = 0; i < cvs.length; ++i) {
153             cvs[i].visitLookupSwitchInsn(getLabel(dflt, i),
154                     keys, getLabels(labels, i));
155         }
156     }
157
158     public void visitMultiANewArrayInsn(final String JavaDoc desc, final int dims) {
159         for (int i = 0; i < cvs.length; ++i) {
160             cvs[i].visitMultiANewArrayInsn(desc, dims);
161         }
162     }
163
164     public void visitTryCatchBlock(final Label start,
165                                    final Label end,
166                                    final Label handler,
167                                    final String JavaDoc type) {
168         for (int i = 0; i < cvs.length; ++i) {
169             cvs[i].visitTryCatchBlock(getLabel(start, i),
170                     getLabel(end, i), getLabel(handler, i), type);
171         }
172     }
173
174     public void visitMaxs(final int maxStack, final int maxLocals) {
175         for (int i = 0; i < cvs.length; ++i) {
176             cvs[i].visitMaxs(maxStack, maxLocals);
177         }
178     }
179
180     public void visitLocalVariable(final String JavaDoc name,
181                                    final String JavaDoc desc,
182                                    final Label start,
183                                    final Label end,
184                                    final int index) {
185         for (int i = 0; i < cvs.length; ++i) {
186             cvs[i].visitLocalVariable(name,
187                     desc, getLabel(start, i), getLabel(end, i), index);
188         }
189     }
190
191     public void visitLineNumber(final int line, final Label start) {
192         for (int i = 0; i < cvs.length; ++i) {
193             cvs[i].visitLineNumber(line, getLabel(start, i));
194         }
195     }
196
197     public void visitAttribute(Attribute attribute) {
198         for (int i = 0; i < cvs.length; ++i) {
199             cvs[i].visitAttribute(attribute);
200         }
201     }
202
203     // OTHER METHODS : LABELS MANAGEMENT //
204
// ----------------------------------//
205

206     /**
207      * Returns the label corresponding to the given label for the i-th copy.
208      *
209      * @param label a label of the method that is visited by this visitor
210      * @param i index of the copy for which the new label must be computed
211      * @return the label corresponding to the given label for the i-th copy.
212      */

213     private Label getLabel(final Label label, final int i) {
214         if (labels[i] == null) {
215             labels[i] = new HashMap JavaDoc();
216         }
217         Label l = (Label) labels[i].get(label);
218         if (l == null) {
219             l = new Label();
220             labels[i].put(label, l);
221         }
222         return l;
223     }
224
225     /**
226      * Returns the labels corresponding to the given labels for the i-th copy.
227      *
228      * @param labels some labels of the method that is visited by this visitor
229      * @param i index of the copy for which the new label must be computed
230      * @return the labels corresponding to the given labels for the i-th copy.
231      */

232     private Label[] getLabels(final Label[] labels, final int i) {
233         Label[] l = new Label[labels.length];
234         for (int j = 0; j < l.length; ++j) {
235             l[j] = getLabel(labels[j], i);
236         }
237         return l;
238     }
239 }
240
Popular Tags