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()
this
public final boolean leq(VarContext<T> that)
Ordered
leq
in interface Ordered<VarContext<T extends AbstractValue<T>>>
that
- object to compare to this
o
public 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
that
widen
- if true use the widening operatorVarContext
that is the upper bound of this
and that
public VarContext<T> upperBound(VarContext<T> that)
Ordered
this
and o
upperBound
in interface Ordered<VarContext<T extends AbstractValue<T>>>
that
- object to upper bound with thisthis
with o
public VarContext<T> widen(VarContext<T> that)
Ordered
this
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 this
this
and o
protected T valUpperBound(T a, T b, boolean widen)
a
and b
a
- valueb
- valuewiden
- if true use the widening operatora
and b
public java.util.Map<java.lang.String,T> locals()
public VarContext<T> locals(java.util.Map<java.lang.String,T> newLocals)
newLocals
newLocals
- 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)
s
s
- 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 returnResult
returnResult
- new return resultthis
with the return result swapped outpublic VarContext<T> clearReturnResult()
this
this
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)
depth
public 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)
absVal
abstractLocations
- 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
this
this
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.Item
public int hashCode()
hashCode
in class polyglot.visit.DataFlow.Item
protected static java.lang.String printAsObj(java.lang.Object o)
Object
o
- object to printpublic java.lang.String toString()
toString
in class java.lang.Object
public T getLocationAbsVal(AbstractLocation l)
l
- abstract location to get the value forl
public boolean hasLocalAbsVal(java.lang.String localName)
localName
is in the variable contextlocalName
- name of the local to check forthis
public 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
items
items
- list of VarContext
to joinitems
public 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
items
items
- list of VarContext
to joinextendByOneIfNeeded
- if true can add a bottom value to the expression stackclearExprStacks
- clear all expression stacks before computing the joinitems
protected 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 c2
c1
- variable contextc2
- variable contextc1
and c2
public VarContext<T> recordNodeEntry(polyglot.ast.Term node)
public VarContext<T> recordNodeExit(polyglot.ast.Term node)
public java.lang.Integer depthToNodeEntry(polyglot.ast.Term node)