h2jvm
Safe HaskellNone
LanguageGHC2021

JVM.Data.Analyse.StackMap

Description

Generate a stack map table for a method. This process MUST run last in the high level stage - modifications to the code after this point will invalidate the stack map table and cause invalid class files to be generated.

Synopsis

Documentation

data BasicBlock Source #

A basic block is a sequence of instructions with a single entry and exit point. Control flow only enters at the beginning and exits at the end.

Constructors

BasicBlock 

Fields

Instances

Instances details
Show BasicBlock Source # 
Instance details

Defined in JVM.Data.Analyse.StackMap

Eq BasicBlock Source # 
Instance details

Defined in JVM.Data.Analyse.StackMap

data Frame Source #

Represents the JVM frame state at a particular program point. Used for computing stack map frames required by the JVM verifier.

Constructors

Frame 

Fields

Instances

Instances details
Show Frame Source # 
Instance details

Defined in JVM.Data.Analyse.StackMap

Methods

showsPrec :: Int -> Frame -> ShowS #

show :: Frame -> String #

showList :: [Frame] -> ShowS #

Eq Frame Source # 
Instance details

Defined in JVM.Data.Analyse.StackMap

Methods

(==) :: Frame -> Frame -> Bool #

(/=) :: Frame -> Frame -> Bool #

data LocalVariable Source #

Represents the type of a local variable slot in the stack frame

Constructors

Uninitialised

The slot has not been initialised or contains an unusable value

LocalVariable FieldType

The slot contains a value of the given type

data StackEntry Source #

Represents the type of a stack slot.

Constructors

StackEntry FieldType

A typed value on the stack

StackEntryTop

An unusable or uninitialised stack slot

StackEntryNull

A null reference on the stack

Instances

Instances details
Show StackEntry Source # 
Instance details

Defined in JVM.Data.Analyse.StackMap

Eq StackEntry Source # 
Instance details

Defined in JVM.Data.Analyse.StackMap

Pretty StackEntry Source # 
Instance details

Defined in JVM.Data.Analyse.StackMap

lvToStackEntry :: LocalVariable -> StackEntry Source #

Convert a local variable to a stack entry

stackEntryToLV :: StackEntry -> LocalVariable Source #

Convert a stack entry to a local variable

splitIntoBasicBlocks :: [Instruction] -> [BasicBlock] Source #

Split a list of instructions into basic blocks. Blocks are split at labels and after branch/return instructions.

buildLabelToBlockMap :: [BasicBlock] -> Map Label Int Source #

Build a map from labels to the index of the block that starts with that label.

splitOnLabels :: [Instruction] -> [(Maybe Label, [Instruction])] Source #

Split instructions into groups, each starting with an optional label. Also splits after branch instructions to ensure proper block boundaries.

topFrame :: QualifiedClassName -> [MethodAccessFlag] -> MethodDescriptor -> Frame Source #

Compute the initial frame state at method entry. Includes this reference for instance methods, followed by method parameters.

analyseBlockDiff :: HasCallStack => Frame -> BasicBlock -> Frame Source #

Compute the frame state after executing all instructions in a basic block. Takes the frame state at block entry and returns the state at block exit.

diffFrames :: Frame -> Frame -> Label -> StackMapFrame Source #

Compute the delta between two frames to produce a StackMapFrame

lvToVerificationTypeInfo :: LocalVariable -> VerificationTypeInfo Source #

Convert a local variable to its JVM verification type info representation.

seToVerificationTypeInfo :: StackEntry -> VerificationTypeInfo Source #

Convert a stack entry to its JVM verification type info representation.

mergeFrames :: Frame -> Frame -> Maybe Frame Source #

Merge two frames that could both reach the same program point. Returns Nothing if frames are identical, Just the merged frame otherwise. Uses a conservative merge: differing types become Uninitialised.

getSuccessors :: Map Label Int -> Int -> BasicBlock -> [Int] Source #

Get the indices of successor blocks (blocks reachable from this block). Includes both jump targets and fall-through to the next block (if not terminated).

computeBlockFrames :: HasCallStack => Frame -> [BasicBlock] -> Map Int Frame Source #

Compute the frame state at the entry of each basic block using a worklist algorithm. Handles control flow merges by conservatively merging frame states.

calculateStackMapFrames Source #

Arguments

:: HasCallStack 
=> QualifiedClassName

The class containing this method

-> [MethodAccessFlag]

Method access flags (to determine if static)

-> MethodDescriptor

The method descriptor

-> [Instruction]

The method's instruction list

-> [StackMapFrame] 

Calculate the stack map frames for a method's bytecode. This function works by first splitting the code into basic blocks, then computing the frame state at the start of each block using a dataflow analysis, and finally generating the stack map frames by comparing the frame states at block entries.

replaceAtOrGrow :: Int -> LocalVariable -> [LocalVariable] -> [LocalVariable] Source #

Replace element at index in list, growing with Uninitialised if needed.

replaceAt :: Int -> a -> [a] -> [a] Source #

Replace element at index i in list. Appends to end if i is out of bounds.

type Analyser = Eff '[State Frame, Reader BasicBlock] () Source #

Effect stack for analysing instruction effects on the frame state. We can modify the current frame and read the current basic block.

pops :: Int -> Analyser Source #

Pops n items off the stack

pushes :: FieldType -> Analyser Source #

Pushes a single type onto the stack

pushesEntry :: StackEntry -> Analyser Source #

Pushes a raw StackEntry

pushesMaybe :: Maybe FieldType -> Analyser Source #

Pushes an item only if it exists (for void returns)

replaceTop :: FieldType -> Analyser Source #

Replaces the top stack entry with the given type

loads :: String -> U2 -> Analyser Source #

Loads a local variable onto the stack

stores :: Int -> Analyser Source #

Stores the top of the stack into a local variable at the given index

indexOOBError :: HasCallStack => String -> U2 -> Frame -> BasicBlock -> a Source #

Report an error when a local variable index is out of bounds.