/// <summary>
        /// Encodes a method body and adds it to the method body stream.
        /// </summary>
        /// <param name="codeSize">Number of bytes to be reserved for instructions.</param>
        /// <param name="maxStack">Max stack.</param>
        /// <param name="exceptionRegionCount">Number of exception regions.</param>
        /// <param name="hasSmallExceptionRegions">True if the exception regions should be encoded in 'small' format.</param>
        /// <param name="localVariablesSignature">Local variables signature handle.</param>
        /// <param name="attributes">Attributes.</param>
        /// <returns>The offset of the encoded body within the method body stream.</returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="codeSize"/>, <paramref name="exceptionRegionCount"/>, or <paramref name="maxStack"/> is out of allowed range.
        /// </exception>
        public MethodBody AddMethodBody(
            int codeSize,
            int maxStack = 8,
            int exceptionRegionCount = 0,
            bool hasSmallExceptionRegions = true,
            StandaloneSignatureHandle localVariablesSignature = default(StandaloneSignatureHandle),
            MethodBodyAttributes attributes = MethodBodyAttributes.InitLocals)
        {
            if (codeSize < 0)
            {
                Throw.ArgumentOutOfRange(nameof(codeSize));
            }

            if (unchecked((uint)maxStack) > ushort.MaxValue)
            {
                Throw.ArgumentOutOfRange(nameof(maxStack));
            }

            if (!ExceptionRegionEncoder.IsExceptionRegionCountInBounds(exceptionRegionCount))
            {
                Throw.ArgumentOutOfRange(nameof(exceptionRegionCount));
            }

            int bodyOffset = SerializeHeader(codeSize, (ushort)maxStack, exceptionRegionCount, attributes, localVariablesSignature);
            var instructions = Builder.ReserveBytes(codeSize);

            var regionEncoder = (exceptionRegionCount > 0) ? 
                ExceptionRegionEncoder.SerializeTableHeader(Builder, exceptionRegionCount, hasSmallExceptionRegions) : default(ExceptionRegionEncoder);

            return new MethodBody(bodyOffset, instructions, regionEncoder);
        }
        internal StandaloneSignature(MetadataReader reader, StandaloneSignatureHandle handle)
        {
            DebugCorlib.Assert(reader != null);
            DebugCorlib.Assert(!handle.IsNil);

            this.reader = reader;
            this.rowId = handle.RowId;
        }
 internal MethodBodyEncoder(
     BlobBuilder builder,
     ushort maxStack,
     int exceptionRegionCount,
     StandaloneSignatureHandle localVariablesSignature,
     MethodBodyAttributes attributes)
 {
     Builder = builder;
     _maxStack = maxStack;
     _localVariablesSignature = localVariablesSignature;
     _attributes = (byte)attributes;
     _exceptionRegionCount = exceptionRegionCount;
 }
Exemple #4
0
        private MethodBodyBlock(
            bool localVariablesInitialized,
            ushort maxStack,
            StandaloneSignatureHandle localSignatureHandle,
            MemoryBlock il,
            ImmutableArray<ExceptionRegion> exceptionRegions,
            int size)
        {
            Debug.Assert(!exceptionRegions.IsDefault);

            this.localVariablesInitialized = localVariablesInitialized;
            this.maxStack = maxStack;
            this.localSignature = localSignatureHandle;
            this.il = il;
            this.exceptionRegions = exceptionRegions;
            this.size = size;
        }
Exemple #5
0
        public MethodBodyEncoder AddMethodBody(
            int maxStack = 8,
            int exceptionRegionCount = 0,
            StandaloneSignatureHandle localVariablesSignature = default(StandaloneSignatureHandle),
            MethodBodyAttributes attributes = MethodBodyAttributes.InitLocals)
        {
            if (unchecked((ushort)maxStack) > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(maxStack));
            }

            if (exceptionRegionCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(exceptionRegionCount));
            }

            return new MethodBodyEncoder(Builder, (ushort)maxStack, exceptionRegionCount, localVariablesSignature, attributes);
        }
 private void SerializeMethodDebugInfo(IMethodBody bodyOpt, int methodRid, int aggregateMethodRid, StandaloneSignatureHandle localSignatureHandleOpt, ref LocalVariableHandle lastLocalVariableHandle, ref LocalConstantHandle lastLocalConstantHandle)
 {
     if (bodyOpt == null)
     {
         _debugMetadataOpt.AddMethodDebugInformation(document: default, sequencePoints: default);
Exemple #7
0
        private void DefineLocalScopes(ImmutableArray<LocalScope> scopes, StandaloneSignatureHandle localSignatureHandleOpt)
        {
            // VB scope ranges are end-inclusive
            bool endInclusive = this.Module.GenerateVisualBasicStylePdb;

            // The order of OpenScope and CloseScope calls must follow the scope nesting.
            var scopeStack = ArrayBuilder<LocalScope>.GetInstance();

            for (int i = 1; i < scopes.Length; i++)
            {
                var currentScope = scopes[i];

                // Close any scopes that have finished.
                while (scopeStack.Count > 0)
                {
                    LocalScope topScope = scopeStack.Last();
                    if (currentScope.StartOffset < topScope.StartOffset + topScope.Length)
                    {
                        break;
                    }

                    scopeStack.RemoveLast();
                    CloseScope(endInclusive ? topScope.EndOffset - 1 : topScope.EndOffset);
                }

                // Open this scope.
                scopeStack.Add(currentScope);
                OpenScope(currentScope.StartOffset);
                this.DefineScopeLocals(currentScope, localSignatureHandleOpt);
            }

            // Close remaining scopes.
            for (int i = scopeStack.Count - 1; i >= 0; i--)
            {
                LocalScope scope = scopeStack[i];
                CloseScope(endInclusive ? scope.EndOffset - 1 : scope.EndOffset);
            }

            scopeStack.Free();
        }
Exemple #8
0
        private void DefineLocalVariable(uint index, string name, LocalVariableAttributes attributes, StandaloneSignatureHandle localSignatureHandleOpt)
        {
            uint localSignatureToken = localSignatureHandleOpt.IsNil ? 0 : (uint)MetadataTokens.GetToken(localSignatureHandleOpt);

            const uint ADDR_IL_OFFSET = 1;
            try
            {
                _symWriter.DefineLocalVariable2(name, (uint)attributes, localSignatureToken, ADDR_IL_OFFSET, index, 0, 0, 0, 0);
                if (_callLogger.LogOperation(OP.DefineLocalVariable2))
                {
                    _callLogger.LogArgument(name);
                    _callLogger.LogArgument((uint)attributes);
                    _callLogger.LogArgument(localSignatureToken);
                    _callLogger.LogArgument(ADDR_IL_OFFSET);
                    _callLogger.LogArgument(index);
                    _callLogger.LogArgument((uint)0);
                    _callLogger.LogArgument((uint)0);
                    _callLogger.LogArgument((uint)0);
                    _callLogger.LogArgument((uint)0);
                }
            }
            catch (Exception ex)
            {
                throw new PdbWritingException(ex);
            }
        }
Exemple #9
0
 protected abstract ImmutableArray <EncLocalInfo> GetLocalSlotMapFromMetadata(StandaloneSignatureHandle handle, EditAndContinueMethodDebugInformation debugInfo);
Exemple #10
0
        private int SerializeHeader(int codeSize, ushort maxStack, int exceptionRegionCount, MethodBodyAttributes attributes, StandaloneSignatureHandle localVariablesSignature)
        {
            const int  TinyFormat   = 2;
            const int  FatFormat    = 3;
            const int  MoreSections = 8;
            const byte InitLocals   = 0x10;

            int offset;

            bool isTiny = codeSize < 64 && maxStack <= 8 && localVariablesSignature.IsNil && exceptionRegionCount == 0;

            if (isTiny)
            {
                offset = Builder.Count;
                Builder.WriteByte((byte)((codeSize << 2) | TinyFormat));
            }
            else
            {
                Builder.Align(4);

                offset = Builder.Count;

                ushort flags = (3 << 12) | FatFormat;
                if (exceptionRegionCount > 0)
                {
                    flags |= MoreSections;
                }

                if ((attributes & MethodBodyAttributes.InitLocals) != 0)
                {
                    flags |= InitLocals;
                }

                Builder.WriteUInt16((ushort)((int)attributes | flags));
                Builder.WriteUInt16(maxStack);
                Builder.WriteInt32(codeSize);
                Builder.WriteInt32(localVariablesSignature.IsNil ? 0 : MetadataTokens.GetToken(localVariablesSignature));
            }

            return(offset);
        }
Exemple #11
0
        private BlobHandle SerializeSequencePoints(
            StandaloneSignatureHandle localSignatureHandleOpt,
            ImmutableArray <SequencePoint> sequencePoints,
            Dictionary <DebugSourceDocument, DocumentHandle> documentIndex,
            out DocumentHandle singleDocumentHandle)
        {
            if (sequencePoints.Length == 0)
            {
                singleDocumentHandle = default(DocumentHandle);
                return(default(BlobHandle));
            }

            var writer = new BlobBuilder();

            int previousNonHiddenStartLine   = -1;
            int previousNonHiddenStartColumn = -1;

            // header:
            writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(localSignatureHandleOpt));

            var previousDocument = TryGetSingleDocument(sequencePoints);

            singleDocumentHandle = (previousDocument != null) ? GetOrAddDocument(previousDocument, documentIndex) : default(DocumentHandle);

            for (int i = 0; i < sequencePoints.Length; i++)
            {
                var currentDocument = sequencePoints[i].Document;
                if (previousDocument != currentDocument)
                {
                    var documentHandle = GetOrAddDocument(currentDocument, documentIndex);

                    // optional document in header or document record:
                    if (previousDocument != null)
                    {
                        writer.WriteCompressedInteger(0);
                    }

                    writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(documentHandle));
                    previousDocument = currentDocument;
                }

                // delta IL offset:
                if (i > 0)
                {
                    writer.WriteCompressedInteger(sequencePoints[i].Offset - sequencePoints[i - 1].Offset);
                }
                else
                {
                    writer.WriteCompressedInteger(sequencePoints[i].Offset);
                }

                if (sequencePoints[i].IsHidden)
                {
                    writer.WriteInt16(0);
                    continue;
                }

                // Delta Lines & Columns:
                SerializeDeltaLinesAndColumns(writer, sequencePoints[i]);

                // delta Start Lines & Columns:
                if (previousNonHiddenStartLine < 0)
                {
                    Debug.Assert(previousNonHiddenStartColumn < 0);
                    writer.WriteCompressedInteger(sequencePoints[i].StartLine);
                    writer.WriteCompressedInteger(sequencePoints[i].StartColumn);
                }
                else
                {
                    writer.WriteCompressedSignedInteger(sequencePoints[i].StartLine - previousNonHiddenStartLine);
                    writer.WriteCompressedSignedInteger(sequencePoints[i].StartColumn - previousNonHiddenStartColumn);
                }

                previousNonHiddenStartLine   = sequencePoints[i].StartLine;
                previousNonHiddenStartColumn = sequencePoints[i].StartColumn;
            }

            return(_debugMetadataOpt.GetOrAddBlob(writer));
        }
Exemple #12
0
        private void SerializeMethodDebugInfo(IMethodBody bodyOpt, int methodRid, StandaloneSignatureHandle localSignatureHandleOpt, ref LocalVariableHandle lastLocalVariableHandle, ref LocalConstantHandle lastLocalConstantHandle)
        {
            if (bodyOpt == null)
            {
                _debugMetadataOpt.AddMethodDebugInformation(default(DocumentHandle), default(BlobHandle));
                return;
            }

            bool isKickoffMethod = bodyOpt.StateMachineTypeName != null;
            bool emitDebugInfo   = isKickoffMethod || !bodyOpt.SequencePoints.IsEmpty;

            if (!emitDebugInfo)
            {
                _debugMetadataOpt.AddMethodDebugInformation(default(DocumentHandle), default(BlobHandle));
                return;
            }

            var methodHandle = MetadataTokens.MethodDefinitionHandle(methodRid);

            var bodyImportScope   = bodyOpt.ImportScope;
            var importScopeHandle = (bodyImportScope != null) ? GetImportScopeIndex(bodyImportScope, _scopeIndex) : default(ImportScopeHandle);

            // documents & sequence points:
            DocumentHandle singleDocumentHandle;
            BlobHandle     sequencePointsBlob = SerializeSequencePoints(localSignatureHandleOpt, bodyOpt.SequencePoints, _documentIndex, out singleDocumentHandle);

            _debugMetadataOpt.AddMethodDebugInformation(document: singleDocumentHandle, sequencePoints: sequencePointsBlob);

            // Unlike native PDB we don't emit an empty root scope.
            // scopes are already ordered by StartOffset ascending then by EndOffset descending (the longest scope first).

            if (bodyOpt.LocalScopes.Length == 0)
            {
                // TODO: the compiler should produce a scope for each debuggable method
                _debugMetadataOpt.AddLocalScope(
                    method: methodHandle,
                    importScope: importScopeHandle,
                    variableList: NextHandle(lastLocalVariableHandle),
                    constantList: NextHandle(lastLocalConstantHandle),
                    startOffset: 0,
                    length: bodyOpt.IL.Length);
            }
            else
            {
                foreach (LocalScope scope in bodyOpt.LocalScopes)
                {
                    _debugMetadataOpt.AddLocalScope(
                        method: methodHandle,
                        importScope: importScopeHandle,
                        variableList: NextHandle(lastLocalVariableHandle),
                        constantList: NextHandle(lastLocalConstantHandle),
                        startOffset: scope.StartOffset,
                        length: scope.Length);

                    foreach (ILocalDefinition local in scope.Variables)
                    {
                        Debug.Assert(local.SlotIndex >= 0);

                        lastLocalVariableHandle = _debugMetadataOpt.AddLocalVariable(
                            attributes: local.PdbAttributes,
                            index: local.SlotIndex,
                            name: _debugMetadataOpt.GetOrAddString(local.Name));

                        SerializeLocalInfo(local, lastLocalVariableHandle);
                    }

                    foreach (ILocalDefinition constant in scope.Constants)
                    {
                        var mdConstant = constant.CompileTimeValue;
                        Debug.Assert(mdConstant != null);

                        lastLocalConstantHandle = _debugMetadataOpt.AddLocalConstant(
                            name: _debugMetadataOpt.GetOrAddString(constant.Name),
                            signature: SerializeLocalConstantSignature(constant));

                        SerializeLocalInfo(constant, lastLocalConstantHandle);
                    }
                }
            }

            var moveNextBodyInfo = bodyOpt.MoveNextBodyInfo;

            if (moveNextBodyInfo != null)
            {
                _debugMetadataOpt.AddStateMachineMethod(
                    moveNextMethod: methodHandle,
                    kickoffMethod: GetMethodDefinitionHandle(moveNextBodyInfo.KickoffMethod));

                if (moveNextBodyInfo is AsyncMoveNextBodyDebugInfo asyncInfo)
                {
                    SerializeAsyncMethodSteppingInfo(asyncInfo, methodHandle);
                }
            }

            SerializeStateMachineLocalScopes(bodyOpt, methodHandle);

            // delta doesn't need this information - we use information recorded by previous generation emit
            if (Context.Module.CommonCompilation.Options.EnableEditAndContinue && IsFullMetadata)
            {
                SerializeEncMethodDebugInformation(bodyOpt, methodHandle);
            }
        }
Exemple #13
0
 private BlobHandle GetLocalSignature(StandaloneSignatureHandle handle)
 {
     return(Get(handle, (reader, h) => reader.GetStandaloneSignature((StandaloneSignatureHandle)h).Signature));
 }
Exemple #14
0
        public void IsNil()
        {
            Assert.False(ModuleDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(AssemblyDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(InterfaceImplementationHandle.FromRowId(1).IsNil);
            Assert.False(MethodDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(MethodSpecificationHandle.FromRowId(1).IsNil);
            Assert.False(TypeDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(ExportedTypeHandle.FromRowId(1).IsNil);
            Assert.False(TypeReferenceHandle.FromRowId(1).IsNil);
            Assert.False(TypeSpecificationHandle.FromRowId(1).IsNil);
            Assert.False(MemberReferenceHandle.FromRowId(1).IsNil);
            Assert.False(FieldDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(EventDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(PropertyDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(StandaloneSignatureHandle.FromRowId(1).IsNil);
            Assert.False(MemberReferenceHandle.FromRowId(1).IsNil);
            Assert.False(FieldDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(EventDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(PropertyDefinitionHandle.FromRowId(1).IsNil);
            Assert.False(ParameterHandle.FromRowId(1).IsNil);
            Assert.False(GenericParameterHandle.FromRowId(1).IsNil);
            Assert.False(GenericParameterConstraintHandle.FromRowId(1).IsNil);
            Assert.False(ModuleReferenceHandle.FromRowId(1).IsNil);
            Assert.False(CustomAttributeHandle.FromRowId(1).IsNil);
            Assert.False(DeclarativeSecurityAttributeHandle.FromRowId(1).IsNil);
            Assert.False(ManifestResourceHandle.FromRowId(1).IsNil);
            Assert.False(ConstantHandle.FromRowId(1).IsNil);
            Assert.False(ManifestResourceHandle.FromRowId(1).IsNil);
            Assert.False(AssemblyFileHandle.FromRowId(1).IsNil);
            Assert.False(MethodImplementationHandle.FromRowId(1).IsNil);
            Assert.False(AssemblyReferenceHandle.FromRowId(1).IsNil);

            Assert.False(((EntityHandle)ModuleDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)AssemblyDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)InterfaceImplementationHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)MethodDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)MethodSpecificationHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)TypeDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)ExportedTypeHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)TypeReferenceHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)TypeSpecificationHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)MemberReferenceHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)FieldDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)EventDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)PropertyDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)StandaloneSignatureHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)MemberReferenceHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)FieldDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)EventDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)PropertyDefinitionHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)ParameterHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)GenericParameterHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)GenericParameterConstraintHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)ModuleReferenceHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)CustomAttributeHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)DeclarativeSecurityAttributeHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)ManifestResourceHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)ConstantHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)ManifestResourceHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)AssemblyFileHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)MethodImplementationHandle.FromRowId(1)).IsNil);
            Assert.False(((EntityHandle)AssemblyReferenceHandle.FromRowId(1)).IsNil);

            Assert.False(StringHandle.FromOffset(1).IsNil);
            Assert.False(BlobHandle.FromOffset(1).IsNil);
            Assert.False(UserStringHandle.FromOffset(1).IsNil);
            Assert.False(GuidHandle.FromIndex(1).IsNil);
            Assert.False(DocumentNameBlobHandle.FromOffset(1).IsNil);

            Assert.False(((Handle)StringHandle.FromOffset(1)).IsNil);
            Assert.False(((Handle)BlobHandle.FromOffset(1)).IsNil);
            Assert.False(((Handle)UserStringHandle.FromOffset(1)).IsNil);
            Assert.False(((Handle)GuidHandle.FromIndex(1)).IsNil);
            Assert.False(((BlobHandle)DocumentNameBlobHandle.FromOffset(1)).IsNil);

            Assert.True(ModuleDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(AssemblyDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(InterfaceImplementationHandle.FromRowId(0).IsNil);
            Assert.True(MethodDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(MethodSpecificationHandle.FromRowId(0).IsNil);
            Assert.True(TypeDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(ExportedTypeHandle.FromRowId(0).IsNil);
            Assert.True(TypeReferenceHandle.FromRowId(0).IsNil);
            Assert.True(TypeSpecificationHandle.FromRowId(0).IsNil);
            Assert.True(MemberReferenceHandle.FromRowId(0).IsNil);
            Assert.True(FieldDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(EventDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(PropertyDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(StandaloneSignatureHandle.FromRowId(0).IsNil);
            Assert.True(MemberReferenceHandle.FromRowId(0).IsNil);
            Assert.True(FieldDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(EventDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(PropertyDefinitionHandle.FromRowId(0).IsNil);
            Assert.True(ParameterHandle.FromRowId(0).IsNil);
            Assert.True(GenericParameterHandle.FromRowId(0).IsNil);
            Assert.True(GenericParameterConstraintHandle.FromRowId(0).IsNil);
            Assert.True(ModuleReferenceHandle.FromRowId(0).IsNil);
            Assert.True(CustomAttributeHandle.FromRowId(0).IsNil);
            Assert.True(DeclarativeSecurityAttributeHandle.FromRowId(0).IsNil);
            Assert.True(ManifestResourceHandle.FromRowId(0).IsNil);
            Assert.True(ConstantHandle.FromRowId(0).IsNil);
            Assert.True(ManifestResourceHandle.FromRowId(0).IsNil);
            Assert.True(AssemblyFileHandle.FromRowId(0).IsNil);
            Assert.True(MethodImplementationHandle.FromRowId(0).IsNil);
            Assert.True(AssemblyReferenceHandle.FromRowId(0).IsNil);

            Assert.True(((EntityHandle)ModuleDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)AssemblyDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)InterfaceImplementationHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)MethodDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)MethodSpecificationHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)TypeDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)ExportedTypeHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)TypeReferenceHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)TypeSpecificationHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)MemberReferenceHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)FieldDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)EventDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)PropertyDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)StandaloneSignatureHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)MemberReferenceHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)FieldDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)EventDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)PropertyDefinitionHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)ParameterHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)GenericParameterHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)GenericParameterConstraintHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)ModuleReferenceHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)CustomAttributeHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)DeclarativeSecurityAttributeHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)ManifestResourceHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)ConstantHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)ManifestResourceHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)AssemblyFileHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)MethodImplementationHandle.FromRowId(0)).IsNil);
            Assert.True(((EntityHandle)AssemblyReferenceHandle.FromRowId(0)).IsNil);

            // heaps:
            Assert.True(StringHandle.FromOffset(0).IsNil);
            Assert.True(BlobHandle.FromOffset(0).IsNil);
            Assert.True(UserStringHandle.FromOffset(0).IsNil);
            Assert.True(GuidHandle.FromIndex(0).IsNil);
            Assert.True(DocumentNameBlobHandle.FromOffset(0).IsNil);

            Assert.True(((Handle)StringHandle.FromOffset(0)).IsNil);
            Assert.True(((Handle)BlobHandle.FromOffset(0)).IsNil);
            Assert.True(((Handle)UserStringHandle.FromOffset(0)).IsNil);
            Assert.True(((Handle)GuidHandle.FromIndex(0)).IsNil);
            Assert.True(((BlobHandle)DocumentNameBlobHandle.FromOffset(0)).IsNil);

            // virtual:
            Assert.False(AssemblyReferenceHandle.FromVirtualIndex(0).IsNil);
            Assert.False(StringHandle.FromVirtualIndex(0).IsNil);
            Assert.False(BlobHandle.FromVirtualIndex(0, 0).IsNil);

            Assert.False(((Handle)AssemblyReferenceHandle.FromVirtualIndex(0)).IsNil);
            Assert.False(((Handle)StringHandle.FromVirtualIndex(0)).IsNil);
            Assert.False(((Handle)BlobHandle.FromVirtualIndex(0, 0)).IsNil);
        }
 public void CallIndirect(StandaloneSignatureHandle signature)
 {
     OpCode(ILOpCode.Calli);
     Token(signature);
 }
Exemple #16
0
 internal static ImmutableArray<CilType> DecodeLocalSignature(StandaloneSignatureHandle handle, CilTypeProvider provider)
 {
     var standaloneSignature = provider.Reader.GetStandaloneSignature(handle);
     var blobReader = provider.Reader.GetBlobReader(standaloneSignature.Signature);
     return NewDecoder(provider).DecodeLocalSignature(ref blobReader);
 }
 public Mapping<StandaloneSignatureHandle> MapStandaloneSignature(StandaloneSignatureHandle handle)
 {
     return _standaloneSignatures.GetOrAdd(handle, MapStandaloneSignatureImpl);
 }
Exemple #18
0
        private void DefineLocalConstant(string name, object value, PrimitiveTypeCode typeCode, StandaloneSignatureHandle constantSignatureHandle)
        {
            uint constantSignatureToken = (uint)MetadataTokens.GetToken(constantSignatureHandle);

            if (value == null)
            {
                // ISymUnmanagedWriter2.DefineConstant2 throws an ArgumentException
                // if you pass in null - Dev10 appears to use 0 instead.
                // (See EMITTER::VariantFromConstVal)
                value = 0;
                typeCode = PrimitiveTypeCode.Int32;
            }

            if (typeCode == PrimitiveTypeCode.String)
            {
                DefineLocalStringConstant(name, (string)value, constantSignatureToken);
            }
            else if (value is DateTime)
            {
                // Marshal.GetNativeVariantForObject would create a variant with type VT_DATE and value equal to the
                // number of days since 1899/12/30.  However, ConstantValue::VariantFromConstant in the native VB
                // compiler actually created a variant with type VT_DATE and value equal to the tick count.
                // http://blogs.msdn.com/b/ericlippert/archive/2003/09/16/eric-s-complete-guide-to-vt-date.aspx
                var dt = (DateTime)value;
                _symWriter.DefineConstant2(name, new VariantStructure(dt), constantSignatureToken);
                if (_callLogger.LogOperation(OP.DefineConstant2))
                {
                    _callLogger.LogArgument(name);
                    _callLogger.LogArgument(constantSignatureToken);
                    _callLogger.LogArgument(dt.ToBinary());
                }
            }
            else
            {
                try
                {
                    DefineLocalConstantImpl(name, value, constantSignatureToken);
                    if (_callLogger.LogOperation(OP.DefineConstant2))
                    {
                        _callLogger.LogArgument(name);
                        _callLogger.LogArgument(constantSignatureToken);
                        _callLogger.LogArgument(value);
                    }
                }
                catch (Exception ex)
                {
                    throw new PdbWritingException(ex);
                }
            }
        }
 private Mapping<StandaloneSignatureHandle> MapStandaloneSignatureImpl(StandaloneSignatureHandle handle)
 {
     throw new NotImplementedException();
 }
Exemple #20
0
        public void SerializeDebugInfo(IMethodBody methodBody, StandaloneSignatureHandle localSignatureHandleOpt, CustomDebugInfoWriter customDebugInfoWriter)
        {
            Debug.Assert(_metadataWriter != null);

            bool isIterator = methodBody.StateMachineTypeName != null;
            bool emitDebugInfo = isIterator || methodBody.HasAnySequencePoints;

            if (!emitDebugInfo)
            {
                return;
            }

            int methodToken = MetadataTokens.GetToken(_metadataWriter.GetMethodHandle(methodBody.MethodDefinition));

            OpenMethod(methodToken, methodBody.MethodDefinition);

            var localScopes = methodBody.LocalScopes;

            // Define locals, constants and namespaces in the outermost local scope (opened in OpenMethod):
            if (localScopes.Length > 0)
            {
                this.DefineScopeLocals(localScopes[0], localSignatureHandleOpt);
            }

            // NOTE: This is an attempt to match Dev10's apparent behavior.  For iterator methods (i.e. the method
            // that appears in source, not the synthesized ones), Dev10 only emits the ForwardIterator and IteratorLocal
            // custom debug info (e.g. there will be no information about the usings that were in scope).
            if (!isIterator && methodBody.ImportScope != null)
            {
                IMethodDefinition forwardToMethod;
                if (customDebugInfoWriter.ShouldForwardNamespaceScopes(Context, methodBody, methodToken, out forwardToMethod))
                {
                    if (forwardToMethod != null)
                    {
                        UsingNamespace("@" + MetadataTokens.GetToken(_metadataWriter.GetMethodHandle(forwardToMethod)), methodBody.MethodDefinition);
                    }
                    // otherwise, the forwarding is done via custom debug info
                }
                else
                {
                    this.DefineNamespaceScopes(methodBody);
                }
            }

            DefineLocalScopes(localScopes, localSignatureHandleOpt);
            ArrayBuilder<Cci.SequencePoint> sequencePoints = ArrayBuilder<Cci.SequencePoint>.GetInstance();
            methodBody.GetSequencePoints(sequencePoints);
            EmitSequencePoints(sequencePoints);
            sequencePoints.Free();

            AsyncMethodBodyDebugInfo asyncDebugInfo = methodBody.AsyncDebugInfo;
            if (asyncDebugInfo != null)
            {
                SetAsyncInfo(
                    methodToken,
                    MetadataTokens.GetToken(_metadataWriter.GetMethodHandle(asyncDebugInfo.KickoffMethod)),
                    asyncDebugInfo.CatchHandlerOffset,
                    asyncDebugInfo.YieldOffsets,
                    asyncDebugInfo.ResumeOffsets);
            }

            var compilationOptions = Context.Module.CommonCompilation.Options;

            // We need to avoid emitting CDI DynamicLocals = 5 and EditAndContinueLocalSlotMap = 6 for files processed by WinMDExp until 
            // bug #1067635 is fixed and available in SDK.
            bool suppressNewCustomDebugInfo = !compilationOptions.ExtendedCustomDebugInformation ||
                (compilationOptions.OutputKind == OutputKind.WindowsRuntimeMetadata);

            bool emitEncInfo = compilationOptions.EnableEditAndContinue && !_metadataWriter.IsFullMetadata;

            bool emitExternNamespaces;
            byte[] blob = customDebugInfoWriter.SerializeMethodDebugInfo(Context, methodBody, methodToken, emitEncInfo, suppressNewCustomDebugInfo, out emitExternNamespaces);
            if (blob != null)
            {
                DefineCustomMetadata("MD2", blob);
            }

            if (emitExternNamespaces)
            {
                this.DefineAssemblyReferenceAliases();
            }

            CloseMethod(methodBody.IL.Length);
        }
        /// <summary>
        /// Encodes a method body and adds it to the method body stream.
        /// </summary>
        /// <param name="instructionEncoder">Instruction encoder.</param>
        /// <param name="maxStack">Max stack.</param>
        /// <param name="localVariablesSignature">Local variables signature handle.</param>
        /// <param name="attributes">Attributes.</param>
        /// <returns>The offset of the encoded body within the method body stream.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="instructionEncoder"/> has default value.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxStack"/> is out of range [0, <see cref="ushort.MaxValue"/>].</exception>
        /// <exception cref="InvalidOperationException">
        /// A label targeted by a branch in the instruction stream has not been marked,
        /// or the distance between a branch instruction and the target label is doesn't fit the size of the instruction operand.
        /// </exception>
        public int AddMethodBody(
            InstructionEncoder instructionEncoder, 
            int maxStack = 8,
            StandaloneSignatureHandle localVariablesSignature = default(StandaloneSignatureHandle),
            MethodBodyAttributes attributes = MethodBodyAttributes.InitLocals)
        {
            if (unchecked((uint)maxStack) > ushort.MaxValue)
            {
                Throw.ArgumentOutOfRange(nameof(maxStack));
            }

            // The branch fixup code expects the operands of branch instructions in the code builder to be contiguous.
            // That's true when we emit thru InstructionEncoder. Taking it as a parameter instead of separate 
            // code and flow builder parameters ensures they match each other.
            var codeBuilder = instructionEncoder.CodeBuilder;
            var flowBuilder = instructionEncoder.ControlFlowBuilder;

            if (codeBuilder == null)
            {
                Throw.ArgumentNull(nameof(instructionEncoder));
            }

            int exceptionRegionCount = flowBuilder?.ExceptionHandlerCount ?? 0;
            if (!ExceptionRegionEncoder.IsExceptionRegionCountInBounds(exceptionRegionCount))
            {
                Throw.ArgumentOutOfRange(nameof(instructionEncoder), SR.TooManyExceptionRegions);
            }

            int bodyOffset = SerializeHeader(codeBuilder.Count, (ushort)maxStack, exceptionRegionCount, attributes, localVariablesSignature);

            if (flowBuilder?.BranchCount > 0)
            {
                flowBuilder.CopyCodeAndFixupBranches(codeBuilder, Builder);
            }
            else
            {
                codeBuilder.WriteContentTo(Builder);
            }

            flowBuilder?.SerializeExceptionTable(Builder);
            
            return bodyOffset;
        }
Exemple #22
0
        private void DefineScopeLocals(LocalScope currentScope, StandaloneSignatureHandle localSignatureHandleOpt)
        {
            foreach (ILocalDefinition scopeConstant in currentScope.Constants)
            {
                var signatureHandle = _metadataWriter.SerializeLocalConstantStandAloneSignature(scopeConstant);
                if (!_metadataWriter.IsLocalNameTooLong(scopeConstant))
                {
                    DefineLocalConstant(scopeConstant.Name, scopeConstant.CompileTimeValue.Value, _metadataWriter.GetConstantTypeCode(scopeConstant), signatureHandle);
                }
            }

            foreach (ILocalDefinition scopeLocal in currentScope.Variables)
            {
                if (!_metadataWriter.IsLocalNameTooLong(scopeLocal))
                {
                    Debug.Assert(scopeLocal.SlotIndex >= 0);
                    DefineLocalVariable((uint)scopeLocal.SlotIndex, scopeLocal.Name, scopeLocal.PdbAttributes, localSignatureHandleOpt);
                }
            }
        }
        private int SerializeHeader(int codeSize, ushort maxStack, int exceptionRegionCount, MethodBodyAttributes attributes, StandaloneSignatureHandle localVariablesSignature)
        {
            const int TinyFormat = 2;
            const int FatFormat = 3;
            const int MoreSections = 8;
            const byte InitLocals = 0x10;

            int offset;

            bool isTiny = codeSize < 64 && maxStack <= 8 && localVariablesSignature.IsNil && exceptionRegionCount == 0;

            if (isTiny)
            {
                offset = Builder.Count;
                Builder.WriteByte((byte)((codeSize << 2) | TinyFormat));
            }
            else
            {
                Builder.Align(4);

                offset = Builder.Count;

                ushort flags = (3 << 12) | FatFormat;
                if (exceptionRegionCount > 0)
                {
                    flags |= MoreSections;
                }

                if ((attributes & MethodBodyAttributes.InitLocals) != 0)
                {
                    flags |= InitLocals;
                }

                Builder.WriteUInt16((ushort)((int)attributes | flags));
                Builder.WriteUInt16(maxStack);
                Builder.WriteInt32(codeSize);
                Builder.WriteInt32(localVariablesSignature.IsNil ? 0 : MetadataTokens.GetToken(localVariablesSignature));
            }

            return offset;
        }
Exemple #24
0
 public StandaloneSignature GetStandaloneSignature(StandaloneSignatureHandle handle)
 {
     return new StandaloneSignature(this, handle);
 }
Exemple #25
0
 /// <summary>
 /// Encodes <code>calli</code> instruction and its operand.
 /// </summary>
 public void CallIndirect(StandaloneSignatureHandle signature)
 {
     OpCode(ILOpCode.Calli);
     Token(signature);
 }