Ejemplo n.º 1
0
        private void SerializeNamespaceScopeMetadata(ref CustomDebugInfoEncoder encoder, EmitContext context, IMethodBody methodBody)
        {
            if (context.Module.GenerateVisualBasicStylePdb)
            {
                return;
            }

            if (ShouldForwardToPreviousMethodWithUsingInfo(context, methodBody))
            {
                Debug.Assert(!ReferenceEquals(_previousMethodBodyWithUsingInfo, methodBody));
                encoder.AddForwardMethodInfo(_previousMethodWithUsingInfo);
                return;
            }

            var usingCounts = ArrayBuilder <int> .GetInstance();

            for (IImportScope scope = methodBody.ImportScope; scope != null; scope = scope.Parent)
            {
                usingCounts.Add(scope.GetUsedNamespaces().Length);
            }

            encoder.AddUsingGroups(usingCounts);
            usingCounts.Free();

            if (_methodBodyWithModuleInfo != null && !ReferenceEquals(_methodBodyWithModuleInfo, methodBody))
            {
                encoder.AddForwardModuleInfo(_methodWithModuleInfo);
            }
        }
 public CompilerContext(IScriptScope scriptScope, ITypeScope typeScope, IImportScope importScope, CompilerOptions options)
 {
     this.m_scriptScope = scriptScope;
     this.m_typeScope   = typeScope;
     this.m_importScope = importScope;
     this.m_options     = options;
 }
Ejemplo n.º 3
0
        protected override void ProcessMethodBody(IMethodDefinition method)
        {
            if (method.HasBody() && !metadataWriter.MetadataOnly)
            {
                var body = method.GetBody(Context);

                if (body != null)
                {
                    this.Visit(body);

                    for (IImportScope scope = body.ImportScope; scope != null; scope = scope.Parent)
                    {
                        if (_alreadySeenScopes.Add(scope))
                        {
                            VisitImports(scope.GetUsedNamespaces());
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                else if (!metadataWriter.MetadataOnly)
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
        }
Ejemplo n.º 4
0
        private ImportScopeHandle GetImportScopeIndex(
            IImportScope scope,
            Dictionary <IImportScope, ImportScopeHandle> scopeIndex
            )
        {
            ImportScopeHandle scopeHandle;

            if (scopeIndex.TryGetValue(scope, out scopeHandle))
            {
                // scope is already indexed:
                return(scopeHandle);
            }

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

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

            scopeIndex.Add(scope, result);
            return(result);
        }
        private BlobHandle SerializeImportsBlob(IImportScope scope)
        {
            var writer = new BlobBuilder();

            foreach (UsedNamespaceOrType import in scope.GetUsedNamespaces())
            {
                SerializeImport(writer, import);
            }

            return(_debugMetadataOpt.GetOrAddBlob(writer));
        }
Ejemplo n.º 6
0
        private BlobIdx SerializeImportsBlob(IImportScope scope)
        {
            var writer = new BlobBuilder();

            foreach (UsedNamespaceOrType import in scope.GetUsedNamespaces())
            {
                SerializeImport(writer, import);
            }

            return(_debugHeapsOpt.GetBlobIndex(writer));
        }
Ejemplo n.º 7
0
        private static IImportScope GetLastScope(IImportScope scope)
        {
            while (true)
            {
                var parent = scope.Parent;
                if (parent == null)
                {
                    return(scope);
                }

                scope = parent;
            }
        }
Ejemplo n.º 8
0
        private void SerializeNamespaceScopeMetadata(EmitContext context, IMethodBody methodBody, ArrayBuilder <MemoryStream> customDebugInfo)
        {
            if (context.Module.GenerateVisualBasicStylePdb)
            {
                return;
            }

            if (ShouldForwardToPreviousMethodWithUsingInfo(context, methodBody))
            {
                Debug.Assert(!ReferenceEquals(_previousMethodBodyWithUsingInfo, methodBody));
                SerializeReferenceToPreviousMethodWithUsingInfo(customDebugInfo);
                return;
            }

            MemoryStream  customMetadata = new MemoryStream();
            List <ushort> usingCounts    = new List <ushort>();
            BinaryWriter  cmw            = new BinaryWriter(customMetadata);

            for (IImportScope scope = methodBody.ImportScope; scope != null; scope = scope.Parent)
            {
                usingCounts.Add((ushort)scope.GetUsedNamespaces().Length);
            }

            // ACASEY: This originally wrote (uint)12, (ushort)1, (ushort)0 in the
            // case where usingCounts was empty, but I'm not sure why.
            if (usingCounts.Count > 0)
            {
                uint streamLength;
                cmw.WriteByte(CDI.CdiVersion);
                cmw.WriteByte(CDI.CdiKindUsingInfo);
                cmw.Align(4);

                cmw.WriteUint(streamLength = BitArithmeticUtilities.Align((uint)usingCounts.Count * 2 + 10, 4));
                cmw.WriteUshort((ushort)usingCounts.Count);
                foreach (ushort uc in usingCounts)
                {
                    cmw.WriteUshort(uc);
                }

                cmw.Align(4);
                Debug.Assert(streamLength == customMetadata.Length);
                customDebugInfo.Add(customMetadata);
            }

            if (_methodBodyWithModuleInfo != null && !ReferenceEquals(_methodBodyWithModuleInfo, methodBody))
            {
                SerializeReferenceToMethodWithModuleInfo(customDebugInfo);
            }
        }
Ejemplo n.º 9
0
        private bool ShouldForwardToPreviousMethodWithUsingInfo(EmitContext context, IMethodBody methodBody)
        {
            if (_previousMethodBodyWithUsingInfo == null ||
                ReferenceEquals(_previousMethodBodyWithUsingInfo, methodBody))
            {
                return(false);
            }

            // VB includes method namespace in namespace scopes:
            if (context.Module.GenerateVisualBasicStylePdb)
            {
                if (_pdbWriter.GetOrCreateSerializedNamespaceName(_previousMethodBodyWithUsingInfo.MethodDefinition.ContainingNamespace) !=
                    _pdbWriter.GetOrCreateSerializedNamespaceName(methodBody.MethodDefinition.ContainingNamespace))
                {
                    return(false);
                }
            }

            IImportScope previousScopes = _previousMethodBodyWithUsingInfo.ImportScope;

            // methods share the same import scope (common case for methods declared in the same file)
            if (methodBody.ImportScope == previousScopes)
            {
                return(true);
            }

            // If methods are in different files they don't share the same scopes,
            // but the imports might be the same nevertheless.
            // Note: not comparing project-level imports since those are the same for all method bodies.
            IImportScope s1 = methodBody.ImportScope;
            IImportScope s2 = previousScopes;

            while (s1 != null && s2 != null)
            {
                if (!s1.GetUsedNamespaces().SequenceEqual(s2.GetUsedNamespaces()))
                {
                    return(false);
                }

                s1 = s1.Parent;
                s2 = s2.Parent;
            }

            return(s1 == s2);
        }
Ejemplo n.º 10
0
        private int GetImportScopeIndex(IImportScope scope, Dictionary <IImportScope, int> scopeIndex)
        {
            int scopeRid;

            if (scopeIndex.TryGetValue(scope, out scopeRid))
            {
                // scope is already indexed:
                return(scopeRid);
            }

            var parent         = scope.Parent;
            int parentScopeRid = (parent != null) ? GetImportScopeIndex(scope.Parent, scopeIndex) : ModuleImportScopeRid;

            _importScopeTable.Add(new ImportScopeRow
            {
                Parent  = (uint)parentScopeRid,
                Imports = SerializeImportsBlob(scope)
            });

            var rid = _importScopeTable.Count;

            scopeIndex.Add(scope, rid);
            return(rid);
        }
Ejemplo n.º 11
0
        private void DefineNamespaceScopes(IMethodBody methodBody)
        {
            var  module        = Module;
            bool isVisualBasic = module.GenerateVisualBasicStylePdb;

            IMethodDefinition method = methodBody.MethodDefinition;

            var namespaceScopes = methodBody.ImportScope;

            // NOTE: All extern aliases are stored on the outermost namespace scope.
            PooledHashSet <string> lazyDeclaredExternAliases = null;

            if (!isVisualBasic)
            {
                foreach (var import in GetLastScope(namespaceScopes).GetUsedNamespaces(Context))
                {
                    if (import.TargetNamespaceOpt == null && import.TargetTypeOpt == null)
                    {
                        Debug.Assert(import.AliasOpt != null);
                        Debug.Assert(import.TargetAssemblyOpt == null);

                        if (lazyDeclaredExternAliases == null)
                        {
                            lazyDeclaredExternAliases = PooledHashSet <string> .GetInstance();
                        }

                        lazyDeclaredExternAliases.Add(import.AliasOpt);
                    }
                }
            }

            // file and namespace level
            for (IImportScope scope = namespaceScopes; scope != null; scope = scope.Parent)
            {
                foreach (UsedNamespaceOrType import in scope.GetUsedNamespaces(Context))
                {
                    var importString = TryEncodeImport(import, lazyDeclaredExternAliases, isProjectLevel: false);
                    if (importString != null)
                    {
                        UsingNamespace(importString, method);
                    }
                }
            }

            lazyDeclaredExternAliases?.Free();

            // project level
            if (isVisualBasic)
            {
                string defaultNamespace = module.DefaultNamespace;

                if (defaultNamespace != null)
                {
                    // VB marks the default/root namespace with an asterisk
                    UsingNamespace("*" + defaultNamespace, module);
                }

                foreach (string assemblyName in module.LinkedAssembliesDebugInfo)
                {
                    UsingNamespace("&" + assemblyName, module);
                }

                foreach (UsedNamespaceOrType import in module.GetImports(Context))
                {
                    var importString = TryEncodeImport(import, null, isProjectLevel: true);
                    if (importString != null)
                    {
                        UsingNamespace(importString, method);
                    }
                }

                // VB current namespace -- VB appends the namespace of the container without prefixes
                UsingNamespace(GetOrCreateSerializedNamespaceName(method.ContainingNamespace), method);
            }
        }
        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.º 13
0
        private IImportScope GetLastScope(IImportScope scope)
        {
            while (true)
            {
                var parent = scope.Parent;
                if (parent == null)
                {
                    return scope;
                }

                scope = parent;
            }
        }