
org.opalj.br.instructions.SimpleConditionalBranchInstruction.scala Maven / Gradle / Ivy
The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package br
package instructions
/**
* Common superclass of all instructions that perform a conditional jump.
*
* @author Michael Eichberg
*/
trait SimpleConditionalBranchInstructionLike
extends ConditionalBranchInstructionLike
with SimpleBranchInstructionLike {
/**
* The comparison operator (incl. the constant) underlying the if instruction.
* E.g., `<`, `< 0` or `!= null`.
*/
def operator: String
final def length: Int = 3
final def isIsomorphic(thisPC: PC, otherPC: PC)(implicit code: Code): Boolean = {
val other = code.instructions(otherPC)
(this eq other) || (this == other)
}
}
trait SimpleConditionalBranchInstruction[T <: SimpleConditionalBranchInstruction[T]]
extends ConditionalBranchInstruction
with SimpleBranchInstruction
with SimpleConditionalBranchInstructionLike {
def copy(branchoffset: Int): SimpleConditionalBranchInstruction[T]
/**
* Returns the IF instruction that - when compared with this if instruction -
* performs a jump in case of a fall-through and vice-versa. I.e., given the
* following condition: `(a < b)`, the negation is performend: `!(a < b)` which
* is equivalent to `(a ≥ b)`. In other words, if this IF instruction is an
* IFGT instruction and IFLE instruction is returned.
*/
def negate(newBranchoffset: Int = branchoffset): SimpleConditionalBranchInstruction[_]
final override def isSimpleConditionalBranchInstruction: Boolean = true
final override def asSimpleConditionalBranchInstruction: this.type = this
/**
* @inheritdoc
*
* A simple conditional branch instruction has two targets unless both targets point
* to the same instruction. In that case the jump has only one target, because the state
* - independent of the taken path - always has to be the same.
*/
final def nextInstructions(
currentPC: PC,
regularSuccessorsOnly: Boolean
)(
implicit
code: Code,
classHierarchy: ClassHierarchy = ClassHierarchy.PreInitializedClassHierarchy
): List[PC] = {
val nextInstruction = indexOfNextInstruction(currentPC)
val jumpInstruction = currentPC + branchoffset
if (nextInstruction == jumpInstruction)
List(nextInstruction)
else
List(nextInstruction, jumpInstruction)
}
override def toString(currentPC: Int): String = {
val jumpDirection = if (branchoffset >= 0) "↓" else "↑"
s"${getClass.getSimpleName}(true=${currentPC + branchoffset}$jumpDirection, false=↓)"
}
}
/**
* Extractor for [[SimpleConditionalBranchInstruction]]s.
*/
object SimpleConditionalBranchInstruction {
/**
* Extracts the instructions branchoffset.
*/
def unapply(i: SimpleConditionalBranchInstruction[_ <: SimpleConditionalBranchInstruction[_]]): Some[Int] = Some(i.branchoffset)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy