1 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 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 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 98 public void pushCheckOnStack(ExpressionContext context) { 99 super.match(context); 100 } 101 102 109 public Object visit(ASTOr node, Object data) { 110 Boolean matchL = (Boolean ) node.jjtGetChild(0).jjtAccept(this, data); 111 Boolean matchR = (Boolean ) node.jjtGetChild(1).jjtAccept(this, data); 112 Boolean intermediate = Undeterministic.or(matchL, matchR); 113 cv.visitInsn(IOR); 114 for (int i = 2; i < node.jjtGetNumChildren(); i++) { 115 Boolean matchNext = (Boolean ) 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 visit(ASTAnd node, Object data) { 123 Boolean matchL = (Boolean ) node.jjtGetChild(0).jjtAccept(this, data); 124 Boolean matchR = (Boolean ) node.jjtGetChild(1).jjtAccept(this, data); 125 Boolean intermediate = Undeterministic.and(matchL, matchR); 126 cv.visitInsn(IAND); 127 for (int i = 2; i < node.jjtGetNumChildren(); i++) { 128 Boolean matchNext = (Boolean ) 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 visit(ASTNot node, Object data) { 136 Boolean match = (Boolean ) node.jjtGetChild(0).jjtAccept(this, data); 137 cv.visitInsn(INEG); 138 return Undeterministic.not(match); 139 } 140 141 public Object visit(ASTTarget node, Object data) { 142 Boolean match = (Boolean ) super.visit(node, data); 143 if (match != null) { 144 push(match); 145 } else { 146 String 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 visit(ASTThis node, Object data) { 155 Boolean match = (Boolean ) super.visit(node, data); 156 push(match); 157 return match; 158 } 159 160 public Object visit(ASTCflow node, Object data) { 161 String 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 ) super.visit(node, data); 170 } 171 172 public Object visit(ASTCflowBelow node, Object data) { 173 String 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 ) super.visit(node, data); 183 } 184 185 public Object visit(ASTArgs node, Object data) { 186 Boolean match = (Boolean ) super.visit(node, data); 187 push(match); 188 return match; 189 } 190 191 public Object visit(ASTPointcutReference node, Object data) { 192 ExpressionContext context = (ExpressionContext) data; 193 ExpressionNamespace namespace = ExpressionNamespace.getNamespace(m_namespace); 194 ExpressionVisitor expression = namespace.getExpression(node.getName()); 195 196 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 visit(ASTExecution node, Object data) { 206 Boolean match = (Boolean ) super.visit(node, data); 207 push(match); 208 return match; 209 } 210 211 public Object visit(ASTCall node, Object data) { 212 Boolean match = (Boolean ) super.visit(node, data); 213 push(match); 214 return match; 215 } 216 217 public Object visit(ASTSet node, Object data) { 218 Boolean match = (Boolean ) super.visit(node, data); 219 push(match); 220 return match; 221 } 222 223 public Object visit(ASTGet node, Object data) { 224 Boolean match = (Boolean ) super.visit(node, data); 225 push(match); 226 return match; 227 } 228 229 public Object visit(ASTHandler node, Object data) { 230 Boolean match = (Boolean ) super.visit(node, data); 231 push(match); 232 return match; 233 } 234 235 public Object visit(ASTStaticInitialization node, Object data) { 236 Boolean match = (Boolean ) super.visit(node, data); 237 push(match); 238 return match; 239 } 240 241 public Object visit(ASTWithin node, Object data) { 242 Boolean match = (Boolean ) super.visit(node, data); 243 push(match); 244 return match; 245 } 246 247 public Object visit(ASTWithinCode node, Object data) { 248 Boolean match = (Boolean ) super.visit(node, data); 249 push(match); 250 return match; 251 } 252 253 public Object visit(ASTHasMethod node, Object data) { 254 Boolean match = (Boolean ) super.visit(node, data); 255 push(match); 256 return match; 257 } 258 259 public Object visit(ASTHasField node, Object data) { 260 Boolean match = (Boolean ) super.visit(node, data); 261 push(match); 262 return match; 263 } 264 265 266 private void push(Boolean b) { 267 if (b == null) { 268 throw new Error ("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 |