Skip to content

Commit 7b9b426

Browse files
author
blacktree
committed
CHABuilder fixed
1 parent 67e9275 commit 7b9b426

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

A4/tai-e/src/main/java/pascal/taie/analysis/graph/callgraph/CHABuilder.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@
2929
import pascal.taie.language.classes.JClass;
3030
import pascal.taie.language.classes.JMethod;
3131
import pascal.taie.language.classes.Subsignature;
32+
import polyglot.util.WorkList;
3233

34+
import java.lang.invoke.CallSite;
3335
import java.util.ArrayDeque;
36+
import java.util.HashSet;
3437
import java.util.Queue;
3538
import java.util.Set;
3639

@@ -49,8 +52,24 @@ public CallGraph<Invoke, JMethod> build() {
4952

5053
private CallGraph<Invoke, JMethod> buildCallGraph(JMethod entry) {
5154
DefaultCallGraph callGraph = new DefaultCallGraph();
52-
callGraph.addEntryMethod(entry);
55+
// callGraph.addEntryMethod(entry);
5356
// TODO - finish me
57+
Queue<JMethod> worklist = new ArrayDeque<>();
58+
worklist.add(entry);
59+
while (!worklist.isEmpty()) {
60+
JMethod method = worklist.remove();
61+
if (!callGraph.contains(method)) {
62+
callGraph.addReachableMethod(method);
63+
callGraph.callSitesIn(method).forEach(cs -> {
64+
var methods = resolve(cs);
65+
for (var m : methods) {
66+
var edge = new Edge<Invoke, JMethod>(CallGraphs.getCallKind(cs), cs, m);
67+
callGraph.addEdge(edge);
68+
worklist.add(m);
69+
}
70+
});
71+
}
72+
}
5473
return callGraph;
5574
}
5675

@@ -59,7 +78,27 @@ private CallGraph<Invoke, JMethod> buildCallGraph(JMethod entry) {
5978
*/
6079
private Set<JMethod> resolve(Invoke callSite) {
6180
// TODO - finish me
62-
return null;
81+
Set<JMethod> candidates = new HashSet<>();
82+
var kind = CallGraphs.getCallKind(callSite);
83+
var methodRef = callSite.getMethodRef();
84+
var declareClass = methodRef.getDeclaringClass();
85+
var signature = methodRef.getSubsignature();
86+
if (kind == CallKind.STATIC) {
87+
var method = declareClass.getDeclaredMethod(signature);
88+
candidates.add(method);
89+
return candidates;
90+
}
91+
if (kind == CallKind.SPECIAL) {
92+
candidates.add(dispatch(declareClass, signature));
93+
return candidates;
94+
}
95+
if (kind == CallKind.VIRTUAL) {
96+
candidates.add(dispatch(declareClass, signature));
97+
hierarchy.getDirectSubclassesOf(declareClass).forEach(jClass -> {
98+
candidates.add(dispatch(jClass, methodRef.getSubsignature()));
99+
});
100+
}
101+
return candidates;
63102
}
64103

65104
/**
@@ -70,6 +109,9 @@ private Set<JMethod> resolve(Invoke callSite) {
70109
*/
71110
private JMethod dispatch(JClass jclass, Subsignature subsignature) {
72111
// TODO - finish me
73-
return null;
112+
var method = jclass.getDeclaredMethod(subsignature);
113+
if (method != null) return method;
114+
if (jclass.getSuperClass() == null) return null;
115+
return dispatch(jclass.getSuperClass(), subsignature);
74116
}
75117
}

0 commit comments

Comments
 (0)