예제 #1
0
        /// <summary>
        /// Serialized #Pdb stream.
        /// </summary>
        protected override void SerializeStandalonePdbStream(BlobBuilder builder)
        {
            int startPosition = builder.Count;

            // the id will be filled in later
            _pdbIdBlob = builder.ReserveBytes(MetadataSizes.PdbIdSize);

            builder.WriteInt32(_entryPoint.IsNil ? 0 : MetadataTokens.GetToken(_entryPoint));

            builder.WriteUInt64(MetadataSizes.ExternalTablesMask);
            MetadataWriterUtilities.SerializeRowCounts(builder, MetadataSizes.ExternalRowCounts);

            int endPosition = builder.Count;

            Debug.Assert(MetadataSizes.CalculateStandalonePdbStreamSize() == endPosition - startPosition);
        }
예제 #2
0
        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 = handler.Kind switch
                {
                    ExceptionRegionKind.Catch => MetadataTokens.GetToken(handler.CatchType),
                    ExceptionRegionKind.Filter => GetLabelOffsetChecked(handler.FilterStart),
                    _ => 0,
                };

                regionEncoder.AddUnchecked(
                    handler.Kind,
                    tryStart,
                    tryEnd - tryStart,
                    handlerStart,
                    handlerEnd - handlerStart,
                    catchTokenOrOffset);
            }
        }
        /// <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);
        }
예제 #4
0
 /// <summary>
 /// Encodes <code>ldstr</code> instruction and its operand.
 /// </summary>
 public void LoadString(UserStringHandle handle)
 {
     OpCode(ILOpCode.Ldstr);
     Token(MetadataTokens.GetToken(handle));
 }
예제 #5
0
 /// <summary>
 /// Encodes a token.
 /// </summary>
 public void Token(EntityHandle handle)
 {
     Token(MetadataTokens.GetToken(handle));
 }