KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > julia > asm > CodeGenerator


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

23
24 package org.objectweb.fractal.julia.asm;
25
26 import org.objectweb.asm.CodeVisitor;
27
28 import java.lang.reflect.Method JavaDoc;
29 import java.util.List JavaDoc;
30
31 /**
32  * A code generator used by an {@link InterceptorClassGenerator} to generate
33  * interception code. The interception
34  * code for a given method is generated by using a kind of {@link
35  * org.objectweb.asm.CodeAdapter}: the original method code is
36  * visited by a code adapter, which adds the interception code on the fly. For
37  * example, to add pre and post code blocks to a method, the previous code
38  * adapter can be of the following form:
39  * <pre>
40  * public class PrePostCodeAdapter implements CodeVisitor {
41  * private CodeVisitor cv;
42  * private Label postBlockLabel;
43  * public PrePostCodeAdapter (CodeVisitor cv) {
44  * this.cv = cv;
45  * this.postBlockLabel = new Label();
46  * // GENERATES PRE CODE BLOCK using cv
47  * }
48  * public void visitInsn (int opcode) {
49  * // replaces xRETURN instructions with the following instructions:
50  * // xSTORE result
51  * // GOTO postBlockLabel
52  * }
53  * public void visitVarInsn (int opcode, int var) {
54  * // inserts a variable to store the result, just after the parameters
55  * // shifts the existing variables to make room for this new variable
56  * }
57  * public void visitMaxs (int maxStack, int maxLocals) {
58  * cv.visitLabel(postBlockLabel);
59  * // GENERATES POST CODE BLOCK using cv
60  * // generates appropriate xLOAD xRETURN instructions
61  * cv.visitMaxs(maxStack, maxLocals);
62  * }
63  * // the other CodeVisitor methods are implemented by just delegating to cv
64  * }
65  * </pre>
66  * When the original method code is visited by this code adapter, the pre code
67  * block is generated immediately. Then the original method code is regenerated
68  * as is, except that returns are replaced with gotos. The post code block is
69  * inserted when the end of the original method code is visited (i.e., when
70  * visitMaxs is called).
71  * <p>
72  * The original method code can also be completely replaced with a code adapter
73  * of the following form:
74  * <pre>
75  * public class AroundCodeAdapter implements CodeVisitor {
76  * public AroundCodeAdapter (CodeVisitor cv) {
77  * // generates the code replacing the original method code
78  * }
79  * // the CodeVisitor methods are implemented by doing nothing
80  * }
81  * </pre>
82  * These code adapters are returned by the {@link #generateInterceptionCode
83  * generateInterceptionCode} method. More precisely, given a code visitor, this
84  * method should return a code adapter that adds the desired interception code
85  * for the given method.
86  * <p>
87  * When several code generators are used by an interceptor class generator, the
88  * code adapters returned by the {@link #generateInterceptionCode
89  * generateInterceptionCode} methods of these code generators are chained
90  * together. The first code adapter in this chain visits the original
91  * code of each method. The second code adapter visits the code modified on the
92  * fly by the first code adapter. The third code adapter visits the code
93  * modified on the fly by the first and second code adapters, and so on. The
94  * result is a code that includes the interception code generated by each
95  * code generator.
96  */

97
98 public interface CodeGenerator {
99
100   /**
101    * The type of code generators that applies only to input interceptor classes.
102    * See {@link InterceptorClassGenerator#in here} for more details.
103    */

104
105   int IN = 0;
106
107   /**
108    * The type of code generators that applies only to output interceptor
109    * classes. See {@link InterceptorClassGenerator#in here} for more details.
110    */

111
112   int OUT = 1;
113
114   /**
115    * The type of code generators that applies to input and output interceptor
116    * classes. See {@link InterceptorClassGenerator#in here} for more details.
117    */

118
119   int IN_OUT = 2;
120
121   /**
122    * Initializes this code generator.
123    *
124    * @param icg the interceptor class generator to which this code generator
125    * belongs.
126    *
127    * @return the type of this code generator, i.e., either {@link #IN IN},
128    * {@link #OUT OUT} or {@link #IN_OUT IN_OUT}.
129    */

130
131   int init (InterceptorClassGenerator icg);
132
133   /**
134    * Generates the initialization code for this code generator. This code is
135    * added to the {@link org.objectweb.fractal.julia.Controller#initFcController
136    * initFcController} method by the interceptor class generator that calls this
137    * method. By hypothesis, the stack is empty at the beginning of the generated
138    * code. Moreover, the stack must also be empty at the end of the code
139    * generated by this method.
140    *
141    * @param cv the method visitor to be used to generate the initialization
142    * code.
143    * @throws ClassGenerationException if a problem occurs.
144    */

145
146   void generateInitCode (CodeVisitor cv) throws ClassGenerationException;
147
148   /**
149    * Generates the interception code for the given method.
150    *
151    * @param m the method for which the interception code must be generated.
152    * @param cv the method visitor to be used to generate the interception code.
153    * @return a method visitor to be used to visit the original method code.
154    * This method visitor should be a kind of {@link
155    * org.objectweb.asm.CodeAdapter}, that should add the
156    * interception code to the visited code on the fly. See {@link
157    * CodeGenerator}.
158    * @throws ClassGenerationException if a problem occurs.
159    */

160
161   CodeVisitor generateInterceptionCode (Method JavaDoc m, CodeVisitor cv)
162     throws ClassGenerationException;
163
164   /**
165    * Generates the cloning code for this code generator. This code is
166    * added to the {@link org.objectweb.fractal.julia.Interceptor#clone clone}
167    * method by the interceptor class generator that calls this method. By
168    * hypothesis, the stack is empty at the beginning of the generated code.
169    * Moreover, the stack must also be empty at the end of the code generated by
170    * this method.
171    *
172    * @param cv the method visitor to be used to generate the cloning code.
173    * @throws ClassGenerationException if a problem occurs.
174    */

175
176   void generateCloneCode (CodeVisitor cv)
177     throws ClassGenerationException;
178
179   /**
180    * Closes this code generator. This method can be used to do some cleanup
181    * before computing the bytecode of the interceptor class.
182    */

183
184   void close ();
185   
186   /**
187    * Permits a CodeGenerator to add interfaces that must be implemented
188    * by the interceptor class being generated. This method is called from
189    * {@link InterceptorClassGenerator#getImplementedInterfaces()}.
190    *
191    * This method should return an empty list when no additional interfaces are required.
192    *
193    * @return the names of all the interfaces this CodeGenerator requires to be implemented by the generated class.
194    * @throws ClassGenerationException if a problem occurs.
195    */

196   List JavaDoc getImplementedInterfaces () throws ClassGenerationException;
197 }
198
Popular Tags