1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.nabla.automatic.analysis;
18
19 import java.util.Iterator;
20 import java.util.List;
21
22 import org.objectweb.asm.Type;
23 import org.objectweb.asm.tree.AbstractInsnNode;
24 import org.objectweb.asm.tree.analysis.AnalyzerException;
25 import org.objectweb.asm.tree.analysis.BasicInterpreter;
26 import org.objectweb.asm.tree.analysis.BasicValue;
27 import org.objectweb.asm.tree.analysis.Value;
28
29
30
31
32
33 public class TrackingInterpreter extends BasicInterpreter {
34
35
36
37 public TrackingInterpreter() {
38 }
39
40
41 @Override
42 public Value newValue(final Type type) {
43 return (type == null) ? TrackingValue.UNINITIALIZED_VALUE : wrap(super.newValue(type), null);
44 }
45
46
47 @Override
48 public Value newOperation(final AbstractInsnNode insn) {
49 return wrap(super.newOperation(insn), insn);
50 }
51
52
53 @Override
54 public Value unaryOperation(final AbstractInsnNode insn,
55 final Value value)
56 throws AnalyzerException {
57 ((TrackingValue) value).addConsumer(insn);
58 return wrap(super.unaryOperation(insn, value), insn);
59 }
60
61
62 @Override
63 public Value binaryOperation(final AbstractInsnNode insn,
64 final Value value1, final Value value2)
65 throws AnalyzerException {
66 ((TrackingValue) value1).addConsumer(insn);
67 ((TrackingValue) value2).addConsumer(insn);
68 return wrap(super.binaryOperation(insn, value1, value2), insn);
69 }
70
71
72 @Override
73 public Value ternaryOperation(final AbstractInsnNode insn,
74 final Value value1, final Value value2,
75 final Value value3)
76 throws AnalyzerException {
77 ((TrackingValue) value1).addConsumer(insn);
78 ((TrackingValue) value2).addConsumer(insn);
79 ((TrackingValue) value3).addConsumer(insn);
80 return wrap(super.ternaryOperation(insn, value1, value2, value3), insn);
81 }
82
83
84 @SuppressWarnings("unchecked")
85 @Override
86 public Value naryOperation(final AbstractInsnNode insn,
87 final List values)
88 throws AnalyzerException {
89 for (final Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
90 ((TrackingValue) iterator.next()).addConsumer(insn);
91 }
92 return wrap(super.naryOperation(insn, values), insn);
93 }
94
95
96 @Override
97 public Value copyOperation(final AbstractInsnNode insn,
98 final Value value)
99 throws AnalyzerException {
100
101
102 final TrackingValue tv = (TrackingValue) value;
103 tv.addConsumer(insn);
104 tv.addProducer(insn);
105 return value;
106 }
107
108
109 @Override
110 public Value merge(final Value v, final Value w) {
111
112 final TrackingValue tv = (TrackingValue) v;
113 final TrackingValue tw = (TrackingValue) w;
114 TrackingValue.merge(tv, tw);
115
116 final BasicValue superMerged = (BasicValue) super.merge(tv.getValue(), tw.getValue());
117 return (superMerged == tv.getValue()) ? tv : new TrackingValue(superMerged);
118
119 }
120
121
122
123
124
125
126 private TrackingValue wrap(final Value value,
127 final AbstractInsnNode producer) {
128
129 if (value == null) {
130 return null;
131 }
132
133
134
135
136 final TrackingValue tv = (value instanceof TrackingValue) ?
137 (TrackingValue) value :
138 new TrackingValue((BasicValue) value);
139
140 if (producer != null) {
141 tv.addProducer(producer);
142 }
143
144 return tv;
145
146 }
147
148 }