OPAL: нулевое значение в operandsArray
В настоящее время я занимаюсь разработкой статического анализа кода Java с использованием инфраструктуры OPAL. Я хочу проанализировать следующий метод Java:
private void indirectCaller2b(double d, Object o1, Object o2) {
indirectCaller1(d, o1, o2);
}
Я знаю, что irectalCaller2b вызывается только с параметрами (double, ArrayList, LinkedList).
Имея это в виду, я сконструировал IndexedSeq для DomainValues, который я передал методу перформанса ob BaseAI. Это выглядит так:
Vector ({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])
Параметр this ({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)
Здесь вызывающая сторона обозначает метод irectCaller2b, а t - известный тип времени выполнения параметра (ArrayList для индекса параметра 1 и LinkedList для индекса параметра 2).
Когда я сейчас выполняю абстрактную интерпретацию метода с
BaseAI.perform(classFile, caller, domain)(Some(parameters))
и выведите индекс стека в программном счетчике, где вызов косвенного вызова1 происходит со следующим кодом:
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]
Это немного сбивает с толку, так как я просто передаю аргументы irectalCaller2 в irect. Следовательно, выходные данные должны совпадать с передачей IndexedSeq в метод execute.
Но в выходных данных параметром после двойного параметра является LinkedList вместо ArrayList. Параметр ArrayList каким-то образом исчез, а последний параметр в операндстаке имеет значение "ноль".
Может кто-нибудь объяснить мне, как это может произойти?
1 ответ
Представление "это"
Чтобы получить правильное представление для этой ссылки, вы должны использовать метод
InitializedObjectValue(
origin: ValueOrigin,
objectType: ObjectType ): DomainReferenceValue
создать представление этого значения. Разница заключается в том, что в этом случае ИИ будет пытаться использовать информацию о том, что (a) значение гарантированно не равно нулю, а также гарантированно будет инициализировано. В частности, первое свойство часто интересно и обычно приводит к более точным результатам.
Инициализация местных жителей
Функция: org.opalj.ai.parameterToValueIndex
вычисляет только информацию о логическом источнике ("pc", связанный со значением, чтобы впоследствии можно было идентифицировать соответствующие значения в качестве параметров).
Чтобы правильно сопоставить операнды с местными жителями, вы можете использовать метод mapOperandsToParameters
или вы просто добавляете все значения в IndexedSeq
но добавь еще null
значение для значений типа 2 вычислительного типа.