KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > transform > inlining > compiler > RuntimeCheckVisitor


1 /**************************************************************************************
2  * Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved. *
3  * http://aspectwerkz.codehaus.org *
4  * ---------------------------------------------------------------------------------- *
5  * The software in this package is published under the terms of the LGPL license *
6  * a copy of which has been included with this distribution in the license.txt file. *
7  **************************************************************************************/

8 package org.codehaus.aspectwerkz.transform.inlining.compiler;
9
10
11 import org.codehaus.aspectwerkz.expression.ExpressionVisitor;
12 import org.codehaus.aspectwerkz.expression.Undeterministic;
13 import org.codehaus.aspectwerkz.expression.ExpressionContext;
14 import org.codehaus.aspectwerkz.expression.ExpressionNamespace;
15 import org.codehaus.aspectwerkz.expression.ExpressionInfo;
16 import org.codehaus.aspectwerkz.expression.ast.ASTOr;
17 import org.codehaus.aspectwerkz.expression.ast.ASTAnd;
18 import org.codehaus.aspectwerkz.expression.ast.ASTNot;
19 import org.codehaus.aspectwerkz.expression.ast.ASTTarget;
20 import org.codehaus.aspectwerkz.expression.ast.ASTPointcutReference;
21 import org.codehaus.aspectwerkz.expression.ast.ASTExecution;
22 import org.codehaus.aspectwerkz.expression.ast.ASTCall;
23 import org.codehaus.aspectwerkz.expression.ast.ASTSet;
24 import org.codehaus.aspectwerkz.expression.ast.ASTGet;
25 import org.codehaus.aspectwerkz.expression.ast.ASTHandler;
26 import org.codehaus.aspectwerkz.expression.ast.ASTStaticInitialization;
27 import org.codehaus.aspectwerkz.expression.ast.ASTWithin;
28 import org.codehaus.aspectwerkz.expression.ast.ASTWithinCode;
29 import org.codehaus.aspectwerkz.expression.ast.ASTHasMethod;
30 import org.codehaus.aspectwerkz.expression.ast.ASTHasField;
31 import org.codehaus.aspectwerkz.expression.ast.ASTThis;
32 import org.codehaus.aspectwerkz.expression.ast.ASTCflow;
33 import org.codehaus.aspectwerkz.expression.ast.ASTCflowBelow;
34 import org.codehaus.aspectwerkz.expression.ast.ASTArgs;
35 import org.codehaus.aspectwerkz.transform.inlining.compiler.AbstractJoinPointCompiler;
36 import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
37 import org.codehaus.aspectwerkz.transform.TransformationConstants;
38 import org.codehaus.aspectwerkz.cflow.CflowCompiler;
39 import org.objectweb.asm.CodeVisitor;
40 import org.objectweb.asm.Constants;
41
42 /**
43  * Visit an expression and push on the bytecode stack the boolean expression that corresponds to the residual
44  * part for the target(CALLEE) filtering and cflow / cflowbelow runtime checks
45  * <p/>
46  * TODO: for now OR / AND / NOT are turned in IAND etc, ie "&" and not "&&" that is more efficient but is using labels.
47  * <p/>
48  * Note: we have to override here (and maintain) every visit Method that visit a node that appears in an expression
49  * (f.e. set , get, etc, but not ASTParameter), since we cannot rely on AND/OR/NOT nodes to push the boolean expressions.
50  *
51  * @author <a HREF="mailto:alex@gnilux.com">Alexandre Vasseur</a>
52  */

53 public class RuntimeCheckVisitor extends ExpressionVisitor implements Constants {
54
55     private AbstractJoinPointCompiler m_compiler;
56
57     private CodeVisitor cv;
58
59     private ExpressionInfo m_expressionInfo;
60
61     private boolean m_isOptimizedJoinPoint;
62
63     private int m_joinPointIndex;
64
65     private int m_calleeIndex;
66
67     /**
68      * Create a new visitor given a specific AdviceInfo
69      *
70      * @param compiler we are working for
71      * @param cv of the method block we are compiling
72      * @param info expression info
73      * @param isOptimizedJoinPoint
74      * @param joinPointIndex
75      */

76     public RuntimeCheckVisitor(final AbstractJoinPointCompiler compiler, final CodeVisitor cv,
77                                final ExpressionInfo info, final boolean isOptimizedJoinPoint,
78                                final int joinPointIndex, final int calleeIndex) {
79         super(
80                 info,
81                 info.toString(),
82                 info.getNamespace(),
83                 info.getExpression().getASTRoot()
84         );
85         m_compiler = compiler;
86         m_expressionInfo = info;
87         m_isOptimizedJoinPoint = isOptimizedJoinPoint;
88         m_joinPointIndex = joinPointIndex;
89         m_calleeIndex = calleeIndex;
90         this.cv = cv;
91     }
92
93     /**
94      * Push the boolean typed expression on the stack.
95      *
96      * @param context
97      */

98     public void pushCheckOnStack(ExpressionContext context) {
99         super.match(context);
100     }
101
102     /**
103      * Handles OR expression
104      *
105      * @param node
106      * @param data
107      * @return
108      */

109     public Object JavaDoc visit(ASTOr node, Object JavaDoc data) {
110         Boolean JavaDoc matchL = (Boolean JavaDoc) node.jjtGetChild(0).jjtAccept(this, data);
111         Boolean JavaDoc matchR = (Boolean JavaDoc) node.jjtGetChild(1).jjtAccept(this, data);
112         Boolean JavaDoc intermediate = Undeterministic.or(matchL, matchR);
113         cv.visitInsn(IOR);
114         for (int i = 2; i < node.jjtGetNumChildren(); i++) {
115             Boolean JavaDoc matchNext = (Boolean JavaDoc) node.jjtGetChild(i).jjtAccept(this, data);
116             intermediate = Undeterministic.or(intermediate, matchNext);
117             cv.visitInsn(IOR);
118         }
119         return intermediate;
120     }
121
122     public Object JavaDoc visit(ASTAnd node, Object JavaDoc data) {
123         Boolean JavaDoc matchL = (Boolean JavaDoc) node.jjtGetChild(0).jjtAccept(this, data);
124         Boolean JavaDoc matchR = (Boolean JavaDoc) node.jjtGetChild(1).jjtAccept(this, data);
125         Boolean JavaDoc intermediate = Undeterministic.and(matchL, matchR);
126         cv.visitInsn(IAND);
127         for (int i = 2; i < node.jjtGetNumChildren(); i++) {
128             Boolean JavaDoc matchNext = (Boolean JavaDoc) node.jjtGetChild(i).jjtAccept(this, data);
129             intermediate = Undeterministic.and(intermediate, matchNext);
130             cv.visitInsn(IAND);
131         }
132         return intermediate;
133     }
134
135     public Object JavaDoc visit(ASTNot node, Object JavaDoc data) {
136         Boolean JavaDoc match = (Boolean JavaDoc) node.jjtGetChild(0).jjtAccept(this, data);
137         cv.visitInsn(INEG);
138         return Undeterministic.not(match);
139     }
140
141     public Object JavaDoc visit(ASTTarget node, Object JavaDoc data) {
142         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
143         if (match != null) {
144             push(match);
145         } else {
146             // runtime check
147
String JavaDoc boundedTypeDesc = AsmHelper.convertReflectDescToTypeDesc(node.getBoundedType(m_expressionInfo));
148             m_compiler.loadCallee(cv, m_isOptimizedJoinPoint, m_joinPointIndex, m_calleeIndex);
149             cv.visitTypeInsn(INSTANCEOF, boundedTypeDesc.substring(1, boundedTypeDesc.length() - 1));
150         }
151         return match;
152     }
153
154     public Object JavaDoc visit(ASTThis node, Object JavaDoc data) {
155         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
156         push(match);
157         return match;
158     }
159
160     public Object JavaDoc visit(ASTCflow node, Object JavaDoc data) {
161         // runtime check
162
String JavaDoc cflowClassName = CflowCompiler.getCflowAspectClassName(node.hashCode());
163         cv.visitMethodInsn(
164                 INVOKESTATIC,
165                 cflowClassName,
166                 TransformationConstants.IS_IN_CFLOW_METOD_NAME,
167                 TransformationConstants.IS_IN_CFLOW_METOD_SIGNATURE
168         );
169         return (Boolean JavaDoc) super.visit(node, data);
170     }
171
172     public Object JavaDoc visit(ASTCflowBelow node, Object JavaDoc data) {
173         // runtime check
174
//TODO: cflowbelow ID will differ from cflow one.. => not optimized
175
String JavaDoc cflowClassName = CflowCompiler.getCflowAspectClassName(node.hashCode());
176         cv.visitMethodInsn(
177                 INVOKESTATIC,
178                 cflowClassName,
179                 TransformationConstants.IS_IN_CFLOW_METOD_NAME,
180                 TransformationConstants.IS_IN_CFLOW_METOD_SIGNATURE
181         );
182         return (Boolean JavaDoc) super.visit(node, data);
183     }
184
185     public Object JavaDoc visit(ASTArgs node, Object JavaDoc data) {
186         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
187         push(match);
188         return match;
189     }
190
191     public Object JavaDoc visit(ASTPointcutReference node, Object JavaDoc data) {
192         ExpressionContext context = (ExpressionContext) data;
193         ExpressionNamespace namespace = ExpressionNamespace.getNamespace(m_namespace);
194         ExpressionVisitor expression = namespace.getExpression(node.getName());
195
196         // build a new RuntimeCheckVisitor to visit the sub expression
197
RuntimeCheckVisitor referenced = new RuntimeCheckVisitor(
198                 m_compiler, cv, expression.getExpressionInfo(),
199                 m_isOptimizedJoinPoint, m_joinPointIndex,
200                 m_calleeIndex
201         );
202         return referenced.matchUndeterministic(context);
203     }
204
205     public Object JavaDoc visit(ASTExecution node, Object JavaDoc data) {
206         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
207         push(match);
208         return match;
209     }
210
211     public Object JavaDoc visit(ASTCall node, Object JavaDoc data) {
212         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
213         push(match);
214         return match;
215     }
216
217     public Object JavaDoc visit(ASTSet node, Object JavaDoc data) {
218         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
219         push(match);
220         return match;
221     }
222
223     public Object JavaDoc visit(ASTGet node, Object JavaDoc data) {
224         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
225         push(match);
226         return match;
227     }
228
229     public Object JavaDoc visit(ASTHandler node, Object JavaDoc data) {
230         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
231         push(match);
232         return match;
233     }
234
235     public Object JavaDoc visit(ASTStaticInitialization node, Object JavaDoc data) {
236         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
237         push(match);
238         return match;
239     }
240
241     public Object JavaDoc visit(ASTWithin node, Object JavaDoc data) {
242         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
243         push(match);
244         return match;
245     }
246
247     public Object JavaDoc visit(ASTWithinCode node, Object JavaDoc data) {
248         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
249         push(match);
250         return match;
251     }
252
253     public Object JavaDoc visit(ASTHasMethod node, Object JavaDoc data) {
254         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
255         push(match);
256         return match;
257     }
258
259     public Object JavaDoc visit(ASTHasField node, Object JavaDoc data) {
260         Boolean JavaDoc match = (Boolean JavaDoc) super.visit(node, data);
261         push(match);
262         return match;
263     }
264
265
266     private void push(Boolean JavaDoc b) {
267         if (b == null) {
268             throw new Error JavaDoc("attempt to push an undetermined match result");
269         } else if (b.booleanValue()) {
270             cv.visitInsn(ICONST_1);
271         } else {
272             cv.visitInsn(ICONST_M1);
273         }
274     }
275 }
276
Popular Tags