accrue.analysis.interprocvarcontext

## Class VarContext<T extends AbstractValue<T>>

- java.lang.Object
- - polyglot.visit.DataFlow.Item
  - - accrue.analysis.interprocvarcontext.VarContext<T>

- All Implemented Interfaces:
    Ordered<VarContext<T>>, java.lang.Cloneable

      public class VarContext<T extends AbstractValue<T>>
      extends polyglot.visit.DataFlow.Item
      implements java.lang.Cloneable, Ordered<VarContext<T>>

  A VarContext keeps track of abstract values for local variables and heap locations. It also tracks abstract values for the expression stack, the return value (either exceptional return or normal return value). It is also used tracks suspended execution contexts appropriate, i.e., when control flow enters a finally block, due to, say, an exception being thrown, if the finally block terminates normally, then the VarContext for the exception needs to be restored (since the exception value will be held in the suspended returnResult field). See VarContextDataFlow for more details.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected int` | `hashCode`
    `protected java.util.Map<AbstractLocation,T>` | `locations`
    `protected boolean` | `needsHashCode`

  - ### Constructor Summary

    Constructors
    Modifier | Constructor and Description
    --- | ---
    `protected` | `VarContext(java.lang.String analysisName, java.util.Map<java.lang.String,T> locals, java.util.Map<AbstractLocation,T> locations, Stack<T> exprResultStack, java.util.Map<polyglot.ast.Term,java.lang.Integer> exprResultStackNodeEntry, SuspendedExecutionStack<T> suspendedExecutionStack, T returnResult, T bottomAbsVal, boolean trackHeapLocations, T defaultHeapLocationValue)` Create a variable context
    `` | `VarContext(java.lang.String analysisName, T bottomAbsVal)` Create a variable context
    `` | `VarContext(java.lang.String analysisName, T bottomAbsVal, boolean trackHeapLocations, T defaultHeapLocationValue)` Create a new variable context

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `VarContext<T>` | `addLocal(java.lang.String name, T absVal)` Add a new local variable to the context
    `protected VarContext<T>` | `addLocations(java.util.Set<AbstractLocation> abstractLocations, T absVal)` Only call this through AnalysisUtil.addLocations AbsVal for abstract locations only increase, they never get replaced...
    `protected VarContext<T>` | `addLocationsImpl(java.util.Set<AbstractLocation> abstractLocations, T absVal)` Add the locations with the upper bound of the existing abstract value (if any) and `absVal`
    `VarContext<T>` | `clearExprResultStack()` Clear the stack of expression results
    `static void` | `clearHashCons(java.lang.String analysisName)` Clear all values for the given analysis
    `VarContext<T>` | `clearReturnResult()` Clear the return result in `this`
    `protected VarContext<T>` | `copy()`
    `java.lang.Integer` | `depthToNodeEntry(polyglot.ast.Term node)` Return number of elements on stack since entry to node was recorded.
    `boolean` | `equals(java.lang.Object o)`
    `Stack<T>` | `exprResultStack()`
    `VarContext<T>` | `exprResultStack(Stack<T> s, java.util.Map<polyglot.ast.Term,java.lang.Integer> nodeEntry)` Swap the expression result stack in this with `s`
    `java.util.Map<polyglot.ast.Term,java.lang.Integer>` | `exprResultStackNodeEntry()`
    `protected T` | `getDefaultLocalAbsVal(java.lang.String localName, polyglot.types.Type localType)` Get the default value for local variables
    `T` | `getLocalAbsVal(java.lang.String localName, polyglot.types.Type localType)` Get the value for the local name
    `T` | `getLocationAbsVal(AbstractLocation l)` Get the abstract value for the given location
    `int` | `hashCode()`
    `protected static <T extends AbstractValue<T>> VarContext<T>` | `hashCons(VarContext<T> c)` Check the memo and return that copy if it exists or add `c` and return it
    `boolean` | `hasLocalAbsVal(java.lang.String localName)` Check whether a local with `localName` is in the variable context
    `static <T extends AbstractValue<T>> VarContext<T>` | `join(java.util.List<VarContext<T>> items)` Compute the `VarContext` that is the join of all the elements of `items`
    `static <T extends AbstractValue<T>> VarContext<T>` | `join(java.util.List<VarContext<T>> items, boolean extendByOneIfNeeded, boolean clearExprStacks, boolean clearSuspendedExecutionContexts)` Compute the `VarContext` that is the join of all the elements of `items`
    `boolean` | `leq(VarContext<T> that)` Is the given object less than or equal to this one
    `boolean` | `leq(VarContext<T> that, java.util.Set<AbstractLocation> locationDomain)` Check leq, but limiting the locations of domains to the specified set.
    `static <T extends AbstractValue<T>> boolean` | `leq(VarContext<T> c1, VarContext<T> c2, java.util.Set<AbstractLocation> locationDomain)` Compute `c1` leq `c2` over the given locations
    `java.util.Map<java.lang.String,T>` | `locals()`
    `VarContext<T>` | `locals(java.util.Map<java.lang.String,T> newLocals)` Copy this variable context and swap the locals for `newLocals`
    `java.util.Map<AbstractLocation,T>` | `locations()`
    `VarContext<T>` | `locations(java.util.Map<AbstractLocation,T> newLocations)` Swap the locations in `this` for the given
    `T` | `peekExprResult()`
    `java.util.List<T>` | `peekExprResults(int i)`
    `java.util.Map<polyglot.visit.FlowGraph.EdgeKey,T>` | `peekSuspendedExecutionStack()`
    `VarContext<T>` | `popAndPushExprResults(int i, T v, polyglot.ast.Node source)` Pop i results off the result stack, and push one
    `VarContext<T>` | `popExprResult()` Pop first result off the result stack.
    `VarContext<T>` | `popExprResults(int i)` Pop `i` results off the result stack.
    `VarContext<T>` | `popSuspendedExecutionStack()` Pop first result off the suspended execution stack.
    `VarContext<T>` | `popSuspendedExecutionStackToDepth(int depth)` Pop results off the suspended execution stack until the size is no more than `depth`
    `protected static java.lang.String` | `printAsObj(java.lang.Object o)` Print the argument as an `Object`
    `VarContext<T>` | `pushExprResult(T v, java.lang.Object source)` Push result
    `VarContext<T>` | `pushExprResults(java.util.List<T> vs, java.lang.Object source)` Push results
    `VarContext<T>` | `pushSuspendedExecutionStack(java.util.Map<polyglot.visit.FlowGraph.EdgeKey,T> m, polyglot.ast.Block fb)` Push suspended execution map
    `VarContext<T>` | `recordNodeEntry(polyglot.ast.Term node)` Record the fact that analysis has entered this node
    `VarContext<T>` | `recordNodeExit(polyglot.ast.Term node)` Record the fact that analysis has entered this node
    `VarContext<T>` | `restoreCallerContext(VarContext<T> toRestore, boolean restoreLocalsAndStack, ExitMap.Key edgeKey)` Restore the appropriate elements of the caller context after analyzing the callee.
    `T` | `returnResult()` Get the abstract value for the return result (could be null)
    `VarContext<T>` | `returnResult(T returnResult)` Swap the return result in `this` for `returnResult`
    `SuspendedExecutionStack<T>` | `suspendedExecutionStack()` Get the stack of maps from finally entry edge keys to abstract values.
    `VarContext<T>` | `suspendedExecutionStack(SuspendedExecutionStack<T> stack)` Get a new `VarContext` identical to `this` with the suspended execution stack replaced with the specified one
    `java.lang.String` | `toString()`
    `VarContext<T>` | `upperBound(VarContext<T> that)` Compute the upper bound of `this` and `o`
    `static <T extends AbstractValue<T>> VarContext<T>` | `upperBound(VarContext<T> c1, VarContext<T> c2)` Compute the upper bound of `c1` and `c2`
    `protected T` | `valUpperBound(T a, T b, boolean widen)` Compute the upper bound of `a` and `b`
    `VarContext<T>` | `widen(VarContext<T> that)` Compute the widening operator on `this` and `o`.
    `VarContext<T>` | `wideningUpperBound(VarContext<T> that, boolean widen)` Return a new VarContext that is an upper bound of `this` and `that`, i.e., this.leq(this.uppperBound(that)) and that.leq(this.upperBound(that)).

    - ### Methods inherited from class java.lang.Object

      `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### locations

          protected java.util.Map<AbstractLocation,T extends AbstractValue<T>> locations

    - #### hashCode

          protected int hashCode

    - #### needsHashCode

          protected boolean needsHashCode

  - ### Constructor Detail

    - #### VarContext

          public VarContext(java.lang.String analysisName,
                    T bottomAbsVal)

      Create a variable context
      Parameters:
        `analysisName` - name of the current analysis
        `bottomAbsVal` - bottom value of the abstract value lattice

    - #### VarContext

          public VarContext(java.lang.String analysisName,
                    T bottomAbsVal,
                    boolean trackHeapLocations,
                    T defaultHeapLocationValue)

      Create a new variable context
      Parameters:
        `analysisName` - name of the current analysis
        `bottomAbsVal` - bottom value of the abstract value lattice
        `trackHeapLocations` - Analyses can choose to lose precision for speed, and not track data flow to heap locations. If so, then they need to provide a default policy for heap locations, which will be used when a value is read from the heap. For soundness, this should be the top value.
        `defaultHeapLocationValue` - Default value for heap locations

    - #### VarContext

          protected VarContext(java.lang.String analysisName,
                    java.util.Map<java.lang.String,T> locals,
                    java.util.Map<AbstractLocation,T> locations,
                    Stack<T> exprResultStack,
                    java.util.Map<polyglot.ast.Term,java.lang.Integer> exprResultStackNodeEntry,
                    SuspendedExecutionStack<T> suspendedExecutionStack,
                    T returnResult,
                    T bottomAbsVal,
                    boolean trackHeapLocations,
                    T defaultHeapLocationValue)

      Create a variable context
      Parameters:
        `analysisName` - name of the current analysis
        `locals` - Map from local variable names to abstract values
        `locations` - Map from abstract locations to abstract values
        `exprResultStack` - stack of values containing the results of the analyses of previous expressions
        `exprResultStackNodeEntry` - Map describing the depth of the stack when flow for various nodes was entered.
        `suspendedExecutionStack` - Stack of maps from finally block entry edge to abstract value used to pass values through a finally block
        `returnResult` - abstract value for the return result
        `bottomAbsVal` - bottom value of the abstract value lattice
        `trackHeapLocations` - Analyses can choose to lose precision for speed, and not track data flow to heap locations. If so, then they need to provide a default policy for heap locations, which will be used when a value is read from the heap. For soundness, this should be the top value.
        `defaultHeapLocationValue` - Default value for heap locations

  - ### Method Detail

    - #### copy

          protected VarContext<T> copy()

      Returns:
        a copy of `this`

    - #### leq

          public final boolean leq(VarContext<T> that)

      Description copied from interface: `Ordered`
      Is the given object less than or equal to this one
      Specified by:
        `leq` in interface `Ordered<VarContext<T extends AbstractValue<T>>>`
      Parameters:
        `that` - object to compare to `this`
      Returns:
        true if this is less than or equal to `o`

    - #### leq

          public boolean leq(VarContext<T> that,
                    java.util.Set<AbstractLocation> locationDomain)

      Check leq, but limiting the locations of domains to the specified set.
      Parameters:
        `that` - `VarContext` to compare to
        `locationDomain` - restrict leq to these locations

    - #### wideningUpperBound

          public VarContext<T> wideningUpperBound(VarContext<T> that,
                                         boolean widen)

      Return a new VarContext that is an upper bound of `this` and `that`, i.e., this.leq(this.uppperBound(that)) and that.leq(this.upperBound(that)).
      Parameters:
        `that` - compute the upper bound of `this` and `that`
        `widen` - if true use the widening operator
      Returns:
        `VarContext` that is the upper bound of `this` and `that`

    - #### upperBound

          public VarContext<T> upperBound(VarContext<T> that)

      Description copied from interface: `Ordered`
      Compute the upper bound of `this` and `o`
      Specified by:
        `upperBound` in interface `Ordered<VarContext<T extends AbstractValue<T>>>`
      Parameters:
        `that` - object to upper bound with this
      Returns:
        the upper bound of `this` with `o`

    - #### widen

          public VarContext<T> widen(VarContext<T> that)

      Description copied from interface: `Ordered`
      Compute the widening operator on `this` and `o`. A widening operator is an upper bound where all ascending chains eventually stabilize.
      Specified by:
        `widen` in interface `Ordered<VarContext<T extends AbstractValue<T>>>`
      Parameters:
        `that` - object to widen with `this`
      Returns:
        Widened upper bound of `this` and `o`

    - #### valUpperBound

          protected T valUpperBound(T a,
                        T b,
                        boolean widen)

      Compute the upper bound of `a` and `b`
      Parameters:
        `a` - value
        `b` - value
        `widen` - if true use the widening operator
      Returns:
        the upper bound of `a` and `b`

    - #### locals

          public java.util.Map<java.lang.String,T> locals()

      Returns:
        Map of names to abstract values

    - #### locals

          public VarContext<T> locals(java.util.Map<java.lang.String,T> newLocals)

      Copy this variable context and swap the locals for `newLocals`
      Parameters:
        `newLocals` - new map of names of local variables to abstract values
      Returns:
        copy of `this` with the new local variable map

    - #### exprResultStack

          public Stack<T> exprResultStack()

      Returns:
        The stack of abstract values that are the results of the previous expression analyses

    - #### exprResultStackNodeEntry

          public java.util.Map<polyglot.ast.Term,java.lang.Integer> exprResultStackNodeEntry()

    - #### popExprResults

          public VarContext<T> popExprResults(int i)

      Pop `i` results off the result stack.
      Parameters:
        `i` - number of results to pop
      Returns:
        the expression results with the first `i` results popped off

    - #### popAndPushExprResults

          public VarContext<T> popAndPushExprResults(int i,
                                            T v,
                                            polyglot.ast.Node source)

      Pop i results off the result stack, and push one
      Parameters:
        `i` - number of results to pop
        `v` - value to push
        `source` - AST node that resulted in the newly pushed value
      Returns:
        an expression result stack with i results popped off and `v` pushed on

    - #### popExprResult

          public VarContext<T> popExprResult()

      Pop first result off the result stack.
      Returns:
        the expression results with the first result popped off

    - #### pushExprResult

          public VarContext<T> pushExprResult(T v,
                                     java.lang.Object source)

      Push result
      Parameters:
        `v` - value to push
        `source` - object associated with the value being pushed
      Returns:
        the expression results with `v` pushed on

    - #### pushExprResults

          public VarContext<T> pushExprResults(java.util.List<T> vs,
                                      java.lang.Object source)

      Push results
      Parameters:
        `v` - values to push
        `source` - object associated with the values being pushed
      Returns:
        the expression results with the elements of `vs` pushed on

    - #### peekExprResults

          public java.util.List<T> peekExprResults(int i)

      Returns:
        a list of the first `i` results on the expression results stack

    - #### peekExprResult

          public T peekExprResult()

      Returns:
        the first result on the expression results stack

    - #### exprResultStack

          public VarContext<T> exprResultStack(Stack<T> s,
                                      java.util.Map<polyglot.ast.Term,java.lang.Integer> nodeEntry)

      Swap the expression result stack in this with `s`
      Parameters:
        `s` - stack to be converted
      Returns:
        copy of this `VarContext` with `s` as its expression result stack

    - #### clearExprResultStack

          public VarContext<T> clearExprResultStack()

      Clear the stack of expression results
      Returns:
        a copy of `this` with an empty expression result stack

    - #### returnResult

          public T returnResult()

      Get the abstract value for the return result (could be null)
      Returns:
        abstract value for the return result

    - #### returnResult

          public VarContext<T> returnResult(T returnResult)

      Swap the return result in `this` for `returnResult`
      Parameters:
        `returnResult` - new return result
      Returns:
        copy of `this` with the return result swapped out

    - #### clearReturnResult

          public VarContext<T> clearReturnResult()

      Clear the return result in `this`
      Returns:
        A copy of `this` with the return result cleared

    - #### suspendedExecutionStack

          public VarContext<T> suspendedExecutionStack(SuspendedExecutionStack<T> stack)

      Get a new `VarContext` identical to `this` with the suspended execution stack replaced with the specified one
      Parameters:
        `stack` - stack of maps from finally block entry edge key to abstract value
      Returns:
        new `VarContext` with the existing suspended execution stack swapped out for the specified one.

    - #### restoreCallerContext

          public VarContext<T> restoreCallerContext(VarContext<T> toRestore,
                                           boolean restoreLocalsAndStack,
                                           ExitMap.Key edgeKey)

      Restore the appropriate elements of the caller context after analyzing the callee. `this` is the callee context. `toRestore` is the caller context to restore.
      Parameters:
        `toRestore` - Context to restore from
        `restoreLocalsAndStack` - If true then the local variables and expression stack will be restored
        `edgeKey` - exit key we are restoring for
      Returns:
        new context with certain elements restored

    - #### suspendedExecutionStack

          public SuspendedExecutionStack<T> suspendedExecutionStack()

      Get the stack of maps from finally entry edge keys to abstract values.
      Returns:
        the stack of maps from finally entry edge keys to abstract values.

    - #### popSuspendedExecutionStack

          public VarContext<T> popSuspendedExecutionStack()

      Pop first result off the suspended execution stack.
      Returns:
        Var context with one suspended execution popped off

    - #### popSuspendedExecutionStackToDepth

          public VarContext<T> popSuspendedExecutionStackToDepth(int depth)

      Pop results off the suspended execution stack until the size is no more than `depth`
      Returns:
        Var context with depth no greater than depth.

    - #### pushSuspendedExecutionStack

          public VarContext<T> pushSuspendedExecutionStack(java.util.Map<polyglot.visit.FlowGraph.EdgeKey,T> m,
                                                  polyglot.ast.Block fb)

      Push suspended execution map
      Parameters:
        `m` - value to push
        `fb` - finally block associated with the value being pushed
      Returns:
        Var context with the suspended execution map pushed onto the stack

    - #### peekSuspendedExecutionStack

          public java.util.Map<polyglot.visit.FlowGraph.EdgeKey,T> peekSuspendedExecutionStack()

      Returns:
        the first result on the suspended execution stack

    - #### addLocal

          public VarContext<T> addLocal(java.lang.String name,
                               T absVal)

      Add a new local variable to the context
      Parameters:
        `name` - name of the local
        `absVal` - abstract value for the local
      Returns:
        Copy of `this` with the new local variable added

    - #### addLocations

          protected final VarContext<T> addLocations(java.util.Set<AbstractLocation> abstractLocations,
                                   T absVal)

      Only call this through AnalysisUtil.addLocations AbsVal for abstract locations only increase, they never get replaced...
      Parameters:
        `abstractLocations` - locations to add
        `absVal` - abstract value for each element of the set of locations

    - #### addLocationsImpl

          protected VarContext<T> addLocationsImpl(java.util.Set<AbstractLocation> abstractLocations,
                                       T absVal)

      Add the locations with the upper bound of the existing abstract value (if any) and `absVal`
      Parameters:
        `abstractLocations` - locations to add
        `absVal` - abstract value for each element of the set of locations

    - #### locations

          public VarContext<T> locations(java.util.Map<AbstractLocation,T> newLocations)

      Swap the locations in `this` for the given
      Parameters:
        `newLocations` - Map of abstract locations to abstract values to set into `this`
      Returns:
        copy of `this` with the new abstract locations and values

    - #### locations

          public java.util.Map<AbstractLocation,T> locations()

      Returns:
        map of abstract locations to values

    - #### equals

          public boolean equals(java.lang.Object o)

      Specified by:
        `equals` in class `polyglot.visit.DataFlow.Item`

    - #### hashCode

          public int hashCode()

      Specified by:
        `hashCode` in class `polyglot.visit.DataFlow.Item`

    - #### printAsObj

          protected static java.lang.String printAsObj(java.lang.Object o)

      Print the argument as an `Object`
      Parameters:
        `o` - object to print
      Returns:
        String for the given object

    - #### toString

          public java.lang.String toString()

      Overrides:
        `toString` in class `java.lang.Object`

    - #### getLocationAbsVal

          public T getLocationAbsVal(AbstractLocation l)

      Get the abstract value for the given location
      Parameters:
        `l` - abstract location to get the value for
      Returns:
        abstract value for `l`

    - #### hasLocalAbsVal

          public boolean hasLocalAbsVal(java.lang.String localName)

      Check whether a local with `localName` is in the variable context
      Parameters:
        `localName` - name of the local to check for
      Returns:
        true if the local exists in `this`

    - #### getLocalAbsVal

          public T getLocalAbsVal(java.lang.String localName,
                         polyglot.types.Type localType)

      Get the value for the local name
      Parameters:
        `localName` - name of the local
        `localType` - `Type` of the local
      Returns:
        The abstract value for the local

    - #### getDefaultLocalAbsVal

          protected T getDefaultLocalAbsVal(java.lang.String localName,
                                polyglot.types.Type localType)

      Get the default value for local variables
      Parameters:
        `localName` - name of the local
        `localType` - `Type` of the local
      Returns:
        The abstract value for the local

    - #### join

          public static <T extends AbstractValue<T>> VarContext<T> join(java.util.List<VarContext<T>> items)

      Compute the `VarContext` that is the join of all the elements of `items`
      Parameters:
        `items` - list of `VarContext` to join
      Returns:
        join of all the elements of `items`

    - #### join

          public static <T extends AbstractValue<T>> VarContext<T> join(java.util.List<VarContext<T>> items,
                                                        boolean extendByOneIfNeeded,
                                                        boolean clearExprStacks,
                                                        boolean clearSuspendedExecutionContexts)

      Compute the `VarContext` that is the join of all the elements of `items`
      Parameters:
        `items` - list of `VarContext` to join
        `extendByOneIfNeeded` - if true can add a bottom value to the expression stack
        `clearExprStacks` - clear all expression stacks before computing the join
      Returns:
        join of all the elements of `items`

    - #### hashCons

          protected static <T extends AbstractValue<T>> VarContext<T> hashCons(VarContext<T> c)

      Check the memo and return that copy if it exists or add `c` and return it
      Parameters:
        `c` - var context to memoize
      Returns:
        an equivalent var context

    - #### clearHashCons

          public static void clearHashCons(java.lang.String analysisName)

      Clear all values for the given analysis
      Parameters:
        `analysisName` - name of analysis

    - #### leq

          public static <T extends AbstractValue<T>> boolean leq(VarContext<T> c1,
                                                 VarContext<T> c2,
                                                 java.util.Set<AbstractLocation> locationDomain)

      Compute `c1` leq `c2` over the given locations
      Parameters:
        `c1` - var context
        `c2` - var context
        `locationDomain` - Only compute leq over these locations
      Returns:
        true if `c1` <= `c2` on the given domain

    - #### upperBound

          public static <T extends AbstractValue<T>> VarContext<T> upperBound(VarContext<T> c1,
                                                              VarContext<T> c2)

      Compute the upper bound of `c1` and `c2`
      Parameters:
        `c1` - variable context
        `c2` - variable context
      Returns:
        the upper bound of `c1` and `c2`

    - #### recordNodeEntry

          public VarContext<T> recordNodeEntry(polyglot.ast.Term node)

      Record the fact that analysis has entered this node

    - #### recordNodeExit

          public VarContext<T> recordNodeExit(polyglot.ast.Term node)

      Record the fact that analysis has entered this node

    - #### depthToNodeEntry

          public java.lang.Integer depthToNodeEntry(polyglot.ast.Term node)

      Return number of elements on stack since entry to node was recorded.