1
2
3
4 package org.softevo.jdynpur.runtime;
5
6 import org.objectweb.asm.MethodVisitor;
7 import org.objectweb.asm.Opcodes;
8 import org.objectweb.asm.commons.LocalVariablesSorter;
9
10 public class ArrayTracingVisitor extends LocalVariablesSorter implements Opcodes {
11
12 private int temporaryVariableIndex = -1;
13
14 public ArrayTracingVisitor(MethodVisitor visitor, int access, String desc) {
15 super(access, desc, visitor);
16 }
17
18 @Override
19 public void visitTypeInsn(int opcode, String typeDescription) {
20 if (opcode == ANEWARRAY) {
21 super.visitTypeInsn(opcode, typeDescription);
22 super.visitInsn(DUP);
23 super.visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "arrayCreated", "(Ljava/lang/Object;)V");
24 } else {
25 super.visitTypeInsn(opcode, typeDescription);
26 }
27 }
28
29 @Override
30 public void visitIntInsn(int opcode, int operand) {
31 if (opcode == NEWARRAY) {
32 super.visitIntInsn(opcode, operand);
33 super.visitInsn(DUP);
34 super.visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "arrayCreated", "(Ljava/lang/Object;)V");
35 } else {
36 super.visitIntInsn(opcode, operand);
37 }
38 }
39
40 @Override
41 public void visitInsn(int opcode) {
42 int storeOpCode, loadOpCode;
43
44 if ((opcode == AASTORE) || (opcode == SASTORE) || (opcode == BASTORE) || (opcode == CASTORE) || (opcode == FASTORE)
45 || (opcode == IASTORE)) {
46 super.visitInsn(DUP2_X1);
47 super.visitInsn(POP2);
48 super.visitInsn(DUP_X2);
49 super
50 .visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "arrayModified", "(Ljava/lang/Object;)V");
51 super.visitInsn(opcode);
52 } else if (opcode == AASTORE) {
53
54 super.visitInsn(DUP2_X1);
55 super.visitInsn(POP2);
56 super.visitInsn(DUP_X2);
57 super.visitInsn(DUP2_X1);
58 super.visitInsn(POP2);
59 super.visitInsn(DUP_X2);
60 super.visitInsn(DUP2_X1);
61 super.visitInsn(POP2);
62 super.visitInsn(DUP_X2);
63 super.visitInsn(opcode);
64 super.visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "objectArrayModified", "(Ljava/lang/Object;ILjava/lang/Object;)V");
65 } else if ((opcode == LASTORE) || (opcode == DASTORE)) {
66 if (opcode == LASTORE) {
67 storeOpCode = LSTORE;
68 loadOpCode = LLOAD;
69 } else {
70 storeOpCode = DSTORE;
71 loadOpCode = DLOAD;
72 }
73 if (temporaryVariableIndex == -1) {
74 temporaryVariableIndex = newLocal(2);
75 }
76 super.visitVarInsn(storeOpCode, temporaryVariableIndex);
77 super.visitInsn(SWAP);
78 super.visitInsn(DUP_X1);
79 super.visitInsn(SWAP);
80 super.visitVarInsn(loadOpCode, temporaryVariableIndex);
81
82 super.visitInsn(opcode);
83 super
84 .visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "arrayModified", "(Ljava/lang/Object;)V");
85 } else {
86 super.visitInsn(opcode);
87 }
88 }
89
90 @Override
91 public void visitMultiANewArrayInsn(String typeDesc, int dimensions) {
92 super.visitMultiANewArrayInsn(typeDesc, dimensions);
93 super.visitInsn(DUP);
94 super.visitInsn(DUP);
95 super.visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "arrayCreated", "(Ljava/lang/Object;)V");
96 super.visitLdcInsn(new Integer(dimensions - 2));
97 super.visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "addArraysRecursively",
98 "([Ljava/lang/Object;I)V");
99 }
100
101 }