Packages

  • package root
    Definition Classes
    root
  • package org
    Definition Classes
    root
  • package opalj

    OPAL is a Scala-based framework for the static analysis, manipulation and creation of Java bytecode.

    OPAL is a Scala-based framework for the static analysis, manipulation and creation of Java bytecode. OPAL is designed with performance, scalability and adaptability in mind.

    Its main components are:

    • a library (Common) which provides generally useful data-structures and algorithms for static analyses.
    • a framework for parsing Java bytecode (Bytecode Infrastructure) that can be used to create arbitrary representations.
    • a library to create a one-to-one in-memory representation of Java bytecode (Bytecode Disassembler).
    • a library to create a representation of Java bytecode that facilitates writing simple static analyses (Bytecode Representation - org.opalj.br).
    • a scalable, easily customizable framework for the abstract interpretation of Java bytecode (Abstract Interpretation Framework - org.opalj.ai).
    • a library to extract dependencies between code elements and to facilitate checking architecture definitions.
    • a library for the lightweight manipulation and creation of Java bytecode.

    General Design Decisions

    Thread Safety

    Unless explicitly noted, OPAL is thread safe. I.e., the classes defined by OPAL can be considered to be thread safe unless otherwise stated. (For example, it is possible to read and process class files concurrently without explicit synchronization on the client side.)

    No null Values

    Unless explicitly noted, OPAL does not null values I.e., fields that are accessible will never contain null values and methods will never return null. If a method accepts null as a value for a parameter or returns a null value it is always explicitly documented. In general, the behavior of methods that are passed null values is undefined unless explicitly documented.

    No Typecasts for Collections

    For efficiency reasons, OPAL sometimes uses mutable data-structures internally. After construction time, these data-structures are generally represented using their generic interfaces (e.g., scala.collection.{Set,Map}). However, a downcast (e.g., to add/remove elements) is always forbidden as it would effectively prevent thread-safety. Furthermore, the concrete data-structure is always considered an implementation detail and may change at any time.

    Assertions

    OPAL makes heavy use of Scala's Assertion Facility to facilitate writing correct code. Hence, for production builds (after thorough testing(!)) it is highly recommend to build OPAL again using -Xdisable-assertions.

    Definition Classes
    org
  • package ai

    Implementation of an abstract interpretation (ai) framework – also referred to as OPAL.

    Implementation of an abstract interpretation (ai) framework – also referred to as OPAL.

    Please note, that OPAL/the abstract interpreter just refers to the classes and traits defined in this package (ai). The classes and traits defined in the sub-packages (in particular in domain) are not considered to be part of the core of OPAL/the abstract interpreter.

    Definition Classes
    opalj
    Note

    This framework assumes that the analyzed bytecode is valid; i.e., the JVM's bytecode verifier would be able to verify the code. Furthermore, load-time errors (e.g., LinkageErrors) are – by default – completely ignored to facilitate the analysis of parts of a project. In general, if the presented bytecode is not valid, the result is undefined (i.e., OPAL may report meaningless results, crash or run indefinitely).

    See also

    org.opalj.ai.Domain - The core interface between the abstract interpretation framework and the abstract domain that is responsible for performing the abstract computations.

    org.opalj.ai.AI - Implements the abstract interpreter that processes a methods code and uses an analysis-specific domain to perform the abstract computations.

  • package domain

    This package contains definitions of common domains that can be used for the implementation of analyses.

    This package contains definitions of common domains that can be used for the implementation of analyses.

    Types of Domains

    In general, we distinguish two types of domains. First, domains that define a general interface (on top of the one defined by Domain), but do not directly provide an implementation. Hence, whenever you develop a new Domain you should consider implementing/using these domains to maximize reusability. Second, Domains that implement a specific interface (trait). In this case, we further distinguish between domains that provide a default implementation (per interface only one of these Domains can be used to create a final Domain) and those that can be stacked and basically refine the overall functionality.

    Examples

    • Domains That Define a General Interface
      • Origin defines two types which domains that provide information abou the origin of a value should consider to implement.
      • TheProject defines a standard mechanism how a domain can access the current project.
      • TheClassHierarchy defines a standard mechanism how to get the project's class hierarchy.
      • ...
    • Domains That Provide a Default Implementation
      • Origin defines the functionality to return a value's origin if the value supports that.
      • TheProject default implementation of the TheClassHierarchy trait that uses the project's class hierarchy.
      • DefaultHandlingOfMethodResults basically implements a Domain's methods related to return instructions an uncaught exceptions.
      • ...
    • Domains That Implement Stackable Functionality
      • RecordThrownExceptions records information about all uncaught exceptions by intercepting a Domain's respective methods. However, it does provide a default implementation. Hence, a typical pattern is:
    class MyDomain extends Domain with ...
        with DefaultHandlingOfMethodResults with RecordThrownExceptions

    Thread Safety

    Unless explicitly documented, a domain is never thread-safe. The general programming model is to use one Domain object per code block/method and therefore, thread-safety is not required for Domains that are used for the evaluation of methods. However domains that are used to adapt/transfer values should be thread safe (see ValuesCoordinatingDomain for further details).

    Definition Classes
    ai
  • package l0
    Definition Classes
    domain
  • package l1

    Commonly useful methods.

    Commonly useful methods.

    Definition Classes
    domain
  • package l2
    Definition Classes
    domain
  • package la
    Definition Classes
    domain
  • package li
    Definition Classes
    domain
  • package tracing
    Definition Classes
    domain
  • AsDomainValue
  • AsJavaObject
  • ConcreteIntegerValues
  • ConcreteLongValues
  • ConstantFieldValuesResolution
  • CurrentCode
  • DefaultDomainValueBinding
  • DefaultExceptionsFactory
  • DefaultHandlingForReturnInstructions
  • DefaultHandlingForThrownExceptions
  • DefaultHandlingOfMethodResults
  • DefaultHandlingOfVoidReturns
  • DefaultRecordMethodCallResults
  • DomainId
  • DomainValues
  • GeneralizedArrayHandling
  • IgnoreSynchronization
  • ImpossibleRefinement
  • MethodCallResults
  • MethodCallsHandling
  • MonitorInstructionsTracker
  • Origin
  • Origins
  • PerInstructionPostProcessing
  • PerformAI
  • PostEvaluationMemoryManagement
  • PredefinedClassHierarchy
  • RecordAllThrownExceptions
  • RecordCFG
  • RecordConstraints
  • RecordDefUse
  • RecordJoinedThrownExceptions
  • RecordLastReturnedValues
  • RecordMethodCallResults
  • RecordReturnFromMethodInstructions
  • RecordReturnedValue
  • RecordReturnedValueInfrastructure
  • RecordReturnedValues
  • RecordReturnedValuesInfrastructure
  • RecordThrownExceptions
  • RecordVoidReturns
  • RefineDefUseUsingOrigins
  • ReifiedConstraints
  • ReturnInstructionsDomain
  • SpecialMethodsHandling
  • TheCode
  • TheMethod
  • TheProject
  • ThePropertyStore
  • ThrowAllPotentialExceptionsConfiguration
  • ThrowNoPotentialExceptionsConfiguration
  • ValuesCoordinatingDomain
o

org.opalj.ai.domain

PerformAI

object PerformAI extends BaseAI

A base abstract interpreter that can be used with any domain that has no special requirements on the abstract interpreter and which provides some convenience factory methods to run the abstract interpretation if the domain provide the necessary information.

The base interpreter can be interrupted by calling the interrupt method of the AI's thread.

Source
PerformAI.scala
See also

BoundedInterruptableAI for an abstract interpreter that can easily be interrupted and which also interrupts itself if a certain threshold is exceeded.

Linear Supertypes
BaseAI, AI[Domain], AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. PerformAI
  2. BaseAI
  3. AI
  4. AnyRef
  5. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. type SomeLocals[V <: AI.SomeLocals.V.d.type.DomainValue forSome {val d: Domain}] = Option[IndexedSeq[V]]
    Definition Classes
    AI

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final val IdentifyDeadVariables: Boolean
    Definition Classes
    AI
  5. def apply(d: TheProject with TheMethod with Domain): AIResult { val domain: org.opalj.ai.domain.PerformAI.<refinement>.type }
  6. def apply(method: Method, theDomain: Domain): AIResult { val domain: theDomain.type }

    Performs an abstract interpretation of the given method using the given domain.

    Performs an abstract interpretation of the given method using the given domain.

    method

    A non-native, non-abstract method of the given class file that will be analyzed. All parameters are automatically initialized with sensible default values.

    theDomain

    The domain that will be used to perform computations related to values.

    Definition Classes
    AI
  7. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  8. def clone(): AnyRef
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  9. def continueInterpretation(code: Code, cfJoins: BitSet, liveVariables: LiveVariables, theDomain: Domain)(initialWorkList: Chain[PC], alreadyEvaluated: Chain[PC], theOperandsArray: AI.D.OperandsArray, theLocalsArray: AI.D.LocalsArray, theMemoryLayoutBeforeSubroutineCall: Chain[(PC, AI.D.OperandsArray, AI.D.LocalsArray)], theSubroutinesOperandsArray: AI.D.OperandsArray, theSubroutinesLocalsArray: AI.D.LocalsArray): AIResult { val domain: theDomain.type }

    Continues the interpretation of/performs an abstract interpretation of the given method (code) using the given domain.

    Continues the interpretation of/performs an abstract interpretation of the given method (code) using the given domain.

    code

    The bytecode that will be interpreted using the given domain.

    cfJoins

    The set of instructions where two or more control flow paths join. The abstract interpretation framework will only perform a join operation for those instructions.

    theDomain

    The domain that will be used to perform the domain dependent computations.

    initialWorkList

    The list of program counters with which the interpretation will continue. If the method was never analyzed before, the list should just contain the value "0"; i.e., we start with the interpretation of the first instruction (see initialWorkList). Note that the worklist may contain negative values. These values are not related to a specific instruction per-se but encode the necessary information to handle subroutines. In case of calls to a subroutine we add the special values SUBROUTINE and SUBROUTINE_START to the list to encode when the evaluation started. This is needed to completely process the subroutine (to explore all paths) before we finally return to the main method.

    alreadyEvaluated

    The list of the program counters (PC) of the instructions that were already evaluated. Initially (i.e., if the given code is analyzed the first time) this list is empty. This list is primarily needed to correctly resolve jumps to sub routines (JSR(_W) and RET instructions.) For each instruction that was evaluated, the operands array and the locals array must be non-empty (not null).

    theOperandsArray

    The array that contains the operand stacks. Each value in the array contains the operand stack before the instruction with the corresponding index is executed. This array can be empty except of the indexes that are referred to by the initialWorklist. The operandsArray data structure is mutated by OPAL-AI and it is recommended that a Domain does not directly mutate the state of this array.

    theLocalsArray

    The array that contains the local variable assignments. Each value in the array contains the local variable assignments before the instruction with the corresponding program counter is executed. The localsArray data structure is mutated by OPAL-AI and it is recommended that a Domain does not directly mutate the state of this array.

    theSubroutinesOperandsArray

    The array that contains the intermediate information about the subroutines' operands. This value should be null unless we are continuing an aborted computation and a subroutine was already analyzed.

    theSubroutinesLocalsArray

    The array that contains the intermediate information about the subroutines' locals. This value should be null unless we are continuing an aborted computation and a subroutine was already analyzed.

    Definition Classes
    AI
  10. def continueInterpretation(code: Code, theDomain: Domain)(initialWorkList: Chain[PC], alreadyEvaluated: Chain[PC], theOperandsArray: AI.D.OperandsArray, theLocalsArray: AI.D.LocalsArray): AIResult { val domain: theDomain.type }
    Definition Classes
    AI
  11. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  12. def equals(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  13. def finalize(): Unit
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  14. final def getClass(): Class[_]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  15. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  16. def initialLocals(method: Method, domain: Domain)(someLocals: SomeLocals[AI.D.DomainValue] = None): AI.D.Locals

    Returns the initial register assignment (the initialized locals) that is used when analyzing a new method.

    Returns the initial register assignment (the initialized locals) that is used when analyzing a new method.

    Initially, only the registers that contain the method's parameters (including the self reference (this)) are used. If no initial assignment is provided (someLocals == None) a valid assignment is automatically created using the domain. See perform(...) for further details regarding the initial register assignment.

    This method is called by the perform method with the same signature. It may be overridden by subclasses to perform some additional processing. In that case, however, it is highly recommended to call this method to finalize the initial assignment.

    method

    A non-native, non-abstract method. I.e., a method that has an implementation in Java bytecode (e.g., method.body.isDefined === true).

    domain

    The domain that will be used to perform computations related to values.

    Definition Classes
    AI
  17. def initialOperands(method: Method, domain: Domain): AI.D.Operands

    Returns the initial set of operands that will be used for the abstract interpretation of the given method.

    Returns the initial set of operands that will be used for the abstract interpretation of the given method.

    In general, an empty list is returned as the JVM specification mandates that the operand stack is empty at the very beginning of a method.

    This method is called by the perform method with the same signature. It may be overridden by subclasses to perform some additional processing.

    Definition Classes
    AI
  18. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  19. def isInterrupted: Boolean

    Determines whether a running (or to be started) abstract interpretation should be interrupted (default: false).

    Determines whether a running (or to be started) abstract interpretation should be interrupted (default: false).

    In general, interrupting the abstract interpreter may be meaningful if the abstract interpretation takes too long or if the currently used domain is not sufficiently precise enough/if additional information is needed to continue with the analysis.

    Called during the abstract interpretation of a method to determine whether the computation should be aborted. This method is always called directly before the evaluation of the first/next instruction. I.e., before the very first instruction or after the ai has completely evaluated an instruction, updated the memory and stated all constraints.

    Definition Classes
    PerformAIBaseAIAI
    Note

    When the abstract interpreter is currently waiting on the result of the interpretation of a called method it may take some time before the interpretation of the current method (this abstract interpreter) is actually aborted. This method needs to be overridden in subclasses to identify situations in which a running abstract interpretation should be interrupted.

  20. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  21. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  22. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  23. def perform(method: Method, theDomain: Domain)(someLocals: Option[IndexedSeq[AI.D.DomainValue]] = None): AIResult { val domain: theDomain.type }

    Analyzes the given method using the given domain and the pre-initialized parameter values (if any).

    Analyzes the given method using the given domain and the pre-initialized parameter values (if any). Basically, first the set of initial operands and locals is calculated before the respective perform(...,initialOperands,initialLocals) method is called.

    Controlling the AI

    The abstract interpretation of a method is aborted if the AI's isInterrupted method returns true.

    method

    A non-abstract, non-native method of the given class file. I.e., a method with a body.

    theDomain

    The abstract domain that will be used for the abstract interpretation of the given method.

    someLocals

    The initial register assignment (the parameters passed to the method). If the values passed to a method are already known, the abstract interpretation will be performed under that assumption. The specified number of locals has to be equal or larger than the number of parameters (including this in case of a non-static method.). If the number is lower than method.body.maxLocals it will be adjusted as required.

    returns

    The result of the abstract interpretation. Basically, the calculated memory layouts; i.e., the list of operands and local variables before each instruction. Each calculated memory layout represents the layout before the instruction with the corresponding program counter was interpreted. If the interpretation was aborted, the returned result object contains all necessary information to continue the interpretation if needed/desired.

    Definition Classes
    AI
  24. def performInterpretation(code: Code, theDomain: Domain)(initialOperands: AI.D.Operands, initialLocals: AI.D.Locals): AIResult { val domain: theDomain.type }

    Performs an abstract interpretation of the given (byte)code using the given domain and the initial operand stack and initial register assignment.

    Performs an abstract interpretation of the given (byte)code using the given domain and the initial operand stack and initial register assignment.

    Definition Classes
    AI
  25. def preInterpretationInitialization(code: Code, instructions: Array[Instruction], cfJoins: BitSet, liveVariables: LiveVariables, theDomain: Domain)(theOperandsArray: AI.D.OperandsArray, theLocalsArray: AI.D.LocalsArray, theMemoryLayoutBeforeSubroutineCall: Chain[(PC, AI.D.OperandsArray, AI.D.LocalsArray)], theSubroutinesOperandsArray: AI.D.OperandsArray, theSubroutinesLocalsArray: AI.D.LocalsArray): Unit

    Performs additional initializations of the Domain, if the Domain implements the trait TheAI, TheCodeStructure, TheMemoryLayout or CustomInitialization.

    Performs additional initializations of the Domain, if the Domain implements the trait TheAI, TheCodeStructure, TheMemoryLayout or CustomInitialization.

    This method is called before the abstract interpretation is started/continued.

    Attributes
    protected[this]
    Definition Classes
    AI
  26. final def synchronized[T0](arg0: ⇒ T0): T0
    Definition Classes
    AnyRef
  27. def toString(): String
    Definition Classes
    AnyRef → Any
  28. def tracer: Option[AITracer]

    The tracer (default: None) that is called by OPAL while performing the abstract interpretation of a method.

    The tracer (default: None) that is called by OPAL while performing the abstract interpretation of a method.

    This method is called at different points to report on the analysis progress (see org.opalj.ai.AITracer for further details)

    It is possible to attach/detach a tracer at any time.

    To attach a tracer to the abstract interpreter override this method in subclasses and return some tracer object.

    Definition Classes
    AI
  29. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  30. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  31. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )

Inherited from BaseAI

Inherited from AI[Domain]

Inherited from AnyRef

Inherited from Any

Ungrouped