DbgLanguageDebugInfo CreateDebugInfo(IDbgDotNetCodeLocation location, CancellationToken cancellationToken) { const DbgLoadModuleOptions options = DbgLoadModuleOptions.AutoLoaded; ModuleDef mdModule; if (location.DbgModule is DbgModule dbgModule) { mdModule = dbgMetadataService.TryGetMetadata(dbgModule, options); } else { mdModule = dbgMetadataService.TryGetMetadata(location.Module, options); } Debug.Assert(mdModule != null); if (mdModule == null) { return(null); } cancellationToken.ThrowIfCancellationRequested(); var method = mdModule.ResolveToken(location.Token) as MethodDef; Debug.Assert(method != null); if (method == null) { return(null); } var context = new DecompilationContext { CancellationToken = cancellationToken, CalculateBinSpans = true, }; var output = DecompilerOutputImplCache.Alloc(); output.Initialize(method.MDToken.Raw); //TODO: Whenever the decompiler options change, we need to invalidate our cache and every // single DbgLanguageDebugInfo instance. decompiler.Decompile(method, output, context); var methodDebugInfo = output.TryGetMethodDebugInfo(); DecompilerOutputImplCache.Free(ref output); cancellationToken.ThrowIfCancellationRequested(); Debug.Assert(methodDebugInfo != null); if (methodDebugInfo == null) { return(null); } // We don't support EnC so the version is always 1 const int methodVersion = 1; return(new DbgLanguageDebugInfo(methodDebugInfo, methodVersion, location.Offset)); }
DbgLanguageDebugInfo CreateDebugInfo(DbgEvaluationContext context, IDbgDotNetCodeLocation location, CancellationToken cancellationToken) { const DbgLoadModuleOptions options = DbgLoadModuleOptions.AutoLoaded; ModuleDef mdModule; if (location.DbgModule is DbgModule dbgModule) { mdModule = dbgMetadataService.TryGetMetadata(dbgModule, options); } else { dbgModule = null; mdModule = dbgMetadataService.TryGetMetadata(location.Module, options); } Debug.Assert(mdModule != null); if (mdModule == null) { return(null); } cancellationToken.ThrowIfCancellationRequested(); var method = mdModule.ResolveToken(location.Token) as MethodDef; // Could be null if it's a dynamic assembly. It will get refreshed later and we'll get called again. if (method == null) { return(null); } var runtime = context.Runtime.GetDotNetRuntime(); int methodToken, localVarSigTok; if (dbgModule == null || !runtime.TryGetMethodToken(dbgModule, method.MDToken.ToInt32(), out methodToken, out localVarSigTok)) { methodToken = method.MDToken.ToInt32(); localVarSigTok = (int)(method.Body?.LocalVarSigTok ?? 0); } var decContext = new DecompilationContext { CancellationToken = cancellationToken, CalculateBinSpans = true, }; var output = DecompilerOutputImplCache.Alloc(); output.Initialize(method.MDToken.Raw); //TODO: Whenever the decompiler options change, we need to invalidate our cache and every // single DbgLanguageDebugInfo instance. decompiler.Decompile(method, output, decContext); var methodDebugInfo = output.TryGetMethodDebugInfo(); DecompilerOutputImplCache.Free(ref output); cancellationToken.ThrowIfCancellationRequested(); Debug.Assert(methodDebugInfo != null); if (methodDebugInfo == null) { return(null); } // We don't support EnC so the version is always 1 const int methodVersion = 1; return(new DbgLanguageDebugInfo(methodDebugInfo, methodToken, localVarSigTok, methodVersion, location.Offset)); }