1 package org.softevo.jdynpur.runtime; 2 import java.util.Collections; 3 import java.util.HashMap; 4 import java.util.Vector; 5 6 import org.objectweb.asm.MethodVisitor; 7 import org.objectweb.asm.MethodAdapter; 8 import org.objectweb.asm.Opcodes; 9 import org.objectweb.asm.Type; 10 import org.softevo.util.asm.MethodIdentifier; 11 12 public class ParameterTracingVisitor extends MethodAdapter implements Opcodes { 13 14 private MethodIdentifier methodIdentifier; 15 16 private HashMap<Integer, Integer> objectParameterIndices = null; 17 18 private boolean isConstructor = false; 19 20 private String superClassName; 21 22 public ParameterTracingVisitor(MethodVisitor visitor, MethodIdentifier methodIdentifier, String superClassName) { 23 super(visitor); 24 this.methodIdentifier = methodIdentifier; 25 this.superClassName = superClassName; 26 objectParameterIndices = getObjectParameterIndices(methodIdentifier); 27 isConstructor = methodIdentifier.getMethodName().equals("<init>"); 28 } 29 30 protected HashMap<Integer, Integer> getObjectParameterIndices(MethodIdentifier methodIdentifier) { 31 HashMap<Integer, Integer> result; 32 Type[] argumentTypes; 33 int counter; 34 35 argumentTypes = Type.getArgumentTypes(methodIdentifier.getSignature()); 36 result = new HashMap<Integer, Integer>(argumentTypes.length); 37 int parameterCounter; 38 if ((ACC_STATIC & methodIdentifier.getAccess()) > 0) { 39 counter = 0; 40 parameterCounter = 0; 41 } else { 42 counter = 1; 43 parameterCounter = 1; 44 result.put(0, 0); 45 } 46 for (Type type : argumentTypes) { 47 if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { 48 result.put(parameterCounter, counter); 49 } else if (type.getSort() == Type.LONG || type.getSort() == Type.DOUBLE) { 50 counter++; 51 } 52 counter++; 53 parameterCounter++; 54 } 55 return result; 56 } 57 58 public void visitMethodInsn(int opCode, String owner, String name, String desc) { 59 if (isConstructor && (opCode == INVOKESPECIAL) && name.equals("<init>") 60 && (owner.equals(methodIdentifier.getClassName()) || owner.equals(superClassName))) { 61 super.visitMethodInsn(opCode, owner, name, desc); 62 Vector<Integer> parameterIndices = new Vector<Integer>(objectParameterIndices.keySet()); 63 Collections.sort(parameterIndices); 64 for (Integer index : parameterIndices) { 65 super.visitLdcInsn(index); 66 super.visitVarInsn(ALOAD, objectParameterIndices.get(index)); 67 super.visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "parameterPassed", 68 "(ILjava/lang/Object;)V"); 69 } 70 } else { 71 super.visitMethodInsn(opCode, owner, name, desc); 72 } 73 } 74 75 @Override 76 public void visitCode() { 77 super.visitCode(); 78 if (!isConstructor) { 79 Vector<Integer> parameterIndices = new Vector<Integer>(objectParameterIndices.keySet()); 80 Collections.sort(parameterIndices); 81 for (Integer index : parameterIndices) { 82 super.visitLdcInsn(index); 83 super.visitVarInsn(ALOAD, objectParameterIndices.get(index)); 84 super.visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "parameterPassed", 85 "(ILjava/lang/Object;)V"); 86 } 87 } 88 } 89 90 91 }