public void AddingRegionSecondTimeShouldThrow() { var graph = new ControlFlowGraph <int>(IntArchitecture.Instance); var region = new BasicControlFlowRegion <int>(); graph.Regions.Add(region); Assert.Throws <ArgumentException>(() => graph.Regions.Add(region)); }
public void AddSubRegionShouldSetParentRegion() { var graph = new ControlFlowGraph <int>(IntArchitecture.Instance); var region = new BasicControlFlowRegion <int>(); Assert.Null(region.ParentRegion); graph.Regions.Add(region); Assert.Same(graph, region.ParentRegion); }
private static Dictionary <AddressRange, BasicControlFlowRegion <TInstruction> > CreateEHRegions <TInstruction>( ControlFlowGraph <TInstruction> cfg, IReadOnlyList <ExceptionHandlerRange> sortedRanges) { var rangeToRegion = new Dictionary <AddressRange, BasicControlFlowRegion <TInstruction> >(); var ehRegions = new Dictionary <AddressRange, ExceptionHandlerRegion <TInstruction> >(); for (int i = 0; i < sortedRanges.Count; i++) { var currentEHRange = sortedRanges[i]; if (!ehRegions.TryGetValue(currentEHRange.ProtectedRange, out var ehRegion)) { // Register new EH region for the protected range. ehRegion = new ExceptionHandlerRegion <TInstruction>(); ehRegions.Add(currentEHRange.ProtectedRange, ehRegion); rangeToRegion.Add(currentEHRange.ProtectedRange, ehRegion.ProtectedRegion); // Since the ranges are sorted by enclosing EHs first, we can backtrack the list of ranges to find. // the parent region (if there is any). BasicControlFlowRegion <TInstruction> parentRegion = null; for (int j = i; j >= 0 && parentRegion is null; j--) { var potentialParentRange = sortedRanges[j]; if (potentialParentRange.ProtectedRange.Contains(currentEHRange.ProtectedRange)) { parentRegion = rangeToRegion[potentialParentRange.ProtectedRange]; } if (potentialParentRange.HandlerRange.Contains(currentEHRange.HandlerRange)) { parentRegion = rangeToRegion[potentialParentRange.HandlerRange]; } } // Insert region into graph or parent region. if (parentRegion is null) { cfg.Regions.Add(ehRegion); } else { parentRegion.Regions.Add(ehRegion); } } // Register handler region. var handlerRegion = new BasicControlFlowRegion <TInstruction>(); handlerRegion.Tag = currentEHRange.UserData; ehRegion.HandlerRegions.Add(handlerRegion); rangeToRegion.Add(currentEHRange.HandlerRange, handlerRegion); } return(rangeToRegion); }
public void AddNodeToNotAddedRegionShouldThrow() { var graph = new ControlFlowGraph <int>(IntArchitecture.Instance); var node = new ControlFlowNode <int>(0); graph.Nodes.Add(node); var region = new BasicControlFlowRegion <int>(); Assert.Throws <InvalidOperationException>(() => region.Nodes.Add(node)); }
public void AddNodeNotAddedToGraphToRegionShouldThrow() { var graph = new ControlFlowGraph <int>(IntArchitecture.Instance); var node = new ControlFlowNode <int>(0); var region = new BasicControlFlowRegion <int>(); graph.Regions.Add(region); Assert.Throws <ArgumentException>(() => region.Nodes.Add(node)); }
public void AddNodeToRegionShouldSetParentRegion() { var graph = new ControlFlowGraph <int>(IntArchitecture.Instance); var node = new ControlFlowNode <int>(0); graph.Nodes.Add(node); var region = new BasicControlFlowRegion <int>(); graph.Regions.Add(region); region.Nodes.Add(node); Assert.Same(region, node.ParentRegion); }
public void RemoveNodeShouldSetRegionBackToParentGraph() { var graph = new ControlFlowGraph <int>(IntArchitecture.Instance); var node = new ControlFlowNode <int>(0); graph.Nodes.Add(node); var region = new BasicControlFlowRegion <int>(); graph.Regions.Add(region); region.Nodes.Add(node); region.Nodes.Remove(node); Assert.Same(graph, node.ParentRegion); }
public void RemoveNodeInRegionShouldRemoveFromRegion() { var graph = new ControlFlowGraph <int>(IntArchitecture.Instance); var node = new ControlFlowNode <int>(0); graph.Nodes.Add(node); var region = new BasicControlFlowRegion <int>(); graph.Regions.Add(region); region.Nodes.Add(node); graph.Nodes.Remove(node); Assert.Null(node.ParentRegion); Assert.DoesNotContain(node, region.Nodes); }
public void AddNodeFromAnotherRegionShouldThrow() { var graph = new ControlFlowGraph <int>(IntArchitecture.Instance); var node = new ControlFlowNode <int>(0); graph.Nodes.Add(node); var region1 = new BasicControlFlowRegion <int>(); var region2 = new BasicControlFlowRegion <int>(); graph.Regions.Add(region1); graph.Regions.Add(region2); region1.Nodes.Add(node); Assert.Throws <ArgumentException>(() => region2.Nodes.Add(node)); }
private ControlFlowRegion <Statement <TInstruction> > TransformRegion(IControlFlowRegion <TInstruction> region) { switch (region) { case BasicControlFlowRegion <TInstruction> basicRegion: // Create new basic region. var newBasicRegion = new BasicControlFlowRegion <Statement <TInstruction> >(); TransformSubRegions(basicRegion, newBasicRegion); // Register basic region pair. _context.RegionsMapping[basicRegion] = newBasicRegion; return(newBasicRegion); case ExceptionHandlerRegion <TInstruction> ehRegion: var newEhRegion = new ExceptionHandlerRegion <Statement <TInstruction> >(); // ProtectedRegion is read-only, so instead we just transform all sub regions and add it to the // existing protected region. TransformSubRegions(ehRegion.ProtectedRegion, newEhRegion.ProtectedRegion); _context.RegionsMapping[ehRegion.ProtectedRegion] = newEhRegion.ProtectedRegion; // Add handler regions. foreach (var subRegion in ehRegion.HandlerRegions) { newEhRegion.HandlerRegions.Add(TransformRegion(subRegion)); } return(newEhRegion); default: throw new ArgumentOutOfRangeException(nameof(region)); } void TransformSubRegions( BasicControlFlowRegion <TInstruction> originalRegion, BasicControlFlowRegion <Statement <TInstruction> > newRegion) { foreach (var subRegion in originalRegion.Regions) { newRegion.Regions.Add(TransformRegion(subRegion)); } } }
public void BasicRegionShouldTranslateToSingleScopeBlock() { var instructions = new[] { DummyInstruction.Push(0, 1), DummyInstruction.JmpCond(1, 4), DummyInstruction.Op(2, 0, 0), DummyInstruction.Jmp(3, 4), DummyInstruction.Op(4, 0, 0), DummyInstruction.Ret(5), }; var cfgBuilder = new StaticFlowGraphBuilder <DummyInstruction>( DummyArchitecture.Instance, instructions, DummyArchitecture.Instance.SuccessorResolver); var cfg = cfgBuilder.ConstructFlowGraph(0); var region = new BasicControlFlowRegion <DummyInstruction>(); cfg.Regions.Add(region); region.Nodes.Add(cfg.Nodes[2]); var blockBuilder = new BlockBuilder <DummyInstruction>(); var rootScope = blockBuilder.ConstructBlocks(cfg); Assert.Equal(3, rootScope.Blocks.Count); Assert.IsAssignableFrom <BasicBlock <DummyInstruction> >(rootScope.Blocks[0]); Assert.IsAssignableFrom <ScopeBlock <DummyInstruction> >(rootScope.Blocks[1]); Assert.IsAssignableFrom <BasicBlock <DummyInstruction> >(rootScope.Blocks[2]); var order = rootScope.GetAllBlocks().ToArray(); Assert.Equal( new long[] { 0, 2, 4 }, order.Select(b => b.Offset)); }