net.sf.jode.flow
Class StructuredBlock

java.lang.Object
  extended by net.sf.jode.flow.StructuredBlock
Direct Known Subclasses:
BreakBlock, CaseBlock, CatchBlock, ContinueBlock, DescriptionBlock, EmptyBlock, FinallyBlock, IfThenElseBlock, InstructionContainer, JsrBlock, LoopBlock, RetBlock, SequentialBlock, SpecialBlock, SynchronizedBlock, TryBlock

public abstract class StructuredBlock
extends Object

A structured block is the building block of the source programm. For every program construct like if, while, try, or blocks there is a corresponding structured block. Some of these Block are only intermediate representation, that get converted to another block later. Every block has to handle the local variables that it contains. This is done by the in/out vectors and the local variable structure themself. Every local variable used in this structured block is either in or out. There are following types of structured blocks:


Constructor Summary
StructuredBlock()
           
 
Method Summary
 StructuredBlock appendBlock(StructuredBlock block)
          Appends a block to this block.
 void checkConsistent()
           
 boolean contains(StructuredBlock child)
          Returns if this block contains the given block.
 void copyJump(Jump jump)
          This function copies the jump to this block.
 boolean doTransformations()
          Do simple transformation on the structuredBlock.
abstract  void dumpInstruction(TabbedPrintWriter writer)
          Print the instruction expressing this structured block.
 void dumpSource(TabbedPrintWriter writer)
          Print the source code for this structured block.
 void fillInGenSet(Set in, Set gen)
          Fill all in variables into the given VariableSet.
 boolean flowMayBeChanged()
          Determines if there is a path, that flows through the end of this block.
 List<InstructionHandle> getBCELInstructions()
           
 List<Instruction> getBytecodeInstructions()
          Returns the list of bytecode instructions that represents this block.
 Set getDeclarables()
           
 StructuredBlock getNextBlock()
          Returns the block where the control will normally flow to, when this block is finished.
 StructuredBlock getNextBlock(StructuredBlock subBlock)
          Returns the block where the control will normally flow to, when the given sub block is finished.
 FlowBlock getNextFlowBlock()
          Returns the flow block where the control will normally flow to, when this block is finished.
 FlowBlock getNextFlowBlock(StructuredBlock subBlock)
           
 StructuredBlock[] getSubBlocks()
          Returns all sub block of this structured block.
 boolean isEmpty()
          Tells if this block is empty and only changes control flow.
 boolean isSingleExit(StructuredBlock subBlock)
          Tells if the sub block is the single exit point of the current block.
 boolean jumpMayBeChanged()
           
 void makeDeclaration(Set done)
          Make the declarations, i.e.
 VariableStack mapStackToLocal(VariableStack stack)
          This is called after the analysis is completely done.
 void moveJump(Jump jump)
          This function moves the jump to this block.
 boolean needsBraces()
          Tells if this block needs braces when used in a if or while block.
 StructuredBlock prependBlock(StructuredBlock block)
          Prepends a block to this block.
 Set propagateUsage()
          Propagate the used set.
 void removeBlock()
          Removes this block, or replaces it with an EmptyBlock.
 void removeJump()
          Removes the jump.
 void removeOnetimeLocals()
          This method should remove local variables that are only written and read one time directly after another.
 void removePush()
          This is called after mapStackToLocal to do the stack to local transformation.
 void replace(StructuredBlock sb)
          This function replaces sb with this block.
 boolean replaceSubBlock(StructuredBlock oldBlock, StructuredBlock newBlock)
          Replaces the given sub block with a new block.
 void setFlowBlock(FlowBlock flowBlock)
          Set the flow block of this block and all sub blocks.
 void setJump(Jump jump)
           
 void setSuccessors(Jump[] jumps)
          Sets the successors of this structured block.
 void simplify()
           
 void swapJump(StructuredBlock block)
          This function swaps the jump with another block.
 String toString()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

StructuredBlock

public StructuredBlock()
Method Detail

getNextBlock

public StructuredBlock getNextBlock()
Returns the block where the control will normally flow to, when this block is finished.


setSuccessors

public void setSuccessors(Jump[] jumps)
Sets the successors of this structured block. This should be only called once, by FlowBlock.setSuccessors().


setJump

public void setJump(Jump jump)

getNextFlowBlock

public FlowBlock getNextFlowBlock()
Returns the flow block where the control will normally flow to, when this block is finished.

Returns:
null, if the control flows into a non empty structured block or if this is the outermost block.

getNextBlock

public StructuredBlock getNextBlock(StructuredBlock subBlock)
Returns the block where the control will normally flow to, when the given sub block is finished. (This is overwritten by SequentialBlock and SwitchBlock). If this isn't called with a direct sub block, the behaviour is undefined, so take care.

Returns:
null, if the control flows to another FlowBlock.

getNextFlowBlock

public FlowBlock getNextFlowBlock(StructuredBlock subBlock)

isEmpty

public boolean isEmpty()
Tells if this block is empty and only changes control flow.


isSingleExit

public boolean isSingleExit(StructuredBlock subBlock)
Tells if the sub block is the single exit point of the current block.

Parameters:
subBlock - the sub block.
Returns:
true, if the sub block is the single exit point of the current block.

replaceSubBlock

public boolean replaceSubBlock(StructuredBlock oldBlock,
                               StructuredBlock newBlock)
Replaces the given sub block with a new block.

Parameters:
oldBlock - the old sub block.
newBlock - the new sub block.
Returns:
false, if oldBlock wasn't a direct sub block.

getSubBlocks

public StructuredBlock[] getSubBlocks()
Returns all sub block of this structured block.


getBytecodeInstructions

public List<Instruction> getBytecodeInstructions()
Returns the list of bytecode instructions that represents this block.


getBCELInstructions

public List<InstructionHandle> getBCELInstructions()

contains

public boolean contains(StructuredBlock child)
Returns if this block contains the given block.

Parameters:
child - the block which should be contained by this block.
Returns:
false, if child is null, or is not contained in this block.

removeJump

public final void removeJump()
Removes the jump. This does not update the successors vector of the flow block, you have to do it yourself.


replace

public void replace(StructuredBlock sb)
This function replaces sb with this block. It copies outer and from sb, and updates the outer block, so it knows that sb was replaced. You have to replace sb.outer or mustn't use sb anymore.

It will also move the definitions of sb and childs to this block, but only descend to sub and not further. It is assumed that sub will become a sub block of this block.

Parameters:
sb - The structured block that should be replaced.

swapJump

public void swapJump(StructuredBlock block)
This function swaps the jump with another block.

Parameters:
block - The block whose jump is swapped.

moveJump

public void moveJump(Jump jump)
This function moves the jump to this block. The jump field of the previous owner is cleared afterwards. If the given jump is null, nothing bad happens.

Parameters:
jump - The jump that should be moved, may be null.

copyJump

public void copyJump(Jump jump)
This function copies the jump to this block. If the given jump is null, nothing bad happens.

Parameters:
jump - The jump that should be moved, may be null.

appendBlock

public StructuredBlock appendBlock(StructuredBlock block)
Appends a block to this block.

Returns:
the new combined block.

prependBlock

public StructuredBlock prependBlock(StructuredBlock block)
Prepends a block to this block.

Returns:
the new combined block.

removeBlock

public final void removeBlock()
Removes this block, or replaces it with an EmptyBlock.


flowMayBeChanged

public boolean flowMayBeChanged()
Determines if there is a path, that flows through the end of this block. If there is such a path, it is forbidden to change the control flow in after this block and this method returns false.

Returns:
true, if the jump may be safely changed.

jumpMayBeChanged

public boolean jumpMayBeChanged()

getDeclarables

public Set getDeclarables()

propagateUsage

public Set propagateUsage()
Propagate the used set. Initially the used block contains the local that are used in some expression directly in this block. This will extend the set, so that a variable is used if it is used in at least two sub blocks.

Returns:
all locals that are used in this block or in some sub block (this is not the used set).

mapStackToLocal

public VariableStack mapStackToLocal(VariableStack stack)
This is called after the analysis is completely done. It will remove all PUSH/stack_i expressions, (if the bytecode is correct).

The default implementation merges the stack after each sub block. This may not be, what you want.

Parameters:
stack - the stackmap at begin of the block
Returns:
the stack after the block has executed.
Throws:
RuntimeException - if something did get wrong.

removePush

public void removePush()
This is called after mapStackToLocal to do the stack to local transformation.


removeOnetimeLocals

public void removeOnetimeLocals()
This method should remove local variables that are only written and read one time directly after another.
This is especially important for stack locals, that are created when there are unusual swap or dup instructions, but also makes inlined functions more pretty (but not that close to the bytecode).


makeDeclaration

public void makeDeclaration(Set done)
Make the declarations, i.e. initialize the declare variable to correct values. This will declare every variable that is marked as used, but not done.
This will now also combine locals, that use the same slot, have compatible types and are declared in the same block.

Parameters:
done - The set of the already declare variables.

checkConsistent

public void checkConsistent()

setFlowBlock

public void setFlowBlock(FlowBlock flowBlock)
Set the flow block of this block and all sub blocks.

Parameters:
flowBlock - the new flow block

needsBraces

public boolean needsBraces()
Tells if this block needs braces when used in a if or while block.

Returns:
true if this block should be sorrounded by braces.

fillInGenSet

public void fillInGenSet(Set in,
                         Set gen)
Fill all in variables into the given VariableSet.

Parameters:
in - The VariableSet, the in variables should be stored to.

dumpSource

public void dumpSource(TabbedPrintWriter writer)
                throws IOException
Print the source code for this structured block. This handles everything that is unique for all structured blocks and calls dumpInstruction afterwards.

Parameters:
writer - The tabbed print writer, where we print to.
Throws:
IOException

dumpInstruction

public abstract void dumpInstruction(TabbedPrintWriter writer)
                              throws IOException
Print the instruction expressing this structured block.

Parameters:
writer - The tabbed print writer, where we print to.
Throws:
IOException

toString

public String toString()
Overrides:
toString in class Object

simplify

public void simplify()

doTransformations

public boolean doTransformations()
Do simple transformation on the structuredBlock.

Returns:
true, if some transformation was done.