/* 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 ) } }