public void MergeMultipleDisjointVariables() { var sources = new[] { CreateDummyNode(0), CreateDummyNode(1), }; var variables = new[] { new DummyVariable("V_1"), new DummyVariable("V_2"), }; var variables1 = ImmutableDictionary <IVariable, SymbolicValue <DummyInstruction> > .Empty; variables1 = variables1.SetItem(variables[0], SymbolicValue <DummyInstruction> .CreateVariableValue(sources[0], variables[0])); var variables2 = ImmutableDictionary <IVariable, SymbolicValue <DummyInstruction> > .Empty; variables2 = variables2.SetItem(variables[1], SymbolicValue <DummyInstruction> .CreateVariableValue(sources[1], variables[1])); var state1 = new SymbolicProgramState <DummyInstruction>(0, variables1); var state2 = new SymbolicProgramState <DummyInstruction>(0, variables2); Assert.True(state1.MergeStates(state2, out var newState)); Assert.Equal(new HashSet <DataFlowNode <DummyInstruction> >(new [] { sources[0] }), newState.Variables[variables[0]].GetNodes()); Assert.Equal(new HashSet <DataFlowNode <DummyInstruction> >(new [] { sources[1] }), newState.Variables[variables[1]].GetNodes()); }
public void MergeMultipleSingleChangeShouldOnlyCreateNewInstancesForChangedSlots() { var nodes = new[] { CreateDummyNode(0), CreateDummyNode(1), CreateDummyNode(2), CreateDummyNode(3), }; var sources = new[] { new[] { nodes[0] }, new[] { nodes[1] }, new[] { nodes[2], nodes[3], } }; var values1 = new[] { SymbolicValue <DummyInstruction> .CreateStackValue(sources[0][0]), SymbolicValue <DummyInstruction> .CreateStackValue(sources[1][0]), SymbolicValue <DummyInstruction> .CreateStackValue(sources[2][0]), }; var stack1 = ImmutableStack.Create(values1); var values2 = new[] { SymbolicValue <DummyInstruction> .CreateStackValue(sources[0][0]), SymbolicValue <DummyInstruction> .CreateStackValue(sources[1][0]), SymbolicValue <DummyInstruction> .CreateStackValue(sources[2][1]), }; var stack2 = ImmutableStack.Create(values2); var state1 = new SymbolicProgramState <DummyInstruction>(0, stack1); var state2 = new SymbolicProgramState <DummyInstruction>(0, stack2); Assert.True(state1.MergeStates(state2, out var newState)); Assert.NotSame(state1.Stack.Peek(), newState.Stack.Peek()); Assert.Same(state1.Stack.ElementAt(1), newState.Stack.ElementAt(1)); Assert.Same(state1.Stack.ElementAt(2), newState.Stack.ElementAt(2)); }
public void MergeMultiple() { var sources = new[] { new[] { CreateDummyNode(0), CreateDummyNode(1) }, new[] { CreateDummyNode(2), CreateDummyNode(3), }, new[] { CreateDummyNode(4), CreateDummyNode(5), } }; var values1 = new[] { SymbolicValue <DummyInstruction> .CreateStackValue(sources[0][0]), SymbolicValue <DummyInstruction> .CreateStackValue(sources[1][0]), SymbolicValue <DummyInstruction> .CreateStackValue(sources[2][0]), }; var stack1 = ImmutableStack.Create(values1); var values2 = new[] { SymbolicValue <DummyInstruction> .CreateStackValue(sources[0][1]), SymbolicValue <DummyInstruction> .CreateStackValue(sources[1][1]), SymbolicValue <DummyInstruction> .CreateStackValue(sources[2][1]), }; var stack2 = ImmutableStack.Create(values2); var state1 = new SymbolicProgramState <DummyInstruction>(0, stack1); var state2 = new SymbolicProgramState <DummyInstruction>(0, stack2); Assert.True(state1.MergeStates(state2, out var newState)); int index = sources.Length - 1; foreach (var slot in newState.Stack) { Assert.Equal(new HashSet <DataFlowNode <DummyInstruction> >(sources[index]), slot.GetNodes()); index--; } }
public void MergeStackImbalance() { var stack1 = ImmutableStack.Create( new SymbolicValue <DummyInstruction>(), new SymbolicValue <DummyInstruction>() ); var stack2 = ImmutableStack.Create(new SymbolicValue <DummyInstruction>()); var state1 = new SymbolicProgramState <DummyInstruction>(0, stack1); var state2 = new SymbolicProgramState <DummyInstruction>(0, stack2); Assert.Throws <StackImbalanceException>(() => state1.MergeStates(state2, out _)); }
public void MergeSingleNoChange() { var source = CreateDummyNode(0); var value1 = SymbolicValue <DummyInstruction> .CreateStackValue(source); var stack1 = ImmutableStack.Create(value1); var value2 = SymbolicValue <DummyInstruction> .CreateStackValue(source); var stack2 = ImmutableStack.Create(value2); var state1 = new SymbolicProgramState <DummyInstruction>(0, stack1); var state2 = new SymbolicProgramState <DummyInstruction>(0, stack2); Assert.False(state1.MergeStates(state2, out var newState)); Assert.Equal(new HashSet <DataFlowNode <DummyInstruction> >(new[] { source }), newState.Stack.Peek().GetNodes()); }
public void MergeSingleVariableNoChange() { var source = CreateDummyNode(0); var variable = new DummyVariable("V_1"); var variables1 = ImmutableDictionary <IVariable, SymbolicValue <DummyInstruction> > .Empty; variables1 = variables1.SetItem(variable, SymbolicValue <DummyInstruction> .CreateVariableValue(source, variable)); var variables2 = ImmutableDictionary <IVariable, SymbolicValue <DummyInstruction> > .Empty; variables2 = variables2.SetItem(variable, SymbolicValue <DummyInstruction> .CreateVariableValue(source, variable)); var state1 = new SymbolicProgramState <DummyInstruction>(0, variables1); var state2 = new SymbolicProgramState <DummyInstruction>(0, variables2); Assert.False(state1.MergeStates(state2, out var newState)); Assert.Equal(new HashSet <DataFlowNode <DummyInstruction> >(new [] { source }), newState.Variables[variable].GetNodes()); }
public void MergeSingle() { var sources = new[] { CreateDummyNode(0), CreateDummyNode(1), }; var value1 = SymbolicValue <DummyInstruction> .CreateStackValue(sources[0]); var stack1 = ImmutableStack.Create(value1); var value2 = SymbolicValue <DummyInstruction> .CreateStackValue(sources[1]); var stack2 = ImmutableStack.Create(value2); var state1 = new SymbolicProgramState <DummyInstruction>(0, stack1); var state2 = new SymbolicProgramState <DummyInstruction>(0, stack2); Assert.True(state1.MergeStates(state2, out var newState)); Assert.Equal(new HashSet <DataFlowNode <DummyInstruction> >(sources), newState.Stack.Peek().GetNodes()); }
private static bool ApplyStateChange( GraphBuilderContext context, ref SymbolicProgramState <TInstruction> currentState) { bool changed; if (context.RecordedStates.TryGetValue(currentState.ProgramCounter, out var recordedState)) { // We are revisiting this address, merge program states. changed = recordedState.MergeStates(currentState, out currentState); if (changed) { context.RecordedStates[currentState.ProgramCounter] = currentState; } } else { // This is a new unvisited address. context.RecordedStates.Add(currentState.ProgramCounter, currentState); changed = true; } return(changed); }
/// <inheritdoc /> public override int GetTransitionCount(SymbolicProgramState <Instruction> currentState, in Instruction instruction)
/// <summary> /// Creates a new program state transition. /// </summary> /// <param name="nextState">The new program state.</param> /// <param name="edgeType">The type of edge that was taken.</param> public StateTransition(SymbolicProgramState <TInstruction> nextState, ControlFlowEdgeType edgeType) { NextState = nextState; EdgeType = edgeType; }
/// <summary> /// Creates a new program state transition. /// </summary> /// <param name="nextState">The new program state.</param> /// <param name="edgeType">The type of edge that was taken.</param> public StateTransition(SymbolicProgramState <TInstruction> nextState, ControlFlowEdgeType edgeType) { NextState = nextState ?? throw new ArgumentNullException(nameof(nextState)); EdgeType = edgeType; }
/// <inheritdoc /> public abstract int GetTransitionCount(SymbolicProgramState <TInstruction> currentState, in TInstruction instruction);
private void ResolveAndScheduleSuccessors( GraphBuilderContext context, SymbolicProgramState <TInstruction> currentState, in TInstruction instruction,