Пример #1
0
        /// <summary>
        /// Adds an exception clause.
        /// </summary>
        /// <param name="kind">Clause kind.</param>
        /// <param name="tryOffset">Try block start offset.</param>
        /// <param name="tryLength">Try block length.</param>
        /// <param name="handlerOffset">Handler start offset.</param>
        /// <param name="handlerLength">Handler length.</param>
        /// <param name="catchType">
        /// <see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle"/> or <see cref="TypeSpecificationHandle"/>,
        /// or nil if <paramref name="kind"/> is not <see cref="ExceptionRegionKind.Catch"/>
        /// </param>
        /// <param name="filterOffset">
        /// Offset of the filter block, or 0 if the <paramref name="kind"/> is not <see cref="ExceptionRegionKind.Filter"/>.
        /// </param>
        /// <returns>Encoder for the next clause.</returns>
        /// <exception cref="ArgumentException"><paramref name="catchType"/> is invalid.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="kind"/> has invalid value.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="tryOffset"/>, <paramref name="tryLength"/>, <paramref name="handlerOffset"/> or <paramref name="handlerLength"/> is out of range.
        /// </exception>
        /// <exception cref="InvalidOperationException">Method body was not declared to have exception regions.</exception>
        public ExceptionRegionEncoder Add(
            ExceptionRegionKind kind,
            int tryOffset,
            int tryLength,
            int handlerOffset,
            int handlerLength,
            EntityHandle catchType = default(EntityHandle),
            int filterOffset       = 0)
        {
            if (Builder == null)
            {
                Throw.InvalidOperation(SR.MethodHasNoExceptionRegions);
            }

            if (HasSmallFormat)
            {
                if (unchecked ((ushort)tryOffset) != tryOffset)
                {
                    Throw.ArgumentOutOfRange(nameof(tryOffset));
                }
                if (unchecked ((byte)tryLength) != tryLength)
                {
                    Throw.ArgumentOutOfRange(nameof(tryLength));
                }
                if (unchecked ((ushort)handlerOffset) != handlerOffset)
                {
                    Throw.ArgumentOutOfRange(nameof(handlerOffset));
                }
                if (unchecked ((byte)handlerLength) != handlerLength)
                {
                    Throw.ArgumentOutOfRange(nameof(handlerLength));
                }
            }
            else
            {
                if (tryOffset < 0)
                {
                    Throw.ArgumentOutOfRange(nameof(tryOffset));
                }
                if (tryLength < 0)
                {
                    Throw.ArgumentOutOfRange(nameof(tryLength));
                }
                if (handlerOffset < 0)
                {
                    Throw.ArgumentOutOfRange(nameof(handlerOffset));
                }
                if (handlerLength < 0)
                {
                    Throw.ArgumentOutOfRange(nameof(handlerLength));
                }
            }

            int catchTokenOrOffset;

            switch (kind)
            {
            case ExceptionRegionKind.Catch:
                if (!IsValidCatchTypeHandle(catchType))
                {
                    Throw.InvalidArgument_Handle(nameof(catchType));
                }

                catchTokenOrOffset = MetadataTokens.GetToken(catchType);
                break;

            case ExceptionRegionKind.Filter:
                if (filterOffset < 0)
                {
                    Throw.ArgumentOutOfRange(nameof(filterOffset));
                }

                catchTokenOrOffset = filterOffset;
                break;

            case ExceptionRegionKind.Finally:
            case ExceptionRegionKind.Fault:
                catchTokenOrOffset = 0;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(kind));
            }

            AddUnchecked(kind, tryOffset, tryLength, handlerOffset, handlerLength, catchTokenOrOffset);
            return(this);
        }