Defines nodes used by statements and expressions.
The computational type of the result of the binary expression.
Common supertrait of statements and expressions calling a method.
A caught exception is essential to ensure that the local variable that stores the exception is reified in the ai-based 3-address code.
A checkcast
as defined by the JVM specification.
A comparison of two values.
A constant value expression.
Identifies a variable which has a single static definition/initialization site.
A (final) variable definition, which is uniquely identified by its origin/the index of the corresponding AssignmentStatement.
A (final) variable definition, which is uniquely identified by its origin/the index of the corresponding AssignmentStatement. I.e., per method there must be at most one D variable which has the given origin. Initially, the pc of the underlying bytecode instruction is used.
Represents an expression.
Represents an expression. In general, every expression should be a simple expression, where the child expressions are just Vars or Consts. However, when the code is going to be transformed to human readable code (e.g., Java oder Scala), then it is possible to build up complex/nested expressions after all transformations and static analyses have been performed.
An expression where the value is not further used.
First the pc
(absolute) of the target instruction in the
original bytecode array; then the index of the respective quadruples
instruction.
Id based variables are named based on the position of the corresponding stack/register value.
The expression left to the relational operator. In general, this can be expected to be a Var. However, it is not expression to facilitate advanced use cases such as generating source code.
The expression right to the relational operator. In general, this can be expected to be a Var. However, it is not expression to facilitate advanced use cases such as generating source code.
Index in the statements array.
An instance of
expression as defined by the JVM specification.
JSR/RET instructions in the bytecode are mapped to corresponding statements where the Ret instruction explicitly encodes the control flow by explicitly listing all target instructions.
JSR/RET instructions in the bytecode are mapped to corresponding statements where the Ret instruction explicitly encodes the control flow by explicitly listing all target instructions. The target instructions implicitly encode the JSR instruction which called the subroutine.
At creation time the pc
(absolute) of the target instruction in the
original bytecode array; then the index of the respective quadruples
instruction.
Allocates memory for the (non-abstract) given object.
Allocates memory for the (non-abstract) given object. Note, that the call of the separator is done later and therefore the object is not considered to be properly initialized and – therefore – no further operations other than the call of a constructor are allowed.
Encodes the number of dimensions that are initialized and the size of the respective dimension.
The type of the array. The number of dimensions is always >= count.size
.
An instance based method call which does not require virtual method lookup.
An instance based method call which does not require virtual method lookup. In other words the target method is either directly found in the specified class or a super class thereof. (Basically corresponds to an invokespecial at bytecode level.)
The type of the Var used by this representation.
The pc of the underlying, original bytecode instruction. Primarily useful to do a lookup in the line-/local-variable tables.
The declaring class of the target method.
true
if the declaring class defines an interface type.
(Required since Java 8.)
The name of the target method.
The descriptor.
The receiver object.
The parameters of the method call (including the implicit this
reference.)
Call of an instance method for which no virtual method call resolution has to happen.
Call of an instance method for which no virtual method call resolution has to happen. I.e., it is either a super-call, a private instance method call or a constructor call.
Explicit reference to a parameter.
Explicit reference to a parameter. Parameter statements are only used by the naive representation (TACNaive) where it is necessary to perform an initial initialization of the register values.
Information about a method's explicit and implicit parameters.
The computational type of the result of the prefix expression.
Return from subroutine; only to be used in combination with JSR instructions.
Return from subroutine; only to be used in combination with JSR instructions.
The set of return addresses. Based on the return addresses it is immediately possible to determine the original JSR instruction that led to the execution of the subroutine. It is the JSR instruction directly preceding the instruction to which this RET instruction jumps to. This information is only relevant in case of flow-sensitive analyses.
The id determines the name of the local variable and is equivalent to "the position of the value on the operand stack" or "-1-(the accessed register)".
The id determines the name of the local variable and is equivalent to "the position of the value on the operand stack" or "-1-(the accessed register)". If the id is Int.MinValue then the variable is an intermediate variable that was artificially generated.
Super trait of all quadruple statements.
Captures essential information about a method's parameter.
Common interface of all code optimizers that operate on the three-address code representation.
Encapsulates the result of an optimization/transformation of some three-address code.
Contains the 3-address code of a method.
Contains the 3-address code of a method.
The following code attributes are directly
reused (i.e., the PCs are not transformed):
- LineNumberTableAttribute; the statements keep the reference to the underlying/original
instruction which is used to retrieve the respective information.
The variables which store the method's explicit and implicit (this
in case
of an instance method) parameters.
In case of the ai-based representation (TACAI - default representation),
the variables are returned which store (the initial) parameters. If these variables
are written and we have a loop which includes the very first instruction, the
value will reflect this usage.
In case of the naive representation it "just" contains the names of the
registers which store the parameters.
Represents a variable.
Represents a variable. Depending on the concrete usage, it is possible to distinguish between
a use and/or definition site. Typically, V
is directly bound by the direct subtypes of Var.
Specifies the type of Var
used by the three address representation. V
is also
the self type.
trait MyVar extends Var[MyVar]
Defines an extractor to get the definition site of an expression's/statement's value.
Defines an extractor to get the definition site of an expression's/statement's value.
This extractor may fail (i.e., throw an exception), when the expr is not a DVar or a Const; this decision was made to capture programming failures as early as possible (flat).
To get a return value's definition sites (unless the value is constant).
val tac.ReturnValue(pc,tac.DefSites(defSites)) = code.stmts(5)
Key to get the 3-address based code of a method computed using the result of the
data-flow analysis performed by SimpleAIKey
.
Key to get the 3-address based code of a method computed using the result of the
data-flow analysis performed by SimpleAIKey
.
To get the index use the org.opalj.br.analyses.Project's get
method and
pass in this
object.
A very simple peephole optimizer which performs intra-basic block constant and copy propagation for the naive representation (in case of the ai-based representation these steps are already done at abstract-interpretation time).
Key to get the 3-address based code of a method computed using the configured domain/data-flow analysis.
Key to get the 3-address based code of a method computed using the configured domain/data-flow analysis. This key performs the underlying data-flow analysis on demand using the configured data-flow analyses; the results of the data-flow analyses are NOT shared. Hence, this key should only be used if the result of the underlying analysis is no longer required after generating the TAC.
To get the index use the org.opalj.br.analyses.Project's get
method and
pass in this
object.
Creates the three-address representation for some method(s) and prints it to std out or writes it to a file.
Creates the three-address representation for some method(s) and prints it to std out or writes it to a file.
To convert all files of a project to the AI based three-address code, you can use:
import org.opalj.io.write import org.opalj.util.PerformanceEvaluation.time import org.opalj.tac._ val f = new java.io.File("OPAL/bi/target/scala-2.11/resource_managed/test/ai.jar") val p = org.opalj.br.analyses.Project(f) var i = 0 val errors = time { p.parForeachMethodWithBody(parallelizationLevel=32){ mi => val TACode(code,cfg,ehs,_) = org.opalj.tac.TACAI(p,mi.method)() val tac = ToTxt(code, Some(cfg)) val fileNamePrefix = mi.classFile.thisType.toJava+"."+mi.method.name val file = write(tac, fileNamePrefix, ".tac.txt") i+= 1 println(i+":"+file) } }(t => println("transformation time: "+t.toSeconds)) if(errors.nonEmpty) println(errors.mkString("\n"))
Factory to convert the bytecode of a method into a three address representation using the results of a(n) (local) abstract interpretation of the method.
Factory to convert the bytecode of a method into a three address representation using the results of a(n) (local) abstract interpretation of the method.
The generated representation is completely parameterized over the domains that were used to perform the abstract interpretation. The only requirement is that the Def/Use information is recorded while performing the abstract interpretation (see org.opalj.ai.domain.RecordDefUse). The generated representation is necessarily in static single assignment form: each variable is assigned exactly once, and every variable is defined before it is used. However, no PHI instructions are inserted; instead - in case of a use - we simply directly refer to all def sites.
Converts the bytecode of a method into a three address representation using a very naive approach where each each operand stack value is stored in a local variable based on the position of the value on the stack and where each local variable is stored in a local variable named based on the register's index (In general, you should use the three-address code create using TACAI).
Converts the bytecode of a method into a three address representation using a very naive approach where each each operand stack value is stored in a local variable based on the position of the value on the stack and where each local variable is stored in a local variable named based on the register's index (In general, you should use the three-address code create using TACAI).
The converted method has an isomorophic CFG when compared to the original method, but may contain more instructions due to the way how the stack manipulation instructions are transformed. In general - unless JSR/RET instructions are found - no CFG is created and used. This approach relies on the invariant that the stack has to have the same layout on all paths. This makes the transformation very fast, but also makes it impossible to trivially compute the type information.
Converts a list of three-address instructions into a text-based representation for comprehension purposes only.
Converts a list of three-address instructions into a text-based representation for comprehension purposes only.
This representation is primarily provided for debugging purposes and is not performance optimized.
Updates the exception handlers by adjusting the start, end and handler index (pc).
Updates the exception handlers by adjusting the start, end and handler index (pc).
A map that contains for each previous index the new index that should be used.
The result of the abstract interpretation of the method.
The new exception handlers.
This method can only be used in cases where the order of instructions remains the same and/or instructions are deleted. If instructions are reordered this method cannot be used!
Common definitions related to the definition and processing of three address code.