1 8 package org.codehaus.aspectwerkz.cflow; 9 10 import org.objectweb.asm.Constants; 11 import org.objectweb.asm.ClassWriter; 12 import org.objectweb.asm.CodeVisitor; 13 import org.objectweb.asm.Label; 14 import org.codehaus.aspectwerkz.transform.TransformationConstants; 15 import org.codehaus.aspectwerkz.transform.inlining.AsmHelper; 16 import org.codehaus.aspectwerkz.transform.inlining.compiler.AbstractJoinPointCompiler; 17 18 23 public class CflowCompiler implements Constants, TransformationConstants { 24 25 public final static String JIT_CFLOW_CLASS = "org/codehaus/aspectwerkz/cflow/Cflow_"; 26 private final static String ABSTRACT_CFLOW_CLASS = "org/codehaus/aspectwerkz/cflow/AbstractCflowSystemAspect"; 27 private final static String INSTANCE_CFLOW_FIELD_NAME = "INSTANCE"; 28 private final static String [] EMPTY_STRING_ARRAY = new String [0]; 29 public static final String IN_CFLOW_METOD_NAME = "inCflow"; 30 public static final String IN_CFLOW_METOD_SIGNATURE = "()Z"; 31 public static final String CFLOW_ASPECTOF_METHOD_NAME = "aspectOf"; 32 33 39 public static boolean isCflowClass(String className) { 40 return className.indexOf(JIT_CFLOW_CLASS) >= 0; 41 } 42 43 46 private final String m_className; 47 48 51 private final String m_classSignature; 52 53 private ClassWriter m_cw; 54 55 59 private CflowCompiler(int cflowId) { 60 m_className = getCflowAspectClassName(cflowId); 61 m_classSignature = "L"+m_className+";"; 62 } 63 64 68 private byte[] compile() { 69 m_cw = AsmHelper.newClassWriter(true); 70 71 m_cw.visit( 73 AsmHelper.JAVA_VERSION, 74 ACC_PUBLIC + ACC_SUPER + ACC_SYNTHETIC, 75 m_className, 76 ABSTRACT_CFLOW_CLASS, 77 EMPTY_STRING_ARRAY, 78 null 79 ); 80 81 m_cw.visitField( 83 ACC_PRIVATE + ACC_STATIC, 84 INSTANCE_CFLOW_FIELD_NAME, 85 m_classSignature, 86 null, 87 null 88 ); 89 90 CodeVisitor ctor = m_cw.visitMethod( 92 ACC_PRIVATE, 93 INIT_METHOD_NAME, 94 NO_PARAM_RETURN_VOID_SIGNATURE, 95 EMPTY_STRING_ARRAY, 96 null 97 ); 98 ctor.visitVarInsn(ALOAD, 0); 100 ctor.visitMethodInsn(INVOKESPECIAL, ABSTRACT_CFLOW_CLASS, INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE); 101 ctor.visitInsn(RETURN); 102 ctor.visitMaxs(0, 0); 103 104 CodeVisitor isInCflow = m_cw.visitMethod( 106 ACC_PUBLIC + ACC_STATIC, 107 IS_IN_CFLOW_METOD_NAME, 108 IS_IN_CFLOW_METOD_SIGNATURE, 109 EMPTY_STRING_ARRAY, 110 null 111 ); 112 isInCflow.visitFieldInsn(GETSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 113 Label isNull = new Label(); 114 isInCflow.visitJumpInsn(IFNULL, isNull); 115 isInCflow.visitFieldInsn(GETSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 116 isInCflow.visitMethodInsn(INVOKEVIRTUAL, ABSTRACT_CFLOW_CLASS, IN_CFLOW_METOD_NAME, IN_CFLOW_METOD_SIGNATURE); 117 isInCflow.visitInsn(IRETURN); 118 isInCflow.visitLabel(isNull); 119 isInCflow.visitInsn(ICONST_0); 120 isInCflow.visitInsn(IRETURN); 121 isInCflow.visitMaxs(0, 0); 122 123 CodeVisitor aspectOf = m_cw.visitMethod( 125 ACC_PUBLIC + ACC_STATIC, 126 CFLOW_ASPECTOF_METHOD_NAME, 127 "()"+m_classSignature, 128 EMPTY_STRING_ARRAY, 129 null 130 ); 131 aspectOf.visitFieldInsn(GETSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 132 Label isNotNull = new Label(); 133 aspectOf.visitJumpInsn(IFNONNULL, isNotNull); 134 aspectOf.visitTypeInsn(NEW, m_className); 135 aspectOf.visitInsn(DUP); 136 aspectOf.visitMethodInsn(INVOKESPECIAL, m_className, INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE); 137 aspectOf.visitFieldInsn(PUTSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 138 aspectOf.visitLabel(isNotNull); 139 aspectOf.visitFieldInsn(GETSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 140 aspectOf.visitInsn(ARETURN); 141 aspectOf.visitMaxs(0, 0); 142 143 m_cw.visitEnd(); 144 145 return m_cw.toByteArray(); 146 } 147 148 153 public static String getCflowAspectClassName(int cflowID) { 154 return JIT_CFLOW_CLASS + cflowID; 155 } 156 157 164 public static Class compileCflowAspectAndAttachToClassLoader(ClassLoader loader, int cflowID) { 165 CompiledCflowAspect cflowAspect = compileCflowAspect(cflowID); 169 170 if (AbstractJoinPointCompiler.DUMP_JIT_CLASSES) { 171 try { 172 AsmHelper.dumpClass("_dump", getCflowAspectClassName(cflowID), cflowAspect.bytecode); 173 } catch (Throwable t) {;} 174 } 175 176 Class cflowAspectClass = AsmHelper.defineClass( 177 loader, 178 cflowAspect.bytecode, 179 getCflowAspectClassName(cflowID) 180 ); 181 return cflowAspectClass; 182 } 183 184 190 public static CompiledCflowAspect compileCflowAspect(int cflowID) { 191 CompiledCflowAspect cflowAspect = new CompiledCflowAspect(); 192 CflowCompiler compiler = new CflowCompiler(cflowID); 193 cflowAspect.bytecode = compiler.compile(); 194 cflowAspect.className = compiler.m_className; 195 return cflowAspect; 196 } 197 198 201 public static class CompiledCflowAspect { 202 public byte[] bytecode; 203 public String className; 205 public boolean equals(Object o) { 206 if (this == o) return true; 207 if (!(o instanceof CompiledCflowAspect)) return false; 208 209 final CompiledCflowAspect compiledCflowAspect = (CompiledCflowAspect) o; 210 211 if (!className.equals(compiledCflowAspect.className)) return false; 212 213 return true; 214 } 215 216 public int hashCode() { 217 return className.hashCode(); 218 } 219 } 220 } 221 | Popular Tags |