protected override void OnBeforePathStepExtended(FlowEdge edge) { this.smtSolver.Push(); this.Heap.PushState(); if (edge is OuterFlowEdge outerEdge) { if (outerEdge.Kind == OuterFlowEdgeKind.MethodCall && outerEdge.To is EnterFlowNode enterNode) { var callNode = (CallFlowNode)outerEdge.From; if (callNode.IsObjectCreation) { // This is needed in the case when the exploration itself started from a constructor (or from a // method called by it). We need to let the heap know that this object is not a part of the input // heap. var newVar = enterNode.Parameters[0]; var versionedVar = new VersionedVariable(newVar, this.GetVariableVersion(newVar)); this.Heap.AllocateNew(versionedVar); } else if (callNode.IsInstanceCall) { var thisVar = enterNode.Parameters[0]; var versionedThisVar = new VersionedVariable(thisVar, this.GetVariableVersion(thisVar)); this.Heap.AssertEquality(false, versionedThisVar, VersionedVariable.Null); } } } }
protected override void OnFieldReadAsserted( VersionedVariable result, VersionedVariable reference, IFieldDefinition field) { this.Heap.ReadField(result, reference, field); }
protected override void OnFieldWriteAsserted( VersionedVariable reference, IFieldDefinition field, Expression value) { this.Heap.WriteField(reference, field, value); }
protected override void OnReferenceEqualityAsserted( bool areEqual, VersionedVariable left, VersionedVariable right) { this.Heap.AssertEquality(areEqual, left, right); }
protected override void OnFieldReadRetracted( VersionedVariable result, VersionedVariable reference, IFieldDefinition field) { this.heapModelRecorder.ReadField(reference, field); this.AddVariableValue(result); }
private void AddVariableValue(VersionedVariable variable) { if (variable.Variable.IsReference) { this.AddVariableHeapLocation(variable); } else { this.AddVariableInterpretation(variable); } }
protected override void OnReferenceEqualityRetracted( bool areEqual, VersionedVariable left, VersionedVariable right) { // TODO: Store the comparison result to the interpretation stack when expected in ViewModel // Only let the heap model know that we are interested in them // so that it displays them later this.heapModelRecorder.GetLocation(left); this.heapModelRecorder.GetLocation(right); }
private void AddVariableHeapLocation(VersionedVariable variable) { Contract.Requires(variable.Variable.IsReference); var heapLocation = this.heapModelRecorder.GetLocation(variable); if (this.areAssignmentsPostponedToNextNode) { this.nextNodeHeapLocations.Add(heapLocation); } else { this.currentNodeHeapLocations.Add(heapLocation); } }
private void AddVariableInterpretation(VersionedVariable variable) { Contract.Requires(!variable.Variable.IsReference); var symbolName = this.smtContextHandler.GetVariableVersionSymbol( variable.Variable, variable.Version); var interpretation = this.smtModel.GetInterpretation(symbolName); if (this.areAssignmentsPostponedToNextNode) { this.nextNodeInterpretations.Add(interpretation); } else { this.currentNodeInterpretations.Add(interpretation); } }
protected override void OnAfterPathStepRetracted(FlowEdge edge) { // Identify the creation of new objects on the heap if (edge is OuterFlowEdge outerEdge && outerEdge.Kind == OuterFlowEdgeKind.MethodCall && outerEdge.From is CallFlowNode callNode && callNode.IsObjectCreation) { // "this" must be the first variable in the constructor by convention var thisVar = edge.To.Graph.LocalVariables[0]; Contract.Assert(thisVar.IsReference); var versionedVar = new VersionedVariable(thisVar, this.GetVariableVersion(thisVar)); this.heapModelRecorder.AllocateNew(versionedVar); } this.AddNodeValues(); }
protected override void OnFieldWriteRetracted( VersionedVariable reference, IFieldDefinition field, Expression value) { if (value.Sort == References.Sort) { if (!(value is FlowVariable valVar)) { throw new NotSupportedException("Only versioned flow variables supported as references"); } this.heapModelRecorder.WriteReferenceField(reference, field, this.GetVersioned(valVar)); } else { var valueInterpretation = this.smtModel.GetInterpretation(this.NameProvider, value); this.heapModelRecorder.WriteValueField(reference, field, valueInterpretation); } this.AddVariableHeapLocation(reference); }
protected override void OnVariableAssigned( FlowVariable variable, int lastVersion, Expression value) { if (variable.IsReference) { var leftRef = new VersionedVariable(variable, lastVersion); var rightRef = this.GetVersioned((FlowVariable)value); this.Heap.AssignReference(leftRef, rightRef); } else if (References.IsReferenceComparison(value, out bool areEqual, out var left, out var right)) { var varLeft = this.GetVersioned(left); var varRight = this.GetVersioned(right); value = this.Heap.GetEqualityExpression(areEqual, varLeft, varRight); } if (!variable.IsReference) { this.AssertEquals(variable, lastVersion, value); } }
public NamedVariable GetNamedVariable(VersionedVariable variable) { var name = this.owner.contextHandler.GetVariableVersionSymbol(variable.Variable, variable.Version); return(ExpressionFactory.NamedVariable(variable.Variable.Sort, name)); }