2016-06-18 14 views
0

Ich entwickle derzeit eine statische Analyse von Java-Code mit dem OPAL-Framework. Ich möchte folgende Java-Methode analysieren:OPAL: Null-Wert in OperandenArray

private void indirectCaller2b(double d, Object o1, Object o2) { 
    indirectCaller1(d, o1, o2); 
} 

Ich weiß, dass indirectCaller2b nur mit den Parametern (Doppel, Arraylist, LinkedList) genannt wird.

Vor diesem Hintergrund konstruierte ich einen IndexedSeq von DomainValues, die ich an die Perform-Methode Ob BaseAI übergeben. Es sieht wie folgt aus:

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])

Der this-Parameter ({ai.native_methods_parameter_type_approximation.PublicClass, null} [@ 0; t = 101]) wurde mit folgendem Code erstellt:

domain.TypedValue(0, project.classFile(caller).thisType) 

andere Domänenwerte wurden unter Verwendung der Methode parameterToValueIndex erstellt:

org.opalj.ai.parameterToValueIndex(caller.isStatic, caller.descriptor, index), t) 

Hier Anrufer stehen für das Verfahren indirectCaller2b und t ist der bekannte Laufzeittyp des Parameters (für Arrayparameterindex 1 und VerketteteListe für Parameter-Index 2).

Als ich nun die abstrakte Interpretation des Verfahrens mit

BaseAI.perform(classFile, caller, domain)(Some(parameters)) 

zuführen und den Stapelindex an dem Programmzähler drucken, wo der Anruf von indirectCaller1 mit dem folgenden Code geschieht,

for (i <- 0 to analysisResult.operandsArray(pc).size - 1) { 
     println(s"stack index $i: ${analysisResult.operandsArray(pc)(i)}") 
} 

Ich bekomme die folgende Ausgabe:

Stapelindex 0: null

Stapelindex 1: {_ <: java.util.LinkedList, null} [@ - 5; t = 103]

Stapelindex 2: ADoubleValue

Stapelindex 3: {ai.native_methods_parameter_type_approximation.PublicClass , null} [@ 0; t = 101]

Das ist ein wenig verwirrend, da ich die Argumente von indirectCaller2b nur an indirectCaller1 weitergebe. Daher sollte die Ausgabe die gleiche sein wie die IndexedSeq an die perform -Methode übergeben wird.

Aber in der Ausgabe, Parameter nach dem Doppelparameter ist LinkedList anstelle von ArrayList. Der ArrayList-Parameter ist irgendwie verschwunden, und der letzte Parameter im operandStack ist "null".

Kann mir jemand erklären, wie das passieren kann?

Antwort

1

Darstellung von „dieser“

Um die korrekte Darstellung erhalten für die „dieser“ Referenz Sie die Methode

InitializedObjectValue(
    origin:  ValueOrigin, 
    objectType: ObjectType ): DomainReferenceValue 

erstellen eine Darstellung des diesen Wert verwenden soll. Der Unterschied ist, dass in diesem Fall die KI versuchen wird, die Information zu verwenden, dass (a) der Wert garantiert nicht null ist und auch garantiert initialisiert wird. Insbesondere das ehemalige Grundstück ist oft interessant und führt in der Regel zu genaueren Ergebnissen.

Initialisieren Lokale

die Funktion: org.opalj.ai.parameterToValueIndex berechnet nur die logische Herkunftsinformation (der „PC“, die mit dem Wert assoziiert ist, um es möglich, die jeweiligen Werte als Parameter später zu identifizieren).

Um richtig Operanden zu Einheimischen ordnen Sie entweder die Methode mapOperandsToParameters oder einfach alle Werte hinzufügen zu einem IndexedSeq aber fügen Sie eine weitere null Wert für Rechentypkategorie 2 Werte verwenden können.

+0

Vielen Dank, der Ansatz zum Hinzufügen eines Null-Wert nach einem CTC2-Typ gearbeitet. Der Ansatz mit mapOperandsToParameters funktionierte jedoch nicht. Vor einem ctc2-Type wurde ein Nullwert hinzugefügt und nicht danach. – mariotrageser