1 23 24 package org.objectweb.fractal.julia.asm; 25 26 import org.objectweb.asm.CodeAdapter; 27 import org.objectweb.asm.CodeVisitor; 28 import org.objectweb.asm.Constants; 29 import org.objectweb.asm.Label; 30 31 import java.lang.reflect.Method ; 32 33 42 43 public abstract class InterceptorCodeAdapter 44 extends CodeAdapter 45 implements Constants 46 { 47 48 51 52 public final static int EMPTY = 0; 53 54 58 59 public final static int NORMAL = 1; 60 61 65 66 public final static int FINALLY = 2; 67 68 71 72 protected Method m; 73 74 78 79 protected int nbFormals; 80 81 84 85 protected int returnLocal; 86 87 91 92 private int newLocals; 93 94 97 98 private int postBlockType; 99 100 103 104 protected Label postBlockLabel; 105 106 110 125 126 public InterceptorCodeAdapter ( 127 final CodeVisitor cv, 128 final Method m, 129 final int newLocals, 130 final int postBlockType) 131 { 132 super(cv); 133 int parameterSize = 1; 135 Class [] formals = m.getParameterTypes(); 136 for (int i = 0; i < formals.length; ++i) { 137 if (formals[i] == Long.TYPE || formals[i] == Double.TYPE) { 138 parameterSize += 2; 139 } else { 140 parameterSize += 1; 141 } 142 } 143 int returnSize; 145 Class result = m.getReturnType(); 146 if (result == Long.TYPE || result == Double.TYPE) { 147 returnSize = 2; 148 } else if (result != Void.TYPE) { 149 returnSize = 1; 150 } else { 151 returnSize = 0; 152 } 153 this.m = m; 155 this.nbFormals = parameterSize; 156 this.returnLocal = parameterSize + newLocals; 157 this.newLocals = newLocals + returnSize; 158 this.postBlockType = postBlockType; 159 this.postBlockLabel = new Label(); 160 } 161 162 166 186 187 public void visitInsn (final int opcode) { 188 if (postBlockType == EMPTY) { 189 cv.visitInsn(opcode); 190 return; 191 } 192 switch (opcode) { 193 case IRETURN: 194 case LRETURN: 195 case FRETURN: 196 case DRETURN: 197 case ARETURN: 198 int opcOffset = opcode - IRETURN; 199 cv.visitVarInsn(ISTORE + opcOffset, returnLocal); 200 if (postBlockType == NORMAL) { 201 cv.visitJumpInsn(GOTO, postBlockLabel); 202 } else { 203 cv.visitJumpInsn(JSR, postBlockLabel); 204 cv.visitVarInsn(ILOAD + opcOffset, returnLocal); 205 cv.visitInsn(opcode); 206 } 207 break; 208 case RETURN: 209 if (postBlockType == NORMAL) { 210 cv.visitJumpInsn(GOTO, postBlockLabel); 211 } else { 212 cv.visitJumpInsn(JSR, postBlockLabel); 213 cv.visitInsn(RETURN); 214 } 215 break; 216 default: 217 cv.visitInsn(opcode); 218 } 219 } 220 221 227 228 public void visitVarInsn (final int opcode, final int var) { 229 cv.visitVarInsn(opcode, var >= nbFormals ? var + newLocals : var); 230 } 231 232 238 239 public void visitIincInsn (final int var, final int increment) { 240 cv.visitIincInsn(var >= nbFormals ? var + newLocals : var, increment); 241 } 242 243 247 256 257 protected void generateReturnCode () { 258 Class c = m.getReturnType(); 259 if (c.isPrimitive()) { 260 if (c == Void.TYPE) { 261 cv.visitInsn(RETURN); 262 } else if (c == Long.TYPE) { 263 cv.visitVarInsn(LLOAD, returnLocal); 264 cv.visitInsn(LRETURN); 265 } else if (c == Float.TYPE) { 266 cv.visitVarInsn(FLOAD, returnLocal); 267 cv.visitInsn(FRETURN); 268 } else if (c == Double.TYPE) { 269 cv.visitVarInsn(DLOAD, returnLocal); 270 cv.visitInsn(DRETURN); 271 } else { 272 cv.visitVarInsn(ILOAD, returnLocal); 273 cv.visitInsn(IRETURN); 274 } 275 } else { 276 cv.visitVarInsn(ALOAD, returnLocal); 277 cv.visitInsn(ARETURN); 278 } 279 } 280 } 281 | Popular Tags |