public RegionMap AddRegion(RegionType type, InstructionRange range) { if (Range.Equals(range)) { if (Type != type) { throw new NotSupportedException("Multipurpose regions!"); } return(this); } if (!Range.IsContained(range)) { throw new ArgumentException("Cannot create sub regionMap with a subregion not contained"); } foreach (RegionMap sregion in ChildRegions) { if (sregion.Range.IsContained(range)) { return(sregion.AddRegion(type, range)); } } RegionMap newRegionMap = new RegionMap(type, range); ChildRegions.Add(newRegionMap); return(newRegionMap); }
private void GenerateRegion(BlockRegion region, RegionMap map) { _regionMappings[map] = region; foreach (RegionMap childRegion in map.ChildRegions) { if (childRegion.Type != RegionMap.RegionType.Try) { continue; } Zone newZone = new Zone(region); region.AddChildZone(newZone); newZone.TryRegion = new BlockRegion(BlockRegion.RegionType.Primary, newZone); GenerateRegion(newZone.TryRegion, childRegion); foreach (RegionMap associatedRegion in childRegion.AssociatedRegions) { switch (associatedRegion.Type) { case RegionMap.RegionType.Catch: BlockRegion catchRegion = new BlockRegion(BlockRegion.RegionType.Catch, newZone); GenerateRegion(catchRegion, associatedRegion); CatchCase catchCase = new CatchCase(_assemblyLoader.ResolveType(associatedRegion.CatchReference), catchRegion); newZone.AddCatchRegion(catchCase); break; case RegionMap.RegionType.Finally: if (newZone.FinalRegion != null) { throw new ArgumentException("Two final regions should not occur!"); } newZone.FinalRegion = new BlockRegion(BlockRegion.RegionType.Final, newZone); GenerateRegion(newZone.FinalRegion, associatedRegion); break; default: throw new ArgumentOutOfRangeException(); } } } }
private void ParseRegions() { _regionMap = new RegionMap(RegionMap.RegionType.Root, new InstructionRange(_body.Instructions.First(), _body.Instructions.Last())); foreach (ExceptionHandler exceptionHandler in _body.ExceptionHandlers.Reverse()) { RegionMap tryRegionMap = _regionMap.AddRegion(RegionMap.RegionType.Try, new InstructionRange(exceptionHandler.TryStart, exceptionHandler.TryEnd.Previous)); switch (exceptionHandler.HandlerType) { case ExceptionHandlerType.Catch: { RegionMap regionMap = _regionMap.AddRegion(RegionMap.RegionType.Catch, new InstructionRange(exceptionHandler.HandlerStart, exceptionHandler.HandlerEnd.Previous)); regionMap.CatchReference = exceptionHandler.CatchType; regionMap.AddAssociatedRegion(tryRegionMap); tryRegionMap.AddAssociatedRegion(regionMap); break; } case ExceptionHandlerType.Finally: { RegionMap regionMap = _regionMap.AddRegion(RegionMap.RegionType.Finally, new InstructionRange(exceptionHandler.HandlerStart, exceptionHandler.HandlerEnd.Previous)); regionMap.AddAssociatedRegion(tryRegionMap); tryRegionMap.AddAssociatedRegion(regionMap); break; } default: throw new NotSupportedException(); } } _regionMap.EnsureEdges(GetJumpDestinations()); }
public void AddAssociatedRegion(RegionMap regionMap) { AssociatedRegions.Add(regionMap); }