/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package da
import scala.xml.Node
import scala.xml.NodeSeq
import scala.xml.Text
/**
* @author Michael Eichberg
* @author Wael Alkhatib
* @author Isbel Isbel
* @author Noorulla Sharief
*/
sealed abstract class StackMapFrame {
/**
* The number of bytes required by the StackMapFrame in a class file.
*/
def attribute_length: Int
def frame_type: Int
def toXHTML(
implicit
cp: Constant_Pool,
previous_frame_offset: Int
): (Node, Int /* new offset*/ )
protected def verification_type_infos_toXHTML(
verification_type_infos: VerificationTypeInfos
)(
implicit cp: Constant_Pool
): NodeSeq = {
NodeSeq.fromSeq(
if (verification_type_infos.isEmpty) {
List(<Empty>)
} else {
val vtis = verification_type_infos.map(l => l.toXHTML)
val vtisIt = vtis.iterator
val head = vtisIt.next()
vtisIt.foldLeft(List(head)) { (r, n) => r ++ List(Text(", "), n) }
}
)
}
}
case class SameFrame(frame_type: Int) extends StackMapFrame {
override final def attribute_length: Int = 1
override def toXHTML(
implicit
cp: Constant_Pool,
previous_frame_offset: Int
): (Node, Int /* new offset*/ ) = {
val newOffset = previous_frame_offset + frame_type + 1
(
| {newOffset} |
SameFrame |
{frame_type} |
{frame_type} |
Stack: <Empty> Locals: Unchanged |
,
newOffset
)
}
}
case class SameLocals1StackItemFrame(
frame_type: Int,
verification_type_info_stack: VerificationTypeInfo
) extends StackMapFrame {
override final def attribute_length: Int = 1 + verification_type_info_stack.attribute_length
override def toXHTML(
implicit
cp: Constant_Pool,
previous_frame_offset: Int
): (Node, Int /* new offset*/ ) = {
val newOffset = previous_frame_offset + frame_type - 64 + 1
(
| {newOffset} |
SameLocals1StackItemFrame |
{frame_type} |
{frame_type - 64} |
Stack: <Empty>
, {verification_type_info_stack.toXHTML}
Locals: Unchanged
|
,
newOffset
)
}
}
case class SameLocals1StackItemFrameExtended(
frame_type: Int = 247,
offset_delta: Int,
verification_type_info_stack: VerificationTypeInfo
) extends StackMapFrame {
override final def attribute_length: Int = 1 + 2 + verification_type_info_stack.attribute_length
override def toXHTML(
implicit
cp: Constant_Pool,
previous_frame_offset: Int
): (Node, Int /* new offset*/ ) = {
val newOffset = previous_frame_offset + offset_delta + 1
(
| {newOffset} |
SameLocals1StackItemFrameExtended |
247 |
{offset_delta} |
Stack: <Empty>
, {verification_type_info_stack.toXHTML}
Locals: Unchanged
|
,
newOffset
)
}
}
case class ChopFrame(frame_type: Int, offset_delta: Int) extends StackMapFrame {
override final def attribute_length: Int = 1 + 2
override def toXHTML(
implicit
cp: Constant_Pool,
previous_frame_offset: Int
): (Node, Int /* new offset*/ ) = {
val newOffset = previous_frame_offset + offset_delta + 1
(
| {newOffset} |
ChopFrame |
{frame_type} |
{offset_delta} |
Stack: <Empty>
Locals: The last {251 - frame_type}
locals(s) are absent
|
,
newOffset
)
}
}
case class SameFrameExtended(frame_type: Int = 251, offset_delta: Int) extends StackMapFrame {
override final def attribute_length: Int = 1 + 2
override def toXHTML(
implicit
cp: Constant_Pool,
previous_frame_offset: Int
): (Node, Int /* new offset*/ ) = {
val newOffset = previous_frame_offset + offset_delta + 1
(
| {newOffset} |
SameFrameExtended |
251 |
{offset_delta} |
Stack: <Empty>
Locals: Unchanged
|
,
newOffset
)
}
}
case class AppendFrame(
frame_type: Int,
offset_delta: Int,
verification_type_info_locals: VerificationTypeInfos
) extends StackMapFrame {
override final def attribute_length: Int = {
val initial = 1 + 2
verification_type_info_locals.foldLeft(initial)((c, n) => c + n.attribute_length)
}
override def toXHTML(
implicit
cp: Constant_Pool,
previous_frame_offset: Int
): (Node, Int /* new offset*/ ) = {
val newOffset = previous_frame_offset + offset_delta + 1
(
| {newOffset} |
AppendFrame |
{frame_type} |
{offset_delta} |
Stack: <Empty>
Locals: {verification_type_infos_toXHTML(verification_type_info_locals)}
|
,
newOffset
)
}
}
case class FullFrame(
frame_type: Int,
offset_delta: Int,
verification_type_info_locals: VerificationTypeInfos,
verification_type_info_stack: VerificationTypeInfos
) extends StackMapFrame {
override final def attribute_length: Int = {
val initial = 1 + 2
val locals = verification_type_info_locals.foldLeft(2 /*count*/ )(_ + _.attribute_length)
val stack = verification_type_info_stack.foldLeft(2 /*count*/ )(_ + _.attribute_length)
initial + locals + stack
}
override def toXHTML(
implicit
cp: Constant_Pool,
previous_frame_offset: Int
): (Node, Int /* new offset*/ ) = {
val newOffset = previous_frame_offset + offset_delta + 1
(
| {newOffset} |
FullFrame |
{frame_type} |
{offset_delta} |
Stack: {verification_type_infos_toXHTML(verification_type_info_stack)}
Locals: {verification_type_infos_toXHTML(verification_type_info_locals)}
|
,
newOffset
)
}
}