1 23 24 package org.objectweb.fractal.julia.asm; 25 26 import org.objectweb.fractal.julia.InitializationContext; 27 28 import org.objectweb.asm.CodeVisitor; 29 import org.objectweb.asm.Label; 30 import org.objectweb.asm.Type; 31 32 import java.lang.reflect.Method ; 33 34 80 81 public class LifeCycleCodeGenerator extends AbstractCodeGenerator { 82 83 86 87 private InterceptorClassGenerator icg; 88 89 92 93 private String lcFieldDesc; 94 95 98 99 private String scFieldsOwner; 100 101 105 public int init (final InterceptorClassGenerator icg) { 106 this.icg = icg; 107 return IN; 108 } 109 110 public void generateInitCode (final CodeVisitor cv) 111 throws ClassGenerationException 112 { 113 String owner = null; 116 for (int i = 0; i < icg.controllerClasses.length; ++i) { 117 Class c = icg.controllerClasses[i]; 118 try { 119 c.getField("fcInvocationCounter"); 120 owner = c.getName(); 121 break; 122 } catch (Exception ignored) { 123 } 124 } 125 if (owner == null) { 126 throw new ClassGenerationException( 127 null, 128 icg.args.toString(), 129 "Cannot find a controller providing a 'fcInvocationCounter' field"); 130 } 131 owner = owner.replace('.', '/'); 132 133 lcFieldDesc = "L" + owner + ";"; 134 scFieldsOwner = owner; 135 136 icg.cw.visitField(ACC_PRIVATE, "lc", lcFieldDesc, null, null); 137 138 cv.visitVarInsn(ALOAD, 0); 139 cv.visitVarInsn(ALOAD, 1); 140 cv.visitLdcInsn("lifecycle-controller"); 141 cv.visitMethodInsn( 142 INVOKEVIRTUAL, 143 Type.getInternalName(InitializationContext.class), 144 "getInterface", 145 "(Ljava/lang/String;)Ljava/lang/Object;"); 146 cv.visitTypeInsn(CHECKCAST, owner); 147 cv.visitFieldInsn(PUTFIELD, icg.name, "lc", lcFieldDesc); 148 } 149 150 protected int getInterceptionType (final Method m) { 151 return InterceptorCodeAdapter.FINALLY; 152 } 153 154 protected int getInterceptionCodeFormals (final Method m) { 155 return 1; 157 } 158 159 public void generateCloneCode (final CodeVisitor cv) { 160 cv.visitVarInsn(ALOAD, 1); 161 cv.visitVarInsn(ALOAD, 0); 162 cv.visitFieldInsn(GETFIELD, icg.name, "lc", lcFieldDesc); 163 cv.visitFieldInsn(PUTFIELD, icg.name, "lc", lcFieldDesc); 164 } 165 166 170 protected void generateInterceptionCodeBlock ( 171 final Method m, 172 final boolean pre, 173 final CodeVisitor cv, 174 final int formals) 175 { 176 if (scFieldsOwner == null) { 177 scFieldsOwner = icg.name; 182 } 183 184 Label beginHandler = new Label(); 185 Label endHandler = new Label(); 186 Label ifLabel = new Label(); 187 Label endIfLabel = new Label(); 188 Label endLabel = new Label(); 189 190 cv.visitVarInsn(ALOAD, 0); 192 if (lcFieldDesc != null) { 195 cv.visitFieldInsn(GETFIELD, icg.name, "lc", lcFieldDesc); 196 } 197 cv.visitInsn(DUP); 198 cv.visitVarInsn(ASTORE, formals); 199 cv.visitInsn(MONITORENTER); 200 cv.visitLabel(beginHandler); 201 202 cv.visitVarInsn(ALOAD, 0); 204 if (lcFieldDesc != null) { 205 cv.visitFieldInsn(GETFIELD, icg.name, "lc", lcFieldDesc); 206 } 207 cv.visitFieldInsn(GETFIELD, scFieldsOwner, "fcState", "I"); 208 cv.visitInsn(ICONST_2); 209 cv.visitJumpInsn(IF_ICMPEQ, ifLabel); 210 211 cv.visitVarInsn(ALOAD, 0); 213 if (lcFieldDesc != null) { 214 cv.visitFieldInsn(GETFIELD, icg.name, "lc", lcFieldDesc); 215 } 216 cv.visitMethodInsn( 217 INVOKEVIRTUAL, 218 scFieldsOwner, 219 pre ? "incrementFcInvocationCounter" : "decrementFcInvocationCounter", 220 "()V"); 221 222 cv.visitJumpInsn(GOTO, endIfLabel); 224 cv.visitLabel(ifLabel); 225 226 cv.visitVarInsn(ALOAD, 0); 228 if (lcFieldDesc != null) { 229 cv.visitFieldInsn(GETFIELD, icg.name, "lc", lcFieldDesc); 230 } 231 cv.visitInsn(DUP); 232 cv.visitFieldInsn(GETFIELD, scFieldsOwner, "fcInvocationCounter", "I"); 233 cv.visitInsn(ICONST_1); 234 cv.visitInsn(pre ? IADD : ISUB); 235 cv.visitFieldInsn(PUTFIELD, scFieldsOwner, "fcInvocationCounter", "I"); 236 237 cv.visitLabel(endIfLabel); 239 cv.visitVarInsn(ALOAD, formals); 240 cv.visitInsn(MONITOREXIT); 241 cv.visitJumpInsn(GOTO, endLabel); 242 cv.visitLabel(endHandler); 243 cv.visitVarInsn(ALOAD, formals); 244 cv.visitInsn(MONITOREXIT); 245 cv.visitInsn(ATHROW); 246 cv.visitLabel(endLabel); 247 248 cv.visitTryCatchBlock(beginHandler, endHandler, endHandler, null); 249 } 250 } 251 | Popular Tags |