/// <summary> /// Adds catch region. /// </summary> /// <param name="tryStart">Label marking the first instruction of the try block.</param> /// <param name="tryEnd">Label marking the instruction immediately following the try block.</param> /// <param name="handlerStart">Label marking the first instruction of the handler.</param> /// <param name="handlerEnd">Label marking the instruction immediately following the handler.</param> /// <param name="catchType">The type of exception to be caught: <see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle"/> or <see cref="TypeSpecificationHandle"/>.</param> /// <exception cref="ArgumentException">A label was not defined by an instruction encoder this builder is associated with.</exception> /// <exception cref="ArgumentException"><paramref name="catchType"/> is not a valid type handle.</exception> /// <exception cref="ArgumentNullException">A label has default value.</exception> public void AddCatchRegion(LabelHandle tryStart, LabelHandle tryEnd, LabelHandle handlerStart, LabelHandle handlerEnd, EntityHandle catchType) { if (!ExceptionRegionEncoder.IsValidCatchTypeHandle(catchType)) { Throw.InvalidArgument_Handle(nameof(catchType)); } AddExceptionRegion(ExceptionRegionKind.Catch, tryStart, tryEnd, handlerStart, handlerEnd, catchType: catchType); }
internal void SerializeExceptionTable(BlobBuilder builder) { if (_lazyExceptionHandlers == null || _lazyExceptionHandlers.Count == 0) { return; } var regionEncoder = ExceptionRegionEncoder.SerializeTableHeader(builder, _lazyExceptionHandlers.Count, HasSmallExceptionRegions()); foreach (var handler in _lazyExceptionHandlers) { // Note that labels have been validated when added to the handler list, // they might not have been marked though. int tryStart = GetLabelOffsetChecked(handler.TryStart); int tryEnd = GetLabelOffsetChecked(handler.TryEnd); int handlerStart = GetLabelOffsetChecked(handler.HandlerStart); int handlerEnd = GetLabelOffsetChecked(handler.HandlerEnd); if (tryStart > tryEnd) { Throw.InvalidOperation(SR.Format(SR.InvalidExceptionRegionBounds, tryStart, tryEnd)); } if (handlerStart > handlerEnd) { Throw.InvalidOperation(SR.Format(SR.InvalidExceptionRegionBounds, handlerStart, handlerEnd)); } int catchTokenOrOffset; switch (handler.Kind) { case ExceptionRegionKind.Catch: catchTokenOrOffset = MetadataTokens.GetToken(handler.CatchType); break; case ExceptionRegionKind.Filter: catchTokenOrOffset = GetLabelOffsetChecked(handler.FilterStart); break; default: catchTokenOrOffset = 0; break; } regionEncoder.AddUnchecked( handler.Kind, tryStart, tryEnd - tryStart, handlerStart, handlerEnd - handlerStart, catchTokenOrOffset); } }
private bool HasSmallExceptionRegions() { Debug.Assert(_lazyExceptionHandlers != null); if (!ExceptionRegionEncoder.IsSmallRegionCount(_lazyExceptionHandlers.Count)) { return(false); } foreach (var handler in _lazyExceptionHandlers) { if (!ExceptionRegionEncoder.IsSmallExceptionRegionFromBounds(GetLabelOffsetChecked(handler.TryStart), GetLabelOffsetChecked(handler.TryEnd)) || !ExceptionRegionEncoder.IsSmallExceptionRegionFromBounds(GetLabelOffsetChecked(handler.HandlerStart), GetLabelOffsetChecked(handler.HandlerEnd))) { return(false); } } return(true); }