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); }
internal ImportScope(MetadataReader reader, ImportScopeHandle handle) { Debug.Assert(reader != null); Debug.Assert(!handle.IsNil); _reader = reader; _rowId = handle.RowId; }
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); }
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; }
public ImportScopeHandle AddImportScope(ImportScopeHandle parentScope, BlobHandle imports) { _importScopeTable.Add(new ImportScopeRow { Parent = (uint)MetadataTokens.GetRowNumber(parentScope), Imports = imports }); return MetadataTokens.ImportScopeHandle(_importScopeTable.Count); }
internal ImportScopeHandle GetParent(ImportScopeHandle handle) { int rowOffset = (handle.RowId - 1) * RowSize; return(ImportScopeHandle.FromRowId(Block.PeekReference(rowOffset + ParentOffset, _isImportScopeRefSizeSmall))); }
internal BlobHandle GetImports(ImportScopeHandle handle) { int rowOffset = (handle.RowId - 1) * RowSize; return BlobHandle.FromOffset(Block.PeekHeapReference(rowOffset + _importsOffset, _isBlobHeapRefSizeSmall)); }
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); } }
/// <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(); }
public ImportScope GetImportScope(ImportScopeHandle handle) { return new ImportScope(this, handle); }
internal ImportScopeHandle GetImportScope(LocalScopeHandle handle) { int rowOffset = (handle.RowId - 1) * RowSize; return(ImportScopeHandle.FromRowId(Block.PeekReference(rowOffset + _importScopeOffset, _isImportScopeRefSmall))); }
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); }
internal BlobHandle GetImports(ImportScopeHandle handle) { int rowOffset = (handle.RowId - 1) * RowSize; return(BlobHandle.FromOffset(Block.PeekHeapReference(rowOffset + _importsOffset, _isBlobHeapRefSizeSmall))); }
public static ImportScope GetImportScope(this ImportScopeHandle handle, MetadataReader reader) => reader.GetImportScope(handle);