/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package da
import scala.xml.Node
import scala.xml.Text
import scala.xml.NodeSeq
/**
* @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 {
final override 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 {
final override 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(cp) }
Locals: Unchanged
|
,
newOffset
)
}
}
case class SameLocals1StackItemFrameExtended(
frame_type: Int = 247,
offset_delta: Int,
verification_type_info_stack: VerificationTypeInfo
) extends StackMapFrame {
final override 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(cp) }
Locals: Unchanged
|
,
newOffset
)
}
}
case class ChopFrame(frame_type: Int, offset_delta: Int) extends StackMapFrame {
final override 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 {
final override 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 {
final override 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 {
final override 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
)
}
}