Represents some filtered code.
Represents some filtered code. Primarily, implicitly used when a for-comprehension is used to process the code.
Tests if the straight-line sequence of instructions that starts with the given pc
always ends with an ATHROW instruction or a method call that always throws an
exception.
Tests if the straight-line sequence of instructions that starts with the given pc
always ends with an ATHROW instruction or a method call that always throws an
exception. The call sequence furthermore has to contain no complex logic.
Here, complex means that evaluating the instruction may result in multiple control flows.
If the sequence contains complex logic, false will be returned.
One use case of this method is, e.g., to check if the code
of the default case of a switch instruction always throws some error
(e.g., an UnknownError or AssertionError).
switch(...) {
case X : ....
default :
throw new AssertionError();
}This is a typical idiom used in Java programs and which may be relevant for certain analyses to detect.
The program counter of an instruction that strictly dominates all
succeeding instructions up until the next instruction (as determined
by #cfJoins where two or more paths join. If the pc belongs to an instruction
where multiple paths join, false will be returned.
When the analysis finds a method call, it calls this method
to let the caller decide whether the called method is an (indirect) way
of always throwing an exception.
If true is returned the analysis terminates and returns true; otherwise
the analysis continues.
If all (non-exception) paths will always end in one specific
ATHROW instruction then this function is called (callback) to let the
caller decide if the "expected" exception is thrown. This analysis will
return with the result of this call.
true if the bytecode sequence starting with the instruction with the
given pc always ends with an org.opalj.br.instructions.ATHROW instruction.
false in all other cases (i.e., the sequence does not end with an athrow
instruction or the control flow is more complex.)
If complex control flows should also be considered it is possible to compute a methods org.opalj.br.cfg.CFG and use that one.
Returns a new sequence that pairs the program counter of an instruction with the instruction.
Calculates for each instruction to which subroutine the respective instruction belongs to – if any.
Calculates for each instruction to which subroutine the respective instruction belongs to – if any. This information is required to, e.g., identify the subroutine contexts that need to be reset in case of an exception in a subroutine.
Basically a map that maps the pc of each instruction to the id of the
subroutine.
For each instruction (with a specific pc) the pc of the first instruction
of the subroutine it belongs to is returned. The pc 0 identifies the instruction
as belonging to the core method. The pc -1 identifies the instruction as
dead by compilation.
Calling this method only makes sense for Java bytecode that actually contains org.opalj.br.instructions.JSR and org.opalj.br.instructions.RET instructions.
Returns the set of all program counters where two or more control flow paths may join.
Returns the set of all program counters where two or more control flow paths may join.
0: iload_1 1: ifgt 6 2: iconst_1 5: goto 10 6: ... 9: iload_1 10:return // <= PATH JOIN: the predecessors are the instructions 5 and 9.
In case of exception handlers the sound overapproximation is made that all exception handlers with a fitting type may be reached on multiple paths.
Returns the set of all program counters where two or more control flow paths join or fork.
Returns the set of all program counters where two or more control flow paths join or fork.
0: iload_1 1: ifgt 6 // <= PATH FORK 2: iconst_1 5: goto 10 6: ... 9: iload_1 10:return // <= PATH JOIN: the predecessors are the instructions 5 and 9.
In case of exception handlers the sound overapproximation is made that all exception handlers may be reached on multiple paths.
A triple which contains (1) the set of pcs of those instruction where multiple control-flow paths join; (2) the pcs of the instructions which may result in multiple different control-flow paths and (3) for each of the later instructions the set of all potential targets.
Collects all instructions for which the given function is defined.
Collects all instructions for which the given function is defined.
Use this function if you want to search for and collect specific instructions and when you do not immediately require the program counter/index of the instruction in the instruction array to make the decision whether you want to collect the instruction.
Example usage to collect the declaring class of all get field accesses where the field name is "last".
collect({
case GETFIELD(declaringClass, "last", _) ⇒ declaringClass
})Example usage to collect all instances of a "DUP" instruction.
code.collect({ case dup @ DUP ⇒ dup })The result of applying the function f to all instructions for which f is defined combined with the index (program counter) of the instruction in the code array.
Applies the given function to the first instruction for which the given function is defined.
Collects all instructions for which the given function is defined.
Collects all instructions for which the given function is defined. The order in which the instructions are collected is reversed when compared to the order in the instructions array.
Finds a pair of consecutive instructions that are matched by the given partial function.
Finds a pair of consecutive instructions that are matched by the given partial function.
(pc, _) ← body.findPair {
case (
INVOKESPECIAL(receiver1, _, SingleArgumentMethodDescriptor((paramType: BaseType, _))),
INVOKEVIRTUAL(receiver2, name, NoArgumentMethodDescriptor(returnType: BaseType))
) if (...) ⇒ (...)
} yield ...
Collects the results of the evaluation of the partial function until the partial function is not defined.
Collects the results of the evaluation of the partial function until the partial function is not defined.
The program counter of the instruction for which the given partial function was not defined along with the list of previous results. The results are sorted in descending order w.r.t. the PC.
Applies the given function f to all instruction objects for which the function is
defined.
Applies the given function f to all instruction objects for which the function is
defined. The function is passed a tuple consisting of the current program
counter/index in the code array and the corresponding instruction.
Example usage to collect the program counters (indexes) of all instructions that are the target of a conditional branch instruction:
code.collectWithIndex({
case (pc, cbi: ConditionalBranchInstruction) ⇒
Seq(cbi.indexOfNextInstruction(pc, code), pc + cbi.branchoffset)
}) // .flatten should equal (Seq(...))
Returns a view of all potential exception handlers (if any) for the
instruction with the given program counter (pc).
Returns a view of all potential exception handlers (if any) for the
instruction with the given program counter (pc). Finally handlers
(catchType == None) are not returned but will stop the evaluation (as all further
exception handlers have no further meaning w.r.t. the runtime)!
In case of identical caught exceptions only the
first of them will be returned. No further checks (w.r.t. the typehierarchy) are done.
The program counter of an instruction of this Code array.
Iterates over all instructions until an instruction is found that matches the given predicate.
Iterates over all instructions until an instruction is found that matches the given predicate.
Tests if an instruction matches the given filter.
Tests if an instruction matches the given filter. If so, the index of the first matching instruction is returned.
Finds a sequence of instructions that are matched by the given partial function.
Finds a sequence of instructions that are matched by the given partial function.
List of pairs where the first element is the pc of the first instruction of a matched sequence and the second value is the result of the evaluation of the partial function.
If possible, use one of the more specialized methods, such as, collectPair. The pure iteration overhead caused by this method is roughly 10-20 times higher than this one.
Returns the smallest line number (if any).
Returns the smallest line number (if any).
The line number associated with the first instruction (pc === 0) is not necessarily the smallest one.
public void foo(int i) {
super.foo( // The call has the smallest line number.
i+=1; // THIS IS THE FIRST OPERATION...
)
}
Iterates over all instructions and calls the given function f
for every instruction.
Iterates over all instructions and calls the given function f
for every instruction.
The list of pcs of those instructions that may handle an exception if the evaluation
of the instruction with the given pc throws an exception.
The list of pcs of those instructions that may handle an exception if the evaluation
of the instruction with the given pc throws an exception.
In case of multiple finally handlers only the first one will be returned and no further exception handlers will be returned. In case of identical caught exceptions only the first of them will be returned. No further checks (w.r.t. the type hierarchy) are done.
If different exceptions are handled by the same handler, the corresponding pc is returned multiple times.
Returns a view of all handlers (exception and finally handlers) for the
instruction with the given program counter (pc) that may catch an exception; as soon
as a finally handler is found no further handlers will be returned!
Returns a view of all handlers (exception and finally handlers) for the
instruction with the given program counter (pc) that may catch an exception; as soon
as a finally handler is found no further handlers will be returned!
In case of multiple exception handlers that are identical (in particular in case of the finally handlers) only the first one is returned as that one is the one that will be used by the JVM at runtime. No further checks (w.r.t. the type hierarchy) are done.
The program counter of an instruction of this Code array.
Returns the handlers that may handle the given exception.
Returns the handlers that may handle the given exception.
The (known/given) type hierarchy is taken into account as well as the order between the exception handlers.
Returns Some(true) if both pcs have the same line number.
Returns Some(true) if both pcs have the same line number. If line number information
is not available None is returned.
The instructions of this Code array/Code block.
The instructions of this Code array/Code block. Since the code
array is not completely filled (it contains null values) the preferred way
to iterate over all instructions is to use for-comprehensions and pattern
matching or to use one of the predefined methods foreach, collect,
collectPair, collectWithIndex, etc..
The instructions array must not be mutated!
Computes the number of instructions.
Computes the number of instructions.
This operation has complexity O(n).
,The number of instructions is always smaller or equal to the size of the code array.
True if the instruction with the given program counter is modified by wide.
True if the instruction with the given program counter is modified by wide.
A valid index in the code array.
Iterates over all instructions and calls the given function f for every instruction.
Iterates over all instructions and calls the given function f for every instruction.
This attribute's kind id.
Returns the line number associated with the instruction with the given pc if it is available.
Returns the line number associated with the instruction with the given pc if it is available.
Index of the instruction for which we want to get the line number.
Some line number or None if no line-number information is available.
Returns the line number table - if any.
Returns the line number table - if any.
Depending on the configuration of the reader for ClassFiles this
attribute may not be reified.
A code attribute is allowed to have multiple line number tables. However, all tables are merged into one by OPAL at class loading time.
Performs a live variable analysis restricted to a method's locals.
Performs a live variable analysis restricted to a method's locals.
For each instruction (identified by its pc) the set of variables (register values) which are live (identified by their index.) is determined. I.e., if you need to know if the variable with the index 5 is (still) live at instruction j with pc 37 it is sufficient to test if the bit set stored at index 37 contains the value 5.
An IINC instruction does not change live variable information.
Computes for each instruction which variables are live; see
liveVariables(predecessorPCs: Array[PCs], finalPCs: PCs, cfJoins: BitSet) for further
details.
Returns the local variable stored at the given local variable index that is live at the given instruction (pc).
Collects (the merged if necessary) local variable table.
Collects (the merged if necessary) local variable table.
Depending on the configuration of the reader for ClassFiles this
attribute may not be reified.
A code attribute is allowed to have multiple local variable tables. However, all tables are merged into one by OPAL at class loading time.
Collects all local variable type tables.
Collects all local variable type tables.
Depending on the configuration of the reader for ClassFiles this
attribute may not be reified.
Returns the set of local variables defined at the given pc base on debug information.
Returns the set of local variables defined at the given pc base on debug information.
A mapping of the index to the name of the local variable. The map is empty if no debug information is available.
Matches pairs of two consecutive instructions.
Matches pairs of two consecutive instructions. For each matched pair, the program counter of the first instruction is returned.
for { classFile ← project.view.map(_._1).par method @ MethodWithBody(body) ← classFile.methods pc ← body.matchPair({ case ( INVOKESPECIAL(receiver1, _, TheArgument(parameterType: BaseType)), INVOKEVIRTUAL(receiver2, name, NoArgumentMethodDescriptor(returnType: BaseType)) ) ⇒ { (receiver1 eq receiver2) && (returnType ne parameterType) } case _ ⇒ false }) } yield (classFile, method, pc)
Finds a sequence of 3 consecutive instructions for which the given function returns
true, and returns the PC of the first instruction in each found sequence.
Finds a sequence of 3 consecutive instructions for which the given function returns
true, and returns the PC of the first instruction in each found sequence.
Is the maximum number of triples that is passed to f.
E.g., if matchMaxTriples is "1" only the first three instructions are
passed to f.
Finds all sequences of three consecutive instructions that are matched by f.
The number of registers/local variables needed to execute the method.
The number of registers/local variables needed to execute the method.
As in case of maxStack this number is expected to be the minimum, but this is
not guaranteed.
The maximum size of the stack during the execution of the method.
The maximum size of the stack during the execution of the method. This value is determined by the compiler and is not necessarily the minimum. However, in the vast majority of cases it is the minimum.
Returns the next instruction that will be executed at runtime that is not a org.opalj.br.instructions.GotoInstruction.
Returns the next instruction that will be executed at runtime that is not a org.opalj.br.instructions.GotoInstruction. If the given instruction is not a org.opalj.br.instructions.GotoInstruction, the given instruction is returned.
Returns the program counter of the next instruction after the instruction with
the given counter (currentPC).
Returns the program counter of the next instruction after the instruction with
the given counter (currentPC).
The program counter of an instruction. If currentPC is the
program counter of the last instruction of the code block then the returned
program counter will be equivalent to the length of the Code/Instructions
array.
Returns the program counter of the previous instruction in the code array.
Returns the program counter of the previous instruction in the code array.
currentPC must be the program counter of an instruction.
This function is only defined if currentPC is larger than 0; i.e., if there
is a previous instruction! If currentPC is larger than instructions.size the
behavior is undefined.
Computes for each instruction the set of predecessor instructions as well as all instructions without predecessors.
Computes for each instruction the set of predecessor instructions as well as all instructions without predecessors. Those instructions with multiple predecessors are also returned.
An array which contains for each instruction the set of all predecessors as well
as the set of all instructions which have only predecessors; i.e., no successors
and also the set of all instructions where multiple paths join.
(Array[PCs]/*PREDECESSOR_PCs*/, PCs/*FINAL_PCs*/, BitSet/*CF_JOINS*/)
Returns an iterator to iterate over the program counters (pcs) of the instructions
of this Code block.
Returns an iterator to iterate over the program counters (pcs) of the instructions
of this Code block.
See the method foreach for an alternative.
Collects all local variable type tables.
Collects all local variable type tables.
Depending on the configuration of the reader for ClassFiles this
attribute may not be reified.
Slides over the code array and tries to apply the given function to each sequence
of instructions consisting of windowSize elements.
Slides over the code array and tries to apply the given function to each sequence
of instructions consisting of windowSize elements.
If you want to search for specific patterns of bytecode instructions. Some "bug patterns" are directly related to specific bytecode sequences and these patterns can easily be identified using this method.
Search for sequences of the bytecode instructions PUTFIELD and ALOAD_O in the
method's body and return the list of program counters of the start of the
identified sequences.
code.slidingCollect(2)({ case (pc, Seq(PUTFIELD(_, _, _), ALOAD_0)) ⇒ (pc) }) should be(Seq(...))
The size of the sequence of instructions that is passed to the
partial function.
It must be larger than 0. **Do not use this method with windowSize "1"**;
it is more efficient to use the collect or collectWithIndex methods
instead.
The list of results of applying the function f for each matching sequence.
If possible, use one of the more specialized methods, such as, collectPair. The pure iteration overhead caused by this method is roughly 10-20 times higher than this one.
The JVM specification mandates that a Code attribute has at most one StackMapTable attribute.
The JVM specification mandates that a Code attribute has at most one StackMapTable attribute.
Depending on the configuration of the reader for ClassFiles this
attribute may not be reified.
A complete representation of this code attribute (including instructions, attributes, etc.).
A complete representation of this code attribute (including instructions, attributes, etc.).
Representation of a method's code attribute, that is, representation of a method's implementation.