private static void GetConstants( ArrayBuilder<LocalSymbol> builder, MethodSymbol method, IEnumerable<ISymUnmanagedScope> scopes, MetadataDecoder metadataDecoder, ImmutableDictionary<string, ImmutableArray<bool>> dynamicLocalConstantMap, SourceAssemblySymbol containingAssembly) { foreach (var scope in scopes) { foreach (var constant in scope.GetConstants()) { string name = constant.GetName(); object rawValue = constant.GetValue(); var signature = constant.GetSignature(); var info = metadataDecoder.GetLocalInfo(signature); Debug.Assert(!info.IsByRef); Debug.Assert(!info.IsPinned); var type = info.Type; var constantValue = PdbHelpers.GetConstantValue(type.EnumUnderlyingType(), rawValue); ImmutableArray<bool> dynamicFlags; if (dynamicLocalConstantMap != null && dynamicLocalConstantMap.TryGetValue(name, out dynamicFlags)) { type = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags( type, containingAssembly, RefKind.None, dynamicFlags); } builder.Add(new EELocalConstantSymbol(method, name, type, constantValue)); } } }
internal static EvaluationContext CreateMethodContext( CSharpCompilation compilation, object symReader, Guid moduleVersionId, int methodToken, int methodVersion, int ilOffset, int localSignatureToken) { Debug.Assert(MetadataTokens.Handle(methodToken).Kind == HandleKind.MethodDefinition); var typedSymReader = (ISymUnmanagedReader)symReader; var allScopes = ArrayBuilder<ISymUnmanagedScope>.GetInstance(); var containingScopes = ArrayBuilder<ISymUnmanagedScope>.GetInstance(); typedSymReader.GetScopes(methodToken, methodVersion, ilOffset, IsLocalScopeEndInclusive, allScopes, containingScopes); var methodContextReuseConstraints = allScopes.GetReuseConstraints(moduleVersionId, methodToken, methodVersion, ilOffset, IsLocalScopeEndInclusive); allScopes.Free(); var localNames = containingScopes.GetLocalNames(); var inScopeHoistedLocals = InScopeHoistedLocals.Empty; var methodDebugInfo = default(MethodDebugInfo); if (typedSymReader != null) { try { // TODO (https://github.com/dotnet/roslyn/issues/702): switch on the type of typedSymReader and call the appropriate helper. methodDebugInfo = typedSymReader.GetMethodDebugInfo(methodToken, methodVersion, localNames.FirstOrDefault()); var inScopeHoistedLocalIndices = methodDebugInfo.GetInScopeHoistedLocalIndices(ilOffset, ref methodContextReuseConstraints); inScopeHoistedLocals = new CSharpInScopeHoistedLocals(inScopeHoistedLocalIndices); } catch (InvalidOperationException) { // bad CDI, ignore } } var methodHandle = (MethodDefinitionHandle)MetadataTokens.Handle(methodToken); var currentFrame = compilation.GetMethod(moduleVersionId, methodHandle); Debug.Assert((object)currentFrame != null); var metadataDecoder = new MetadataDecoder((PEModuleSymbol)currentFrame.ContainingModule, currentFrame); var localInfo = metadataDecoder.GetLocalInfo(localSignatureToken); var localBuilder = ArrayBuilder<LocalSymbol>.GetInstance(); var sourceAssembly = compilation.SourceAssembly; GetLocals(localBuilder, currentFrame, localNames, localInfo, methodDebugInfo.DynamicLocalMap, sourceAssembly); GetConstants(localBuilder, currentFrame, containingScopes, metadataDecoder, methodDebugInfo.DynamicLocalConstantMap, sourceAssembly); containingScopes.Free(); var locals = localBuilder.ToImmutableAndFree(); return new EvaluationContext( methodContextReuseConstraints, compilation, metadataDecoder, currentFrame, locals, inScopeHoistedLocals, methodDebugInfo); }
/// <summary> /// Create a context for evaluating expressions within a method scope. /// </summary> /// <param name="previous">Previous context, if any, for possible re-use.</param> /// <param name="metadataBlocks">Module metadata</param> /// <param name="symReader"><see cref="ISymUnmanagedReader"/> for PDB associated with <paramref name="moduleVersionId"/></param> /// <param name="moduleVersionId">Module containing method</param> /// <param name="methodToken">Method metadata token</param> /// <param name="methodVersion">Method version.</param> /// <param name="ilOffset">IL offset of instruction pointer in method</param> /// <param name="localSignatureToken">Method local signature token</param> /// <returns>Evaluation context</returns> internal static EvaluationContext CreateMethodContext( CSharpMetadataContext previous, ImmutableArray<MetadataBlock> metadataBlocks, object symReader, Guid moduleVersionId, int methodToken, int methodVersion, int ilOffset, int localSignatureToken) { Debug.Assert(MetadataTokens.Handle(methodToken).Kind == HandleKind.MethodDefinition); var typedSymReader = (ISymUnmanagedReader)symReader; var scopes = ArrayBuilder<ISymUnmanagedScope>.GetInstance(); typedSymReader.GetScopes(methodToken, methodVersion, ilOffset, IsLocalScopeEndInclusive, scopes); var scope = scopes.GetMethodScope(methodToken, methodVersion); // Re-use the previous compilation if possible. CSharpCompilation compilation; if (metadataBlocks.HaveNotChanged(previous)) { // Re-use entire context if method scope has not changed. var previousContext = previous.EvaluationContext; if ((scope != null) && (previousContext != null) && scope.Equals(previousContext.MethodScope)) { return previousContext; } compilation = previous.Compilation; } else { compilation = metadataBlocks.ToCompilation(); } var localNames = scopes.GetLocalNames(); var dynamicLocalMap = ImmutableDictionary<int, ImmutableArray<bool>>.Empty; var dynamicLocalConstantMap = ImmutableDictionary<string, ImmutableArray<bool>>.Empty; var inScopeHoistedLocalIndices = ImmutableSortedSet<int>.Empty; var groupedImportStrings = default(ImmutableArray<ImmutableArray<string>>); var externAliasStrings = default(ImmutableArray<string>); if (typedSymReader != null) { try { var cdi = typedSymReader.GetCustomDebugInfo(methodToken, methodVersion); if (cdi != null) { CustomDebugInfoReader.GetCSharpDynamicLocalInfo( cdi, methodToken, methodVersion, localNames.FirstOrDefault(), out dynamicLocalMap, out dynamicLocalConstantMap); inScopeHoistedLocalIndices = CustomDebugInfoReader.GetCSharpInScopeHoistedLocalIndices( cdi, methodToken, methodVersion, ilOffset); } groupedImportStrings = typedSymReader.GetCSharpGroupedImportStrings(methodToken, methodVersion, out externAliasStrings); } catch (InvalidOperationException) { // bad CDI, ignore } } var methodHandle = (MethodDefinitionHandle)MetadataTokens.Handle(methodToken); var currentFrame = compilation.GetMethod(moduleVersionId, methodHandle); Debug.Assert((object)currentFrame != null); var metadataDecoder = new MetadataDecoder((PEModuleSymbol)currentFrame.ContainingModule, currentFrame); var localInfo = metadataDecoder.GetLocalInfo(localSignatureToken); var localBuilder = ArrayBuilder<LocalSymbol>.GetInstance(); var sourceAssembly = compilation.SourceAssembly; GetLocals(localBuilder, currentFrame, localNames, localInfo, dynamicLocalMap, sourceAssembly); GetConstants(localBuilder, currentFrame, scopes.GetConstantSignatures(), metadataDecoder, dynamicLocalConstantMap, sourceAssembly); scopes.Free(); var locals = localBuilder.ToImmutableAndFree(); return new EvaluationContext( metadataBlocks, scope, compilation, metadataDecoder, currentFrame, locals, inScopeHoistedLocalIndices, groupedImportStrings, externAliasStrings); }
private static void GetConstants( ArrayBuilder<LocalSymbol> builder, MethodSymbol method, ImmutableArray<NamedLocalConstant> constants, MetadataDecoder metadataDecoder, ImmutableDictionary<string, ImmutableArray<bool>> dynamicLocalConstantMap, SourceAssemblySymbol containingAssembly) { foreach (var constant in constants) { var info = metadataDecoder.GetLocalInfo(constant.Signature); Debug.Assert(!info.IsByRef); Debug.Assert(!info.IsPinned); var type = info.Type; ImmutableArray<bool> dynamicFlags; if (dynamicLocalConstantMap.TryGetValue(constant.Name, out dynamicFlags)) { type = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags( type, containingAssembly, RefKind.None, dynamicFlags); } var constantValue = ReinterpretConstantValue(constant.Value, type.SpecialType); builder.Add(new EELocalConstantSymbol(method, constant.Name, type, constantValue)); } }
private static EvaluationContext CreateMethodContext( CSharpCompilation compilation, object symReader, Guid moduleVersionId, int methodToken, int methodVersion, int ilOffset, int localSignatureToken) { var methodHandle = (MethodDefinitionHandle)MetadataTokens.Handle(methodToken); var localSignatureHandle = (localSignatureToken != 0) ? (StandaloneSignatureHandle)MetadataTokens.Handle(localSignatureToken) : default(StandaloneSignatureHandle); var currentFrame = compilation.GetMethod(moduleVersionId, methodHandle); Debug.Assert((object)currentFrame != null); var sourceAssembly = compilation.SourceAssembly; var symbolProvider = new CSharpEESymbolProvider(sourceAssembly, (PEModuleSymbol)currentFrame.ContainingModule, currentFrame); var metadataDecoder = new MetadataDecoder((PEModuleSymbol)currentFrame.ContainingModule, currentFrame); var localInfo = metadataDecoder.GetLocalInfo(localSignatureHandle); var typedSymReader = (ISymUnmanagedReader3)symReader; var inScopeHoistedLocals = InScopeHoistedLocals.Empty; var debugInfo = MethodDebugInfo<TypeSymbol, LocalSymbol>.ReadMethodDebugInfo(typedSymReader, symbolProvider, methodToken, methodVersion, ilOffset, isVisualBasicMethod: false); var reuseSpan = debugInfo.ReuseSpan; var localsBuilder = ArrayBuilder<LocalSymbol>.GetInstance(); MethodDebugInfo<TypeSymbol, LocalSymbol>.GetLocals(localsBuilder, symbolProvider, debugInfo.LocalVariableNames, localInfo, debugInfo.DynamicLocalMap); if (!debugInfo.HoistedLocalScopeRecords.IsDefaultOrEmpty) { inScopeHoistedLocals = new CSharpInScopeHoistedLocals(debugInfo.GetInScopeHoistedLocalIndices(ilOffset, ref reuseSpan)); } localsBuilder.AddRange(debugInfo.LocalConstants); return new EvaluationContext( new MethodContextReuseConstraints(moduleVersionId, methodToken, methodVersion, reuseSpan), compilation, currentFrame, localsBuilder.ToImmutableAndFree(), inScopeHoistedLocals, debugInfo); }