org.apache.bcel.verifier.structurals
Class Subroutines

java.lang.Object
  extended by org.apache.bcel.verifier.structurals.Subroutines

public class Subroutines
extends java.lang.Object

Instances of this class contain information about the subroutines found in a code array of a method. This implementation considers the top-level (the instructions reachable without a JSR or JSR_W starting off from the first instruction in a code array of a method) being a special subroutine; see getTopLevel() for that. Please note that the definition of subroutines in the Java Virtual Machine Specification, Second Edition is somewhat incomplete. Therefore, JustIce uses an own, more rigid notion. Basically, a subroutine is a piece of code that starts at the target of a JSR of JSR_W instruction and ends at a corresponding RET instruction. Note also that the control flow of a subroutine may be complex and non-linear; and that subroutines may be nested. JustIce also mandates subroutines not to be protected by exception handling code (for the sake of control flow predictability). To understand JustIce's notion of subroutines, please read TODO: refer to the paper.

Version:
$Id: Subroutines.java 386056 2006-03-15 11:31:56Z tcurdt $
Author:
Enver Haase
See Also:
getTopLevel()

Nested Class Summary
private  class Subroutines.SubroutineImpl
          This inner class implements the Subroutine interface.
 
Field Summary
private static java.lang.Integer BLACK
           
private static java.lang.Integer GRAY
           
private  java.util.Hashtable subroutines
          The Hashtable containing the subroutines found.
 Subroutine TOPLEVEL
          This is referring to a special subroutine, namely the top level.
private static java.lang.Integer WHITE
           
 
Constructor Summary
Subroutines(MethodGen mg)
          Constructor.
 
Method Summary
 Subroutine getSubroutine(InstructionHandle leader)
          Returns the Subroutine object associated with the given leader (that is, the first instruction of the subroutine).
private static InstructionHandle[] getSuccessors(InstructionHandle instruction)
          A utility method that calculates the successors of a given InstructionHandle in the same subroutine.
 Subroutine getTopLevel()
          For easy handling, the piece of code that is not a subroutine, the top-level, is also modeled as a Subroutine object.
private  void noRecursiveCalls(Subroutine sub, java.util.Set set)
          This (recursive) utility method makes sure that no subroutine is calling a subroutine that uses the same local variable for the RET as themselves (recursively).
 Subroutine subroutineOf(InstructionHandle any)
          Returns the subroutine object associated with the given instruction.
 java.lang.String toString()
          Returns a String representation of this object; merely for debugging puposes.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

WHITE

private static final java.lang.Integer WHITE

GRAY

private static final java.lang.Integer GRAY

BLACK

private static final java.lang.Integer BLACK

subroutines

private java.util.Hashtable subroutines
The Hashtable containing the subroutines found. Key: InstructionHandle of the leader of the subroutine. Elements: SubroutineImpl objects.


TOPLEVEL

public final Subroutine TOPLEVEL
This is referring to a special subroutine, namely the top level. This is not really a subroutine but we use it to distinguish between top level instructions and unreachable instructions.

Constructor Detail

Subroutines

public Subroutines(MethodGen mg)
Constructor.

Parameters:
mg - A MethodGen object representing method to create the Subroutine objects of.
Method Detail

noRecursiveCalls

private void noRecursiveCalls(Subroutine sub,
                              java.util.Set set)
This (recursive) utility method makes sure that no subroutine is calling a subroutine that uses the same local variable for the RET as themselves (recursively). This includes that subroutines may not call themselves recursively, even not through intermediate calls to other subroutines.

Throws:
StructuralCodeConstraintException - if the above constraint is not satisfied.

getSubroutine

public Subroutine getSubroutine(InstructionHandle leader)
Returns the Subroutine object associated with the given leader (that is, the first instruction of the subroutine). You must not use this to get the top-level instructions modeled as a Subroutine object.

See Also:
getTopLevel()

subroutineOf

public Subroutine subroutineOf(InstructionHandle any)
Returns the subroutine object associated with the given instruction. This is a costly operation, you should consider using getSubroutine(InstructionHandle). Returns 'null' if the given InstructionHandle lies in so-called 'dead code', i.e. code that can never be executed.

See Also:
getSubroutine(InstructionHandle), getTopLevel()

getTopLevel

public Subroutine getTopLevel()
For easy handling, the piece of code that is not a subroutine, the top-level, is also modeled as a Subroutine object. It is a special Subroutine object where you must not invoke getEnteringJsrInstructions() or getLeavingRET().

See Also:
Subroutine.getEnteringJsrInstructions(), Subroutine.getLeavingRET()

getSuccessors

private static InstructionHandle[] getSuccessors(InstructionHandle instruction)
A utility method that calculates the successors of a given InstructionHandle in the same subroutine. That means, a RET does not have any successors as defined here. A JsrInstruction has its physical successor as its successor (opposed to its target) as defined here.


toString

public java.lang.String toString()
Returns a String representation of this object; merely for debugging puposes.

Overrides:
toString in class java.lang.Object