public class VarContext<T extends AbstractValue<T>> extends polyglot.visit.DataFlow.Item implements java.lang.Cloneable, Ordered<VarContext<T>>
| Modifier and Type | Field and Description |
|---|---|
protected int |
hashCode |
protected java.util.Map<AbstractLocation,T> |
locations |
protected boolean |
needsHashCode |
| 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
|
| 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>> |
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>> |
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>> |
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>> |
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>> |
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)). |
protected java.util.Map<AbstractLocation,T extends AbstractValue<T>> locations
protected int hashCode
protected boolean needsHashCode
public VarContext(java.lang.String analysisName,
T bottomAbsVal)
analysisName - name of the current analysisbottomAbsVal - bottom value of the abstract value latticepublic VarContext(java.lang.String analysisName,
T bottomAbsVal,
boolean trackHeapLocations,
T defaultHeapLocationValue)
analysisName - name of the current analysisbottomAbsVal - bottom value of the abstract value latticetrackHeapLocations - 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 locationsprotected 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)
analysisName - name of the current analysislocals - Map from local variable names to abstract valueslocations - Map from abstract locations to abstract valuesexprResultStack - stack of values containing the results of the analyses of
previous expressionsexprResultStackNodeEntry - 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 blockreturnResult - abstract value for the return resultbottomAbsVal - bottom value of the abstract value latticetrackHeapLocations - 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 locationsprotected VarContext<T> copy()
thispublic final boolean leq(VarContext<T> that)
Orderedleq in interface Ordered<VarContext<T extends AbstractValue<T>>>that - object to compare to thisopublic boolean leq(VarContext<T> that, java.util.Set<AbstractLocation> locationDomain)
that - VarContext to compare tolocationDomain - restrict leq to these locationspublic VarContext<T> wideningUpperBound(VarContext<T> that, boolean widen)
this and
that, i.e., this.leq(this.uppperBound(that)) and
that.leq(this.upperBound(that)).that - compute the upper bound of this and
thatwiden - if true use the widening operatorVarContext that is the upper bound of this
and thatpublic VarContext<T> upperBound(VarContext<T> that)
Orderedthis and oupperBound in interface Ordered<VarContext<T extends AbstractValue<T>>>that - object to upper bound with thisthis with opublic VarContext<T> widen(VarContext<T> that)
Orderedthis and o. A
widening operator is an upper bound where all ascending chains eventually
stabilize.widen in interface Ordered<VarContext<T extends AbstractValue<T>>>that - object to widen with thisthis and oprotected T valUpperBound(T a, T b, boolean widen)
a and ba - valueb - valuewiden - if true use the widening operatora and bpublic java.util.Map<java.lang.String,T> locals()
public VarContext<T> locals(java.util.Map<java.lang.String,T> newLocals)
newLocalsnewLocals - new map of names of local variables to abstract valuesthis with the new local variable mappublic Stack<T> exprResultStack()
public java.util.Map<polyglot.ast.Term,java.lang.Integer> exprResultStackNodeEntry()
public VarContext<T> popExprResults(int i)
i results off the result stack.i - number of results to popi results
popped offpublic VarContext<T> popAndPushExprResults(int i, T v, polyglot.ast.Node source)
i - number of results to popv - value to pushsource - AST node that resulted in the newly pushed valuev pushed onpublic VarContext<T> popExprResult()
public VarContext<T> pushExprResult(T v, java.lang.Object source)
v - value to pushsource - object associated with the value being pushedv pushed onpublic VarContext<T> pushExprResults(java.util.List<T> vs, java.lang.Object source)
v - values to pushsource - object associated with the values being pushedvs
pushed onpublic java.util.List<T> peekExprResults(int i)
i results on the expression
results stackpublic T peekExprResult()
public VarContext<T> exprResultStack(Stack<T> s, java.util.Map<polyglot.ast.Term,java.lang.Integer> nodeEntry)
ss - stack to be convertedVarContext with s as its
expression result stackpublic VarContext<T> clearExprResultStack()
this with an empty expression result stackpublic T returnResult()
public VarContext<T> returnResult(T returnResult)
this for returnResultreturnResult - new return resultthis with the return result swapped outpublic VarContext<T> clearReturnResult()
thisthis with the return result clearedpublic VarContext<T> suspendedExecutionStack(SuspendedExecutionStack<T> stack)
VarContext identical to this with the
suspended execution stack replaced with the specified onestack - stack of maps from finally block entry edge key to abstract valueVarContext with the existing suspended execution stack
swapped out for the specified one.public VarContext<T> restoreCallerContext(VarContext<T> toRestore, boolean restoreLocalsAndStack, ExitMap.Key edgeKey)
this is the callee context. toRestore
is the caller context to restore.toRestore - Context to restore fromrestoreLocalsAndStack - If true then the local variables and expression stack will be
restorededgeKey - exit key we are restoring forpublic SuspendedExecutionStack<T> suspendedExecutionStack()
public VarContext<T> popSuspendedExecutionStack()
public VarContext<T> popSuspendedExecutionStackToDepth(int depth)
depthpublic VarContext<T> pushSuspendedExecutionStack(java.util.Map<polyglot.visit.FlowGraph.EdgeKey,T> m, polyglot.ast.Block fb)
m - value to pushfb - finally block associated with the value being pushedpublic java.util.Map<polyglot.visit.FlowGraph.EdgeKey,T> peekSuspendedExecutionStack()
public VarContext<T> addLocal(java.lang.String name, T absVal)
name - name of the localabsVal - abstract value for the localthis with the new local variable addedprotected final VarContext<T> addLocations(java.util.Set<AbstractLocation> abstractLocations, T absVal)
abstractLocations - locations to addabsVal - abstract value for each element of the set of locationsprotected VarContext<T> addLocationsImpl(java.util.Set<AbstractLocation> abstractLocations, T absVal)
absValabstractLocations - locations to addabsVal - abstract value for each element of the set of locationspublic VarContext<T> locations(java.util.Map<AbstractLocation,T> newLocations)
this for the givennewLocations - Map of abstract locations to abstract values to set into
thisthis with the new abstract locations and
valuespublic java.util.Map<AbstractLocation,T> locations()
public boolean equals(java.lang.Object o)
equals in class polyglot.visit.DataFlow.Itempublic int hashCode()
hashCode in class polyglot.visit.DataFlow.Itemprotected static java.lang.String printAsObj(java.lang.Object o)
Objecto - object to printpublic java.lang.String toString()
toString in class java.lang.Objectpublic T getLocationAbsVal(AbstractLocation l)
l - abstract location to get the value forlpublic boolean hasLocalAbsVal(java.lang.String localName)
localName is in the variable contextlocalName - name of the local to check forthispublic T getLocalAbsVal(java.lang.String localName, polyglot.types.Type localType)
localName - name of the locallocalType - Type of the localprotected T getDefaultLocalAbsVal(java.lang.String localName, polyglot.types.Type localType)
localName - name of the locallocalType - Type of the localpublic static <T extends AbstractValue<T>> VarContext<T> join(java.util.List<VarContext<T>> items)
VarContext that is the join of all the elements of
itemsitems - list of VarContext to joinitemspublic static <T extends AbstractValue<T>> VarContext<T> join(java.util.List<VarContext<T>> items, boolean extendByOneIfNeeded, boolean clearExprStacks, boolean clearSuspendedExecutionContexts)
VarContext that is the join of all the elements of
itemsitems - list of VarContext to joinextendByOneIfNeeded - if true can add a bottom value to the expression stackclearExprStacks - clear all expression stacks before computing the joinitemsprotected static <T extends AbstractValue<T>> VarContext<T> hashCons(VarContext<T> c)
c
and return itc - var context to memoizepublic static void clearHashCons(java.lang.String analysisName)
analysisName - name of analysispublic static <T extends AbstractValue<T>> boolean leq(VarContext<T> c1, VarContext<T> c2, java.util.Set<AbstractLocation> locationDomain)
c1 leq c2 over the given locationsc1 - var contextc2 - var contextlocationDomain - Only compute leq over these locationsc1 <= c2 on the given domainpublic static <T extends AbstractValue<T>> VarContext<T> upperBound(VarContext<T> c1, VarContext<T> c2)
c1 and c2c1 - variable contextc2 - variable contextc1 and c2public VarContext<T> recordNodeEntry(polyglot.ast.Term node)
public VarContext<T> recordNodeExit(polyglot.ast.Term node)
public java.lang.Integer depthToNodeEntry(polyglot.ast.Term node)