| File: PEWriter\ExceptionHandlerRegion.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Diagnostics; using System.Reflection.Metadata; namespace Microsoft.Cci { /// <summary> /// A region representing an exception handler clause. The region exposes the type (catch or /// finally) and the bounds of the try block and catch or finally block as needed by /// </summary> internal abstract class ExceptionHandlerRegion { /// <summary> /// Label instruction corresponding to the start of try block /// </summary> public int TryStartOffset { get; } /// <summary> /// Label instruction corresponding to the end of try block /// </summary> public int TryEndOffset { get; } /// <summary> /// Label instruction corresponding to the start of handler block /// </summary> public int HandlerStartOffset { get; } /// <summary> /// Label instruction corresponding to the end of handler block /// </summary> public int HandlerEndOffset { get; } public ExceptionHandlerRegion( int tryStartOffset, int tryEndOffset, int handlerStartOffset, int handlerEndOffset) { Debug.Assert(tryStartOffset < tryEndOffset); Debug.Assert(tryEndOffset <= handlerStartOffset); Debug.Assert(handlerStartOffset < handlerEndOffset); Debug.Assert(tryStartOffset >= 0); Debug.Assert(tryEndOffset >= 0); Debug.Assert(handlerStartOffset >= 0); Debug.Assert(handlerEndOffset >= 0); TryStartOffset = tryStartOffset; TryEndOffset = tryEndOffset; HandlerStartOffset = handlerStartOffset; HandlerEndOffset = handlerEndOffset; } public int HandlerLength => HandlerEndOffset - HandlerStartOffset; public int TryLength => TryEndOffset - TryStartOffset; /// <summary> /// Handler kind for this SEH info /// </summary> public abstract ExceptionRegionKind HandlerKind { get; } /// <summary> /// If HandlerKind == HandlerKind.Catch, this is the type of exception to catch. If HandlerKind == HandlerKind.Filter, this is System.Object. /// Otherwise this is a Dummy.TypeReference. /// </summary> public virtual ITypeReference? ExceptionType { get { return null; } } /// <summary> /// Label instruction corresponding to the start of filter decision block /// </summary> public virtual int FilterDecisionStartOffset { get { return 0; } } } internal sealed class ExceptionHandlerRegionFinally : ExceptionHandlerRegion { public ExceptionHandlerRegionFinally( int tryStartOffset, int tryEndOffset, int handlerStartOffset, int handlerEndOffset) : base(tryStartOffset, tryEndOffset, handlerStartOffset, handlerEndOffset) { } public override ExceptionRegionKind HandlerKind { get { return ExceptionRegionKind.Finally; } } } internal sealed class ExceptionHandlerRegionFault : ExceptionHandlerRegion { public ExceptionHandlerRegionFault( int tryStartOffset, int tryEndOffset, int handlerStartOffset, int handlerEndOffset) : base(tryStartOffset, tryEndOffset, handlerStartOffset, handlerEndOffset) { } public override ExceptionRegionKind HandlerKind { get { return ExceptionRegionKind.Fault; } } } internal sealed class ExceptionHandlerRegionCatch : ExceptionHandlerRegion { private readonly ITypeReference _exceptionType; public ExceptionHandlerRegionCatch( int tryStartOffset, int tryEndOffset, int handlerStartOffset, int handlerEndOffset, ITypeReference exceptionType) : base(tryStartOffset, tryEndOffset, handlerStartOffset, handlerEndOffset) { _exceptionType = exceptionType; } public override ExceptionRegionKind HandlerKind { get { return ExceptionRegionKind.Catch; } } public override ITypeReference ExceptionType { get { return _exceptionType; } } } internal sealed class ExceptionHandlerRegionFilter : ExceptionHandlerRegion { private readonly int _filterDecisionStartOffset; public ExceptionHandlerRegionFilter( int tryStartOffset, int tryEndOffset, int handlerStartOffset, int handlerEndOffset, int filterDecisionStartOffset) : base(tryStartOffset, tryEndOffset, handlerStartOffset, handlerEndOffset) { Debug.Assert(filterDecisionStartOffset >= 0); _filterDecisionStartOffset = filterDecisionStartOffset; } public override ExceptionRegionKind HandlerKind { get { return ExceptionRegionKind.Filter; } } public override int FilterDecisionStartOffset { get { return _filterDecisionStartOffset; } } } }