1 4 package com.tc.aspectwerkz.cflow; 5 6 import com.tc.asm.Opcodes; 7 import com.tc.asm.ClassWriter; 8 import com.tc.asm.MethodVisitor; 9 import com.tc.asm.Label; 10 11 import com.tc.aspectwerkz.transform.TransformationConstants; 12 import com.tc.aspectwerkz.transform.inlining.AsmHelper; 13 import com.tc.aspectwerkz.transform.inlining.compiler.AbstractJoinPointCompiler; 14 15 20 public class CflowCompiler implements Opcodes, TransformationConstants { 21 22 public final static String JIT_CFLOW_CLASS = "com/tc/aspectwerkz/cflow/Cflow_"; 23 private final static String ABSTRACT_CFLOW_CLASS = "com/tc/aspectwerkz/cflow/AbstractCflowSystemAspect"; 24 private final static String INSTANCE_CFLOW_FIELD_NAME = "INSTANCE"; 25 public static final String IN_CFLOW_METOD_NAME = "inCflow"; 26 public static final String IN_CFLOW_METOD_SIGNATURE = "()Z"; 27 public static final String CFLOW_ASPECTOF_METHOD_NAME = "aspectOf"; 28 29 35 public static boolean isCflowClass(String className) { 36 return className.indexOf(JIT_CFLOW_CLASS) >= 0; 37 } 38 39 42 private final String m_className; 43 44 47 private final String m_classSignature; 48 49 private ClassWriter m_cw; 50 51 56 private CflowCompiler(int cflowId) { 57 m_className = getCflowAspectClassName(cflowId); 58 m_classSignature = "L" + m_className + ";"; 59 } 60 61 66 private byte[] compile() { 67 m_cw = AsmHelper.newClassWriter(true); 68 69 m_cw.visit( 71 AsmHelper.JAVA_VERSION, 72 ACC_PUBLIC + ACC_SUPER + ACC_SYNTHETIC, 73 m_className, 74 null, 75 ABSTRACT_CFLOW_CLASS, 76 EMPTY_STRING_ARRAY 77 ); 78 79 m_cw.visitField( 81 ACC_PRIVATE + ACC_STATIC, 82 INSTANCE_CFLOW_FIELD_NAME, 83 m_classSignature, 84 null, 85 null 86 ); 87 88 MethodVisitor ctor = m_cw.visitMethod( 90 ACC_PRIVATE, 91 INIT_METHOD_NAME, 92 NO_PARAM_RETURN_VOID_SIGNATURE, 93 null, 94 EMPTY_STRING_ARRAY 95 ); 96 ctor.visitVarInsn(ALOAD, 0); 98 ctor.visitMethodInsn(INVOKESPECIAL, ABSTRACT_CFLOW_CLASS, INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE); 99 ctor.visitInsn(RETURN); 100 ctor.visitMaxs(0, 0); 101 102 MethodVisitor isInCflow = m_cw.visitMethod( 104 ACC_PUBLIC + ACC_STATIC, 105 IS_IN_CFLOW_METOD_NAME, 106 IS_IN_CFLOW_METOD_SIGNATURE, 107 null, 108 EMPTY_STRING_ARRAY 109 ); 110 isInCflow.visitFieldInsn(GETSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 111 Label isNull = new Label(); 112 isInCflow.visitJumpInsn(IFNULL, isNull); 113 isInCflow.visitFieldInsn(GETSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 114 isInCflow.visitMethodInsn(INVOKEVIRTUAL, ABSTRACT_CFLOW_CLASS, IN_CFLOW_METOD_NAME, IN_CFLOW_METOD_SIGNATURE); 115 isInCflow.visitInsn(IRETURN); 116 isInCflow.visitLabel(isNull); 117 isInCflow.visitInsn(ICONST_0); 118 isInCflow.visitInsn(IRETURN); 119 isInCflow.visitMaxs(0, 0); 120 121 MethodVisitor aspectOf = m_cw.visitMethod( 123 ACC_PUBLIC + ACC_STATIC, 124 CFLOW_ASPECTOF_METHOD_NAME, 125 "()" + m_classSignature, 126 null, 127 EMPTY_STRING_ARRAY 128 ); 129 aspectOf.visitFieldInsn(GETSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 130 Label isNotNull = new Label(); 131 aspectOf.visitJumpInsn(IFNONNULL, isNotNull); 132 aspectOf.visitTypeInsn(NEW, m_className); 133 aspectOf.visitInsn(DUP); 134 aspectOf.visitMethodInsn(INVOKESPECIAL, m_className, INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE); 135 aspectOf.visitFieldInsn(PUTSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 136 aspectOf.visitLabel(isNotNull); 137 aspectOf.visitFieldInsn(GETSTATIC, m_className, INSTANCE_CFLOW_FIELD_NAME, m_classSignature); 138 aspectOf.visitInsn(ARETURN); 139 aspectOf.visitMaxs(0, 0); 140 141 m_cw.visitEnd(); 142 143 return m_cw.toByteArray(); 144 } 145 146 152 public static String getCflowAspectClassName(int cflowID) { 153 return JIT_CFLOW_CLASS + cflowID; 154 } 155 156 163 public static Class compileCflowAspectAndAttachToClassLoader(ClassLoader loader, int cflowID) { 164 CompiledCflowAspect cflowAspect = compileCflowAspect(cflowID); 169 170 if (AbstractJoinPointCompiler.DUMP_JP_CLASSES) { 171 try { 172 AsmHelper.dumpClass("_dump", getCflowAspectClassName(cflowID), cflowAspect.bytecode); 173 } catch (Throwable t) { 174 ; 175 } 176 } 177 178 Class cflowAspectClass = AsmHelper.defineClass( 179 loader, 180 cflowAspect.bytecode, 181 getCflowAspectClassName(cflowID) 182 ); 183 return cflowAspectClass; 184 } 185 186 192 public static CompiledCflowAspect compileCflowAspect(int cflowID) { 193 CompiledCflowAspect cflowAspect = new CompiledCflowAspect(); 194 CflowCompiler compiler = new CflowCompiler(cflowID); 195 cflowAspect.bytecode = compiler.compile(); 196 cflowAspect.className = compiler.m_className; 197 return cflowAspect; 198 } 199 200 203 public static class CompiledCflowAspect { 204 public byte[] bytecode; 205 public String className; 207 public boolean equals(Object o) { 208 if (this == o) return true; 209 if (!(o instanceof CompiledCflowAspect)) return false; 210 211 final CompiledCflowAspect compiledCflowAspect = (CompiledCflowAspect) o; 212 213 if (!className.equals(compiledCflowAspect.className)) return false; 214 215 return true; 216 } 217 218 public int hashCode() { 219 return className.hashCode(); 220 } 221 } 222 } 223 | Popular Tags |