View Javadoc

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  }