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 }