diff --git a/Src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs b/Src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs index 5b7fb8ddf0f421fb33ce9a35892c6287f2c1d808..8085a9c1ee0e93db5dab5316123c761ed3135ffa 100644 --- a/Src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs +++ b/Src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs @@ -2348,6 +2348,7 @@ internal override FunctionId EmitFunctionId // testData is only passed when running tests. if (testData != null) { + testData.Compilation = this; moduleBeingBuilt.SetMethodTestData(testData.Methods); testData.Module = moduleBeingBuilt; } diff --git a/Src/Compilers/CSharp/Portable/Emitter/EditAndContinue/EmitHelpers.cs b/Src/Compilers/CSharp/Portable/Emitter/EditAndContinue/EmitHelpers.cs index 767bb55a87a054bb2cf2b57dfd4d8afe285d4990..c4858050a41fcb57ae3ca8554200f8283404a5ad 100644 --- a/Src/Compilers/CSharp/Portable/Emitter/EditAndContinue/EmitHelpers.cs +++ b/Src/Compilers/CSharp/Portable/Emitter/EditAndContinue/EmitHelpers.cs @@ -54,6 +54,7 @@ internal static class EmitHelpers if (testData != null) { + testData.Compilation = compilation; moduleBeingBuilt.SetMethodTestData(testData.Methods); testData.Module = moduleBeingBuilt; } diff --git a/Src/Compilers/Core/Portable/CodeGen/CompilationTestData.cs b/Src/Compilers/Core/Portable/CodeGen/CompilationTestData.cs index 2495c9857fc0f1d17ec26ffe1d0d49bb8e0febc9..c9a27d06cae626d8de4bb57c1663f8d0867392fb 100644 --- a/Src/Compilers/Core/Portable/CodeGen/CompilationTestData.cs +++ b/Src/Compilers/Core/Portable/CodeGen/CompilationTestData.cs @@ -19,6 +19,10 @@ public MethodData(ILBuilder ilBuilder, IMethodSymbol method) } } + // ILBuilder requires that Symbols still be alive when visualizing tokens from the IL stream. + // We'll hold on to a reference here. + public Compilation Compilation; + // The map is used for storing a list of methods and their associated IL. // The key is a formatted qualified method name, e.g. Namespace.Class.m public readonly ConcurrentDictionary Methods = new ConcurrentDictionary(); @@ -27,5 +31,13 @@ public MethodData(ILBuilder ilBuilder, IMethodSymbol method) public Cci.IModule Module; public Func SymWriterFactory; + + public void Reset() + { + this.Compilation = null; + this.Methods.Clear(); + this.Module = null; + this.SymWriterFactory = null; + } } } diff --git a/Src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb b/Src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb index 93077fc22340dbdd6ea04139c0c730184b09e8a0..25f8d762e604a136961e626bcd3a5c9c8c07dd80 100644 --- a/Src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb +++ b/Src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb @@ -2174,6 +2174,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End If If testData IsNot Nothing Then + testData.Compilation = Me moduleBeingBuilt.SetMethodTestData(testData.Methods) testData.Module = moduleBeingBuilt End If diff --git a/Src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/EmitHelpers.vb b/Src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/EmitHelpers.vb index acca17e2957c6bccc8fae6ffade6d5715ec239be..ff1920aa27f4e074b6dbceef221b1c1464dddb22 100644 --- a/Src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/EmitHelpers.vb +++ b/Src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/EmitHelpers.vb @@ -46,6 +46,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit edits:=edits) If testData IsNot Nothing Then + testData.Compilation = compilation moduleBeingBuilt.SetMethodTestData(testData.Methods) testData.Module = moduleBeingBuilt End If diff --git a/Src/Test/Utilities/HostedRuntimeEnvironment.cs b/Src/Test/Utilities/HostedRuntimeEnvironment.cs index aacfcd99a473f54a6618fbe0ee2510743a92f4ec..ab05157a6bb869cc4b19ca274593c876b5525e43 100644 --- a/Src/Test/Utilities/HostedRuntimeEnvironment.cs +++ b/Src/Test/Utilities/HostedRuntimeEnvironment.cs @@ -220,7 +220,7 @@ public void Emit(Compilation mainCompilation, IEnumerable m var diagnostics = DiagnosticBag.GetInstance(); var dependencies = new List(); - testData.Methods.Clear(); + testData.Reset(); ImmutableArray mainImage, mainPdb; bool succeeded = EmitCompilation(mainCompilation, manifestResources, dependencies, diagnostics, testData, out mainImage, out mainPdb); @@ -409,6 +409,7 @@ void IDisposable.Dispose() internal CompilationTestData GetCompilationTestData() { + Debug.Assert(testData.Compilation != null, "If CompilationTestData does not have a pointer to the compilation that initialized it, then AVs may result when attempting to access Symbols during IL visualization."); if (testData.Module == null) { throw new InvalidOperationException("You must call Emit before calling GetCompilationTestData.");