コード例 #1
0
 /// <summary>
 /// Encodes <code>ldstr</code> instruction and its operand.
 /// </summary>
 public void LoadString(UserStringHandle handle)
 {
     OpCode(ILOpCode.Ldstr);
     Token(MetadataTokens.GetToken(handle));
 }
コード例 #2
0
 /// <summary>
 /// Encodes a token.
 /// </summary>
 public void Token(EntityHandle handle)
 {
     Token(MetadataTokens.GetToken(handle));
 }
コード例 #3
0
        public Handle GetGenerationHandle(Handle handle, out int generation)
        {
            if (handle.IsVirtual)
            {
                // TODO: if a virtual handle is connected to real handle then translate the rid,
                // otherwise return vhandle and base.
                throw new NotSupportedException();
            }

            if (handle.IsHeapHandle)
            {
                int heapOffset = handle.Offset;

                HeapIndex heapIndex;
                MetadataTokens.TryGetHeapIndex(handle.Kind, out heapIndex);

                var sizes = _heapSizes[(int)heapIndex];

                generation = sizes.BinarySearch(heapOffset);
                if (generation >= 0)
                {
                    Debug.Assert(sizes[generation] == heapOffset);

                    // the index points to the start of the next generation that added data to the heap:
                    do
                    {
                        generation++;
                    }while (generation < sizes.Length && sizes[generation] == heapOffset);
                }
                else
                {
                    generation = ~generation;
                }

                if (generation >= sizes.Length)
                {
                    throw new ArgumentException(SR.HandleBelongsToFutureGeneration, nameof(handle));
                }

                // GUID heap accumulates - previous heap is copied to the next generation
                int relativeHeapOffset = (handle.Type == HandleType.Guid || generation == 0) ? heapOffset : heapOffset - sizes[generation - 1];

                return(new Handle((byte)handle.Type, relativeHeapOffset));
            }
            else
            {
                int rowId = handle.RowId;

                var sizes = _rowCounts[(int)handle.Type];

                generation = sizes.BinarySearch(new RowCounts {
                    AggregateInserts = rowId
                });
                if (generation >= 0)
                {
                    Debug.Assert(sizes[generation].AggregateInserts == rowId);

                    // the row is in a generation that inserted exactly one row -- the one that we are looking for;
                    // or it's in a preceding generation if the current one didn't insert any rows of the kind:
                    while (generation > 0 && sizes[generation - 1].AggregateInserts == rowId)
                    {
                        generation--;
                    }
                }
                else
                {
                    // the row is in a generation that inserted multiple new rows:
                    generation = ~generation;

                    if (generation >= sizes.Length)
                    {
                        throw new ArgumentException(SR.HandleBelongsToFutureGeneration, nameof(handle));
                    }
                }

                // In each delta table updates always precede inserts.
                int relativeRowId = (generation == 0) ? rowId :
                                    rowId -
                                    sizes[generation - 1].AggregateInserts +
                                    sizes[generation].Updates;

                return(new Handle((byte)handle.Type, relativeRowId));
            }
        }
コード例 #4
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);
        }
コード例 #5
0
        public Handle GetGenerationHandle(Handle handle, out int generation)
        {
            if (handle.IsVirtual)
            {
                // TODO: if a virtual handle is connected to real handle then translate the rid,
                // otherwise return vhandle and base.
                throw new NotSupportedException();
            }

            int  rowId  = (int)handle.RowId;
            uint typeId = handle.TokenType;
            int  relativeRowId;

            if (handle.IsHeapHandle)
            {
                HeapIndex heapIndex;
                MetadataTokens.TryGetHeapIndex(handle.Kind, out heapIndex);

                var sizes = heapSizes[(int)heapIndex];

                generation = sizes.BinarySearch(rowId);
                if (generation >= 0)
                {
                    DebugCorlib.Assert(sizes[generation] == rowId);

                    // the index points to the start of the next generation that added data to the heap:
                    do
                    {
                        generation++;
                    }while (generation < sizes.Length && sizes[generation] == rowId);
                }
                else
                {
                    generation = ~generation;
                }

                if (generation >= sizes.Length)
                {
                    throw new ArgumentException("Handle belongs to a future generation", "handle");
                }

                // GUID heap accumulates - previous heap is copied to the next generation
                relativeRowId = (typeId == TokenTypeIds.Guid || generation == 0) ? rowId : rowId - sizes[generation - 1];
            }
            else
            {
                var sizes = rowCounts[(int)handle.value >> TokenTypeIds.RowIdBitCount];

                generation = sizes.BinarySearch(new RowCounts {
                    AggregateInserts = rowId
                });
                if (generation >= 0)
                {
                    DebugCorlib.Assert(sizes[generation].AggregateInserts == rowId);

                    // the row is in a generation that inserted exactly one row -- the one that we are looking for;
                    // or it's in a preceeding generation if the current one didn't insert any rows of the kind:
                    while (generation > 0 && sizes[generation - 1].AggregateInserts == rowId)
                    {
                        generation--;
                    }
                }
                else
                {
                    // the row is in a generation that inserted multiple new rows:
                    generation = ~generation;

                    if (generation >= sizes.Length)
                    {
                        throw new ArgumentException("Handle belongs to a future generation", "handle");
                    }
                }

                // In each delta table updates always precede inserts.
                relativeRowId = (generation == 0) ? rowId :
                                rowId -
                                sizes[generation - 1].AggregateInserts +
                                sizes[generation].Updates;
            }

            return(new Handle(typeId | (uint)relativeRowId));
        }