我目前正在使用 OPAL 框架开发 Java 代码的静态分析。我想分析以下Java方法:
private void indirectCaller2b(double d, Object o1, Object o2) {
indirectCaller1(d, o1, o2);
}
我知道,indirectCaller2b 仅使用参数(double、ArrayList、LinkedList)调用。
考虑到这一点,我构造了一个 DomainValues 的 IndexedSeq,我将它传递给 perform-method ob BaseAI。它看起来像这样:
向量({ai.native_methods_parameter_type_approximation.PublicClass, null}[@0;t=101], ADoubleValue, {_ <: java.util.ArrayList, null}[@-4;t=102], {_ <: java. util.LinkedList, null}[@-5;t=103])
这个参数 ({ai.native_methods_parameter_type_approximation.PublicClass, null}[@0;t=101]) 是使用以下代码创建的:
domain.TypedValue(0, project.classFile(caller).thisType)
其他域值是使用 parameterToValueIndex 方法创建的:
org.opalj.ai.parameterToValueIndex(caller.isStatic, caller.descriptor, index), t)
这里,caller 代表方法indirectCaller2b,t 是参数的已知运行时类型(参数索引1 的ArrayList 和参数索引2 的LinkedList)。
当我现在对方法进行抽象解释时
BaseAI.perform(classFile, caller, domain)(Some(parameters))
并在程序计数器上打印堆栈索引,indirectCaller1 的调用发生在以下代码中,
for (i <- 0 to analysisResult.operandsArray(pc).size - 1) {
println(s"stack index $i: ${analysisResult.operandsArray(pc)(i)}")
}
我得到以下输出:
堆栈索引 0:空
堆栈索引 1: {_ <: java.util.LinkedList, null}[@-5;t=103]
堆栈索引 2:ADoubleValue
堆栈索引 3: {ai.native_methods_parameter_type_approximation.PublicClass, null}[@0;t=101]
这有点令人困惑,因为我只是将indirectCaller2b 的参数传递给了indirectCaller1。因此,输出应该与传递给 perform 方法的 IndexedSeq 相同。
但是在输出中,double 参数后面的参数是 LinkedList 而不是 ArrayList。ArrayList 参数不知何故消失了,operandStack 上的最后一个参数是“null”。
谁能解释一下,这怎么会发生?