public async Task <object?> ProcessAsync(IWorkSession session, IList <Diagnostic> diagnostics, CancellationToken cancellationToken) { PerformanceLog.Checkpoint("SlowUpdate.ProcessAsync.Start"); var targetName = GetAndEnsureTargetName(session); if (targetName == TargetNames.Ast || targetName == TargetNames.Explain) { var astTarget = _astTargets[session.LanguageName]; var ast = await astTarget.GetAstAsync(session, cancellationToken).ConfigureAwait(false); if (targetName == TargetNames.Explain) { return(await _explainer.ExplainAsync(ast, session, cancellationToken).ConfigureAwait(false)); } return(ast); } if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error)) { return(null); } if (targetName == LanguageNames.VisualBasic) { return(VisualBasicNotAvailable); } if (targetName != TargetNames.Run && targetName != TargetNames.Verify && !_decompilers.ContainsKey(targetName)) { throw new NotSupportedException($"Target '{targetName}' is not (yet?) supported by this branch."); } MemoryStream?assemblyStream = null; MemoryStream?symbolStream = null; try { assemblyStream = _memoryStreamManager.GetStream(); if (targetName == TargetNames.Run || targetName == TargetNames.IL) { symbolStream = _memoryStreamManager.GetStream(); } var compiled = await _compiler.TryCompileToStreamAsync(assemblyStream, symbolStream, session, diagnostics, cancellationToken).ConfigureAwait(false); if (!compiled.assembly) { assemblyStream.Dispose(); symbolStream?.Dispose(); return(null); } if (targetName == TargetNames.Verify) { assemblyStream.Dispose(); symbolStream?.Dispose(); return("✔️ Compilation completed."); } assemblyStream.Seek(0, SeekOrigin.Begin); symbolStream?.Seek(0, SeekOrigin.Begin); var streams = new CompilationStreamPair(assemblyStream, compiled.symbols ? symbolStream : null); if (targetName == TargetNames.Run) { return(_executor.Execute(streams, session)); } // it's fine not to Dispose() here -- MirrorSharp will dispose it after calling WriteResult() return(streams); } catch { assemblyStream?.Dispose(); symbolStream?.Dispose(); throw; } }
public async Task <object?> ProcessAsync(IWorkSession session, IList <Diagnostic> diagnostics, CancellationToken cancellationToken) { PerformanceLog.Checkpoint("SlowUpdate.ProcessAsync.Start"); var targetName = GetAndEnsureTargetName(session); _topLevelProgramSupport.UpdateOutputKind(session, diagnostics); if (targetName is TargetNames.Ast or TargetNames.Explain) { var astTarget = _astTargets[session.LanguageName]; var ast = await astTarget.GetAstAsync(session, cancellationToken).ConfigureAwait(false); if (targetName == TargetNames.Explain) { return(await _explainer.ExplainAsync(ast, session, cancellationToken).ConfigureAwait(false)); } return(ast); } if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error)) { return(null); } if (targetName == LanguageNames.VisualBasic) { return(VisualBasicNotAvailable); } if (targetName is not(TargetNames.Run or TargetNames.Verify) && !_decompilers.ContainsKey(targetName)) { throw new NotSupportedException($"Target '{targetName}' is not (yet?) supported by this branch."); } MemoryStream?assemblyStream = null; MemoryStream?symbolStream = null; try { assemblyStream = _memoryStreamManager.GetStream(); if (targetName is TargetNames.Run or TargetNames.IL) { symbolStream = _memoryStreamManager.GetStream(); } var compilationStopwatch = session.ShouldReportPerformance() ? Stopwatch.StartNew() : null; var compiled = await _compiler.TryCompileToStreamAsync(assemblyStream, symbolStream, session, diagnostics, cancellationToken).ConfigureAwait(false); compilationStopwatch?.Stop(); if (!compiled.assembly) { assemblyStream.Dispose(); symbolStream?.Dispose(); return(null); } if (targetName == TargetNames.Verify) { assemblyStream.Dispose(); symbolStream?.Dispose(); return("✔️ Compilation completed."); } assemblyStream.Seek(0, SeekOrigin.Begin); symbolStream?.Seek(0, SeekOrigin.Begin); AssemblyLog.Log("1.Compiled", assemblyStream, compiled.symbols ? symbolStream : null); var streams = new CompilationStreamPair(assemblyStream, compiled.symbols ? symbolStream : null); if (targetName == TargetNames.Run) { if (!session.HasContainerExperimentFailed()) { try { var output = await _containerExecutor.ExecuteAsync(streams, session, cancellationToken); if (compilationStopwatch != null) { // TODO: Prettify output += $"\n COMPILATION: {compilationStopwatch.ElapsedMilliseconds,15}ms"; } streams.Dispose(); _monitor.Metric(ContainerExperimentMetrics.ContainerRunCount, 1); return(output); } catch (Exception ex) { _monitor.Metric(ContainerExperimentMetrics.ContainerFailureCount, 1); _monitor.Exception(ex, session); session.SetContainerExperimentException(ex); assemblyStream.Seek(0, SeekOrigin.Begin); symbolStream?.Seek(0, SeekOrigin.Begin); } } _monitor.Metric(ContainerExperimentMetrics.LegacyRunCount, 1); return(_executor.Execute(streams, session)); } // it's fine not to Dispose() here -- MirrorSharp will dispose it after calling WriteResult() return(streams); } catch { assemblyStream?.Dispose(); symbolStream?.Dispose(); throw; } }