private static ImportScopeHandle DefineImportScope(
            ImmutableArray <ImmutableArray <ImportInfo> > importGroups,
            Dictionary <ImportScopeInfo, ImportScopeHandle> importScopeIndex,
            List <ImportScopeInfo> importScopes)
        {
            ImportScopeHandle parentHandle = ModuleImportScopeHandle;

            for (int i = importGroups.Length - 1; i >= 0; i--)
            {
                var info = new ImportScopeInfo(importGroups[i], parentHandle);

                ImportScopeHandle existingScopeHandle;
                if (importScopeIndex.TryGetValue(info, out existingScopeHandle))
                {
                    parentHandle = existingScopeHandle;
                }
                else
                {
                    importScopes.Add(info);
                    parentHandle = MetadataTokens.ImportScopeHandle(importScopes.Count);
                }
            }

            return(parentHandle);
        }
Ejemplo n.º 2
0
        internal ImportScope(MetadataReader reader, ImportScopeHandle handle)
        {
            Debug.Assert(reader != null);
            Debug.Assert(!handle.IsNil);

            _reader = reader;
            _rowId = handle.RowId;
        }
Ejemplo n.º 3
0
 public ImportScopeEntry(PEFile module, MetadataReader metadata, bool isEmbedded, ImportScopeHandle handle)
 {
     this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.ImportScope)
                   + metadata.GetTableRowSize(TableIndex.ImportScope) * (MetadataTokens.GetRowNumber(handle) - 1);
     this.module     = module;
     this.metadata   = metadata;
     this.handle     = handle;
     this.localScope = metadata.GetImportScope(handle);
 }
Ejemplo n.º 4
0
        private static void PopulateImports(
            MetadataReader reader,
            ImportScopeHandle handle,
            EESymbolProvider <TTypeSymbol, TLocalSymbol> symbolProvider,
            bool isVisualBasicMethod,
            ArrayBuilder <ImmutableArray <ImportRecord> > importGroupsBuilder,
            ArrayBuilder <ExternAliasRecord> externAliasesBuilder
            )
        {
            var importGroupBuilder = ArrayBuilder <ImportRecord> .GetInstance();

            while (!handle.IsNil)
            {
                var importScope = reader.GetImportScope(handle);

                try
                {
                    PopulateImports(
                        reader,
                        importScope,
                        symbolProvider,
                        importGroupBuilder,
                        externAliasesBuilder
                        );
                }
                catch (BadImageFormatException)
                {
                    // ignore invalid imports
                }

                // Portable PDBs represent project-level scope as the root of the chain of scopes.
                // This scope might contain aliases for assembly references, but is not considered
                // to be part of imports groups.
                if (isVisualBasicMethod || !importScope.Parent.IsNil)
                {
                    importGroupsBuilder.Add(importGroupBuilder.ToImmutable());
                    importGroupBuilder.Clear();
                }
                else
                {
                    // C# currently doesn't support global imports in PDBs
                    // https://github.com/dotnet/roslyn/issues/21862
                    Debug.Assert(importGroupBuilder.Count == 0);
                }

                handle = importScope.Parent;
            }

            importGroupBuilder.Free();
        }
        private ImportScopeHandle GetImportScopeIndex(IImportScope scope, Dictionary <IImportScope, ImportScopeHandle> scopeIndex)
        {
            if (scopeIndex.TryGetValue(scope, out ImportScopeHandle scopeHandle))
            {
                // scope is already indexed:
                return(scopeHandle);
            }

            IImportScope      parent            = scope.Parent;
            ImportScopeHandle parentScopeHandle = (parent != null) ? GetImportScopeIndex(scope.Parent, scopeIndex) : ModuleImportScopeHandle;

            ImportScopeHandle result = _debugMetadataOpt.AddImportScope(
                parentScope: parentScopeHandle,
                imports: SerializeImportsBlob(scope));

            scopeIndex.Add(scope, result);
            return(result);
        }
        private void DefineModuleImportScope()
        {
            // module-level import scope:
            BlobBuilder writer = new BlobBuilder();

            SerializeModuleDefaultNamespace();

            foreach (AssemblyReferenceAlias alias in module.GetAssemblyReferenceAliases(Context))
            {
                SerializeImport(writer, alias);
            }

            foreach (UsedNamespaceOrType import in module.GetImports())
            {
                SerializeImport(writer, import);
            }

            ImportScopeHandle rid = _debugMetadataOpt.AddImportScope(
                parentScope: default(ImportScopeHandle),
                imports: _debugMetadataOpt.GetOrAddBlob(writer));

            Debug.Assert(rid == ModuleImportScopeHandle);
        }
        private static void PopulateImports(
            MetadataReader reader,
            ImportScopeHandle handle,
            EESymbolProvider <TTypeSymbol, TLocalSymbol> symbolProvider,
            bool isVisualBasicMethod,
            ArrayBuilder <ImmutableArray <ImportRecord> > importGroupsBuilder,
            ArrayBuilder <ExternAliasRecord> externAliasesBuilder)
        {
            var importGroupBuilder = ArrayBuilder <ImportRecord> .GetInstance();

            while (!handle.IsNil)
            {
                var importScope = reader.GetImportScope(handle);

                try
                {
                    PopulateImports(reader, importScope, symbolProvider, importGroupBuilder, externAliasesBuilder);
                }
                catch (BadImageFormatException)
                {
                    // ignore invalid imports
                }

                // VB always expects two import groups (even if they are empty).
                // TODO: consider doing this for C# as well and handle empty groups in the binder.
                if (isVisualBasicMethod || importGroupBuilder.Count > 0)
                {
                    importGroupsBuilder.Add(importGroupBuilder.ToImmutable());
                    importGroupBuilder.Clear();
                }

                handle = importScope.Parent;
            }

            importGroupBuilder.Free();
        }
        private static void SerializeScope(
            MetadataBuilder metadataBuilder,
            MetadataModel metadataModel,
            MethodDefinitionHandle methodHandle,
            ImportScopeHandle importScopeHandle,
            ISymUnmanagedScope symScope,
            Dictionary <int, DynamicLocalInfo> dynamicSlots,
            Dictionary <string, DynamicLocalInfo> dynamicNames,
            bool vbSemantics,
            ref LocalVariableHandle lastLocalVariableHandle,
            ref LocalConstantHandle lastLocalConstantHandle)
        {
            // VB Windows PDB encode the range as end-inclusive,
            // all Portable PDBs use end-exclusive encoding.
            int start = symScope.GetStartOffset();
            int end   = symScope.GetEndOffset() + (vbSemantics ? 1 : 0);

            metadataBuilder.AddLocalScope(
                method: methodHandle,
                importScope: importScopeHandle,
                variableList: NextHandle(lastLocalVariableHandle),
                constantList: NextHandle(lastLocalConstantHandle),
                startOffset: start,
                length: end - start);

            foreach (var symLocal in symScope.GetLocals())
            {
                int    slot = symLocal.GetSlot();
                string name = symLocal.GetName();

                lastLocalVariableHandle = metadataBuilder.AddLocalVariable(
                    attributes: (LocalVariableAttributes)symLocal.GetAttributes(),
                    index: slot,
                    name: metadataBuilder.GetOrAddString(name));

                DynamicLocalInfo dynamicInfo;
                if (slot > 0 && dynamicSlots.TryGetValue(slot, out dynamicInfo) ||
                    slot == 0 && dynamicNames.TryGetValue(name, out dynamicInfo))
                {
                    metadataBuilder.AddCustomDebugInformation(
                        parent: lastLocalVariableHandle,
                        kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.DynamicLocalVariables),
                        value: SerializeDynamicLocalBlob(metadataBuilder, dynamicInfo));
                }
            }

            foreach (var symConstant in symScope.GetConstants())
            {
                string name  = symConstant.GetName();
                object value = symConstant.GetValue();

                lastLocalConstantHandle = metadataBuilder.AddLocalConstant(
                    name: metadataBuilder.GetOrAddString(name),
                    signature: SerializeConstantSignature(metadataBuilder, metadataModel, symConstant.GetSignature(), value));

                DynamicLocalInfo dynamicInfo;
                if (dynamicNames.TryGetValue(name, out dynamicInfo))
                {
                    metadataBuilder.AddCustomDebugInformation(
                        parent: lastLocalConstantHandle,
                        kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.DynamicLocalVariables),
                        value: SerializeDynamicLocalBlob(metadataBuilder, dynamicInfo));
                }
            }

            int previousChildScopeEnd = start;

            foreach (ISymUnmanagedScope child in symScope.GetChildren())
            {
                int childScopeStart = child.GetStartOffset();
                int childScopeEnd   = child.GetEndOffset();

                // scopes are properly nested:
                if (childScopeStart < previousChildScopeEnd || childScopeEnd > end)
                {
                    // TODO: loc/warning
                    throw new BadImageFormatException($"Invalid scope IL offset range: [{childScopeStart}, {childScopeEnd}), method 0x{MetadataTokens.GetToken(methodHandle):x}.");
                }

                previousChildScopeEnd = childScopeEnd;

                SerializeScope(metadataBuilder, metadataModel, methodHandle, importScopeHandle, child, dynamicSlots, dynamicNames, vbSemantics, ref lastLocalVariableHandle, ref lastLocalConstantHandle);
            }
        }
 public ImportScopeInfo(ImmutableArray <ImportInfo> imports, ImportScopeHandle parent)
 {
     Parent  = parent;
     Imports = imports;
 }
Ejemplo n.º 10
0
        public ImportScopeHandle AddImportScope(ImportScopeHandle parentScope, BlobHandle imports)
        {
            _importScopeTable.Add(new ImportScopeRow
            {
                Parent = (uint)MetadataTokens.GetRowNumber(parentScope),
                Imports = imports
            });

            return MetadataTokens.ImportScopeHandle(_importScopeTable.Count);
        }
Ejemplo n.º 11
0
        internal ImportScopeHandle GetParent(ImportScopeHandle handle)
        {
            int rowOffset = (handle.RowId - 1) * RowSize;

            return(ImportScopeHandle.FromRowId(Block.PeekReference(rowOffset + ParentOffset, _isImportScopeRefSizeSmall)));
        }
Ejemplo n.º 12
0
 internal BlobHandle GetImports(ImportScopeHandle handle)
 {
     int rowOffset = (handle.RowId - 1) * RowSize;
     return BlobHandle.FromOffset(Block.PeekHeapReference(rowOffset + _importsOffset, _isBlobHeapRefSizeSmall));
 }
Ejemplo n.º 13
0
 internal ImportScopeHandle GetParent(ImportScopeHandle handle)
 {
     int rowOffset = (handle.RowId - 1) * RowSize;
     return ImportScopeHandle.FromRowId(Block.PeekReference(rowOffset + ParentOffset, _isImportScopeRefSizeSmall));
 }
        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 isIterator    = bodyOpt.StateMachineTypeName != null;
            bool emitDebugInfo = isIterator || bodyOpt.HasAnySequencePoints;

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

            MethodDefinitionHandle methodHandle = MetadataTokens.MethodDefinitionHandle(methodRid);

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

            // documents & sequence points:
            ArrayBuilder <Cci.SequencePoint> sequencePoints = ArrayBuilder <Cci.SequencePoint> .GetInstance();

            bodyOpt.GetSequencePoints(sequencePoints);
            BlobHandle sequencePointsBlob = SerializeSequencePoints(localSignatureHandleOpt, sequencePoints.ToImmutableAndFree(), _documentIndex, out DocumentHandle 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)
                    {
                        CodeAnalysis.CodeGen.MetadataConstant mdConstant = constant.CompileTimeValue;
                        Debug.Assert(mdConstant != null);

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

                        SerializeLocalInfo(constant, lastLocalConstantHandle);
                    }
                }
            }

            AsyncMethodBodyDebugInfo asyncDebugInfo = bodyOpt.AsyncDebugInfo;

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

                SerializeAsyncMethodSteppingInfo(asyncDebugInfo, 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);
            }
        }
Ejemplo n.º 15
0
        /// <exception cref="BadImageFormatException">Invalid data format.</exception>
        private static void PopulateImports(
            MetadataReader reader,
            ImportScopeHandle handle,
            EESymbolProvider <TTypeSymbol, TLocalSymbol> symbolProvider,
            bool isVisualBasicMethod,
            ArrayBuilder <ImmutableArray <ImportRecord> > importGroupsBuilder,
            ArrayBuilder <ExternAliasRecord> externAliasesBuilder)
        {
            var importGroupBuilder = ArrayBuilder <ImportRecord> .GetInstance();

            while (!handle.IsNil)
            {
                var importScope = reader.GetImportScope(handle);

                foreach (ImportDefinition import in importScope.GetImports())
                {
                    switch (import.Kind)
                    {
                    case ImportDefinitionKind.ImportNamespace:
                        importGroupBuilder.Add(new ImportRecord(
                                                   ImportTargetKind.Namespace,
                                                   targetString: ReadUtf8String(reader, import.TargetNamespace)));
                        break;

                    case ImportDefinitionKind.ImportAssemblyNamespace:
                        importGroupBuilder.Add(new ImportRecord(
                                                   ImportTargetKind.Namespace,
                                                   targetString: ReadUtf8String(reader, import.TargetNamespace),
                                                   targetAssembly: symbolProvider.GetReferencedAssembly(import.TargetAssembly)));
                        break;

                    case ImportDefinitionKind.ImportType:
                        importGroupBuilder.Add(new ImportRecord(
                                                   ImportTargetKind.Type,
                                                   targetType: symbolProvider.GetType(import.TargetType)));
                        break;

                    case ImportDefinitionKind.ImportXmlNamespace:
                        importGroupBuilder.Add(new ImportRecord(
                                                   ImportTargetKind.XmlNamespace,
                                                   alias: ReadUtf8String(reader, import.Alias),
                                                   targetString: ReadUtf8String(reader, import.TargetNamespace)));
                        break;

                    case ImportDefinitionKind.ImportAssemblyReferenceAlias:
                        importGroupBuilder.Add(new ImportRecord(
                                                   ImportTargetKind.Assembly,
                                                   alias: ReadUtf8String(reader, import.Alias)));
                        break;

                    case ImportDefinitionKind.AliasAssemblyReference:
                        externAliasesBuilder.Add(new ExternAliasRecord(
                                                     alias: ReadUtf8String(reader, import.Alias),
                                                     targetAssembly: symbolProvider.GetReferencedAssembly(import.TargetAssembly)));
                        break;

                    case ImportDefinitionKind.AliasNamespace:
                        importGroupBuilder.Add(new ImportRecord(
                                                   ImportTargetKind.Namespace,
                                                   alias: ReadUtf8String(reader, import.Alias),
                                                   targetString: ReadUtf8String(reader, import.TargetNamespace)));
                        break;

                    case ImportDefinitionKind.AliasAssemblyNamespace:
                        importGroupBuilder.Add(new ImportRecord(
                                                   ImportTargetKind.Namespace,
                                                   alias: ReadUtf8String(reader, import.Alias),
                                                   targetString: ReadUtf8String(reader, import.TargetNamespace),
                                                   targetAssembly: symbolProvider.GetReferencedAssembly(import.TargetAssembly)));
                        break;

                    case ImportDefinitionKind.AliasType:
                        importGroupBuilder.Add(new ImportRecord(
                                                   ImportTargetKind.Type,
                                                   alias: ReadUtf8String(reader, import.Alias),
                                                   targetType: symbolProvider.GetType(import.TargetType)));
                        break;
                    }
                }

                // VB always expects two import groups (even if they are empty).
                // TODO: consider doing this for C# as well and handle empty groups in the binder.
                if (isVisualBasicMethod || importGroupBuilder.Count > 0)
                {
                    importGroupsBuilder.Add(importGroupBuilder.ToImmutable());
                    importGroupBuilder.Clear();
                }

                handle = importScope.Parent;
            }

            importGroupBuilder.Free();
        }
Ejemplo n.º 16
0
 public ImportScope GetImportScope(ImportScopeHandle handle)
 {
     return new ImportScope(this, handle);
 }
Ejemplo n.º 17
0
        internal ImportScopeHandle GetImportScope(LocalScopeHandle handle)
        {
            int rowOffset = (handle.RowId - 1) * RowSize;

            return(ImportScopeHandle.FromRowId(Block.PeekReference(rowOffset + _importScopeOffset, _isImportScopeRefSmall)));
        }
Ejemplo n.º 18
0
        public LocalScopeHandle AddLocalScope(MethodDefinitionHandle method, ImportScopeHandle importScope, LocalVariableHandle variableList, LocalConstantHandle constantList, int startOffset, int length)
        {
            _localScopeTable.Add(new LocalScopeRow
            {
                Method = (uint)MetadataTokens.GetRowNumber(method),
                ImportScope = (uint)MetadataTokens.GetRowNumber(importScope),
                VariableList = (uint)MetadataTokens.GetRowNumber(variableList),
                ConstantList = (uint)MetadataTokens.GetRowNumber(constantList),
                StartOffset = (uint)startOffset,
                Length = (uint)length
            });

            return MetadataTokens.LocalScopeHandle(_localScopeTable.Count);
        }
Ejemplo n.º 19
0
        internal BlobHandle GetImports(ImportScopeHandle handle)
        {
            int rowOffset = (handle.RowId - 1) * RowSize;

            return(BlobHandle.FromOffset(Block.PeekHeapReference(rowOffset + _importsOffset, _isBlobHeapRefSizeSmall)));
        }
Ejemplo n.º 20
0
 public static ImportScope GetImportScope(this ImportScopeHandle handle, MetadataReader reader) => reader.GetImportScope(handle);