@@ -38,109 +38,108 @@ class OpalCallGraph(
38
38
entryPoints : Set [Method ]
39
39
) extends CallGraph {
40
40
41
- // TODO Deal with <clinit>
42
- callGraph
43
- .reachableMethods()
44
- .foreach(method => {
45
- method.method match {
46
- case definedMethod : DefinedMethod =>
47
- if (definedMethod.definedMethod.body.isDefined) {
48
- addEdgesFromMethod(definedMethod)
49
- }
50
- // TODO Should this case be considered?
51
- // case definedMethods: MultipleDefinedMethods =>
52
- // definedMethods.foreachDefinedMethod(m => addEdgesFromMethod(m))
53
- case _ =>
54
- }
55
- })
41
+ callGraph
42
+ .reachableMethods()
43
+ .foreach(method => {
44
+ method.method match {
45
+ case definedMethod : DefinedMethod =>
46
+ if (definedMethod.definedMethod.body.isDefined) {
47
+ addEdgesFromMethod(definedMethod)
48
+ }
49
+ // TODO Should this case be considered?
50
+ // case definedMethods: MultipleDefinedMethods =>
51
+ // definedMethods.foreachDefinedMethod(m => addEdgesFromMethod(m))
52
+ case _ =>
53
+ }
54
+ })
56
55
57
- private def addEdgesFromMethod (method : DefinedMethod ): Unit = {
58
- val tacCode = TacBodyBuilder (project, method.definedMethod)
56
+ private def addEdgesFromMethod (method : DefinedMethod ): Unit = {
57
+ val tacCode = TacBodyBuilder (project, method.definedMethod)
59
58
60
- tacCode.statements.foreach(stmt => {
61
- val srcStatement =
62
- new OpalStatement (stmt, OpalMethod (method.definedMethod, tacCode))
59
+ tacCode.statements.foreach(stmt => {
60
+ val srcStatement =
61
+ new OpalStatement (stmt, OpalMethod (method.definedMethod, tacCode))
63
62
64
- if (srcStatement.containsInvokeExpr()) {
65
- // Due to inlining variables, the PC's of statements and invoke expressions may differ
66
- val invokeExprPc = getPcForInvokeExpr(srcStatement.getInvokeExpr)
67
- val callees = callGraph.directCalleesOf(method, invokeExprPc)
63
+ if (srcStatement.containsInvokeExpr()) {
64
+ // Due to inlining variables, the PC's of statements and invoke expressions may differ
65
+ val invokeExprPc = getPcForInvokeExpr(srcStatement.getInvokeExpr)
66
+ val callees = callGraph.directCalleesOf(method, invokeExprPc)
68
67
69
- callees.foreach(callee => {
70
- callee.method match {
71
- case definedMethod : DefinedMethod =>
72
- val method = definedMethod.definedMethod
68
+ callees.foreach(callee => {
69
+ callee.method match {
70
+ case definedMethod : DefinedMethod =>
71
+ val method = definedMethod.definedMethod
73
72
74
- if (method.body.isDefined) {
75
- val targetMethod = OpalMethod (method)
73
+ if (method.body.isDefined) {
74
+ val targetMethod = OpalMethod (method)
76
75
77
- addEdge(new Edge (srcStatement, targetMethod))
78
- } else {
79
- val targetMethod = OpalPhantomMethod (
80
- definedMethod.declaringClassType,
81
- definedMethod.name,
82
- definedMethod.descriptor,
83
- method.isStatic
84
- )
76
+ addEdge(new Edge (srcStatement, targetMethod))
77
+ } else {
78
+ val targetMethod = OpalPhantomMethod (
79
+ definedMethod.declaringClassType,
80
+ definedMethod.name,
81
+ definedMethod.descriptor,
82
+ method.isStatic
83
+ )
85
84
86
- addEdge(new Edge (srcStatement, targetMethod))
87
- }
88
- case virtualMethod : VirtualDeclaredMethod =>
89
- val targetMethod = OpalPhantomMethod (
90
- virtualMethod.declaringClassType,
91
- virtualMethod.name,
92
- virtualMethod.descriptor,
93
- srcStatement.getInvokeExpr.isStaticInvokeExpr
94
- )
85
+ addEdge(new Edge (srcStatement, targetMethod))
86
+ }
87
+ case virtualMethod : VirtualDeclaredMethod =>
88
+ val targetMethod = OpalPhantomMethod (
89
+ virtualMethod.declaringClassType,
90
+ virtualMethod.name,
91
+ virtualMethod.descriptor,
92
+ srcStatement.getInvokeExpr.isStaticInvokeExpr
93
+ )
95
94
96
- addEdge(new Edge (srcStatement, targetMethod))
97
- case definedMethods : MultipleDefinedMethods =>
98
- definedMethods.foreachDefinedMethod(method => {
99
- val targetMethod = OpalMethod (method)
95
+ addEdge(new Edge (srcStatement, targetMethod))
96
+ case definedMethods : MultipleDefinedMethods =>
97
+ definedMethods.foreachDefinedMethod(method => {
98
+ val targetMethod = OpalMethod (method)
100
99
101
- addEdge(new Edge (srcStatement, targetMethod))
102
- })
103
- }
104
- })
105
- }
100
+ addEdge(new Edge (srcStatement, targetMethod))
101
+ })
102
+ }
106
103
})
107
- }
104
+ }
105
+ })
106
+ }
108
107
109
- private def getPcForInvokeExpr (invokeExpr : InvokeExpr ): Int = {
110
- invokeExpr match {
111
- case methodInvokeExpr : OpalMethodInvokeExpr =>
112
- methodInvokeExpr.delegate.pc
113
- case functionInvokeExpr : OpalFunctionInvokeExpr =>
114
- functionInvokeExpr.delegate match {
115
- case call : NonVirtualFunctionCall [_] => call.pc
116
- case call : VirtualFunctionCall [_] => call.pc
117
- case call : StaticFunctionCall [_] => call.pc
118
- case _ =>
119
- throw new RuntimeException (
120
- " Unknown function call: " + functionInvokeExpr
121
- )
122
- }
123
- case _ =>
124
- throw new RuntimeException (" Unknown invoke expression: " + invokeExpr)
108
+ private def getPcForInvokeExpr (invokeExpr : InvokeExpr ): Int = {
109
+ invokeExpr match {
110
+ case methodInvokeExpr : OpalMethodInvokeExpr =>
111
+ methodInvokeExpr.delegate.pc
112
+ case functionInvokeExpr : OpalFunctionInvokeExpr =>
113
+ functionInvokeExpr.delegate match {
114
+ case call : NonVirtualFunctionCall [_] => call.pc
115
+ case call : VirtualFunctionCall [_] => call.pc
116
+ case call : StaticFunctionCall [_] => call.pc
117
+ case _ =>
118
+ throw new RuntimeException (
119
+ " Unknown function call: " + functionInvokeExpr
120
+ )
125
121
}
122
+ case _ =>
123
+ throw new RuntimeException (" Unknown invoke expression: " + invokeExpr)
126
124
}
125
+ }
127
126
128
- // Explicitly add static initializers (<clinit>) as they are called only implicitly
129
- callGraph
130
- .reachableMethods()
131
- .foreach(method => {
132
- method.method match {
133
- case definedMethod : DefinedMethod if definedMethod.definedMethod.isStaticInitializer =>
134
- if (definedMethod.definedMethod.body.isDefined) {
135
- addEntryPoint(OpalMethod (definedMethod.definedMethod))
136
- }
137
- case _ =>
138
- }
139
- })
140
-
141
- entryPoints.foreach(entryPoint => {
142
- if (entryPoint.body.isDefined) {
143
- addEntryPoint(OpalMethod (entryPoint))
144
- }
127
+ // Explicitly add static initializers (<clinit>) as they are called only implicitly
128
+ callGraph
129
+ .reachableMethods()
130
+ .foreach(method => {
131
+ method.method match {
132
+ case definedMethod : DefinedMethod if definedMethod.definedMethod.isStaticInitializer =>
133
+ if (definedMethod.definedMethod.body.isDefined) {
134
+ addEntryPoint(OpalMethod (definedMethod.definedMethod))
135
+ }
136
+ case _ =>
137
+ }
145
138
})
139
+
140
+ entryPoints.foreach(entryPoint => {
141
+ if (entryPoint.body.isDefined) {
142
+ addEntryPoint(OpalMethod (entryPoint))
143
+ }
144
+ })
146
145
}
0 commit comments